#include #include #include "utils/simple_json.h" namespace rk3588 { namespace { TEST(SimpleJsonTest, ParseNull) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("null", v, err)); EXPECT_TRUE(v.IsNull()); } TEST(SimpleJsonTest, ParseBoolTrue) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("true", v, err)); EXPECT_TRUE(v.IsBool()); EXPECT_TRUE(v.AsBool()); } TEST(SimpleJsonTest, ParseBoolFalse) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("false", v, err)); EXPECT_TRUE(v.IsBool()); EXPECT_FALSE(v.AsBool()); } TEST(SimpleJsonTest, ParseInteger) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("42", v, err)); EXPECT_TRUE(v.IsNumber()); EXPECT_EQ(v.AsNumber(), 42.0); EXPECT_EQ(v.AsInt(), 42); } TEST(SimpleJsonTest, ParseNegativeNumber) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("-123", v, err)); EXPECT_TRUE(v.IsNumber()); EXPECT_EQ(v.AsInt(), -123); } TEST(SimpleJsonTest, ParseFloat) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("3.14159", v, err)); EXPECT_TRUE(v.IsNumber()); EXPECT_NEAR(v.AsNumber(), 3.14159, 0.00001); } TEST(SimpleJsonTest, ParseScientific) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("1.5e10", v, err)); EXPECT_TRUE(v.IsNumber()); EXPECT_NEAR(v.AsNumber(), 1.5e10, 1e6); } TEST(SimpleJsonTest, ParseString) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("\"hello world\"", v, err)); EXPECT_TRUE(v.IsString()); EXPECT_EQ(v.AsString(), "hello world"); } TEST(SimpleJsonTest, ParseStringEscapes) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("\"line1\\nline2\\ttab\\\\slash\\\"quote\"", v, err)); EXPECT_TRUE(v.IsString()); EXPECT_EQ(v.AsString(), "line1\nline2\ttab\\slash\"quote"); } TEST(SimpleJsonTest, ParseEmptyArray) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("[]", v, err)); EXPECT_TRUE(v.IsArray()); EXPECT_TRUE(v.AsArray().empty()); } TEST(SimpleJsonTest, ParseArray) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("[1, 2, 3]", v, err)); EXPECT_TRUE(v.IsArray()); EXPECT_EQ(v.AsArray().size(), 3u); EXPECT_EQ(v.AsArray()[0].AsInt(), 1); EXPECT_EQ(v.AsArray()[1].AsInt(), 2); EXPECT_EQ(v.AsArray()[2].AsInt(), 3); } TEST(SimpleJsonTest, ParseMixedArray) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("[1, \"two\", true, null]", v, err)); EXPECT_TRUE(v.IsArray()); EXPECT_EQ(v.AsArray().size(), 4u); EXPECT_TRUE(v.AsArray()[0].IsNumber()); EXPECT_TRUE(v.AsArray()[1].IsString()); EXPECT_TRUE(v.AsArray()[2].IsBool()); EXPECT_TRUE(v.AsArray()[3].IsNull()); } TEST(SimpleJsonTest, ParseEmptyObject) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("{}", v, err)); EXPECT_TRUE(v.IsObject()); EXPECT_TRUE(v.AsObject().empty()); } TEST(SimpleJsonTest, ParseObject) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(R"({"name": "test", "value": 42})", v, err)); EXPECT_TRUE(v.IsObject()); EXPECT_EQ(v.AsObject().size(), 2u); EXPECT_EQ(v.ValueOr("name", ""), "test"); EXPECT_EQ(v.ValueOr("value", 0), 42); } TEST(SimpleJsonTest, ParseNestedObject) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(R"({"outer": {"inner": "value"}})", v, err)); EXPECT_TRUE(v.IsObject()); const SimpleJson* outer = v.Find("outer"); ASSERT_NE(outer, nullptr); EXPECT_TRUE(outer->IsObject()); EXPECT_EQ(outer->ValueOr("inner", ""), "value"); } TEST(SimpleJsonTest, ParseNestedArray) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("[[1, 2], [3, 4]]", v, err)); EXPECT_TRUE(v.IsArray()); EXPECT_EQ(v.AsArray().size(), 2u); EXPECT_EQ(v.AsArray()[0].AsArray().size(), 2u); EXPECT_EQ(v.AsArray()[0].AsArray()[0].AsInt(), 1); } TEST(SimpleJsonTest, FindNonExistent) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(R"({"a": 1})", v, err)); EXPECT_EQ(v.Find("b"), nullptr); } TEST(SimpleJsonTest, ValueOrDefaults) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(R"({"a": 1})", v, err)); EXPECT_EQ(v.ValueOr("a", 0), 1); EXPECT_EQ(v.ValueOr("b", 99), 99); EXPECT_EQ(v.ValueOr("c", "default"), "default"); EXPECT_EQ(v.ValueOr("d", true), true); } TEST(SimpleJsonTest, StringToBoolCoercion) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(R"({"a": "true", "b": "false", "c": "yes", "d": "no"})", v, err)); EXPECT_TRUE(v.ValueOr("a", false)); EXPECT_FALSE(v.ValueOr("b", true)); EXPECT_TRUE(v.ValueOr("c", false)); EXPECT_FALSE(v.ValueOr("d", true)); } TEST(SimpleJsonTest, StringToNumberCoercion) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(R"({"a": "42", "b": "3.14", "c": "not a number"})", v, err)); EXPECT_EQ(v.ValueOr("a", 0), 42); EXPECT_NEAR(v.ValueOr("b", 0.0), 3.14, 0.001); EXPECT_EQ(v.ValueOr("c", -1.0), -1.0); // returns default } TEST(SimpleJsonTest, ParseError_UnterminatedString) { SimpleJson v; std::string err; EXPECT_FALSE(ParseSimpleJson("\"unterminated", v, err)); EXPECT_FALSE(err.empty()); } TEST(SimpleJsonTest, ParseError_UnterminatedArray) { SimpleJson v; std::string err; EXPECT_FALSE(ParseSimpleJson("[1, 2, 3", v, err)); EXPECT_FALSE(err.empty()); } TEST(SimpleJsonTest, ParseError_UnterminatedObject) { SimpleJson v; std::string err; EXPECT_FALSE(ParseSimpleJson("{\"a\": 1", v, err)); EXPECT_FALSE(err.empty()); } TEST(SimpleJsonTest, ParseError_TrailingContent) { SimpleJson v; std::string err; EXPECT_FALSE(ParseSimpleJson("{\"a\": 1} extra", v, err)); EXPECT_FALSE(err.empty()); } TEST(SimpleJsonTest, ParseError_InvalidValue) { SimpleJson v; std::string err; EXPECT_FALSE(ParseSimpleJson("undefined", v, err)); EXPECT_FALSE(err.empty()); } TEST(SimpleJsonTest, ParseError_MissingColon) { SimpleJson v; std::string err; EXPECT_FALSE(ParseSimpleJson("{\"a\" 1}", v, err)); EXPECT_FALSE(err.empty()); } TEST(SimpleJsonTest, ParseWhitespace) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(" \n\t { \"a\" : 1 } \n ", v, err)); EXPECT_TRUE(v.IsObject()); EXPECT_EQ(v.ValueOr("a", 0), 1); } TEST(SimpleJsonTest, ComplexDocument) { const char* json = R"({ "name": "test_config", "version": 1.5, "enabled": true, "settings": { "timeout": 30, "retries": 3 }, "items": [ {"id": 1, "name": "first"}, {"id": 2, "name": "second"} ], "tags": ["a", "b", "c"] })"; SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson(json, v, err)); EXPECT_TRUE(v.IsObject()); EXPECT_EQ(v.ValueOr("name", ""), "test_config"); EXPECT_NEAR(v.ValueOr("version", 0.0), 1.5, 0.01); EXPECT_TRUE(v.ValueOr("enabled", false)); const SimpleJson* settings = v.Find("settings"); ASSERT_NE(settings, nullptr); EXPECT_EQ(settings->ValueOr("timeout", 0), 30); EXPECT_EQ(settings->ValueOr("retries", 0), 3); const SimpleJson* items = v.Find("items"); ASSERT_NE(items, nullptr); EXPECT_EQ(items->AsArray().size(), 2u); EXPECT_EQ(items->AsArray()[0].ValueOr("id", 0), 1); EXPECT_EQ(items->AsArray()[1].ValueOr("name", ""), "second"); const SimpleJson* tags = v.Find("tags"); ASSERT_NE(tags, nullptr); EXPECT_EQ(tags->AsArray().size(), 3u); } TEST(SimpleJsonTest, AsArrayOnNonArray) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("42", v, err)); // Should return empty array reference EXPECT_TRUE(v.AsArray().empty()); } TEST(SimpleJsonTest, AsObjectOnNonObject) { SimpleJson v; std::string err; EXPECT_TRUE(ParseSimpleJson("[1,2,3]", v, err)); // Should return empty object reference EXPECT_TRUE(v.AsObject().empty()); } TEST(SimpleJsonTest, ConstructFromValues) { SimpleJson null_val(nullptr); EXPECT_TRUE(null_val.IsNull()); SimpleJson bool_val(true); EXPECT_TRUE(bool_val.IsBool()); EXPECT_TRUE(bool_val.AsBool()); SimpleJson num_val(42.0); EXPECT_TRUE(num_val.IsNumber()); EXPECT_EQ(num_val.AsNumber(), 42.0); SimpleJson str_val(std::string("hello")); EXPECT_TRUE(str_val.IsString()); EXPECT_EQ(str_val.AsString(), "hello"); } } // namespace } // namespace rk3588