OrangePi3588Media/tests/test_simple_json.cpp

314 lines
8.7 KiB
C++

#include <gtest/gtest.h>
#include <string>
#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<std::string>("name", ""), "test");
EXPECT_EQ(v.ValueOr<int>("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<std::string>("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<int>("a", 0), 1);
EXPECT_EQ(v.ValueOr<int>("b", 99), 99);
EXPECT_EQ(v.ValueOr<std::string>("c", "default"), "default");
EXPECT_EQ(v.ValueOr<bool>("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<bool>("a", false));
EXPECT_FALSE(v.ValueOr<bool>("b", true));
EXPECT_TRUE(v.ValueOr<bool>("c", false));
EXPECT_FALSE(v.ValueOr<bool>("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<int>("a", 0), 42);
EXPECT_NEAR(v.ValueOr<double>("b", 0.0), 3.14, 0.001);
EXPECT_EQ(v.ValueOr<double>("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<int>("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<std::string>("name", ""), "test_config");
EXPECT_NEAR(v.ValueOr<double>("version", 0.0), 1.5, 0.01);
EXPECT_TRUE(v.ValueOr<bool>("enabled", false));
const SimpleJson* settings = v.Find("settings");
ASSERT_NE(settings, nullptr);
EXPECT_EQ(settings->ValueOr<int>("timeout", 0), 30);
EXPECT_EQ(settings->ValueOr<int>("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<int>("id", 0), 1);
EXPECT_EQ(items->AsArray()[1].ValueOr<std::string>("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