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
19 using namespace rapidjson;
20
TEST(Value,DefaultConstructor)21 TEST(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
TEST(Value,Traits)39 TEST(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
TEST(Value,MoveConstructor)75 TEST(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
TEST(Value,AssignmentOperator)100 TEST(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
143 template <typename A, typename B>
TestEqual(const A & a,const B & b)144 void 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
151 template <typename A, typename B>
TestUnequal(const A & a,const B & b)152 void 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
TEST(Value,EqualtoOperator)159 TEST(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
228 template <typename Value>
TestCopyFrom()229 void 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
TEST(Value,CopyFrom)262 TEST(Value, CopyFrom) {
263 TestCopyFrom<Value>();
264 TestCopyFrom<GenericValue<UTF8<>, CrtAllocator> >();
265 }
266
TEST(Value,Swap)267 TEST(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
TEST(Value,Null)283 TEST(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
TEST(Value,True)306 TEST(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
TEST(Value,False)331 TEST(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
TEST(Value,Int)357 TEST(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
TEST(Value,Uint)410 TEST(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
TEST(Value,Int64)449 TEST(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
TEST(Value,Uint64)503 TEST(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
TEST(Value,Double)547 TEST(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
TEST(Value,String)573 TEST(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
TEST(Value,SetStringNullException)710 TEST(Value, SetStringNullException) {
711 Value v;
712 EXPECT_THROW(v.SetString(0, 0), AssertException);
713 }
714
TEST(Value,Array)715 TEST(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
TEST(Value,Object)908 TEST(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
TEST(Value,EraseMember_String)1191 TEST(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
TEST(Value,BigNestedArray)1209 TEST(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
TEST(Value,BigNestedObject)1230 TEST(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
TEST(Value,RemoveLastElement)1271 TEST(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
TEST(Document,CrtAllocator)1284 TEST(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
TestShortStringOptimization(const char * str)1295 static 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
TEST(Value,AllocateShortString)1306 TEST(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
1315 template <int e>
1316 struct TerminateHandler {
NullTerminateHandler1317 bool Null() { return e != 0; }
BoolTerminateHandler1318 bool Bool(bool) { return e != 1; }
IntTerminateHandler1319 bool Int(int) { return e != 2; }
UintTerminateHandler1320 bool Uint(unsigned) { return e != 3; }
Int64TerminateHandler1321 bool Int64(int64_t) { return e != 4; }
Uint64TerminateHandler1322 bool Uint64(uint64_t) { return e != 5; }
DoubleTerminateHandler1323 bool Double(double) { return e != 6; }
StringTerminateHandler1324 bool String(const char*, SizeType, bool) { return e != 7; }
StartObjectTerminateHandler1325 bool StartObject() { return e != 8; }
KeyTerminateHandler1326 bool Key(const char*, SizeType, bool) { return e != 9; }
EndObjectTerminateHandler1327 bool EndObject(SizeType) { return e != 10; }
StartArrayTerminateHandler1328 bool StartArray() { return e != 11; }
EndArrayTerminateHandler1329 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
TEST(Value,AcceptTerminationByHandler)1341 TEST(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