"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "test/unittest/valuetest.cpp" between
rapidjson-1.0.2.tar.gz and rapidjson-1.1.0.tar.gz

About: RapidJSON is a fast JSON parser/generator for C++ with both SAX/DOM style API.

valuetest.cpp  (rapidjson-1.0.2):valuetest.cpp  (rapidjson-1.1.0)
skipping to change at line 19 skipping to change at line 19
// //
// Unless required by applicable law or agreed to in writing, software distribut ed // Unless required by applicable law or agreed to in writing, software distribut ed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the // CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License. // specific language governing permissions and limitations under the License.
#include "unittest.h" #include "unittest.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include <algorithm> #include <algorithm>
#ifdef __clang__
RAPIDJSON_DIAG_PUSH
RAPIDJSON_DIAG_OFF(c++98-compat)
#endif
using namespace rapidjson; 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) { TEST(Value, DefaultConstructor) {
Value x; Value x;
EXPECT_EQ(kNullType, x.GetType()); EXPECT_EQ(kNullType, x.GetType());
EXPECT_TRUE(x.IsNull()); EXPECT_TRUE(x.IsNull());
//std::cout << "sizeof(Value): " << sizeof(x) << std::endl; //std::cout << "sizeof(Value): " << sizeof(x) << std::endl;
} }
// Should not pass compilation // Should not pass compilation
//TEST(Value, copy_constructor) { //TEST(Value, copy_constructor) {
// Value x(1234); // Value x(1234);
// Value y = x; // Value y = x;
//} //}
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
#if 0 // Many old compiler does not support these. Turn it off temporaily.
#include <type_traits> #include <type_traits>
TEST(Value, Traits) { TEST(Value, Traits) {
typedef GenericValue<UTF8<>, CrtAllocator> Value; typedef GenericValue<UTF8<>, CrtAllocator> Value;
static_assert(std::is_constructible<Value>::value, ""); static_assert(std::is_constructible<Value>::value, "");
static_assert(std::is_default_constructible<Value>::value, ""); static_assert(std::is_default_constructible<Value>::value, "");
#ifndef _MSC_VER #ifndef _MSC_VER
static_assert(!std::is_copy_constructible<Value>::value, ""); static_assert(!std::is_copy_constructible<Value>::value, "");
#endif #endif
static_assert(std::is_move_constructible<Value>::value, ""); static_assert(std::is_move_constructible<Value>::value, "");
skipping to change at line 75 skipping to change at line 94
#ifndef _MSC_VER #ifndef _MSC_VER
static_assert(std::is_nothrow_move_assignable<Value>::value, ""); static_assert(std::is_nothrow_move_assignable<Value>::value, "");
#endif #endif
static_assert(std::is_destructible<Value>::value, ""); static_assert(std::is_destructible<Value>::value, "");
#ifndef _MSC_VER #ifndef _MSC_VER
static_assert(std::is_nothrow_destructible<Value>::value, ""); static_assert(std::is_nothrow_destructible<Value>::value, "");
#endif #endif
} }
#endif
TEST(Value, MoveConstructor) { TEST(Value, MoveConstructor) {
typedef GenericValue<UTF8<>, CrtAllocator> Value; typedef GenericValue<UTF8<>, CrtAllocator> V;
Value::AllocatorType allocator; V::AllocatorType allocator;
Value x((Value(kArrayType))); V x((V(kArrayType)));
x.Reserve(4u, allocator); x.Reserve(4u, allocator);
x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushB ack(4, allocator); x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushB ack(4, allocator);
EXPECT_TRUE(x.IsArray()); EXPECT_TRUE(x.IsArray());
EXPECT_EQ(4u, x.Size()); EXPECT_EQ(4u, x.Size());
// Value y(x); // does not compile (!is_copy_constructible) // Value y(x); // does not compile (!is_copy_constructible)
Value y(std::move(x)); V y(std::move(x));
EXPECT_TRUE(x.IsNull()); EXPECT_TRUE(x.IsNull());
EXPECT_TRUE(y.IsArray()); EXPECT_TRUE(y.IsArray());
EXPECT_EQ(4u, y.Size()); EXPECT_EQ(4u, y.Size());
// Value z = y; // does not compile (!is_copy_assignable) // Value z = y; // does not compile (!is_copy_assignable)
Value z = std::move(y); V z = std::move(y);
EXPECT_TRUE(y.IsNull()); EXPECT_TRUE(y.IsNull());
EXPECT_TRUE(z.IsArray()); EXPECT_TRUE(z.IsArray());
EXPECT_EQ(4u, z.Size()); EXPECT_EQ(4u, z.Size());
} }
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, AssignmentOperator) { TEST(Value, AssignmentOperator) {
Value x(1234); Value x(1234);
Value y; Value y;
skipping to change at line 274 skipping to change at line 295
} }
TEST(Value, Swap) { TEST(Value, Swap) {
Value v1(1234); Value v1(1234);
Value v2(kObjectType); Value v2(kObjectType);
EXPECT_EQ(&v1, &v1.Swap(v2)); EXPECT_EQ(&v1, &v1.Swap(v2));
EXPECT_TRUE(v1.IsObject()); EXPECT_TRUE(v1.IsObject());
EXPECT_TRUE(v2.IsInt()); EXPECT_TRUE(v2.IsInt());
EXPECT_EQ(1234, v2.GetInt()); EXPECT_EQ(1234, v2.GetInt());
// testing std::swap compatibility
using std::swap;
swap(v1, v2);
EXPECT_TRUE(v1.IsInt());
EXPECT_TRUE(v2.IsObject());
} }
TEST(Value, Null) { TEST(Value, Null) {
// Default constructor // Default constructor
Value x; Value x;
EXPECT_EQ(kNullType, x.GetType()); EXPECT_EQ(kNullType, x.GetType());
EXPECT_TRUE(x.IsNull()); EXPECT_TRUE(x.IsNull());
EXPECT_FALSE(x.IsTrue()); EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsFalse()); EXPECT_FALSE(x.IsFalse());
skipping to change at line 322 skipping to change at line 349
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
// Constructor with type // Constructor with type
Value y(kTrueType); Value y(kTrueType);
EXPECT_TRUE(y.IsTrue()); EXPECT_TRUE(y.IsTrue());
// SetBool() // SetBool()
Value z; Value z;
z.SetBool(true); z.SetBool(true);
EXPECT_TRUE(z.IsTrue()); 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) { TEST(Value, False) {
// Constructor with bool // Constructor with bool
Value x(false); Value x(false);
EXPECT_EQ(kFalseType, x.GetType()); EXPECT_EQ(kFalseType, x.GetType());
EXPECT_TRUE(x.IsBool()); EXPECT_TRUE(x.IsBool());
EXPECT_TRUE(x.IsFalse()); EXPECT_TRUE(x.IsFalse());
EXPECT_FALSE(x.IsNull()); EXPECT_FALSE(x.IsNull());
skipping to change at line 371 skipping to change at line 404
//EXPECT_EQ(1234, (int64_t)x); //EXPECT_EQ(1234, (int64_t)x);
//EXPECT_EQ(1234, (uint64_t)x); //EXPECT_EQ(1234, (uint64_t)x);
//EXPECT_EQ(1234, (double)x); //EXPECT_EQ(1234, (double)x);
EXPECT_TRUE(x.IsNumber()); EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt()); EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint()); EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64()); EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64()); EXPECT_TRUE(x.IsUint64());
EXPECT_FALSE(x.IsDouble()); EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull()); EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool()); EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse()); EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue()); EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString()); EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject()); EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
Value nx(-1234); Value nx(-1234);
EXPECT_EQ(-1234, nx.GetInt()); EXPECT_EQ(-1234, nx.GetInt());
skipping to change at line 401 skipping to change at line 435
EXPECT_EQ(0, y.GetInt()); EXPECT_EQ(0, y.GetInt());
// SetInt() // SetInt()
Value z; Value z;
z.SetInt(1234); z.SetInt(1234);
EXPECT_EQ(1234, z.GetInt()); EXPECT_EQ(1234, z.GetInt());
// operator=(int) // operator=(int)
z = 5678; z = 5678;
EXPECT_EQ(5678, z.GetInt()); 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) { TEST(Value, Uint) {
// Constructor with int // Constructor with int
Value x(1234u); Value x(1234u);
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt()); EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint()); EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64()); EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64()); EXPECT_EQ(1234u, x.GetUint64());
EXPECT_TRUE(x.IsNumber()); EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt()); EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint()); EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64()); EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64()); EXPECT_TRUE(x.IsUint64());
EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as d ouble but !IsDouble(). EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as d ouble but !IsDouble().
EXPECT_FALSE(x.IsDouble()); EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull()); EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool()); EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse()); EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue()); EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString()); EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject()); EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
// SetUint() // SetUint()
Value z; Value z;
skipping to change at line 440 skipping to change at line 481
EXPECT_EQ(1234u, z.GetUint()); EXPECT_EQ(1234u, z.GetUint());
// operator=(unsigned) // operator=(unsigned)
z = 5678u; z = 5678u;
EXPECT_EQ(5678u, z.GetUint()); EXPECT_EQ(5678u, z.GetUint());
z = 2147483648u; // 2^31, cannot cast as int z = 2147483648u; // 2^31, cannot cast as int
EXPECT_EQ(2147483648u, z.GetUint()); EXPECT_EQ(2147483648u, z.GetUint());
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int n umber types EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int n umber 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) { TEST(Value, Int64) {
// Constructor with int // Constructor with int
Value x(int64_t(1234LL)); Value x(int64_t(1234));
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt()); EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint()); EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64()); EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64()); EXPECT_EQ(1234u, x.GetUint64());
EXPECT_TRUE(x.IsNumber()); EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt()); EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint()); EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64()); EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64()); EXPECT_TRUE(x.IsUint64());
EXPECT_FALSE(x.IsDouble()); EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull()); EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool()); EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse()); EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue()); EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString()); EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject()); EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
Value nx(int64_t(-1234LL)); Value nx(int64_t(-1234));
EXPECT_EQ(-1234, nx.GetInt()); EXPECT_EQ(-1234, nx.GetInt());
EXPECT_EQ(-1234, nx.GetInt64()); EXPECT_EQ(-1234, nx.GetInt64());
EXPECT_TRUE(nx.IsInt()); EXPECT_TRUE(nx.IsInt());
EXPECT_TRUE(nx.IsInt64()); EXPECT_TRUE(nx.IsInt64());
EXPECT_FALSE(nx.IsUint()); EXPECT_FALSE(nx.IsUint());
EXPECT_FALSE(nx.IsUint64()); EXPECT_FALSE(nx.IsUint64());
// SetInt64() // SetInt64()
Value z; Value z;
z.SetInt64(1234); z.SetInt64(1234);
EXPECT_EQ(1234, z.GetInt64()); EXPECT_EQ(1234, z.GetInt64());
z.SetInt64(2147483648LL); // 2^31, cannot cast as int z.SetInt64(2147483648u); // 2^31, cannot cast as int
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsUint()); EXPECT_TRUE(z.IsUint());
EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0); EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0);
z.SetInt64(4294967296LL); // 2^32, cannot cast as uint z.SetInt64(int64_t(4294967295u) + 1); // 2^32, cannot cast as uint
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_FALSE(z.IsUint()); EXPECT_FALSE(z.IsUint());
EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0); EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0);
z.SetInt64(-2147483649LL); // -2^31-1, cannot cast as int z.SetInt64(-int64_t(2147483648u) - 1); // -2^31-1, cannot cast as int
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0); 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()); EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble());
// Templated functions
EXPECT_TRUE(z.Is<int64_t>());
EXPECT_EQ(i, z.Get<int64_t>());
#if 0 // signed integer underflow is undefined behaviour
EXPECT_EQ(i - 1, z.Set(i - 1).Get<int64_t>());
EXPECT_EQ(i - 2, z.Set<int64_t>(i - 2).Get<int64_t>());
#endif
} }
TEST(Value, Uint64) { TEST(Value, Uint64) {
// Constructor with int // Constructor with int
Value x(uint64_t(1234LL)); Value x(uint64_t(1234));
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_EQ(1234, x.GetInt()); EXPECT_EQ(1234, x.GetInt());
EXPECT_EQ(1234u, x.GetUint()); EXPECT_EQ(1234u, x.GetUint());
EXPECT_EQ(1234, x.GetInt64()); EXPECT_EQ(1234, x.GetInt64());
EXPECT_EQ(1234u, x.GetUint64()); EXPECT_EQ(1234u, x.GetUint64());
EXPECT_TRUE(x.IsNumber()); EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsInt()); EXPECT_TRUE(x.IsInt());
EXPECT_TRUE(x.IsUint()); EXPECT_TRUE(x.IsUint());
EXPECT_TRUE(x.IsInt64()); EXPECT_TRUE(x.IsInt64());
EXPECT_TRUE(x.IsUint64()); EXPECT_TRUE(x.IsUint64());
EXPECT_FALSE(x.IsDouble()); EXPECT_FALSE(x.IsDouble());
EXPECT_FALSE(x.IsFloat());
EXPECT_FALSE(x.IsNull()); EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool()); EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse()); EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue()); EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString()); EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject()); EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
// SetUint64() // SetUint64()
Value z; Value z;
z.SetUint64(1234); z.SetUint64(1234);
EXPECT_EQ(1234u, z.GetUint64()); EXPECT_EQ(1234u, z.GetUint64());
z.SetUint64(2147483648LL); // 2^31, cannot cast as int z.SetUint64(uint64_t(2147483648u)); // 2^31, cannot cast as int
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_TRUE(z.IsUint()); EXPECT_TRUE(z.IsUint());
EXPECT_TRUE(z.IsInt64()); EXPECT_TRUE(z.IsInt64());
z.SetUint64(4294967296LL); // 2^32, cannot cast as uint z.SetUint64(uint64_t(4294967295u) + 1); // 2^32, cannot cast as uint
EXPECT_FALSE(z.IsInt()); EXPECT_FALSE(z.IsInt());
EXPECT_FALSE(z.IsUint()); EXPECT_FALSE(z.IsUint());
EXPECT_TRUE(z.IsInt64()); EXPECT_TRUE(z.IsInt64());
z.SetUint64(9223372036854775808uLL); // 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_FALSE(z.IsInt64());
EXPECT_EQ(9223372036854775808uLL, z.GetUint64()); // Issue 48 EXPECT_EQ(u, z.GetUint64()); // Issue 48
EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble()); 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) { TEST(Value, Double) {
// Constructor with double // Constructor with double
Value x(12.34); Value x(12.34);
EXPECT_EQ(kNumberType, x.GetType()); EXPECT_EQ(kNumberType, x.GetType());
EXPECT_NEAR(12.34, x.GetDouble(), 0.0); EXPECT_NEAR(12.34, x.GetDouble(), 0.0);
EXPECT_TRUE(x.IsNumber()); EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsDouble()); EXPECT_TRUE(x.IsDouble());
skipping to change at line 564 skipping to change at line 629
EXPECT_FALSE(x.IsObject()); EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray()); EXPECT_FALSE(x.IsArray());
// SetDouble() // SetDouble()
Value z; Value z;
z.SetDouble(12.34); z.SetDouble(12.34);
EXPECT_NEAR(12.34, z.GetDouble(), 0.0); EXPECT_NEAR(12.34, z.GetDouble(), 0.0);
z = 56.78; z = 56.78;
EXPECT_NEAR(56.78, z.GetDouble(), 0.0); 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) {
// Constructor with double
Value x(12.34f);
EXPECT_EQ(kNumberType, x.GetType());
EXPECT_NEAR(12.34f, x.GetFloat(), 0.0);
EXPECT_TRUE(x.IsNumber());
EXPECT_TRUE(x.IsDouble());
EXPECT_TRUE(x.IsFloat());
EXPECT_FALSE(x.IsInt());
EXPECT_FALSE(x.IsNull());
EXPECT_FALSE(x.IsBool());
EXPECT_FALSE(x.IsFalse());
EXPECT_FALSE(x.IsTrue());
EXPECT_FALSE(x.IsString());
EXPECT_FALSE(x.IsObject());
EXPECT_FALSE(x.IsArray());
// SetFloat()
Value z;
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(0.0).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, 0x00
000000))).IsLosslessDouble());
#if !(defined(_MSC_VER) && _MSC_VER < 1800) // VC2010 has problem
EXPECT_TRUE(Value(RAPIDJSON_UINT64_C2(0xA0000000, 0x00000000)).IsLosslessDou
ble());
#endif
EXPECT_FALSE(Value(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFF
FFFFFF))).IsLosslessDouble()); // INT64_MAX
EXPECT_FALSE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xF
FFFFFFF))).IsLosslessDouble()); // -INT64_MAX
EXPECT_TRUE(Value(-static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x7FFFFFFF, 0xFF
FFFFFF)) - 1).IsLosslessDouble()); // INT64_MIN
EXPECT_FALSE(Value(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)).IsLosslessDo
uble()); // UINT64_MAX
EXPECT_TRUE(Value(3.4028234e38f).IsLosslessDouble()); // FLT_MAX
EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessDouble()); // -FLT_MAX
EXPECT_TRUE(Value(1.17549435e-38f).IsLosslessDouble()); // FLT_MIN
EXPECT_TRUE(Value(-1.17549435e-38f).IsLosslessDouble()); // -FLT_MIN
EXPECT_TRUE(Value(1.7976931348623157e+308).IsLosslessDouble()); // DBL_MAX
EXPECT_TRUE(Value(-1.7976931348623157e+308).IsLosslessDouble()); // -DBL_MAX
EXPECT_TRUE(Value(2.2250738585072014e-308).IsLosslessDouble()); // DBL_MIN
EXPECT_TRUE(Value(-2.2250738585072014e-308).IsLosslessDouble()); // -DBL_MIN
}
TEST(Value, IsLosslessFloat) {
EXPECT_TRUE(Value(12.25).IsLosslessFloat());
EXPECT_TRUE(Value(-123).IsLosslessFloat());
EXPECT_TRUE(Value(2147483648u).IsLosslessFloat());
EXPECT_TRUE(Value(3.4028234e38f).IsLosslessFloat());
EXPECT_TRUE(Value(-3.4028234e38f).IsLosslessFloat());
EXPECT_FALSE(Value(3.4028235e38).IsLosslessFloat());
EXPECT_FALSE(Value(0.3).IsLosslessFloat());
} }
TEST(Value, String) { TEST(Value, String) {
// Construction with const string // Construction with const string
Value x("Hello", 5); // literal Value x("Hello", 5); // literal
EXPECT_EQ(kStringType, x.GetType()); EXPECT_EQ(kStringType, x.GetType());
EXPECT_TRUE(x.IsString()); EXPECT_TRUE(x.IsString());
EXPECT_STREQ("Hello", x.GetString()); EXPECT_STREQ("Hello", x.GetString());
EXPECT_EQ(5u, x.GetStringLength()); EXPECT_EQ(5u, x.GetStringLength());
skipping to change at line 658 skipping to change at line 801
EXPECT_TRUE(z.IsString()); EXPECT_TRUE(z.IsString());
EXPECT_EQ(cstr, z.GetString()); EXPECT_EQ(cstr, z.GetString());
z = cstr; z = cstr;
EXPECT_TRUE(z.IsString()); EXPECT_TRUE(z.IsString());
EXPECT_EQ(cstr, z.GetString()); EXPECT_EQ(cstr, z.GetString());
// SetString() // SetString()
char s[] = "World"; char s[] = "World";
Value w; Value w;
w.SetString(s, (SizeType)strlen(s), allocator); w.SetString(s, static_cast<SizeType>(strlen(s)), allocator);
s[0] = '\0'; s[0] = '\0';
EXPECT_STREQ("World", w.GetString()); EXPECT_STREQ("World", w.GetString());
EXPECT_EQ(5u, w.GetStringLength()); 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 #if RAPIDJSON_HAS_STDSTRING
{ {
std::string str = "Hello World"; std::string str = "Hello World";
str[5] = '\0'; str[5] = '\0';
EXPECT_STREQ(str.data(),"Hello"); // embedded '\0' EXPECT_STREQ(str.data(),"Hello"); // embedded '\0'
EXPECT_EQ(str.size(), 11u); EXPECT_EQ(str.size(), 11u);
// no copy // no copy
Value vs0(StringRef(str)); Value vs0(StringRef(str));
EXPECT_TRUE(vs0.IsString()); EXPECT_TRUE(vs0.IsString());
skipping to change at line 698 skipping to change at line 846
EXPECT_TRUE(vs0.IsString()); EXPECT_TRUE(vs0.IsString());
EXPECT_STREQ(vs0.GetString(), str.c_str()); EXPECT_STREQ(vs0.GetString(), str.c_str());
EXPECT_EQ(vs0.GetStringLength(), str.size()); EXPECT_EQ(vs0.GetStringLength(), str.size());
TestEqual(str, vs0); TestEqual(str, vs0);
TestUnequal(str, vs1); TestUnequal(str, vs1);
// vs1 = str; // should not compile // vs1 = str; // should not compile
vs1 = StringRef(str); vs1 = StringRef(str);
TestEqual(str, vs1); TestEqual(str, vs1);
TestEqual(vs0, 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 #endif // RAPIDJSON_HAS_STDSTRING
} }
// Issue 226: Value of string type should not point to NULL // Issue 226: Value of string type should not point to NULL
TEST(Value, SetStringNullException) { TEST(Value, SetStringNullException) {
Value v; Value v;
EXPECT_THROW(v.SetString(0, 0), AssertException); EXPECT_THROW(v.SetString(0, 0), AssertException);
} }
TEST(Value, Array) { template <typename T, typename Allocator>
Value x(kArrayType); static void TestArray(T& x, Allocator& allocator) {
const Value& y = x; const T& 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());
// PushBack() // PushBack()
Value v; Value v;
x.PushBack(v, allocator); x.PushBack(v, allocator);
v.SetBool(true); v.SetBool(true);
x.PushBack(v, allocator); x.PushBack(v, allocator);
v.SetBool(false); v.SetBool(false);
x.PushBack(v, allocator); x.PushBack(v, allocator);
v.SetInt(123); v.SetInt(123);
x.PushBack(v, allocator); x.PushBack(v, allocator);
skipping to change at line 760 skipping to change at line 900
EXPECT_TRUE(y[1].IsTrue()); EXPECT_TRUE(y[1].IsTrue());
EXPECT_TRUE(y[2].IsFalse()); EXPECT_TRUE(y[2].IsFalse());
EXPECT_TRUE(y[3].IsInt()); EXPECT_TRUE(y[3].IsInt());
EXPECT_EQ(123, y[3].GetInt()); EXPECT_EQ(123, y[3].GetInt());
EXPECT_TRUE(y[4].IsString()); EXPECT_TRUE(y[4].IsString());
EXPECT_STREQ("foo", y[4].GetString()); EXPECT_STREQ("foo", y[4].GetString());
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
// PushBack(GenericValue&&, Allocator&); // PushBack(GenericValue&&, Allocator&);
{ {
Value y(kArrayType); Value y2(kArrayType);
y.PushBack(Value(true), allocator); y2.PushBack(Value(true), allocator);
y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).Pus y2.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).Pu
hBack("foo", allocator)), allocator); shBack("foo", allocator)), allocator);
EXPECT_EQ(2u, y.Size()); EXPECT_EQ(2u, y2.Size());
EXPECT_TRUE(y[0].IsTrue()); EXPECT_TRUE(y2[0].IsTrue());
EXPECT_TRUE(y[1].IsArray()); EXPECT_TRUE(y2[1].IsArray());
EXPECT_EQ(2u, y[1].Size()); EXPECT_EQ(2u, y2[1].Size());
EXPECT_TRUE(y[1][0].IsInt()); EXPECT_TRUE(y2[1][0].IsInt());
EXPECT_TRUE(y[1][1].IsString()); EXPECT_TRUE(y2[1][1].IsString());
} }
#endif #endif
// iterator // iterator
Value::ValueIterator itr = x.Begin(); typename T::ValueIterator itr = x.Begin();
EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsNull()); EXPECT_TRUE(itr->IsNull());
++itr; ++itr;
EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsTrue()); EXPECT_TRUE(itr->IsTrue());
++itr; ++itr;
EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsFalse()); EXPECT_TRUE(itr->IsFalse());
++itr; ++itr;
EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsInt()); EXPECT_TRUE(itr->IsInt());
EXPECT_EQ(123, itr->GetInt()); EXPECT_EQ(123, itr->GetInt());
++itr; ++itr;
EXPECT_TRUE(itr != x.End()); EXPECT_TRUE(itr != x.End());
EXPECT_TRUE(itr->IsString()); EXPECT_TRUE(itr->IsString());
EXPECT_STREQ("foo", itr->GetString()); EXPECT_STREQ("foo", itr->GetString());
// const iterator // const iterator
Value::ConstValueIterator citr = y.Begin(); typename T::ConstValueIterator citr = y.Begin();
EXPECT_TRUE(citr != y.End()); EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsNull()); EXPECT_TRUE(citr->IsNull());
++citr; ++citr;
EXPECT_TRUE(citr != y.End()); EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsTrue()); EXPECT_TRUE(citr->IsTrue());
++citr; ++citr;
EXPECT_TRUE(citr != y.End()); EXPECT_TRUE(citr != y.End());
EXPECT_TRUE(citr->IsFalse()); EXPECT_TRUE(citr->IsFalse());
++citr; ++citr;
EXPECT_TRUE(citr != y.End()); EXPECT_TRUE(citr != y.End());
skipping to change at line 837 skipping to change at line 977
// Use array of array to ensure removed elements' destructor is called. // Use array of array to ensure removed elements' destructor is called.
// [[0],[1],[2],...] // [[0],[1],[2],...]
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator); x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator);
// Erase the first // Erase the first
itr = x.Erase(x.Begin()); itr = x.Erase(x.Begin());
EXPECT_EQ(x.Begin(), itr); EXPECT_EQ(x.Begin(), itr);
EXPECT_EQ(9u, x.Size()); EXPECT_EQ(9u, x.Size());
for (int i = 0; i < 9; i++) for (int i = 0; i < 9; i++)
EXPECT_EQ(i + 1, x[i][0].GetInt()); EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
// Ease the last // Ease the last
itr = x.Erase(x.End() - 1); itr = x.Erase(x.End() - 1);
EXPECT_EQ(x.End(), itr); EXPECT_EQ(x.End(), itr);
EXPECT_EQ(8u, x.Size()); EXPECT_EQ(8u, x.Size());
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
EXPECT_EQ(i + 1, x[i][0].GetInt()); EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
// Erase the middle // Erase the middle
itr = x.Erase(x.Begin() + 4); itr = x.Erase(x.Begin() + 4);
EXPECT_EQ(x.Begin() + 4, itr); EXPECT_EQ(x.Begin() + 4, itr);
EXPECT_EQ(7u, x.Size()); EXPECT_EQ(7u, x.Size());
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
EXPECT_EQ(i + 1, x[i][0].GetInt()); EXPECT_EQ(i + 1, x[static_cast<SizeType>(i)][0].GetInt());
for (int i = 4; i < 7; i++) for (int i = 4; i < 7; i++)
EXPECT_EQ(i + 2, x[i][0].GetInt()); EXPECT_EQ(i + 2, x[static_cast<SizeType>(i)][0].GetInt());
// Erase(ValueIterator, ValueIterator) // Erase(ValueIterator, ValueIterator)
// Exhaustive test with all 0 <= first < n, first <= last <= n cases // Exhaustive test with all 0 <= first < n, first <= last <= n cases
const unsigned n = 10; const unsigned n = 10;
for (unsigned first = 0; first < n; first++) { for (unsigned first = 0; first < n; first++) {
for (unsigned last = first; last <= n; last++) { for (unsigned last = first; last <= n; last++) {
x.Clear(); x.Clear();
for (unsigned i = 0; i < n; i++) for (unsigned i = 0; i < n; i++)
x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allo cator); x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allo cator);
skipping to change at line 875 skipping to change at line 1015
if (last == n) if (last == n)
EXPECT_EQ(x.End(), itr); EXPECT_EQ(x.End(), itr);
else else
EXPECT_EQ(x.Begin() + first, itr); EXPECT_EQ(x.Begin() + first, itr);
size_t removeCount = last - first; size_t removeCount = last - first;
EXPECT_EQ(n - removeCount, x.Size()); EXPECT_EQ(n - removeCount, x.Size());
for (unsigned i = 0; i < first; i++) for (unsigned i = 0; i < first; i++)
EXPECT_EQ(i, x[i][0].GetUint()); EXPECT_EQ(i, x[i][0].GetUint());
for (unsigned i = first; i < n - removeCount; i++) for (unsigned i = first; i < n - removeCount; i++)
EXPECT_EQ(i + removeCount, x[i][0].GetUint()); EXPECT_EQ(i + removeCount, x[static_cast<SizeType>(i)][0].GetUin t());
} }
} }
}
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. // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed.
// http://en.wikipedia.org/wiki/Erase-remove_idiom // http://en.wikipedia.org/wiki/Erase-remove_idiom
x.Clear(); x.Clear();
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
if (i % 2 == 0) if (i % 2 == 0)
x.PushBack(i, allocator); x.PushBack(i, allocator);
else else
x.PushBack(Value(kNullType).Move(), allocator); x.PushBack(Value(kNullType).Move(), allocator);
const Value null(kNullType); const Value null(kNullType);
x.Erase(std::remove(x.Begin(), x.End(), null), x.End()); x.Erase(std::remove(x.Begin(), x.End(), null), x.End());
EXPECT_EQ(5u, x.Size()); EXPECT_EQ(5u, x.Size());
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
EXPECT_EQ(i * 2, x[i]); EXPECT_EQ(i * 2, x[static_cast<SizeType>(i)]);
// SetArray() // SetArray()
Value z; Value z;
z.SetArray(); z.SetArray();
EXPECT_TRUE(z.IsArray()); EXPECT_TRUE(z.IsArray());
EXPECT_TRUE(z.Empty()); EXPECT_TRUE(z.Empty());
} }
TEST(Value, Object) { TEST(Value, ArrayHelper) {
Value x(kObjectType);
const Value& y = x; // const version
Value::AllocatorType allocator; Value::AllocatorType allocator;
{
Value x(kArrayType);
Value::Array a = x.GetArray();
TestArray(a, allocator);
}
EXPECT_EQ(kObjectType, x.GetType()); {
EXPECT_TRUE(x.IsObject()); Value x(kArrayType);
EXPECT_TRUE(x.ObjectEmpty()); Value::Array a = x.GetArray();
EXPECT_EQ(0u, x.MemberCount()); a.PushBack(1, allocator);
EXPECT_EQ(kObjectType, y.GetType());
EXPECT_TRUE(y.IsObject()); Value::Array a2(a); // copy constructor
EXPECT_TRUE(y.ObjectEmpty()); EXPECT_EQ(1, a2.Size());
EXPECT_EQ(0u, y.MemberCount());
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 conve
rt 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());
i++;
}
EXPECT_EQ(i, 10);
}
{
int i = 0;
for (const auto& v : const_cast<const Value&>(x).GetArray()) {
EXPECT_EQ(i, v.GetInt());
i++;
}
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() // AddMember()
x.AddMember("A", "Apple", allocator); x.AddMember("A", "Apple", allocator);
EXPECT_FALSE(x.ObjectEmpty()); EXPECT_FALSE(x.ObjectEmpty());
EXPECT_EQ(1u, x.MemberCount()); EXPECT_EQ(1u, x.MemberCount());
Value value("Banana", 6); Value value("Banana", 6);
x.AddMember("B", "Banana", allocator); x.AddMember("B", "Banana", allocator);
EXPECT_EQ(2u, x.MemberCount()); EXPECT_EQ(2u, x.MemberCount());
// AddMember<T>(StringRefType, T, Allocator) // AddMember<T>(StringRefType, T, Allocator)
{ {
Value o(kObjectType); Value o(kObjectType);
o.AddMember("true", true, allocator); o.AddMember("true", true, allocator);
o.AddMember("false", false, allocator); o.AddMember("false", false, allocator);
o.AddMember("int", -1, allocator); o.AddMember("int", -1, allocator);
o.AddMember("uint", 1u, allocator); o.AddMember("uint", 1u, allocator);
o.AddMember("int64", INT64_C(-4294967296), allocator); o.AddMember("int64", int64_t(-4294967296), allocator);
o.AddMember("uint64", UINT64_C(4294967296), allocator); o.AddMember("uint64", uint64_t(4294967296), allocator);
o.AddMember("double", 3.14, allocator); o.AddMember("double", 3.14, allocator);
o.AddMember("string", "Jelly", allocator); o.AddMember("string", "Jelly", allocator);
EXPECT_TRUE(o["true"].GetBool()); EXPECT_TRUE(o["true"].GetBool());
EXPECT_FALSE(o["false"].GetBool()); EXPECT_FALSE(o["false"].GetBool());
EXPECT_EQ(-1, o["int"].GetInt()); EXPECT_EQ(-1, o["int"].GetInt());
EXPECT_EQ(1u, o["uint"].GetUint()); EXPECT_EQ(1u, o["uint"].GetUint());
EXPECT_EQ(INT64_C(-4294967296), o["int64"].GetInt64()); EXPECT_EQ(int64_t(-4294967296), o["int64"].GetInt64());
EXPECT_EQ(UINT64_C(4294967296), o["uint64"].GetUint64()); EXPECT_EQ(uint64_t(4294967296), o["uint64"].GetUint64());
EXPECT_STREQ("Jelly",o["string"].GetString()); EXPECT_STREQ("Jelly",o["string"].GetString());
EXPECT_EQ(8u, o.MemberCount()); EXPECT_EQ(8u, o.MemberCount());
} }
// AddMember<T>(Value&, T, Allocator) // AddMember<T>(Value&, T, Allocator)
{ {
Value o(kObjectType); Value o(kObjectType);
Value n("s"); Value n("s");
o.AddMember(n, "string", allocator); o.AddMember(n, "string", allocator);
skipping to change at line 1121 skipping to change at line 1365
// MemberCount, iterator difference // MemberCount, iterator difference
EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin())); EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin()));
// Erase the first // Erase the first
itr = x.EraseMember(x.MemberBegin()); itr = x.EraseMember(x.MemberBegin());
EXPECT_FALSE(x.HasMember(keys[0])); EXPECT_FALSE(x.HasMember(keys[0]));
EXPECT_EQ(x.MemberBegin(), itr); EXPECT_EQ(x.MemberBegin(), itr);
EXPECT_EQ(9u, x.MemberCount()); EXPECT_EQ(9u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) { for (; itr != x.MemberEnd(); ++itr) {
int i = (itr - x.MemberBegin()) + 1; size_t i = static_cast<size_t>((itr - x.MemberBegin())) + 1;
EXPECT_STREQ(itr->name.GetString(), keys[i]); EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(i, itr->value[0].GetInt()); EXPECT_EQ(i, itr->value[0].GetInt());
} }
// Erase the last // Erase the last
itr = x.EraseMember(x.MemberEnd() - 1); itr = x.EraseMember(x.MemberEnd() - 1);
EXPECT_FALSE(x.HasMember(keys[9])); EXPECT_FALSE(x.HasMember(keys[9]));
EXPECT_EQ(x.MemberEnd(), itr); EXPECT_EQ(x.MemberEnd(), itr);
EXPECT_EQ(8u, x.MemberCount()); EXPECT_EQ(8u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) { for (; itr != x.MemberEnd(); ++itr) {
int i = (itr - x.MemberBegin()) + 1; size_t i = static_cast<size_t>(itr - x.MemberBegin()) + 1;
EXPECT_STREQ(itr->name.GetString(), keys[i]); EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(i, itr->value[0].GetInt()); EXPECT_EQ(i, itr->value[0].GetInt());
} }
// Erase the middle // Erase the middle
itr = x.EraseMember(x.MemberBegin() + 4); itr = x.EraseMember(x.MemberBegin() + 4);
EXPECT_FALSE(x.HasMember(keys[5])); EXPECT_FALSE(x.HasMember(keys[5]));
EXPECT_EQ(x.MemberBegin() + 4, itr); EXPECT_EQ(x.MemberBegin() + 4, itr);
EXPECT_EQ(7u, x.MemberCount()); EXPECT_EQ(7u, x.MemberCount());
for (; itr != x.MemberEnd(); ++itr) { for (; itr != x.MemberEnd(); ++itr) {
int i = (itr - x.MemberBegin()); size_t i = static_cast<size_t>(itr - x.MemberBegin());
i += (i<4) ? 1 : 2; i += (i < 4) ? 1 : 2;
EXPECT_STREQ(itr->name.GetString(), keys[i]); EXPECT_STREQ(itr->name.GetString(), keys[i]);
EXPECT_EQ(i, itr->value[0].GetInt()); EXPECT_EQ(i, itr->value[0].GetInt());
} }
// EraseMember(ConstMemberIterator, ConstMemberIterator) // EraseMember(ConstMemberIterator, ConstMemberIterator)
// Exhaustive test with all 0 <= first < n, first <= last <= n cases // Exhaustive test with all 0 <= first < n, first <= last <= n cases
const unsigned n = 10; const unsigned n = 10;
for (unsigned first = 0; first < n; first++) { for (unsigned first = 0; first < n; first++) {
for (unsigned last = first; last <= n; last++) { for (unsigned last = first; last <= n; last++) {
Value(kObjectType).Swap(x); x.RemoveAllMembers();
for (unsigned i = 0; i < n; i++) for (unsigned i = 0; i < n; i++)
x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), a llocator); x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), a llocator);
itr = x.EraseMember(x.MemberBegin() + first, x.MemberBegin() + last) ; itr = x.EraseMember(x.MemberBegin() + static_cast<int>(first), x.Mem berBegin() + static_cast<int>(last));
if (last == n) if (last == n)
EXPECT_EQ(x.MemberEnd(), itr); EXPECT_EQ(x.MemberEnd(), itr);
else else
EXPECT_EQ(x.MemberBegin() + first, itr); EXPECT_EQ(x.MemberBegin() + static_cast<int>(first), itr);
size_t removeCount = last - first; size_t removeCount = last - first;
EXPECT_EQ(n - removeCount, x.MemberCount()); EXPECT_EQ(n - removeCount, x.MemberCount());
for (unsigned i = 0; i < first; i++) for (unsigned i = 0; i < first; i++)
EXPECT_EQ(i, x[keys[i]][0].GetUint()); EXPECT_EQ(i, x[keys[i]][0].GetUint());
for (unsigned i = first; i < n - removeCount; i++) for (unsigned i = first; i < n - removeCount; i++)
EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint()); EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint());
} }
} }
// RemoveAllMembers() // RemoveAllMembers()
x.RemoveAllMembers(); x.RemoveAllMembers();
EXPECT_TRUE(x.ObjectEmpty()); EXPECT_TRUE(x.ObjectEmpty());
EXPECT_EQ(0u, x.MemberCount()); 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() // SetObject()
Value z; Value z;
z.SetObject(); z.SetObject();
EXPECT_TRUE(z.IsObject()); 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);
x.AddMember("A", "Apple", allocator);
x.AddMember("B", "Banana", allocator);
EXPECT_TRUE(x.EraseMember("B"));
EXPECT_FALSE(x.HasMember("B"));
EXPECT_FALSE(x.EraseMember("nonexist"));
GenericValue<UTF8<>, CrtAllocator> othername("A");
EXPECT_TRUE(x.EraseMember(othername));
EXPECT_FALSE(x.HasMember("A"));
EXPECT_TRUE(x.MemberBegin() == x.MemberEnd());
}
TEST(Value, BigNestedArray) { TEST(Value, BigNestedArray) {
MemoryPoolAllocator<> allocator; MemoryPoolAllocator<> allocator;
Value x(kArrayType); Value x(kArrayType);
static const SizeType n = 200; static const SizeType n = 200;
for (SizeType i = 0; i < n; i++) { for (SizeType i = 0; i < n; i++) {
Value y(kArrayType); Value y(kArrayType);
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
Value number((int)(i * n + j)); Value number(static_cast<int>(i * n + j));
y.PushBack(number, allocator); y.PushBack(number, allocator);
} }
x.PushBack(y, allocator); x.PushBack(y, allocator);
} }
for (SizeType i = 0; i < n; i++) for (SizeType i = 0; i < n; i++)
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
EXPECT_TRUE(x[i][j].IsInt()); EXPECT_TRUE(x[i][j].IsInt());
EXPECT_EQ((int)(i * n + j), x[i][j].GetInt()); EXPECT_EQ(static_cast<int>(i * n + j), x[i][j].GetInt());
} }
} }
TEST(Value, BigNestedObject) { TEST(Value, BigNestedObject) {
MemoryPoolAllocator<> allocator; MemoryPoolAllocator<> allocator;
Value x(kObjectType); Value x(kObjectType);
static const SizeType n = 200; static const SizeType n = 200;
for (SizeType i = 0; i < n; i++) { for (SizeType i = 0; i < n; i++) {
char name1[10]; char name1[10];
sprintf(name1, "%d", i); sprintf(name1, "%d", i);
// Value name(name1); // should not compile // Value name(name1); // should not compile
Value name(name1, (SizeType)strlen(name1), allocator); Value name(name1, static_cast<SizeType>(strlen(name1)), allocator);
Value object(kObjectType); Value object(kObjectType);
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
char name2[10]; char name2[10];
sprintf(name2, "%d", j); sprintf(name2, "%d", j);
Value name(name2, (SizeType)strlen(name2), allocator); Value name3(name2, static_cast<SizeType>(strlen(name2)), allocator);
Value number((int)(i * n + j)); Value number(static_cast<int>(i * n + j));
object.AddMember(name, number, allocator); object.AddMember(name3, number, allocator);
} }
// x.AddMember(name1, object, allocator); // should not compile // x.AddMember(name1, object, allocator); // should not compile
x.AddMember(name, object, allocator); x.AddMember(name, object, allocator);
} }
for (SizeType i = 0; i < n; i++) { for (SizeType i = 0; i < n; i++) {
char name1[10]; char name1[10];
sprintf(name1, "%d", i); sprintf(name1, "%d", i);
for (SizeType j = 0; j < n; j++) { for (SizeType j = 0; j < n; j++) {
char name2[10]; char name2[10];
sprintf(name2, "%d", j); sprintf(name2, "%d", j);
x[name1]; x[name1];
EXPECT_EQ((int)(i * n + j), x[name1][name2].GetInt()); EXPECT_EQ(static_cast<int>(i * n + j), x[name1][name2].GetInt());
} }
} }
} }
// Issue 18: Error removing last element of object // Issue 18: Error removing last element of object
// http://code.google.com/p/rapidjson/issues/detail?id=18 // http://code.google.com/p/rapidjson/issues/detail?id=18
TEST(Value, RemoveLastElement) { TEST(Value, RemoveLastElement) {
rapidjson::Document doc; rapidjson::Document doc;
rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
rapidjson::Value objVal(rapidjson::kObjectType); rapidjson::Value objVal(rapidjson::kObjectType);
skipping to change at line 1271 skipping to change at line 1644
V::AllocatorType allocator; V::AllocatorType allocator;
V o(kObjectType); V o(kObjectType);
o.AddMember("x", 1, allocator); // Should not call destructor on uninitializ ed name/value of newly allocated members. o.AddMember("x", 1, allocator); // Should not call destructor on uninitializ ed name/value of newly allocated members.
V a(kArrayType); V a(kArrayType);
a.PushBack(1, allocator); // Should not call destructor on uninitialized V alue of newly allocated elements. a.PushBack(1, allocator); // Should not call destructor on uninitialized V alue of newly allocated elements.
} }
static void TestShortStringOptimization(const char* str) { static void TestShortStringOptimization(const char* str) {
const rapidjson::SizeType len = (rapidjson::SizeType)strlen(str); const rapidjson::SizeType len = static_cast<rapidjson::SizeType>(strlen(str) );
rapidjson::Document doc; rapidjson::Document doc;
rapidjson::Value val; rapidjson::Value val;
val.SetString(str, len, doc.GetAllocator()); val.SetString(str, len, doc.GetAllocator());
EXPECT_EQ(val.GetStringLength(), len); EXPECT_EQ(val.GetStringLength(), len);
EXPECT_STREQ(val.GetString(), str); EXPECT_STREQ(val.GetString(), str);
} }
TEST(Value, AllocateShortString) { TEST(Value, AllocateShortString) {
skipping to change at line 1299 skipping to change at line 1672
template <int e> template <int e>
struct TerminateHandler { struct TerminateHandler {
bool Null() { return e != 0; } bool Null() { return e != 0; }
bool Bool(bool) { return e != 1; } bool Bool(bool) { return e != 1; }
bool Int(int) { return e != 2; } bool Int(int) { return e != 2; }
bool Uint(unsigned) { return e != 3; } bool Uint(unsigned) { return e != 3; }
bool Int64(int64_t) { return e != 4; } bool Int64(int64_t) { return e != 4; }
bool Uint64(uint64_t) { return e != 5; } bool Uint64(uint64_t) { return e != 5; }
bool Double(double) { return e != 6; } bool Double(double) { return e != 6; }
bool String(const char*, SizeType, bool) { return e != 7; } bool RawNumber(const char*, SizeType, bool) { return e != 7; }
bool StartObject() { return e != 8; } bool String(const char*, SizeType, bool) { return e != 8; }
bool Key(const char*, SizeType, bool) { return e != 9; } bool StartObject() { return e != 9; }
bool EndObject(SizeType) { return e != 10; } bool Key(const char*, SizeType, bool) { return e != 10; }
bool StartArray() { return e != 11; } bool EndObject(SizeType) { return e != 11; }
bool EndArray(SizeType) { return e != 12; } bool StartArray() { return e != 12; }
bool EndArray(SizeType) { return e != 13; }
}; };
#define TEST_TERMINATION(e, json)\ #define TEST_TERMINATION(e, json)\
{\ {\
Document d; \ Document d; \
EXPECT_FALSE(d.Parse(json).HasParseError()); \ EXPECT_FALSE(d.Parse(json).HasParseError()); \
Reader reader; \ Reader reader; \
TerminateHandler<e> h;\ TerminateHandler<e> h;\
EXPECT_FALSE(d.Accept(h));\ EXPECT_FALSE(d.Accept(h));\
} }
TEST(Value, AcceptTerminationByHandler) { TEST(Value, AcceptTerminationByHandler) {
TEST_TERMINATION(0, "[null]"); TEST_TERMINATION(0, "[null]");
TEST_TERMINATION(1, "[true]"); TEST_TERMINATION(1, "[true]");
TEST_TERMINATION(1, "[false]"); TEST_TERMINATION(1, "[false]");
TEST_TERMINATION(2, "[-1]"); TEST_TERMINATION(2, "[-1]");
TEST_TERMINATION(3, "[2147483648]"); TEST_TERMINATION(3, "[2147483648]");
TEST_TERMINATION(4, "[-1234567890123456789]"); TEST_TERMINATION(4, "[-1234567890123456789]");
TEST_TERMINATION(5, "[9223372036854775808]"); TEST_TERMINATION(5, "[9223372036854775808]");
TEST_TERMINATION(6, "[0.5]"); TEST_TERMINATION(6, "[0.5]");
TEST_TERMINATION(7, "[\"a\"]"); // RawNumber() is never called
TEST_TERMINATION(8, "[{}]"); TEST_TERMINATION(8, "[\"a\"]");
TEST_TERMINATION(9, "[{\"a\":1}]"); TEST_TERMINATION(9, "[{}]");
TEST_TERMINATION(10, "[{}]"); TEST_TERMINATION(10, "[{\"a\":1}]");
TEST_TERMINATION(11, "{\"a\":[]}"); TEST_TERMINATION(11, "[{}]");
TEST_TERMINATION(12, "{\"a\":[]}"); TEST_TERMINATION(12, "{\"a\":[]}");
TEST_TERMINATION(13, "{\"a\":[]}");
} }
struct ValueIntComparer {
bool operator()(const Value& lhs, const Value& rhs) const {
return lhs.GetInt() < rhs.GetInt();
}
};
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
TEST(Value, Sorting) {
Value::AllocatorType allocator;
Value a(kArrayType);
a.PushBack(5, allocator);
a.PushBack(1, allocator);
a.PushBack(3, allocator);
std::sort(a.Begin(), a.End(), ValueIntComparer());
EXPECT_EQ(1, a[0].GetInt());
EXPECT_EQ(3, a[1].GetInt());
EXPECT_EQ(5, a[2].GetInt());
}
#endif
// http://stackoverflow.com/questions/35222230/
static void MergeDuplicateKey(Value& v, Value::AllocatorType& a) {
if (v.IsObject()) {
// Convert all key:value into key:[value]
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();
++itr)
itr->value = Value(kArrayType).Move().PushBack(itr->value, a);
// Merge arrays if key is duplicated
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();)
{
Value::MemberIterator itr2 = v.FindMember(itr->name);
if (itr != itr2) {
itr2->value.PushBack(itr->value[0], a);
itr = v.EraseMember(itr);
}
else
++itr;
}
// Convert key:[values] back to key:value if there is only one value
for (Value::MemberIterator itr = v.MemberBegin(); itr != v.MemberEnd();
++itr) {
if (itr->value.Size() == 1)
itr->value = itr->value[0];
MergeDuplicateKey(itr->value, a); // Recursion on the value
}
}
else if (v.IsArray())
for (Value::ValueIterator itr = v.Begin(); itr != v.End(); ++itr)
MergeDuplicateKey(*itr, a);
}
TEST(Value, MergeDuplicateKey) {
Document d;
d.Parse(
"{"
" \"key1\": {"
" \"a\": \"asdf\","
" \"b\": \"foo\","
" \"b\": \"bar\","
" \"c\": \"fdas\""
" }"
"}");
Document d2;
d2.Parse(
"{"
" \"key1\": {"
" \"a\": \"asdf\","
" \"b\": ["
" \"foo\","
" \"bar\""
" ],"
" \"c\": \"fdas\""
" }"
"}");
EXPECT_NE(d2, d);
MergeDuplicateKey(d, d.GetAllocator());
EXPECT_EQ(d2, d);
}
#ifdef __clang__
RAPIDJSON_DIAG_POP
#endif
 End of changes. 67 change blocks. 
95 lines changed or deleted 477 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)