diff options
Diffstat (limited to '3rdparty/rapidjson/test/unittest/valuetest.cpp')
-rw-r--r-- | 3rdparty/rapidjson/test/unittest/valuetest.cpp | 370 |
1 files changed, 321 insertions, 49 deletions
diff --git a/3rdparty/rapidjson/test/unittest/valuetest.cpp b/3rdparty/rapidjson/test/unittest/valuetest.cpp index 5e88a77e3a3..d6c7492deae 100644 --- a/3rdparty/rapidjson/test/unittest/valuetest.cpp +++ b/3rdparty/rapidjson/test/unittest/valuetest.cpp @@ -23,6 +23,18 @@ RAPIDJSON_DIAG_OFF(c++98-compat) using namespace rapidjson; +TEST(Value, Size) { + if (sizeof(SizeType) == 4) { +#if RAPIDJSON_48BITPOINTER_OPTIMIZATION + EXPECT_EQ(16, sizeof(Value)); +#elif RAPIDJSON_64BIT + EXPECT_EQ(24, sizeof(Value)); +#else + EXPECT_EQ(16, sizeof(Value)); +#endif + } +} + TEST(Value, DefaultConstructor) { Value x; EXPECT_EQ(kNullType, x.GetType()); @@ -335,6 +347,12 @@ TEST(Value, True) { Value z; z.SetBool(true); EXPECT_TRUE(z.IsTrue()); + + // Templated functions + EXPECT_TRUE(z.Is<bool>()); + EXPECT_TRUE(z.Get<bool>()); + EXPECT_FALSE(z.Set<bool>(false).Get<bool>()); + EXPECT_TRUE(z.Set(true).Get<bool>()); } TEST(Value, False) { @@ -414,6 +432,12 @@ TEST(Value, Int) { // operator=(int) z = 5678; EXPECT_EQ(5678, z.GetInt()); + + // Templated functions + EXPECT_TRUE(z.Is<int>()); + EXPECT_EQ(5678, z.Get<int>()); + EXPECT_EQ(5679, z.Set(5679).Get<int>()); + EXPECT_EQ(5680, z.Set<int>(5680).Get<int>()); } TEST(Value, Uint) { @@ -453,6 +477,12 @@ TEST(Value, Uint) { EXPECT_EQ(2147483648u, z.GetUint()); EXPECT_FALSE(z.IsInt()); EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types + + // Templated functions + EXPECT_TRUE(z.Is<unsigned>()); + EXPECT_EQ(2147483648u, z.Get<unsigned>()); + EXPECT_EQ(2147483649u, z.Set(2147483649u).Get<unsigned>()); + EXPECT_EQ(2147483650u, z.Set<unsigned>(2147483650u).Get<unsigned>()); } TEST(Value, Int64) { @@ -505,8 +535,15 @@ TEST(Value, Int64) { EXPECT_FALSE(z.IsInt()); EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0); - z.SetInt64(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000))); + int64_t i = static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000)); + z.SetInt64(i); EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble()); + + // Templated functions + EXPECT_TRUE(z.Is<int64_t>()); + EXPECT_EQ(i, z.Get<int64_t>()); + EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>()); + EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>()); } TEST(Value, Uint64) { @@ -547,10 +584,17 @@ TEST(Value, Uint64) { EXPECT_FALSE(z.IsUint()); EXPECT_TRUE(z.IsInt64()); - z.SetUint64(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)); // 2^63 cannot cast as int64 + uint64_t u = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000); + z.SetUint64(u); // 2^63 cannot cast as int64 EXPECT_FALSE(z.IsInt64()); - EXPECT_EQ(RAPIDJSON_UINT64_C2(0x80000000, 0x00000000), z.GetUint64()); // Issue 48 + EXPECT_EQ(u, z.GetUint64()); // Issue 48 EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble()); + + // Templated functions + EXPECT_TRUE(z.Is<uint64_t>()); + EXPECT_EQ(u, z.Get<uint64_t>()); + EXPECT_EQ(u + 1, z.Set(u + 1).Get<uint64_t>()); + EXPECT_EQ(u + 2, z.Set<uint64_t>(u + 2).Get<uint64_t>()); } TEST(Value, Double) { @@ -577,6 +621,12 @@ TEST(Value, Double) { z = 56.78; EXPECT_NEAR(56.78, z.GetDouble(), 0.0); + + // Templated functions + EXPECT_TRUE(z.Is<double>()); + EXPECT_EQ(56.78, z.Get<double>()); + EXPECT_EQ(57.78, z.Set(57.78).Get<double>()); + EXPECT_EQ(58.78, z.Set<double>(58.78).Get<double>()); } TEST(Value, Float) { @@ -602,18 +652,30 @@ TEST(Value, Float) { z.SetFloat(12.34f); EXPECT_NEAR(12.34f, z.GetFloat(), 0.0f); + // Issue 573 + z.SetInt(0); + EXPECT_EQ(0.0f, z.GetFloat()); + z = 56.78f; EXPECT_NEAR(56.78f, z.GetFloat(), 0.0f); + + // Templated functions + EXPECT_TRUE(z.Is<float>()); + EXPECT_EQ(56.78f, z.Get<float>()); + EXPECT_EQ(57.78f, z.Set(57.78f).Get<float>()); + EXPECT_EQ(58.78f, z.Set<float>(58.78f).Get<float>()); } TEST(Value, IsLosslessDouble) { EXPECT_TRUE(Value(12.34).IsLosslessDouble()); EXPECT_TRUE(Value(-123).IsLosslessDouble()); EXPECT_TRUE(Value(2147483648u).IsLosslessDouble()); - EXPECT_TRUE(Value(static_cast<int64_t>(-RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble()); + EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x40000000, 0x00000000))).IsLosslessDouble()); +#if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDouble()); +#endif - EXPECT_FALSE(Value(static_cast<int64_t>(-RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); + EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFFFFFFFF))).IsLosslessDouble()); EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDouble()); } @@ -724,6 +786,11 @@ TEST(Value, String) { EXPECT_STREQ("World", w.GetString()); EXPECT_EQ(5u, w.GetStringLength()); + // templated functions + EXPECT_TRUE(z.Is<const char*>()); + EXPECT_STREQ(cstr, z.Get<const char*>()); + EXPECT_STREQ("Apple", z.Set<const char*>("Apple").Get<const char*>()); + #if RAPIDJSON_HAS_STDSTRING { std::string str = "Hello World"; @@ -759,6 +826,14 @@ TEST(Value, String) { vs1 = StringRef(str); TestEqual(str, vs1); TestEqual(vs0, vs1); + + // Templated function. + EXPECT_TRUE(vs0.Is<std::string>()); + EXPECT_EQ(str, vs0.Get<std::string>()); + vs0.Set<std::string>(std::string("Apple"), allocator); + EXPECT_EQ(std::string("Apple"), vs0.Get<std::string>()); + vs0.Set(std::string("Orange"), allocator); + EXPECT_EQ(std::string("Orange"), vs0.Get<std::string>()); } #endif // RAPIDJSON_HAS_STDSTRING } @@ -769,25 +844,9 @@ TEST(Value, SetStringNullException) { EXPECT_THROW(v.SetString(0, 0), AssertException); } -TEST(Value, Array) { - Value x(kArrayType); - const Value& y = x; - Value::AllocatorType allocator; - - EXPECT_EQ(kArrayType, x.GetType()); - EXPECT_TRUE(x.IsArray()); - EXPECT_TRUE(x.Empty()); - EXPECT_EQ(0u, x.Size()); - EXPECT_TRUE(y.IsArray()); - EXPECT_TRUE(y.Empty()); - EXPECT_EQ(0u, y.Size()); - - EXPECT_FALSE(x.IsNull()); - EXPECT_FALSE(x.IsBool()); - EXPECT_FALSE(x.IsFalse()); - EXPECT_FALSE(x.IsTrue()); - EXPECT_FALSE(x.IsString()); - EXPECT_FALSE(x.IsObject()); +template <typename T, typename Allocator> +static void TestArray(T& x, Allocator& allocator) { + const T& y = x; // PushBack() Value v; @@ -834,7 +893,7 @@ TEST(Value, Array) { #endif // iterator - Value::ValueIterator itr = x.Begin(); + typename T::ValueIterator itr = x.Begin(); EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr->IsNull()); ++itr; @@ -853,7 +912,7 @@ TEST(Value, Array) { EXPECT_STREQ("foo", itr->GetString()); // const iterator - Value::ConstValueIterator citr = y.Begin(); + typename T::ConstValueIterator citr = y.Begin(); EXPECT_TRUE(citr != y.End()); EXPECT_TRUE(citr->IsNull()); ++citr; @@ -939,6 +998,29 @@ TEST(Value, Array) { EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUint()); } } +} + +TEST(Value, Array) { + Value x(kArrayType); + const Value& y = x; + Value::AllocatorType allocator; + + EXPECT_EQ(kArrayType, x.GetType()); + EXPECT_TRUE(x.IsArray()); + EXPECT_TRUE(x.Empty()); + EXPECT_EQ(0u, x.Size()); + EXPECT_TRUE(y.IsArray()); + EXPECT_TRUE(y.Empty()); + EXPECT_EQ(0u, y.Size()); + + EXPECT_FALSE(x.IsNull()); + EXPECT_FALSE(x.IsBool()); + EXPECT_FALSE(x.IsFalse()); + EXPECT_FALSE(x.IsTrue()); + EXPECT_FALSE(x.IsString()); + EXPECT_FALSE(x.IsObject()); + + TestArray(x, allocator); // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed. // http://en.wikipedia.org/wiki/Erase-remove_idiom @@ -962,19 +1044,96 @@ TEST(Value, Array) { EXPECT_TRUE(z.Empty()); } -TEST(Value, Object) { - Value x(kObjectType); - const Value& y = x; // const version +TEST(Value, ArrayHelper) { Value::AllocatorType allocator; + { + Value x(kArrayType); + Value::Array a = x.GetArray(); + TestArray(a, allocator); + } - EXPECT_EQ(kObjectType, x.GetType()); - EXPECT_TRUE(x.IsObject()); - EXPECT_TRUE(x.ObjectEmpty()); - EXPECT_EQ(0u, x.MemberCount()); - EXPECT_EQ(kObjectType, y.GetType()); - EXPECT_TRUE(y.IsObject()); - EXPECT_TRUE(y.ObjectEmpty()); - EXPECT_EQ(0u, y.MemberCount()); + { + Value x(kArrayType); + Value::Array a = x.GetArray(); + a.PushBack(1, allocator); + + Value::Array a2(a); // copy constructor + EXPECT_EQ(1, a2.Size()); + + Value::Array a3 = a; + EXPECT_EQ(1, a3.Size()); + + Value::ConstArray y = static_cast<const Value&>(x).GetArray(); + (void)y; + // y.PushBack(1, allocator); // should not compile + + // Templated functions + x.Clear(); + EXPECT_TRUE(x.Is<Value::Array>()); + EXPECT_TRUE(x.Is<Value::ConstArray>()); + a.PushBack(1, allocator); + EXPECT_EQ(1, x.Get<Value::Array>()[0].GetInt()); + EXPECT_EQ(1, x.Get<Value::ConstArray>()[0].GetInt()); + + Value x2; + x2.Set<Value::Array>(a); + EXPECT_TRUE(x.IsArray()); // IsArray() is invariant after moving. + EXPECT_EQ(1, x2.Get<Value::Array>()[0].GetInt()); + } + + { + Value y(kArrayType); + y.PushBack(123, allocator); + + Value x(y.GetArray()); // Construct value form array. + EXPECT_TRUE(x.IsArray()); + EXPECT_EQ(123, x[0].GetInt()); + EXPECT_TRUE(y.IsArray()); // Invariant + EXPECT_TRUE(y.Empty()); + } + + { + Value x(kArrayType); + Value y(kArrayType); + y.PushBack(123, allocator); + x.PushBack(y.GetArray(), allocator); // Implicit constructor to convert Array to GenericValue + + EXPECT_EQ(1, x.Size()); + EXPECT_EQ(123, x[0][0].GetInt()); + EXPECT_TRUE(y.IsArray()); + EXPECT_TRUE(y.Empty()); + } +} + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR +TEST(Value, ArrayHelperRangeFor) { + Value::AllocatorType allocator; + Value x(kArrayType); + + for (int i = 0; i < 10; i++) + x.PushBack(i, allocator); + + { + int i = 0; + for (auto& v : x.GetArray()) + EXPECT_EQ(i++, v.GetInt()); + EXPECT_EQ(i, 10); + } + { + int i = 0; + for (const auto& v : const_cast<const Value&>(x).GetArray()) + EXPECT_EQ(i++, v.GetInt()); + EXPECT_EQ(i, 10); + } + + // Array a = x.GetArray(); + // Array ca = const_cast<const Value&>(x).GetArray(); +} +#endif + +template <typename T, typename Allocator> +static void TestObject(T& x, Allocator& allocator) { + const T& y = x; // const version // AddMember() x.AddMember("A", "Apple", allocator); @@ -1215,7 +1374,7 @@ TEST(Value, Object) { const unsigned n = 10; for (unsigned first = 0; first < n; first++) { for (unsigned last = first; last <= n; last++) { - Value(kObjectType).Swap(x); + x.RemoveAllMembers(); for (unsigned i = 0; i < n; i++) x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator); @@ -1238,6 +1397,23 @@ TEST(Value, Object) { x.RemoveAllMembers(); EXPECT_TRUE(x.ObjectEmpty()); EXPECT_EQ(0u, x.MemberCount()); +} + +TEST(Value, Object) { + Value x(kObjectType); + const Value& y = x; // const version + Value::AllocatorType allocator; + + EXPECT_EQ(kObjectType, x.GetType()); + EXPECT_TRUE(x.IsObject()); + EXPECT_TRUE(x.ObjectEmpty()); + EXPECT_EQ(0u, x.MemberCount()); + EXPECT_EQ(kObjectType, y.GetType()); + EXPECT_TRUE(y.IsObject()); + EXPECT_TRUE(y.ObjectEmpty()); + EXPECT_EQ(0u, y.MemberCount()); + + TestObject(x, allocator); // SetObject() Value z; @@ -1245,6 +1421,100 @@ TEST(Value, Object) { EXPECT_TRUE(z.IsObject()); } +TEST(Value, ObjectHelper) { + Value::AllocatorType allocator; + { + Value x(kObjectType); + Value::Object o = x.GetObject(); + TestObject(o, allocator); + } + + { + Value x(kObjectType); + Value::Object o = x.GetObject(); + o.AddMember("1", 1, allocator); + + Value::Object o2(o); // copy constructor + EXPECT_EQ(1, o2.MemberCount()); + + Value::Object o3 = o; + EXPECT_EQ(1, o3.MemberCount()); + + Value::ConstObject y = static_cast<const Value&>(x).GetObject(); + (void)y; + // y.AddMember("1", 1, allocator); // should not compile + + // Templated functions + x.RemoveAllMembers(); + EXPECT_TRUE(x.Is<Value::Object>()); + EXPECT_TRUE(x.Is<Value::ConstObject>()); + o.AddMember("1", 1, allocator); + EXPECT_EQ(1, x.Get<Value::Object>()["1"].GetInt()); + EXPECT_EQ(1, x.Get<Value::ConstObject>()["1"].GetInt()); + + Value x2; + x2.Set<Value::Object>(o); + EXPECT_TRUE(x.IsObject()); // IsObject() is invariant after moving + EXPECT_EQ(1, x2.Get<Value::Object>()["1"].GetInt()); + } + + { + Value x(kObjectType); + x.AddMember("a", "apple", allocator); + Value y(x.GetObject()); + EXPECT_STREQ("apple", y["a"].GetString()); + EXPECT_TRUE(x.IsObject()); // Invariant + } + + { + Value x(kObjectType); + x.AddMember("a", "apple", allocator); + Value y(kObjectType); + y.AddMember("fruits", x.GetObject(), allocator); + EXPECT_STREQ("apple", y["fruits"]["a"].GetString()); + EXPECT_TRUE(x.IsObject()); // Invariant + } +} + +#if RAPIDJSON_HAS_CXX11_RANGE_FOR +TEST(Value, ObjectHelperRangeFor) { + Value::AllocatorType allocator; + Value x(kObjectType); + + for (int i = 0; i < 10; i++) { + char name[10]; + Value n(name, static_cast<SizeType>(sprintf(name, "%d", i)), allocator); + x.AddMember(n, i, allocator); + } + + { + int i = 0; + for (auto& m : x.GetObject()) { + char name[10]; + sprintf(name, "%d", i); + EXPECT_STREQ(name, m.name.GetString()); + EXPECT_EQ(i, m.value.GetInt()); + i++; + } + EXPECT_EQ(i, 10); + } + { + int i = 0; + for (const auto& m : const_cast<const Value&>(x).GetObject()) { + char name[10]; + sprintf(name, "%d", i); + EXPECT_STREQ(name, m.name.GetString()); + EXPECT_EQ(i, m.value.GetInt()); + i++; + } + EXPECT_EQ(i, 10); + } + + // Object a = x.GetObject(); + // Object ca = const_cast<const Value&>(x).GetObject(); +} +#endif + TEST(Value, EraseMember_String) { Value::AllocatorType allocator; Value x(kObjectType); @@ -1378,12 +1648,13 @@ struct TerminateHandler { bool Int64(int64_t) { return e != 4; } bool Uint64(uint64_t) { return e != 5; } bool Double(double) { return e != 6; } - bool String(const char*, SizeType, bool) { return e != 7; } - bool StartObject() { return e != 8; } - bool Key(const char*, SizeType, bool) { return e != 9; } - bool EndObject(SizeType) { return e != 10; } - bool StartArray() { return e != 11; } - bool EndArray(SizeType) { return e != 12; } + bool RawNumber(const char*, SizeType, bool) { return e != 7; } + bool String(const char*, SizeType, bool) { return e != 8; } + bool StartObject() { return e != 9; } + bool Key(const char*, SizeType, bool) { return e != 10; } + bool EndObject(SizeType) { return e != 11; } + bool StartArray() { return e != 12; } + bool EndArray(SizeType) { return e != 13; } }; #define TEST_TERMINATION(e, json)\ @@ -1404,12 +1675,13 @@ TEST(Value, AcceptTerminationByHandler) { TEST_TERMINATION(4, "[-1234567890123456789]"); TEST_TERMINATION(5, "[9223372036854775808]"); TEST_TERMINATION(6, "[0.5]"); - TEST_TERMINATION(7, "[\"a\"]"); - TEST_TERMINATION(8, "[{}]"); - TEST_TERMINATION(9, "[{\"a\":1}]"); - TEST_TERMINATION(10, "[{}]"); - TEST_TERMINATION(11, "{\"a\":[]}"); + // RawNumber() is never called + TEST_TERMINATION(8, "[\"a\"]"); + TEST_TERMINATION(9, "[{}]"); + TEST_TERMINATION(10, "[{\"a\":1}]"); + TEST_TERMINATION(11, "[{}]"); TEST_TERMINATION(12, "{\"a\":[]}"); + TEST_TERMINATION(13, "{\"a\":[]}"); } struct ValueIntComparer { |