314 lines
8.7 KiB
C++
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
|