1
0
json/test.cpp
2025-07-31 22:24:41 -05:00

179 lines
5.2 KiB
C++

#include "json.hpp"
#include <iostream>
#include <cassert>
void test_basic_types() {
JsonParser parser;
// Test null
auto null_val = parser.parse("null");
assert(null_val.is<JsonParser::JsonNull>());
// Test boolean
auto true_val = parser.parse("true");
assert(true_val.is<JsonParser::JsonBool>() && true_val.as<JsonParser::JsonBool>() == true);
auto false_val = parser.parse("false");
assert(false_val.is<JsonParser::JsonBool>() && false_val.as<JsonParser::JsonBool>() == false);
// Test numbers
auto int_val = parser.parse("42");
assert(int_val.is<JsonParser::JsonNumber>() && int_val.as<JsonParser::JsonNumber>() == 42.0);
auto float_val = parser.parse("3.14159");
assert(float_val.is<JsonParser::JsonNumber>() && abs(float_val.as<JsonParser::JsonNumber>() - 3.14159) < 0.00001);
auto neg_val = parser.parse("-123.45");
assert(neg_val.is<JsonParser::JsonNumber>() && neg_val.as<JsonParser::JsonNumber>() == -123.45);
auto exp_val = parser.parse("1.5e3");
assert(exp_val.is<JsonParser::JsonNumber>() && exp_val.as<JsonParser::JsonNumber>() == 1500.0);
// Test string
auto str_val = parser.parse("\"hello world\"");
assert(str_val.is<JsonParser::JsonString>() && str_val.as<JsonParser::JsonString>() == "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<JsonParser::JsonString>());
assert(escaped.as<JsonParser::JsonString>() == "line1\nline2\ttab\"quote\\backslash");
auto unicode = parser.parse("\"\\u0048\\u0065\\u006c\\u006c\\u006f\"");
assert(unicode.is<JsonParser::JsonString>());
assert(unicode.as<JsonParser::JsonString>() == "Hello");
std::cout << "✓ String escapes test passed\n";
}
void test_arrays() {
JsonParser parser;
// Empty array
auto empty_arr = parser.parse("[]");
assert(empty_arr.is<JsonParser::JsonArray>());
assert(empty_arr.as<JsonParser::JsonArray>().empty());
// Mixed array
auto mixed_arr = parser.parse("[1, \"hello\", true, null, [2, 3]]");
assert(mixed_arr.is<JsonParser::JsonArray>());
const auto& arr = mixed_arr.as<JsonParser::JsonArray>();
assert(arr.size() == 5);
assert(arr[0].is<JsonParser::JsonNumber>() && arr[0].as<JsonParser::JsonNumber>() == 1.0);
assert(arr[1].is<JsonParser::JsonString>() && arr[1].as<JsonParser::JsonString>() == "hello");
assert(arr[2].is<JsonParser::JsonBool>() && arr[2].as<JsonParser::JsonBool>() == true);
assert(arr[3].is<JsonParser::JsonNull>());
assert(arr[4].is<JsonParser::JsonArray>());
std::cout << "✓ Arrays test passed\n";
}
void test_objects() {
JsonParser parser;
// Empty object
auto empty_obj = parser.parse("{}");
assert(empty_obj.is<JsonParser::JsonObject>());
assert(empty_obj.as<JsonParser::JsonObject>().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<JsonParser::JsonObject>());
const auto& obj = complex_obj.as<JsonParser::JsonObject>();
assert(obj.at("name").as<JsonParser::JsonString>() == "John Doe");
assert(obj.at("age").as<JsonParser::JsonNumber>() == 30.0);
assert(obj.at("is_active").as<JsonParser::JsonBool>() == true);
assert(obj.at("spouse").is<JsonParser::JsonNull>());
const auto& scores = obj.at("scores").as<JsonParser::JsonArray>();
assert(scores.size() == 3);
assert(scores[0].as<JsonParser::JsonNumber>() == 85.0);
const auto& address = obj.at("address").as<JsonParser::JsonObject>();
assert(address.at("street").as<JsonParser::JsonString>() == "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<JsonParser::JsonObject>());
const auto& obj = file_json.as<JsonParser::JsonObject>();
// Verify some expected content
assert(obj.at("library").as<JsonParser::JsonString>() == "fast-json-parser");
assert(obj.at("version").as<JsonParser::JsonString>() == "1.0.0");
const auto& features = obj.at("features").as<JsonParser::JsonArray>();
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<std::string> 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;
}