1// Tencent is pleased to support the open source community by making RapidJSON available. 2// 3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 4// 5// Licensed under the MIT License (the "License"); you may not use this file except 6// in compliance with the License. You may obtain a copy of the License at 7// 8// http://opensource.org/licenses/MIT 9// 10// Unless required by applicable law or agreed to in writing, software distributed 11// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12// CONDITIONS OF ANY KIND, either express or implied. See the License for the 13// specific language governing permissions and limitations under the License. 14 15#include "unittest.h" 16#include "rapidjson/document.h" 17#include <algorithm> 18 19using namespace rapidjson; 20 21TEST(Value, DefaultConstructor) { 22 Value x; 23 EXPECT_EQ(kNullType, x.GetType()); 24 EXPECT_TRUE(x.IsNull()); 25 26 //std::cout << "sizeof(Value): " << sizeof(x) << std::endl; 27} 28 29// Should not pass compilation 30//TEST(Value, copy_constructor) { 31// Value x(1234); 32// Value y = x; 33//} 34 35#if RAPIDJSON_HAS_CXX11_RVALUE_REFS 36 37#include <type_traits> 38 39TEST(Value, Traits) { 40 typedef GenericValue<UTF8<>, CrtAllocator> Value; 41 static_assert(std::is_constructible<Value>::value, ""); 42 static_assert(std::is_default_constructible<Value>::value, ""); 43#ifndef _MSC_VER 44 static_assert(!std::is_copy_constructible<Value>::value, ""); 45#endif 46 static_assert(std::is_move_constructible<Value>::value, ""); 47 48#ifndef _MSC_VER 49 static_assert(std::is_nothrow_constructible<Value>::value, ""); 50 static_assert(std::is_nothrow_default_constructible<Value>::value, ""); 51 static_assert(!std::is_nothrow_copy_constructible<Value>::value, ""); 52 static_assert(std::is_nothrow_move_constructible<Value>::value, ""); 53#endif 54 55 static_assert(std::is_assignable<Value,Value>::value, ""); 56#ifndef _MSC_VER 57 static_assert(!std::is_copy_assignable<Value>::value, ""); 58#endif 59 static_assert(std::is_move_assignable<Value>::value, ""); 60 61#ifndef _MSC_VER 62 static_assert(std::is_nothrow_assignable<Value, Value>::value, ""); 63#endif 64 static_assert(!std::is_nothrow_copy_assignable<Value>::value, ""); 65#ifndef _MSC_VER 66 static_assert(std::is_nothrow_move_assignable<Value>::value, ""); 67#endif 68 69 static_assert(std::is_destructible<Value>::value, ""); 70#ifndef _MSC_VER 71 static_assert(std::is_nothrow_destructible<Value>::value, ""); 72#endif 73} 74 75TEST(Value, MoveConstructor) { 76 typedef GenericValue<UTF8<>, CrtAllocator> Value; 77 Value::AllocatorType allocator; 78 79 Value x((Value(kArrayType))); 80 x.Reserve(4u, allocator); 81 x.PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator).PushBack(4, allocator); 82 EXPECT_TRUE(x.IsArray()); 83 EXPECT_EQ(4u, x.Size()); 84 85 // Value y(x); // does not compile (!is_copy_constructible) 86 Value y(std::move(x)); 87 EXPECT_TRUE(x.IsNull()); 88 EXPECT_TRUE(y.IsArray()); 89 EXPECT_EQ(4u, y.Size()); 90 91 // Value z = y; // does not compile (!is_copy_assignable) 92 Value z = std::move(y); 93 EXPECT_TRUE(y.IsNull()); 94 EXPECT_TRUE(z.IsArray()); 95 EXPECT_EQ(4u, z.Size()); 96} 97 98#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 99 100TEST(Value, AssignmentOperator) { 101 Value x(1234); 102 Value y; 103 y = x; 104 EXPECT_TRUE(x.IsNull()); // move semantic 105 EXPECT_EQ(1234, y.GetInt()); 106 107 y = 5678; 108 EXPECT_TRUE(y.IsInt()); 109 EXPECT_EQ(5678, y.GetInt()); 110 111 x = "Hello"; 112 EXPECT_TRUE(x.IsString()); 113 EXPECT_STREQ(x.GetString(),"Hello"); 114 115 y = StringRef(x.GetString(),x.GetStringLength()); 116 EXPECT_TRUE(y.IsString()); 117 EXPECT_EQ(y.GetString(),x.GetString()); 118 EXPECT_EQ(y.GetStringLength(),x.GetStringLength()); 119 120 static char mstr[] = "mutable"; 121 // y = mstr; // should not compile 122 y = StringRef(mstr); 123 EXPECT_TRUE(y.IsString()); 124 EXPECT_EQ(y.GetString(),mstr); 125 126#if RAPIDJSON_HAS_CXX11_RVALUE_REFS 127 // C++11 move assignment 128 x = Value("World"); 129 EXPECT_TRUE(x.IsString()); 130 EXPECT_STREQ("World", x.GetString()); 131 132 x = std::move(y); 133 EXPECT_TRUE(y.IsNull()); 134 EXPECT_TRUE(x.IsString()); 135 EXPECT_EQ(x.GetString(), mstr); 136 137 y = std::move(Value().SetInt(1234)); 138 EXPECT_TRUE(y.IsInt()); 139 EXPECT_EQ(1234, y); 140#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 141} 142 143template <typename A, typename B> 144void TestEqual(const A& a, const B& b) { 145 EXPECT_TRUE (a == b); 146 EXPECT_FALSE(a != b); 147 EXPECT_TRUE (b == a); 148 EXPECT_FALSE(b != a); 149} 150 151template <typename A, typename B> 152void TestUnequal(const A& a, const B& b) { 153 EXPECT_FALSE(a == b); 154 EXPECT_TRUE (a != b); 155 EXPECT_FALSE(b == a); 156 EXPECT_TRUE (b != a); 157} 158 159TEST(Value, EqualtoOperator) { 160 Value::AllocatorType allocator; 161 Value x(kObjectType); 162 x.AddMember("hello", "world", allocator) 163 .AddMember("t", Value(true).Move(), allocator) 164 .AddMember("f", Value(false).Move(), allocator) 165 .AddMember("n", Value(kNullType).Move(), allocator) 166 .AddMember("i", 123, allocator) 167 .AddMember("pi", 3.14, allocator) 168 .AddMember("a", Value(kArrayType).Move().PushBack(1, allocator).PushBack(2, allocator).PushBack(3, allocator), allocator); 169 170 // Test templated operator==() and operator!=() 171 TestEqual(x["hello"], "world"); 172 const char* cc = "world"; 173 TestEqual(x["hello"], cc); 174 char* c = strdup("world"); 175 TestEqual(x["hello"], c); 176 free(c); 177 178 TestEqual(x["t"], true); 179 TestEqual(x["f"], false); 180 TestEqual(x["i"], 123); 181 TestEqual(x["pi"], 3.14); 182 183 // Test operator==() (including different allocators) 184 CrtAllocator crtAllocator; 185 GenericValue<UTF8<>, CrtAllocator> y; 186 GenericDocument<UTF8<>, CrtAllocator> z(&crtAllocator); 187 y.CopyFrom(x, crtAllocator); 188 z.CopyFrom(y, z.GetAllocator()); 189 TestEqual(x, y); 190 TestEqual(y, z); 191 TestEqual(z, x); 192 193 // Swapping member order should be fine. 194 EXPECT_TRUE(y.RemoveMember("t")); 195 TestUnequal(x, y); 196 TestUnequal(z, y); 197 EXPECT_TRUE(z.RemoveMember("t")); 198 TestUnequal(x, z); 199 TestEqual(y, z); 200 y.AddMember("t", false, crtAllocator); 201 z.AddMember("t", false, z.GetAllocator()); 202 TestUnequal(x, y); 203 TestUnequal(z, x); 204 y["t"] = true; 205 z["t"] = true; 206 TestEqual(x, y); 207 TestEqual(y, z); 208 TestEqual(z, x); 209 210 // Swapping element order is not OK 211 x["a"][0].Swap(x["a"][1]); 212 TestUnequal(x, y); 213 x["a"][0].Swap(x["a"][1]); 214 TestEqual(x, y); 215 216 // Array of different size 217 x["a"].PushBack(4, allocator); 218 TestUnequal(x, y); 219 x["a"].PopBack(); 220 TestEqual(x, y); 221 222 // Issue #129: compare Uint64 223 x.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFF0)); 224 y.SetUint64(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0xFFFFFFFF)); 225 TestUnequal(x, y); 226} 227 228template <typename Value> 229void TestCopyFrom() { 230 typename Value::AllocatorType a; 231 Value v1(1234); 232 Value v2(v1, a); // deep copy constructor 233 EXPECT_TRUE(v1.GetType() == v2.GetType()); 234 EXPECT_EQ(v1.GetInt(), v2.GetInt()); 235 236 v1.SetString("foo"); 237 v2.CopyFrom(v1, a); 238 EXPECT_TRUE(v1.GetType() == v2.GetType()); 239 EXPECT_STREQ(v1.GetString(), v2.GetString()); 240 EXPECT_EQ(v1.GetString(), v2.GetString()); // string NOT copied 241 242 v1.SetString("bar", a); // copy string 243 v2.CopyFrom(v1, a); 244 EXPECT_TRUE(v1.GetType() == v2.GetType()); 245 EXPECT_STREQ(v1.GetString(), v2.GetString()); 246 EXPECT_NE(v1.GetString(), v2.GetString()); // string copied 247 248 249 v1.SetArray().PushBack(1234, a); 250 v2.CopyFrom(v1, a); 251 EXPECT_TRUE(v2.IsArray()); 252 EXPECT_EQ(v1.Size(), v2.Size()); 253 254 v1.PushBack(Value().SetString("foo", a), a); // push string copy 255 EXPECT_TRUE(v1.Size() != v2.Size()); 256 v2.CopyFrom(v1, a); 257 EXPECT_TRUE(v1.Size() == v2.Size()); 258 EXPECT_STREQ(v1[1].GetString(), v2[1].GetString()); 259 EXPECT_NE(v1[1].GetString(), v2[1].GetString()); // string got copied 260} 261 262TEST(Value, CopyFrom) { 263 TestCopyFrom<Value>(); 264 TestCopyFrom<GenericValue<UTF8<>, CrtAllocator> >(); 265} 266 267TEST(Value, Swap) { 268 Value v1(1234); 269 Value v2(kObjectType); 270 271 EXPECT_EQ(&v1, &v1.Swap(v2)); 272 EXPECT_TRUE(v1.IsObject()); 273 EXPECT_TRUE(v2.IsInt()); 274 EXPECT_EQ(1234, v2.GetInt()); 275 276 // testing std::swap compatibility 277 using std::swap; 278 swap(v1, v2); 279 EXPECT_TRUE(v1.IsInt()); 280 EXPECT_TRUE(v2.IsObject()); 281} 282 283TEST(Value, Null) { 284 // Default constructor 285 Value x; 286 EXPECT_EQ(kNullType, x.GetType()); 287 EXPECT_TRUE(x.IsNull()); 288 289 EXPECT_FALSE(x.IsTrue()); 290 EXPECT_FALSE(x.IsFalse()); 291 EXPECT_FALSE(x.IsNumber()); 292 EXPECT_FALSE(x.IsString()); 293 EXPECT_FALSE(x.IsObject()); 294 EXPECT_FALSE(x.IsArray()); 295 296 // Constructor with type 297 Value y(kNullType); 298 EXPECT_TRUE(y.IsNull()); 299 300 // SetNull(); 301 Value z(true); 302 z.SetNull(); 303 EXPECT_TRUE(z.IsNull()); 304} 305 306TEST(Value, True) { 307 // Constructor with bool 308 Value x(true); 309 EXPECT_EQ(kTrueType, x.GetType()); 310 EXPECT_TRUE(x.GetBool()); 311 EXPECT_TRUE(x.IsBool()); 312 EXPECT_TRUE(x.IsTrue()); 313 314 EXPECT_FALSE(x.IsNull()); 315 EXPECT_FALSE(x.IsFalse()); 316 EXPECT_FALSE(x.IsNumber()); 317 EXPECT_FALSE(x.IsString()); 318 EXPECT_FALSE(x.IsObject()); 319 EXPECT_FALSE(x.IsArray()); 320 321 // Constructor with type 322 Value y(kTrueType); 323 EXPECT_TRUE(y.IsTrue()); 324 325 // SetBool() 326 Value z; 327 z.SetBool(true); 328 EXPECT_TRUE(z.IsTrue()); 329} 330 331TEST(Value, False) { 332 // Constructor with bool 333 Value x(false); 334 EXPECT_EQ(kFalseType, x.GetType()); 335 EXPECT_TRUE(x.IsBool()); 336 EXPECT_TRUE(x.IsFalse()); 337 338 EXPECT_FALSE(x.IsNull()); 339 EXPECT_FALSE(x.IsTrue()); 340 EXPECT_FALSE(x.GetBool()); 341 //EXPECT_FALSE((bool)x); 342 EXPECT_FALSE(x.IsNumber()); 343 EXPECT_FALSE(x.IsString()); 344 EXPECT_FALSE(x.IsObject()); 345 EXPECT_FALSE(x.IsArray()); 346 347 // Constructor with type 348 Value y(kFalseType); 349 EXPECT_TRUE(y.IsFalse()); 350 351 // SetBool() 352 Value z; 353 z.SetBool(false); 354 EXPECT_TRUE(z.IsFalse()); 355} 356 357TEST(Value, Int) { 358 // Constructor with int 359 Value x(1234); 360 EXPECT_EQ(kNumberType, x.GetType()); 361 EXPECT_EQ(1234, x.GetInt()); 362 EXPECT_EQ(1234u, x.GetUint()); 363 EXPECT_EQ(1234, x.GetInt64()); 364 EXPECT_EQ(1234u, x.GetUint64()); 365 EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); 366 //EXPECT_EQ(1234, (int)x); 367 //EXPECT_EQ(1234, (unsigned)x); 368 //EXPECT_EQ(1234, (int64_t)x); 369 //EXPECT_EQ(1234, (uint64_t)x); 370 //EXPECT_EQ(1234, (double)x); 371 EXPECT_TRUE(x.IsNumber()); 372 EXPECT_TRUE(x.IsInt()); 373 EXPECT_TRUE(x.IsUint()); 374 EXPECT_TRUE(x.IsInt64()); 375 EXPECT_TRUE(x.IsUint64()); 376 377 EXPECT_FALSE(x.IsDouble()); 378 EXPECT_FALSE(x.IsNull()); 379 EXPECT_FALSE(x.IsBool()); 380 EXPECT_FALSE(x.IsFalse()); 381 EXPECT_FALSE(x.IsTrue()); 382 EXPECT_FALSE(x.IsString()); 383 EXPECT_FALSE(x.IsObject()); 384 EXPECT_FALSE(x.IsArray()); 385 386 Value nx(-1234); 387 EXPECT_EQ(-1234, nx.GetInt()); 388 EXPECT_EQ(-1234, nx.GetInt64()); 389 EXPECT_TRUE(nx.IsInt()); 390 EXPECT_TRUE(nx.IsInt64()); 391 EXPECT_FALSE(nx.IsUint()); 392 EXPECT_FALSE(nx.IsUint64()); 393 394 // Constructor with type 395 Value y(kNumberType); 396 EXPECT_TRUE(y.IsNumber()); 397 EXPECT_TRUE(y.IsInt()); 398 EXPECT_EQ(0, y.GetInt()); 399 400 // SetInt() 401 Value z; 402 z.SetInt(1234); 403 EXPECT_EQ(1234, z.GetInt()); 404 405 // operator=(int) 406 z = 5678; 407 EXPECT_EQ(5678, z.GetInt()); 408} 409 410TEST(Value, Uint) { 411 // Constructor with int 412 Value x(1234u); 413 EXPECT_EQ(kNumberType, x.GetType()); 414 EXPECT_EQ(1234, x.GetInt()); 415 EXPECT_EQ(1234u, x.GetUint()); 416 EXPECT_EQ(1234, x.GetInt64()); 417 EXPECT_EQ(1234u, x.GetUint64()); 418 EXPECT_TRUE(x.IsNumber()); 419 EXPECT_TRUE(x.IsInt()); 420 EXPECT_TRUE(x.IsUint()); 421 EXPECT_TRUE(x.IsInt64()); 422 EXPECT_TRUE(x.IsUint64()); 423 EXPECT_NEAR(1234.0, x.GetDouble(), 0.0); // Number can always be cast as double but !IsDouble(). 424 425 EXPECT_FALSE(x.IsDouble()); 426 EXPECT_FALSE(x.IsNull()); 427 EXPECT_FALSE(x.IsBool()); 428 EXPECT_FALSE(x.IsFalse()); 429 EXPECT_FALSE(x.IsTrue()); 430 EXPECT_FALSE(x.IsString()); 431 EXPECT_FALSE(x.IsObject()); 432 EXPECT_FALSE(x.IsArray()); 433 434 // SetUint() 435 Value z; 436 z.SetUint(1234); 437 EXPECT_EQ(1234u, z.GetUint()); 438 439 // operator=(unsigned) 440 z = 5678u; 441 EXPECT_EQ(5678u, z.GetUint()); 442 443 z = 2147483648u; // 2^31, cannot cast as int 444 EXPECT_EQ(2147483648u, z.GetUint()); 445 EXPECT_FALSE(z.IsInt()); 446 EXPECT_TRUE(z.IsInt64()); // Issue 41: Incorrect parsing of unsigned int number types 447} 448 449TEST(Value, Int64) { 450 // Constructor with int 451 Value x(int64_t(1234LL)); 452 EXPECT_EQ(kNumberType, x.GetType()); 453 EXPECT_EQ(1234, x.GetInt()); 454 EXPECT_EQ(1234u, x.GetUint()); 455 EXPECT_EQ(1234, x.GetInt64()); 456 EXPECT_EQ(1234u, x.GetUint64()); 457 EXPECT_TRUE(x.IsNumber()); 458 EXPECT_TRUE(x.IsInt()); 459 EXPECT_TRUE(x.IsUint()); 460 EXPECT_TRUE(x.IsInt64()); 461 EXPECT_TRUE(x.IsUint64()); 462 463 EXPECT_FALSE(x.IsDouble()); 464 EXPECT_FALSE(x.IsNull()); 465 EXPECT_FALSE(x.IsBool()); 466 EXPECT_FALSE(x.IsFalse()); 467 EXPECT_FALSE(x.IsTrue()); 468 EXPECT_FALSE(x.IsString()); 469 EXPECT_FALSE(x.IsObject()); 470 EXPECT_FALSE(x.IsArray()); 471 472 Value nx(int64_t(-1234LL)); 473 EXPECT_EQ(-1234, nx.GetInt()); 474 EXPECT_EQ(-1234, nx.GetInt64()); 475 EXPECT_TRUE(nx.IsInt()); 476 EXPECT_TRUE(nx.IsInt64()); 477 EXPECT_FALSE(nx.IsUint()); 478 EXPECT_FALSE(nx.IsUint64()); 479 480 // SetInt64() 481 Value z; 482 z.SetInt64(1234); 483 EXPECT_EQ(1234, z.GetInt64()); 484 485 z.SetInt64(2147483648LL); // 2^31, cannot cast as int 486 EXPECT_FALSE(z.IsInt()); 487 EXPECT_TRUE(z.IsUint()); 488 EXPECT_NEAR(2147483648.0, z.GetDouble(), 0.0); 489 490 z.SetInt64(4294967296LL); // 2^32, cannot cast as uint 491 EXPECT_FALSE(z.IsInt()); 492 EXPECT_FALSE(z.IsUint()); 493 EXPECT_NEAR(4294967296.0, z.GetDouble(), 0.0); 494 495 z.SetInt64(-2147483649LL); // -2^31-1, cannot cast as int 496 EXPECT_FALSE(z.IsInt()); 497 EXPECT_NEAR(-2147483649.0, z.GetDouble(), 0.0); 498 499 z.SetInt64(static_cast<int64_t>(RAPIDJSON_UINT64_C2(0x80000000, 00000000))); 500 EXPECT_DOUBLE_EQ(-9223372036854775808.0, z.GetDouble()); 501} 502 503TEST(Value, Uint64) { 504 // Constructor with int 505 Value x(uint64_t(1234LL)); 506 EXPECT_EQ(kNumberType, x.GetType()); 507 EXPECT_EQ(1234, x.GetInt()); 508 EXPECT_EQ(1234u, x.GetUint()); 509 EXPECT_EQ(1234, x.GetInt64()); 510 EXPECT_EQ(1234u, x.GetUint64()); 511 EXPECT_TRUE(x.IsNumber()); 512 EXPECT_TRUE(x.IsInt()); 513 EXPECT_TRUE(x.IsUint()); 514 EXPECT_TRUE(x.IsInt64()); 515 EXPECT_TRUE(x.IsUint64()); 516 517 EXPECT_FALSE(x.IsDouble()); 518 EXPECT_FALSE(x.IsNull()); 519 EXPECT_FALSE(x.IsBool()); 520 EXPECT_FALSE(x.IsFalse()); 521 EXPECT_FALSE(x.IsTrue()); 522 EXPECT_FALSE(x.IsString()); 523 EXPECT_FALSE(x.IsObject()); 524 EXPECT_FALSE(x.IsArray()); 525 526 // SetUint64() 527 Value z; 528 z.SetUint64(1234); 529 EXPECT_EQ(1234u, z.GetUint64()); 530 531 z.SetUint64(2147483648LL); // 2^31, cannot cast as int 532 EXPECT_FALSE(z.IsInt()); 533 EXPECT_TRUE(z.IsUint()); 534 EXPECT_TRUE(z.IsInt64()); 535 536 z.SetUint64(4294967296LL); // 2^32, cannot cast as uint 537 EXPECT_FALSE(z.IsInt()); 538 EXPECT_FALSE(z.IsUint()); 539 EXPECT_TRUE(z.IsInt64()); 540 541 z.SetUint64(9223372036854775808uLL); // 2^63 cannot cast as int64 542 EXPECT_FALSE(z.IsInt64()); 543 EXPECT_EQ(9223372036854775808uLL, z.GetUint64()); // Issue 48 544 EXPECT_DOUBLE_EQ(9223372036854775808.0, z.GetDouble()); 545} 546 547TEST(Value, Double) { 548 // Constructor with double 549 Value x(12.34); 550 EXPECT_EQ(kNumberType, x.GetType()); 551 EXPECT_NEAR(12.34, x.GetDouble(), 0.0); 552 EXPECT_TRUE(x.IsNumber()); 553 EXPECT_TRUE(x.IsDouble()); 554 555 EXPECT_FALSE(x.IsInt()); 556 EXPECT_FALSE(x.IsNull()); 557 EXPECT_FALSE(x.IsBool()); 558 EXPECT_FALSE(x.IsFalse()); 559 EXPECT_FALSE(x.IsTrue()); 560 EXPECT_FALSE(x.IsString()); 561 EXPECT_FALSE(x.IsObject()); 562 EXPECT_FALSE(x.IsArray()); 563 564 // SetDouble() 565 Value z; 566 z.SetDouble(12.34); 567 EXPECT_NEAR(12.34, z.GetDouble(), 0.0); 568 569 z = 56.78; 570 EXPECT_NEAR(56.78, z.GetDouble(), 0.0); 571} 572 573TEST(Value, String) { 574 // Construction with const string 575 Value x("Hello", 5); // literal 576 EXPECT_EQ(kStringType, x.GetType()); 577 EXPECT_TRUE(x.IsString()); 578 EXPECT_STREQ("Hello", x.GetString()); 579 EXPECT_EQ(5u, x.GetStringLength()); 580 581 EXPECT_FALSE(x.IsNumber()); 582 EXPECT_FALSE(x.IsNull()); 583 EXPECT_FALSE(x.IsBool()); 584 EXPECT_FALSE(x.IsFalse()); 585 EXPECT_FALSE(x.IsTrue()); 586 EXPECT_FALSE(x.IsObject()); 587 EXPECT_FALSE(x.IsArray()); 588 589 static const char cstr[] = "World"; // const array 590 Value(cstr).Swap(x); 591 EXPECT_TRUE(x.IsString()); 592 EXPECT_EQ(x.GetString(), cstr); 593 EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1); 594 595 static char mstr[] = "Howdy"; // non-const array 596 // Value(mstr).Swap(x); // should not compile 597 Value(StringRef(mstr)).Swap(x); 598 EXPECT_TRUE(x.IsString()); 599 EXPECT_EQ(x.GetString(), mstr); 600 EXPECT_EQ(x.GetStringLength(), sizeof(mstr)-1); 601 strncpy(mstr,"Hello", sizeof(mstr)); 602 EXPECT_STREQ(x.GetString(), "Hello"); 603 604 const char* pstr = cstr; 605 //Value(pstr).Swap(x); // should not compile 606 Value(StringRef(pstr)).Swap(x); 607 EXPECT_TRUE(x.IsString()); 608 EXPECT_EQ(x.GetString(), cstr); 609 EXPECT_EQ(x.GetStringLength(), sizeof(cstr)-1); 610 611 char* mpstr = mstr; 612 Value(StringRef(mpstr,sizeof(mstr)-1)).Swap(x); 613 EXPECT_TRUE(x.IsString()); 614 EXPECT_EQ(x.GetString(), mstr); 615 EXPECT_EQ(x.GetStringLength(), 5u); 616 EXPECT_STREQ(x.GetString(), "Hello"); 617 618 // Constructor with copy string 619 MemoryPoolAllocator<> allocator; 620 Value c(x.GetString(), x.GetStringLength(), allocator); 621 EXPECT_NE(x.GetString(), c.GetString()); 622 EXPECT_EQ(x.GetStringLength(), c.GetStringLength()); 623 EXPECT_STREQ(x.GetString(), c.GetString()); 624 //x.SetString("World"); 625 x.SetString("World", 5); 626 EXPECT_STREQ("Hello", c.GetString()); 627 EXPECT_EQ(5u, c.GetStringLength()); 628 629 // Constructor with type 630 Value y(kStringType); 631 EXPECT_TRUE(y.IsString()); 632 EXPECT_STREQ("", y.GetString()); // Empty string should be "" instead of 0 (issue 226) 633 EXPECT_EQ(0u, y.GetStringLength()); 634 635 // SetConsttring() 636 Value z; 637 z.SetString("Hello"); 638 EXPECT_TRUE(x.IsString()); 639 z.SetString("Hello", 5); 640 EXPECT_STREQ("Hello", z.GetString()); 641 EXPECT_STREQ("Hello", z.GetString()); 642 EXPECT_EQ(5u, z.GetStringLength()); 643 644 z.SetString("Hello"); 645 EXPECT_TRUE(z.IsString()); 646 EXPECT_STREQ("Hello", z.GetString()); 647 648 //z.SetString(mstr); // should not compile 649 //z.SetString(pstr); // should not compile 650 z.SetString(StringRef(mstr)); 651 EXPECT_TRUE(z.IsString()); 652 EXPECT_STREQ(z.GetString(), mstr); 653 654 z.SetString(cstr); 655 EXPECT_TRUE(z.IsString()); 656 EXPECT_EQ(cstr, z.GetString()); 657 658 z = cstr; 659 EXPECT_TRUE(z.IsString()); 660 EXPECT_EQ(cstr, z.GetString()); 661 662 // SetString() 663 char s[] = "World"; 664 Value w; 665 w.SetString(s, (SizeType)strlen(s), allocator); 666 s[0] = '\0'; 667 EXPECT_STREQ("World", w.GetString()); 668 EXPECT_EQ(5u, w.GetStringLength()); 669 670#if RAPIDJSON_HAS_STDSTRING 671 { 672 std::string str = "Hello World"; 673 str[5] = '\0'; 674 EXPECT_STREQ(str.data(),"Hello"); // embedded '\0' 675 EXPECT_EQ(str.size(), 11u); 676 677 // no copy 678 Value vs0(StringRef(str)); 679 EXPECT_TRUE(vs0.IsString()); 680 EXPECT_EQ(vs0.GetString(), str.data()); 681 EXPECT_EQ(vs0.GetStringLength(), str.size()); 682 TestEqual(vs0, str); 683 684 // do copy 685 Value vs1(str, allocator); 686 EXPECT_TRUE(vs1.IsString()); 687 EXPECT_NE(vs1.GetString(), str.data()); 688 EXPECT_NE(vs1.GetString(), str); // not equal due to embedded '\0' 689 EXPECT_EQ(vs1.GetStringLength(), str.size()); 690 TestEqual(vs1, str); 691 692 // SetString 693 str = "World"; 694 vs0.SetNull().SetString(str, allocator); 695 EXPECT_TRUE(vs0.IsString()); 696 EXPECT_STREQ(vs0.GetString(), str.c_str()); 697 EXPECT_EQ(vs0.GetStringLength(), str.size()); 698 TestEqual(str, vs0); 699 TestUnequal(str, vs1); 700 701 // vs1 = str; // should not compile 702 vs1 = StringRef(str); 703 TestEqual(str, vs1); 704 TestEqual(vs0, vs1); 705 } 706#endif // RAPIDJSON_HAS_STDSTRING 707} 708 709// Issue 226: Value of string type should not point to NULL 710TEST(Value, SetStringNullException) { 711 Value v; 712 EXPECT_THROW(v.SetString(0, 0), AssertException); 713} 714 715TEST(Value, Array) { 716 Value x(kArrayType); 717 const Value& y = x; 718 Value::AllocatorType allocator; 719 720 EXPECT_EQ(kArrayType, x.GetType()); 721 EXPECT_TRUE(x.IsArray()); 722 EXPECT_TRUE(x.Empty()); 723 EXPECT_EQ(0u, x.Size()); 724 EXPECT_TRUE(y.IsArray()); 725 EXPECT_TRUE(y.Empty()); 726 EXPECT_EQ(0u, y.Size()); 727 728 EXPECT_FALSE(x.IsNull()); 729 EXPECT_FALSE(x.IsBool()); 730 EXPECT_FALSE(x.IsFalse()); 731 EXPECT_FALSE(x.IsTrue()); 732 EXPECT_FALSE(x.IsString()); 733 EXPECT_FALSE(x.IsObject()); 734 735 // PushBack() 736 Value v; 737 x.PushBack(v, allocator); 738 v.SetBool(true); 739 x.PushBack(v, allocator); 740 v.SetBool(false); 741 x.PushBack(v, allocator); 742 v.SetInt(123); 743 x.PushBack(v, allocator); 744 //x.PushBack((const char*)"foo", allocator); // should not compile 745 x.PushBack("foo", allocator); 746 747 EXPECT_FALSE(x.Empty()); 748 EXPECT_EQ(5u, x.Size()); 749 EXPECT_FALSE(y.Empty()); 750 EXPECT_EQ(5u, y.Size()); 751 EXPECT_TRUE(x[SizeType(0)].IsNull()); 752 EXPECT_TRUE(x[1].IsTrue()); 753 EXPECT_TRUE(x[2].IsFalse()); 754 EXPECT_TRUE(x[3].IsInt()); 755 EXPECT_EQ(123, x[3].GetInt()); 756 EXPECT_TRUE(y[SizeType(0)].IsNull()); 757 EXPECT_TRUE(y[1].IsTrue()); 758 EXPECT_TRUE(y[2].IsFalse()); 759 EXPECT_TRUE(y[3].IsInt()); 760 EXPECT_EQ(123, y[3].GetInt()); 761 EXPECT_TRUE(y[4].IsString()); 762 EXPECT_STREQ("foo", y[4].GetString()); 763 764#if RAPIDJSON_HAS_CXX11_RVALUE_REFS 765 // PushBack(GenericValue&&, Allocator&); 766 { 767 Value y(kArrayType); 768 y.PushBack(Value(true), allocator); 769 y.PushBack(std::move(Value(kArrayType).PushBack(Value(1), allocator).PushBack("foo", allocator)), allocator); 770 EXPECT_EQ(2u, y.Size()); 771 EXPECT_TRUE(y[0].IsTrue()); 772 EXPECT_TRUE(y[1].IsArray()); 773 EXPECT_EQ(2u, y[1].Size()); 774 EXPECT_TRUE(y[1][0].IsInt()); 775 EXPECT_TRUE(y[1][1].IsString()); 776 } 777#endif 778 779 // iterator 780 Value::ValueIterator itr = x.Begin(); 781 EXPECT_TRUE(itr != x.End()); 782 EXPECT_TRUE(itr->IsNull()); 783 ++itr; 784 EXPECT_TRUE(itr != x.End()); 785 EXPECT_TRUE(itr->IsTrue()); 786 ++itr; 787 EXPECT_TRUE(itr != x.End()); 788 EXPECT_TRUE(itr->IsFalse()); 789 ++itr; 790 EXPECT_TRUE(itr != x.End()); 791 EXPECT_TRUE(itr->IsInt()); 792 EXPECT_EQ(123, itr->GetInt()); 793 ++itr; 794 EXPECT_TRUE(itr != x.End()); 795 EXPECT_TRUE(itr->IsString()); 796 EXPECT_STREQ("foo", itr->GetString()); 797 798 // const iterator 799 Value::ConstValueIterator citr = y.Begin(); 800 EXPECT_TRUE(citr != y.End()); 801 EXPECT_TRUE(citr->IsNull()); 802 ++citr; 803 EXPECT_TRUE(citr != y.End()); 804 EXPECT_TRUE(citr->IsTrue()); 805 ++citr; 806 EXPECT_TRUE(citr != y.End()); 807 EXPECT_TRUE(citr->IsFalse()); 808 ++citr; 809 EXPECT_TRUE(citr != y.End()); 810 EXPECT_TRUE(citr->IsInt()); 811 EXPECT_EQ(123, citr->GetInt()); 812 ++citr; 813 EXPECT_TRUE(citr != y.End()); 814 EXPECT_TRUE(citr->IsString()); 815 EXPECT_STREQ("foo", citr->GetString()); 816 817 // PopBack() 818 x.PopBack(); 819 EXPECT_EQ(4u, x.Size()); 820 EXPECT_TRUE(y[SizeType(0)].IsNull()); 821 EXPECT_TRUE(y[1].IsTrue()); 822 EXPECT_TRUE(y[2].IsFalse()); 823 EXPECT_TRUE(y[3].IsInt()); 824 825 // Clear() 826 x.Clear(); 827 EXPECT_TRUE(x.Empty()); 828 EXPECT_EQ(0u, x.Size()); 829 EXPECT_TRUE(y.Empty()); 830 EXPECT_EQ(0u, y.Size()); 831 832 // Erase(ValueIterator) 833 834 // Use array of array to ensure removed elements' destructor is called. 835 // [[0],[1],[2],...] 836 for (int i = 0; i < 10; i++) 837 x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator); 838 839 // Erase the first 840 itr = x.Erase(x.Begin()); 841 EXPECT_EQ(x.Begin(), itr); 842 EXPECT_EQ(9u, x.Size()); 843 for (int i = 0; i < 9; i++) 844 EXPECT_EQ(i + 1, x[i][0].GetInt()); 845 846 // Ease the last 847 itr = x.Erase(x.End() - 1); 848 EXPECT_EQ(x.End(), itr); 849 EXPECT_EQ(8u, x.Size()); 850 for (int i = 0; i < 8; i++) 851 EXPECT_EQ(i + 1, x[i][0].GetInt()); 852 853 // Erase the middle 854 itr = x.Erase(x.Begin() + 4); 855 EXPECT_EQ(x.Begin() + 4, itr); 856 EXPECT_EQ(7u, x.Size()); 857 for (int i = 0; i < 4; i++) 858 EXPECT_EQ(i + 1, x[i][0].GetInt()); 859 for (int i = 4; i < 7; i++) 860 EXPECT_EQ(i + 2, x[i][0].GetInt()); 861 862 // Erase(ValueIterator, ValueIterator) 863 // Exhaustive test with all 0 <= first < n, first <= last <= n cases 864 const unsigned n = 10; 865 for (unsigned first = 0; first < n; first++) { 866 for (unsigned last = first; last <= n; last++) { 867 x.Clear(); 868 for (unsigned i = 0; i < n; i++) 869 x.PushBack(Value(kArrayType).PushBack(i, allocator).Move(), allocator); 870 871 itr = x.Erase(x.Begin() + first, x.Begin() + last); 872 if (last == n) 873 EXPECT_EQ(x.End(), itr); 874 else 875 EXPECT_EQ(x.Begin() + first, itr); 876 877 size_t removeCount = last - first; 878 EXPECT_EQ(n - removeCount, x.Size()); 879 for (unsigned i = 0; i < first; i++) 880 EXPECT_EQ(i, x[i][0].GetUint()); 881 for (unsigned i = first; i < n - removeCount; i++) 882 EXPECT_EQ(i + removeCount, x[i][0].GetUint()); 883 } 884 } 885 886 // Working in gcc without C++11, but VS2013 cannot compile. To be diagnosed. 887 // http://en.wikipedia.org/wiki/Erase-remove_idiom 888 x.Clear(); 889 for (int i = 0; i < 10; i++) 890 if (i % 2 == 0) 891 x.PushBack(i, allocator); 892 else 893 x.PushBack(Value(kNullType).Move(), allocator); 894 895 const Value null(kNullType); 896 x.Erase(std::remove(x.Begin(), x.End(), null), x.End()); 897 EXPECT_EQ(5u, x.Size()); 898 for (int i = 0; i < 5; i++) 899 EXPECT_EQ(i * 2, x[i]); 900 901 // SetArray() 902 Value z; 903 z.SetArray(); 904 EXPECT_TRUE(z.IsArray()); 905 EXPECT_TRUE(z.Empty()); 906} 907 908TEST(Value, Object) { 909 Value x(kObjectType); 910 const Value& y = x; // const version 911 Value::AllocatorType allocator; 912 913 EXPECT_EQ(kObjectType, x.GetType()); 914 EXPECT_TRUE(x.IsObject()); 915 EXPECT_TRUE(x.ObjectEmpty()); 916 EXPECT_EQ(0u, x.MemberCount()); 917 EXPECT_EQ(kObjectType, y.GetType()); 918 EXPECT_TRUE(y.IsObject()); 919 EXPECT_TRUE(y.ObjectEmpty()); 920 EXPECT_EQ(0u, y.MemberCount()); 921 922 // AddMember() 923 x.AddMember("A", "Apple", allocator); 924 EXPECT_FALSE(x.ObjectEmpty()); 925 EXPECT_EQ(1u, x.MemberCount()); 926 927 Value value("Banana", 6); 928 x.AddMember("B", "Banana", allocator); 929 EXPECT_EQ(2u, x.MemberCount()); 930 931 // AddMember<T>(StringRefType, T, Allocator) 932 { 933 Value o(kObjectType); 934 o.AddMember("true", true, allocator); 935 o.AddMember("false", false, allocator); 936 o.AddMember("int", -1, allocator); 937 o.AddMember("uint", 1u, allocator); 938 o.AddMember("int64", INT64_C(-4294967296), allocator); 939 o.AddMember("uint64", UINT64_C(4294967296), allocator); 940 o.AddMember("double", 3.14, allocator); 941 o.AddMember("string", "Jelly", allocator); 942 943 EXPECT_TRUE(o["true"].GetBool()); 944 EXPECT_FALSE(o["false"].GetBool()); 945 EXPECT_EQ(-1, o["int"].GetInt()); 946 EXPECT_EQ(1u, o["uint"].GetUint()); 947 EXPECT_EQ(INT64_C(-4294967296), o["int64"].GetInt64()); 948 EXPECT_EQ(UINT64_C(4294967296), o["uint64"].GetUint64()); 949 EXPECT_STREQ("Jelly",o["string"].GetString()); 950 EXPECT_EQ(8u, o.MemberCount()); 951 } 952 953 // AddMember<T>(Value&, T, Allocator) 954 { 955 Value o(kObjectType); 956 957 Value n("s"); 958 o.AddMember(n, "string", allocator); 959 EXPECT_EQ(1u, o.MemberCount()); 960 961 Value count("#"); 962 o.AddMember(count, o.MemberCount(), allocator); 963 EXPECT_EQ(2u, o.MemberCount()); 964 } 965 966#if RAPIDJSON_HAS_STDSTRING 967 { 968 // AddMember(StringRefType, const std::string&, Allocator) 969 Value o(kObjectType); 970 o.AddMember("b", std::string("Banana"), allocator); 971 EXPECT_STREQ("Banana", o["b"].GetString()); 972 973 // RemoveMember(const std::string&) 974 o.RemoveMember(std::string("b")); 975 EXPECT_TRUE(o.ObjectEmpty()); 976 } 977#endif 978 979#if RAPIDJSON_HAS_CXX11_RVALUE_REFS 980 // AddMember(GenericValue&&, ...) variants 981 { 982 Value o(kObjectType); 983 o.AddMember(Value("true"), Value(true), allocator); 984 o.AddMember(Value("false"), Value(false).Move(), allocator); // value is lvalue ref 985 o.AddMember(Value("int").Move(), Value(-1), allocator); // name is lvalue ref 986 o.AddMember("uint", std::move(Value().SetUint(1u)), allocator); // name is literal, value is rvalue 987 EXPECT_TRUE(o["true"].GetBool()); 988 EXPECT_FALSE(o["false"].GetBool()); 989 EXPECT_EQ(-1, o["int"].GetInt()); 990 EXPECT_EQ(1u, o["uint"].GetUint()); 991 EXPECT_EQ(4u, o.MemberCount()); 992 } 993#endif 994 995 // Tests a member with null character 996 Value name; 997 const Value C0D("C\0D", 3); 998 name.SetString(C0D.GetString(), 3); 999 value.SetString("CherryD", 7); 1000 x.AddMember(name, value, allocator); 1001 1002 // HasMember() 1003 EXPECT_TRUE(x.HasMember("A")); 1004 EXPECT_TRUE(x.HasMember("B")); 1005 EXPECT_TRUE(y.HasMember("A")); 1006 EXPECT_TRUE(y.HasMember("B")); 1007 1008#if RAPIDJSON_HAS_STDSTRING 1009 EXPECT_TRUE(x.HasMember(std::string("A"))); 1010#endif 1011 1012 name.SetString("C\0D"); 1013 EXPECT_TRUE(x.HasMember(name)); 1014 EXPECT_TRUE(y.HasMember(name)); 1015 1016 GenericValue<UTF8<>, CrtAllocator> othername("A"); 1017 EXPECT_TRUE(x.HasMember(othername)); 1018 EXPECT_TRUE(y.HasMember(othername)); 1019 othername.SetString("C\0D"); 1020 EXPECT_TRUE(x.HasMember(othername)); 1021 EXPECT_TRUE(y.HasMember(othername)); 1022 1023 // operator[] 1024 EXPECT_STREQ("Apple", x["A"].GetString()); 1025 EXPECT_STREQ("Banana", x["B"].GetString()); 1026 EXPECT_STREQ("CherryD", x[C0D].GetString()); 1027 EXPECT_STREQ("CherryD", x[othername].GetString()); 1028 EXPECT_THROW(x["nonexist"], AssertException); 1029 1030 // const operator[] 1031 EXPECT_STREQ("Apple", y["A"].GetString()); 1032 EXPECT_STREQ("Banana", y["B"].GetString()); 1033 EXPECT_STREQ("CherryD", y[C0D].GetString()); 1034 1035#if RAPIDJSON_HAS_STDSTRING 1036 EXPECT_STREQ("Apple", x["A"].GetString()); 1037 EXPECT_STREQ("Apple", y[std::string("A")].GetString()); 1038#endif 1039 1040 // member iterator 1041 Value::MemberIterator itr = x.MemberBegin(); 1042 EXPECT_TRUE(itr != x.MemberEnd()); 1043 EXPECT_STREQ("A", itr->name.GetString()); 1044 EXPECT_STREQ("Apple", itr->value.GetString()); 1045 ++itr; 1046 EXPECT_TRUE(itr != x.MemberEnd()); 1047 EXPECT_STREQ("B", itr->name.GetString()); 1048 EXPECT_STREQ("Banana", itr->value.GetString()); 1049 ++itr; 1050 EXPECT_TRUE(itr != x.MemberEnd()); 1051 EXPECT_TRUE(memcmp(itr->name.GetString(), "C\0D", 4) == 0); 1052 EXPECT_STREQ("CherryD", itr->value.GetString()); 1053 ++itr; 1054 EXPECT_FALSE(itr != x.MemberEnd()); 1055 1056 // const member iterator 1057 Value::ConstMemberIterator citr = y.MemberBegin(); 1058 EXPECT_TRUE(citr != y.MemberEnd()); 1059 EXPECT_STREQ("A", citr->name.GetString()); 1060 EXPECT_STREQ("Apple", citr->value.GetString()); 1061 ++citr; 1062 EXPECT_TRUE(citr != y.MemberEnd()); 1063 EXPECT_STREQ("B", citr->name.GetString()); 1064 EXPECT_STREQ("Banana", citr->value.GetString()); 1065 ++citr; 1066 EXPECT_TRUE(citr != y.MemberEnd()); 1067 EXPECT_TRUE(memcmp(citr->name.GetString(), "C\0D", 4) == 0); 1068 EXPECT_STREQ("CherryD", citr->value.GetString()); 1069 ++citr; 1070 EXPECT_FALSE(citr != y.MemberEnd()); 1071 1072 // member iterator conversions/relations 1073 itr = x.MemberBegin(); 1074 citr = x.MemberBegin(); // const conversion 1075 TestEqual(itr, citr); 1076 EXPECT_TRUE(itr < x.MemberEnd()); 1077 EXPECT_FALSE(itr > y.MemberEnd()); 1078 EXPECT_TRUE(citr < x.MemberEnd()); 1079 EXPECT_FALSE(citr > y.MemberEnd()); 1080 ++citr; 1081 TestUnequal(itr, citr); 1082 EXPECT_FALSE(itr < itr); 1083 EXPECT_TRUE(itr < citr); 1084 EXPECT_FALSE(itr > itr); 1085 EXPECT_TRUE(citr > itr); 1086 EXPECT_EQ(1, citr - x.MemberBegin()); 1087 EXPECT_EQ(0, itr - y.MemberBegin()); 1088 itr += citr - x.MemberBegin(); 1089 EXPECT_EQ(1, itr - y.MemberBegin()); 1090 TestEqual(citr, itr); 1091 EXPECT_TRUE(itr <= citr); 1092 EXPECT_TRUE(citr <= itr); 1093 itr++; 1094 EXPECT_TRUE(itr >= citr); 1095 EXPECT_FALSE(citr >= itr); 1096 1097 // RemoveMember() 1098 EXPECT_TRUE(x.RemoveMember("A")); 1099 EXPECT_FALSE(x.HasMember("A")); 1100 1101 EXPECT_TRUE(x.RemoveMember("B")); 1102 EXPECT_FALSE(x.HasMember("B")); 1103 1104 EXPECT_FALSE(x.RemoveMember("nonexist")); 1105 1106 EXPECT_TRUE(x.RemoveMember(othername)); 1107 EXPECT_FALSE(x.HasMember(name)); 1108 1109 EXPECT_TRUE(x.MemberBegin() == x.MemberEnd()); 1110 1111 // EraseMember(ConstMemberIterator) 1112 1113 // Use array members to ensure removed elements' destructor is called. 1114 // { "a": [0], "b": [1],[2],...] 1115 const char keys[][2] = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" }; 1116 for (int i = 0; i < 10; i++) 1117 x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator); 1118 1119 // MemberCount, iterator difference 1120 EXPECT_EQ(x.MemberCount(), SizeType(x.MemberEnd() - x.MemberBegin())); 1121 1122 // Erase the first 1123 itr = x.EraseMember(x.MemberBegin()); 1124 EXPECT_FALSE(x.HasMember(keys[0])); 1125 EXPECT_EQ(x.MemberBegin(), itr); 1126 EXPECT_EQ(9u, x.MemberCount()); 1127 for (; itr != x.MemberEnd(); ++itr) { 1128 int i = (itr - x.MemberBegin()) + 1; 1129 EXPECT_STREQ(itr->name.GetString(), keys[i]); 1130 EXPECT_EQ(i, itr->value[0].GetInt()); 1131 } 1132 1133 // Erase the last 1134 itr = x.EraseMember(x.MemberEnd() - 1); 1135 EXPECT_FALSE(x.HasMember(keys[9])); 1136 EXPECT_EQ(x.MemberEnd(), itr); 1137 EXPECT_EQ(8u, x.MemberCount()); 1138 for (; itr != x.MemberEnd(); ++itr) { 1139 int i = (itr - x.MemberBegin()) + 1; 1140 EXPECT_STREQ(itr->name.GetString(), keys[i]); 1141 EXPECT_EQ(i, itr->value[0].GetInt()); 1142 } 1143 1144 // Erase the middle 1145 itr = x.EraseMember(x.MemberBegin() + 4); 1146 EXPECT_FALSE(x.HasMember(keys[5])); 1147 EXPECT_EQ(x.MemberBegin() + 4, itr); 1148 EXPECT_EQ(7u, x.MemberCount()); 1149 for (; itr != x.MemberEnd(); ++itr) { 1150 int i = (itr - x.MemberBegin()); 1151 i += (i<4) ? 1 : 2; 1152 EXPECT_STREQ(itr->name.GetString(), keys[i]); 1153 EXPECT_EQ(i, itr->value[0].GetInt()); 1154 } 1155 1156 // EraseMember(ConstMemberIterator, ConstMemberIterator) 1157 // Exhaustive test with all 0 <= first < n, first <= last <= n cases 1158 const unsigned n = 10; 1159 for (unsigned first = 0; first < n; first++) { 1160 for (unsigned last = first; last <= n; last++) { 1161 Value(kObjectType).Swap(x); 1162 for (unsigned i = 0; i < n; i++) 1163 x.AddMember(keys[i], Value(kArrayType).PushBack(i, allocator), allocator); 1164 1165 itr = x.EraseMember(x.MemberBegin() + first, x.MemberBegin() + last); 1166 if (last == n) 1167 EXPECT_EQ(x.MemberEnd(), itr); 1168 else 1169 EXPECT_EQ(x.MemberBegin() + first, itr); 1170 1171 size_t removeCount = last - first; 1172 EXPECT_EQ(n - removeCount, x.MemberCount()); 1173 for (unsigned i = 0; i < first; i++) 1174 EXPECT_EQ(i, x[keys[i]][0].GetUint()); 1175 for (unsigned i = first; i < n - removeCount; i++) 1176 EXPECT_EQ(i + removeCount, x[keys[i+removeCount]][0].GetUint()); 1177 } 1178 } 1179 1180 // RemoveAllMembers() 1181 x.RemoveAllMembers(); 1182 EXPECT_TRUE(x.ObjectEmpty()); 1183 EXPECT_EQ(0u, x.MemberCount()); 1184 1185 // SetObject() 1186 Value z; 1187 z.SetObject(); 1188 EXPECT_TRUE(z.IsObject()); 1189} 1190 1191TEST(Value, EraseMember_String) { 1192 Value::AllocatorType allocator; 1193 Value x(kObjectType); 1194 x.AddMember("A", "Apple", allocator); 1195 x.AddMember("B", "Banana", allocator); 1196 1197 EXPECT_TRUE(x.EraseMember("B")); 1198 EXPECT_FALSE(x.HasMember("B")); 1199 1200 EXPECT_FALSE(x.EraseMember("nonexist")); 1201 1202 GenericValue<UTF8<>, CrtAllocator> othername("A"); 1203 EXPECT_TRUE(x.EraseMember(othername)); 1204 EXPECT_FALSE(x.HasMember("A")); 1205 1206 EXPECT_TRUE(x.MemberBegin() == x.MemberEnd()); 1207} 1208 1209TEST(Value, BigNestedArray) { 1210 MemoryPoolAllocator<> allocator; 1211 Value x(kArrayType); 1212 static const SizeType n = 200; 1213 1214 for (SizeType i = 0; i < n; i++) { 1215 Value y(kArrayType); 1216 for (SizeType j = 0; j < n; j++) { 1217 Value number((int)(i * n + j)); 1218 y.PushBack(number, allocator); 1219 } 1220 x.PushBack(y, allocator); 1221 } 1222 1223 for (SizeType i = 0; i < n; i++) 1224 for (SizeType j = 0; j < n; j++) { 1225 EXPECT_TRUE(x[i][j].IsInt()); 1226 EXPECT_EQ((int)(i * n + j), x[i][j].GetInt()); 1227 } 1228} 1229 1230TEST(Value, BigNestedObject) { 1231 MemoryPoolAllocator<> allocator; 1232 Value x(kObjectType); 1233 static const SizeType n = 200; 1234 1235 for (SizeType i = 0; i < n; i++) { 1236 char name1[10]; 1237 sprintf(name1, "%d", i); 1238 1239 // Value name(name1); // should not compile 1240 Value name(name1, (SizeType)strlen(name1), allocator); 1241 Value object(kObjectType); 1242 1243 for (SizeType j = 0; j < n; j++) { 1244 char name2[10]; 1245 sprintf(name2, "%d", j); 1246 1247 Value name(name2, (SizeType)strlen(name2), allocator); 1248 Value number((int)(i * n + j)); 1249 object.AddMember(name, number, allocator); 1250 } 1251 1252 // x.AddMember(name1, object, allocator); // should not compile 1253 x.AddMember(name, object, allocator); 1254 } 1255 1256 for (SizeType i = 0; i < n; i++) { 1257 char name1[10]; 1258 sprintf(name1, "%d", i); 1259 1260 for (SizeType j = 0; j < n; j++) { 1261 char name2[10]; 1262 sprintf(name2, "%d", j); 1263 x[name1]; 1264 EXPECT_EQ((int)(i * n + j), x[name1][name2].GetInt()); 1265 } 1266 } 1267} 1268 1269// Issue 18: Error removing last element of object 1270// http://code.google.com/p/rapidjson/issues/detail?id=18 1271TEST(Value, RemoveLastElement) { 1272 rapidjson::Document doc; 1273 rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); 1274 rapidjson::Value objVal(rapidjson::kObjectType); 1275 objVal.AddMember("var1", 123, allocator); 1276 objVal.AddMember("var2", "444", allocator); 1277 objVal.AddMember("var3", 555, allocator); 1278 EXPECT_TRUE(objVal.HasMember("var3")); 1279 objVal.RemoveMember("var3"); // Assertion here in r61 1280 EXPECT_FALSE(objVal.HasMember("var3")); 1281} 1282 1283// Issue 38: Segmentation fault with CrtAllocator 1284TEST(Document, CrtAllocator) { 1285 typedef GenericValue<UTF8<>, CrtAllocator> V; 1286 1287 V::AllocatorType allocator; 1288 V o(kObjectType); 1289 o.AddMember("x", 1, allocator); // Should not call destructor on uninitialized name/value of newly allocated members. 1290 1291 V a(kArrayType); 1292 a.PushBack(1, allocator); // Should not call destructor on uninitialized Value of newly allocated elements. 1293} 1294 1295static void TestShortStringOptimization(const char* str) { 1296 const rapidjson::SizeType len = (rapidjson::SizeType)strlen(str); 1297 1298 rapidjson::Document doc; 1299 rapidjson::Value val; 1300 val.SetString(str, len, doc.GetAllocator()); 1301 1302 EXPECT_EQ(val.GetStringLength(), len); 1303 EXPECT_STREQ(val.GetString(), str); 1304} 1305 1306TEST(Value, AllocateShortString) { 1307 TestShortStringOptimization(""); // edge case: empty string 1308 TestShortStringOptimization("12345678"); // regular case for short strings: 8 chars 1309 TestShortStringOptimization("12345678901"); // edge case: 11 chars in 32-bit mode (=> short string) 1310 TestShortStringOptimization("123456789012"); // edge case: 12 chars in 32-bit mode (=> regular string) 1311 TestShortStringOptimization("123456789012345"); // edge case: 15 chars in 64-bit mode (=> short string) 1312 TestShortStringOptimization("1234567890123456"); // edge case: 16 chars in 64-bit mode (=> regular string) 1313} 1314 1315template <int e> 1316struct TerminateHandler { 1317 bool Null() { return e != 0; } 1318 bool Bool(bool) { return e != 1; } 1319 bool Int(int) { return e != 2; } 1320 bool Uint(unsigned) { return e != 3; } 1321 bool Int64(int64_t) { return e != 4; } 1322 bool Uint64(uint64_t) { return e != 5; } 1323 bool Double(double) { return e != 6; } 1324 bool String(const char*, SizeType, bool) { return e != 7; } 1325 bool StartObject() { return e != 8; } 1326 bool Key(const char*, SizeType, bool) { return e != 9; } 1327 bool EndObject(SizeType) { return e != 10; } 1328 bool StartArray() { return e != 11; } 1329 bool EndArray(SizeType) { return e != 12; } 1330}; 1331 1332#define TEST_TERMINATION(e, json)\ 1333{\ 1334 Document d; \ 1335 EXPECT_FALSE(d.Parse(json).HasParseError()); \ 1336 Reader reader; \ 1337 TerminateHandler<e> h;\ 1338 EXPECT_FALSE(d.Accept(h));\ 1339} 1340 1341TEST(Value, AcceptTerminationByHandler) { 1342 TEST_TERMINATION(0, "[null]"); 1343 TEST_TERMINATION(1, "[true]"); 1344 TEST_TERMINATION(1, "[false]"); 1345 TEST_TERMINATION(2, "[-1]"); 1346 TEST_TERMINATION(3, "[2147483648]"); 1347 TEST_TERMINATION(4, "[-1234567890123456789]"); 1348 TEST_TERMINATION(5, "[9223372036854775808]"); 1349 TEST_TERMINATION(6, "[0.5]"); 1350 TEST_TERMINATION(7, "[\"a\"]"); 1351 TEST_TERMINATION(8, "[{}]"); 1352 TEST_TERMINATION(9, "[{\"a\":1}]"); 1353 TEST_TERMINATION(10, "[{}]"); 1354 TEST_TERMINATION(11, "{\"a\":[]}"); 1355 TEST_TERMINATION(12, "{\"a\":[]}"); 1356} 1357