#include "json.hpp" #include #include void test_basic_types() { JsonParser parser; // Test null auto null_val = parser.parse("null"); assert(null_val.is()); // Test boolean auto true_val = parser.parse("true"); assert(true_val.is() && true_val.as() == true); auto false_val = parser.parse("false"); assert(false_val.is() && false_val.as() == false); // Test numbers auto int_val = parser.parse("42"); assert(int_val.is() && int_val.as() == 42.0); auto float_val = parser.parse("3.14159"); assert(float_val.is() && abs(float_val.as() - 3.14159) < 0.00001); auto neg_val = parser.parse("-123.45"); assert(neg_val.is() && neg_val.as() == -123.45); auto exp_val = parser.parse("1.5e3"); assert(exp_val.is() && exp_val.as() == 1500.0); // Test string auto str_val = parser.parse("\"hello world\""); assert(str_val.is() && str_val.as() == "hello world"); std::cout << "✓ Basic types test passed\n"; } void test_string_escapes() { JsonParser parser; auto escaped = parser.parse("\"line1\\nline2\\ttab\\\"quote\\\\backslash\""); assert(escaped.is()); assert(escaped.as() == "line1\nline2\ttab\"quote\\backslash"); auto unicode = parser.parse("\"\\u0048\\u0065\\u006c\\u006c\\u006f\""); assert(unicode.is()); assert(unicode.as() == "Hello"); std::cout << "✓ String escapes test passed\n"; } void test_arrays() { JsonParser parser; // Empty array auto empty_arr = parser.parse("[]"); assert(empty_arr.is()); assert(empty_arr.as().empty()); // Mixed array auto mixed_arr = parser.parse("[1, \"hello\", true, null, [2, 3]]"); assert(mixed_arr.is()); const auto& arr = mixed_arr.as(); assert(arr.size() == 5); assert(arr[0].is() && arr[0].as() == 1.0); assert(arr[1].is() && arr[1].as() == "hello"); assert(arr[2].is() && arr[2].as() == true); assert(arr[3].is()); assert(arr[4].is()); std::cout << "✓ Arrays test passed\n"; } void test_objects() { JsonParser parser; // Empty object auto empty_obj = parser.parse("{}"); assert(empty_obj.is()); assert(empty_obj.as().empty()); // Complex object auto complex_obj = parser.parse(R"({ "name": "John Doe", "age": 30, "is_active": true, "scores": [85, 90, 78], "address": { "street": "123 Main St", "city": "Anytown" }, "spouse": null })"); assert(complex_obj.is()); const auto& obj = complex_obj.as(); assert(obj.at("name").as() == "John Doe"); assert(obj.at("age").as() == 30.0); assert(obj.at("is_active").as() == true); assert(obj.at("spouse").is()); const auto& scores = obj.at("scores").as(); assert(scores.size() == 3); assert(scores[0].as() == 85.0); const auto& address = obj.at("address").as(); assert(address.at("street").as() == "123 Main St"); std::cout << "✓ Objects test passed\n"; } void test_file_parsing() { JsonParser parser; try { auto file_json = parser.parse_file("test.json"); assert(file_json.is()); const auto& obj = file_json.as(); // Verify some expected content assert(obj.at("library").as() == "fast-json-parser"); assert(obj.at("version").as() == "1.0.0"); const auto& features = obj.at("features").as(); assert(features.size() > 0); std::cout << "✓ File parsing test passed\n"; } catch (const std::exception& e) { std::cerr << "File parsing test failed: " << e.what() << "\n"; } } void test_error_cases() { JsonParser parser; // Test various malformed JSON std::vector invalid_json = { "", "{", "}", "[1,]", "{\"key\":}", "\"unterminated string", "123.45.67", "truee", "nul", "{\"key\" \"value\"}", // missing colon "[1 2 3]" // missing commas }; size_t error_count = 0; for (const auto& json : invalid_json) { try { parser.parse(json); std::cerr << "Expected error for: " << json << "\n"; } catch (const std::exception&) { error_count++; } } assert(error_count == invalid_json.size()); std::cout << "✓ Error handling test passed (" << error_count << " errors caught)\n"; } int main() { std::cout << "Running JSON parser tests...\n\n"; test_basic_types(); test_string_escapes(); test_arrays(); test_objects(); test_file_parsing(); test_error_cases(); std::cout << "\n"; return 0; }