1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
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
8 // http://opensource.org/licenses/MIT
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.
16 #include "rapidjson/document.h"
17 #include "rapidjson/writer.h"
18 #include "rapidjson/filereadstream.h"
19 #include "rapidjson/encodedstream.h"
20 #include "rapidjson/stringbuffer.h"
26 RAPIDJSON_DIAG_OFF(c
++98-compat
)
27 RAPIDJSON_DIAG_OFF(missing
-variable
-declarations
)
30 using namespace rapidjson
;
32 template <typename DocumentType
>
33 void ParseCheck(DocumentType
& doc
) {
34 typedef typename
DocumentType::ValueType ValueType
;
36 EXPECT_FALSE(doc
.HasParseError());
37 if (doc
.HasParseError())
38 printf("Error: %d at %zu\n", static_cast<int>(doc
.GetParseError()), doc
.GetErrorOffset());
39 EXPECT_TRUE(static_cast<ParseResult
>(doc
));
41 EXPECT_TRUE(doc
.IsObject());
43 EXPECT_TRUE(doc
.HasMember("hello"));
44 const ValueType
& hello
= doc
["hello"];
45 EXPECT_TRUE(hello
.IsString());
46 EXPECT_STREQ("world", hello
.GetString());
48 EXPECT_TRUE(doc
.HasMember("t"));
49 const ValueType
& t
= doc
["t"];
50 EXPECT_TRUE(t
.IsTrue());
52 EXPECT_TRUE(doc
.HasMember("f"));
53 const ValueType
& f
= doc
["f"];
54 EXPECT_TRUE(f
.IsFalse());
56 EXPECT_TRUE(doc
.HasMember("n"));
57 const ValueType
& n
= doc
["n"];
58 EXPECT_TRUE(n
.IsNull());
60 EXPECT_TRUE(doc
.HasMember("i"));
61 const ValueType
& i
= doc
["i"];
62 EXPECT_TRUE(i
.IsNumber());
63 EXPECT_EQ(123, i
.GetInt());
65 EXPECT_TRUE(doc
.HasMember("pi"));
66 const ValueType
& pi
= doc
["pi"];
67 EXPECT_TRUE(pi
.IsNumber());
68 EXPECT_DOUBLE_EQ(3.1416, pi
.GetDouble());
70 EXPECT_TRUE(doc
.HasMember("a"));
71 const ValueType
& a
= doc
["a"];
72 EXPECT_TRUE(a
.IsArray());
73 EXPECT_EQ(4u, a
.Size());
74 for (SizeType j
= 0; j
< 4; j
++)
75 EXPECT_EQ(j
+ 1, a
[j
].GetUint());
78 template <typename Allocator
, typename StackAllocator
>
80 typedef GenericDocument
<UTF8
<>, Allocator
, StackAllocator
> DocumentType
;
83 const char* json
= " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
90 doc
.template ParseStream
<0>(s
);
94 char *buffer
= strdup(json
);
95 doc
.ParseInsitu(buffer
);
99 // Parse(const Ch*, size_t)
100 size_t length
= strlen(json
);
101 buffer
= reinterpret_cast<char*>(malloc(length
* 2));
102 memcpy(buffer
, json
, length
);
103 memset(buffer
+ length
, 'X', length
);
104 #if RAPIDJSON_HAS_STDSTRING
105 std::string
s2(buffer
, length
); // backup buffer
108 doc
.Parse(buffer
, length
);
112 #if RAPIDJSON_HAS_STDSTRING
113 // Parse(std::string)
120 TEST(Document
, Parse
) {
121 ParseTest
<MemoryPoolAllocator
<>, CrtAllocator
>();
122 ParseTest
<MemoryPoolAllocator
<>, MemoryPoolAllocator
<> >();
123 ParseTest
<CrtAllocator
, MemoryPoolAllocator
<> >();
124 ParseTest
<CrtAllocator
, CrtAllocator
>();
127 TEST(Document
, UnchangedOnParseError
) {
129 doc
.SetArray().PushBack(0, doc
.GetAllocator());
131 ParseResult err
= doc
.Parse("{]");
132 EXPECT_TRUE(doc
.HasParseError());
133 EXPECT_EQ(err
.Code(), doc
.GetParseError());
134 EXPECT_EQ(err
.Offset(), doc
.GetErrorOffset());
135 EXPECT_TRUE(doc
.IsArray());
136 EXPECT_EQ(doc
.Size(), 1u);
138 err
= doc
.Parse("{}");
139 EXPECT_FALSE(doc
.HasParseError());
140 EXPECT_FALSE(err
.IsError());
141 EXPECT_EQ(err
.Code(), doc
.GetParseError());
142 EXPECT_EQ(err
.Offset(), doc
.GetErrorOffset());
143 EXPECT_TRUE(doc
.IsObject());
144 EXPECT_EQ(doc
.MemberCount(), 0u);
147 static FILE* OpenEncodedFile(const char* filename
) {
148 const char *paths
[] = {
152 "../../bin/encodings",
153 "../../../bin/encodings"
156 for (size_t i
= 0; i
< sizeof(paths
) / sizeof(paths
[0]); i
++) {
157 sprintf(buffer
, "%s/%s", paths
[i
], filename
);
158 FILE *fp
= fopen(buffer
, "rb");
165 TEST(Document
, Parse_Encoding
) {
166 const char* json
= " { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ";
168 typedef GenericDocument
<UTF16
<> > DocumentType
;
171 // Parse<unsigned, SourceEncoding>(const SourceEncoding::Ch*)
172 // doc.Parse<kParseDefaultFlags, UTF8<> >(json);
173 // EXPECT_FALSE(doc.HasParseError());
174 // EXPECT_EQ(0, StrCmp(doc[L"hello"].GetString(), L"world"));
176 // Parse<unsigned, SourceEncoding>(const SourceEncoding::Ch*, size_t)
177 size_t length
= strlen(json
);
178 char* buffer
= reinterpret_cast<char*>(malloc(length
* 2));
179 memcpy(buffer
, json
, length
);
180 memset(buffer
+ length
, 'X', length
);
181 #if RAPIDJSON_HAS_STDSTRING
182 std::string
s2(buffer
, length
); // backup buffer
185 doc
.Parse
<kParseDefaultFlags
, UTF8
<> >(buffer
, length
);
187 EXPECT_FALSE(doc
.HasParseError());
188 if (doc
.HasParseError())
189 printf("Error: %d at %zu\n", static_cast<int>(doc
.GetParseError()), doc
.GetErrorOffset());
190 EXPECT_EQ(0, StrCmp(doc
[L
"hello"].GetString(), L
"world"));
192 #if RAPIDJSON_HAS_STDSTRING
193 // Parse<unsigned, SourceEncoding>(std::string)
196 #if defined(_MSC_VER) && _MSC_VER < 1800
197 doc
.Parse
<kParseDefaultFlags
, UTF8
<> >(s2
.c_str()); // VS2010 or below cannot handle templated function overloading. Use const char* instead.
199 doc
.Parse
<kParseDefaultFlags
, UTF8
<> >(s2
);
201 EXPECT_FALSE(doc
.HasParseError());
202 EXPECT_EQ(0, StrCmp(doc
[L
"hello"].GetString(), L
"world"));
206 TEST(Document
, ParseStream_EncodedInputStream
) {
208 FILE* fp
= OpenEncodedFile("utf8.json");
210 FileReadStream
bis(fp
, buffer
, sizeof(buffer
));
211 EncodedInputStream
<UTF8
<>, FileReadStream
> eis(bis
);
213 GenericDocument
<UTF16
<> > d
;
214 d
.ParseStream
<0, UTF8
<> >(eis
);
215 EXPECT_FALSE(d
.HasParseError());
219 wchar_t expected
[] = L
"I can eat glass and it doesn't hurt me.";
220 GenericValue
<UTF16
<> >& v
= d
[L
"en"];
221 EXPECT_TRUE(v
.IsString());
222 EXPECT_EQ(sizeof(expected
) / sizeof(wchar_t) - 1, v
.GetStringLength());
223 EXPECT_EQ(0, StrCmp(expected
, v
.GetString()));
225 // UTF16 -> UTF8 in memory
227 typedef EncodedOutputStream
<UTF8
<>, StringBuffer
> OutputStream
;
228 OutputStream
eos(bos
, false); // Not writing BOM
230 Writer
<OutputStream
, UTF16
<>, UTF8
<> > writer(eos
);
234 // Condense the original file and compare.
235 fp
= OpenEncodedFile("utf8.json");
236 FileReadStream
is(fp
, buffer
, sizeof(buffer
));
239 Writer
<StringBuffer
> writer2(bos2
);
240 reader
.Parse(is
, writer2
);
243 EXPECT_EQ(bos
.GetSize(), bos2
.GetSize());
244 EXPECT_EQ(0, memcmp(bos
.GetString(), bos2
.GetString(), bos2
.GetSize()));
247 TEST(Document
, ParseStream_AutoUTFInputStream
) {
249 FILE* fp
= OpenEncodedFile("utf32be.json");
251 FileReadStream
bis(fp
, buffer
, sizeof(buffer
));
252 AutoUTFInputStream
<unsigned, FileReadStream
> eis(bis
);
255 d
.ParseStream
<0, AutoUTF
<unsigned> >(eis
);
256 EXPECT_FALSE(d
.HasParseError());
260 char expected
[] = "I can eat glass and it doesn't hurt me.";
262 EXPECT_TRUE(v
.IsString());
263 EXPECT_EQ(sizeof(expected
) - 1, v
.GetStringLength());
264 EXPECT_EQ(0, StrCmp(expected
, v
.GetString()));
266 // UTF8 -> UTF8 in memory
268 Writer
<StringBuffer
> writer(bos
);
271 // Condense the original file and compare.
272 fp
= OpenEncodedFile("utf8.json");
273 FileReadStream
is(fp
, buffer
, sizeof(buffer
));
276 Writer
<StringBuffer
> writer2(bos2
);
277 reader
.Parse(is
, writer2
);
280 EXPECT_EQ(bos
.GetSize(), bos2
.GetSize());
281 EXPECT_EQ(0, memcmp(bos
.GetString(), bos2
.GetString(), bos2
.GetSize()));
284 TEST(Document
, Swap
) {
286 Document::AllocatorType
& a
= d1
.GetAllocator();
288 d1
.SetArray().PushBack(1, a
).PushBack(2, a
);
291 o
.SetObject().AddMember("a", 1, a
);
293 // Swap between Document and Value
294 // d1.Swap(o); // doesn't compile
296 EXPECT_TRUE(d1
.IsObject());
297 EXPECT_TRUE(o
.IsArray());
299 // Swap between Document and Document
301 d2
.SetArray().PushBack(3, a
);
303 EXPECT_TRUE(d1
.IsArray());
304 EXPECT_TRUE(d2
.IsObject());
305 EXPECT_EQ(&d2
.GetAllocator(), &a
);
309 EXPECT_TRUE(d1
.IsNull());
311 // reset document, including allocator
313 EXPECT_TRUE(d2
.IsNull());
314 EXPECT_NE(&d2
.GetAllocator(), &a
);
316 // testing std::swap compatibility
320 EXPECT_TRUE(d1
.IsNull());
321 EXPECT_TRUE(d2
.IsTrue());
324 EXPECT_TRUE(o
.IsTrue());
325 EXPECT_TRUE(d2
.IsArray());
329 // This should be slow due to assignment in inner-loop.
330 struct OutputStringStream
: public std::ostringstream
{
333 virtual ~OutputStringStream();
341 OutputStringStream::~OutputStringStream() {}
343 TEST(Document
, AcceptWriter
) {
345 doc
.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
347 OutputStringStream os
;
348 Writer
<OutputStringStream
> writer(os
);
351 EXPECT_EQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3,4]}", os
.str());
354 TEST(Document
, UserBuffer
) {
355 typedef GenericDocument
<UTF8
<>, MemoryPoolAllocator
<>, MemoryPoolAllocator
<> > DocumentType
;
356 char valueBuffer
[4096];
357 char parseBuffer
[1024];
358 MemoryPoolAllocator
<> valueAllocator(valueBuffer
, sizeof(valueBuffer
));
359 MemoryPoolAllocator
<> parseAllocator(parseBuffer
, sizeof(parseBuffer
));
360 DocumentType
doc(&valueAllocator
, sizeof(parseBuffer
) / 2, &parseAllocator
);
361 doc
.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } ");
362 EXPECT_FALSE(doc
.HasParseError());
363 EXPECT_LE(valueAllocator
.Size(), sizeof(valueBuffer
));
364 EXPECT_LE(parseAllocator
.Size(), sizeof(parseBuffer
));
366 // Cover MemoryPoolAllocator::Capacity()
367 EXPECT_LE(valueAllocator
.Size(), valueAllocator
.Capacity());
368 EXPECT_LE(parseAllocator
.Size(), parseAllocator
.Capacity());
371 // Issue 226: Value of string type should not point to NULL
372 TEST(Document
, AssertAcceptInvalidNameType
) {
375 doc
.AddMember("a", 0, doc
.GetAllocator());
376 doc
.FindMember("a")->name
.SetNull(); // Change name to non-string type.
378 OutputStringStream os
;
379 Writer
<OutputStringStream
> writer(os
);
380 ASSERT_THROW(doc
.Accept(writer
), AssertException
);
383 // Issue 44: SetStringRaw doesn't work with wchar_t
384 TEST(Document
, UTF16_Document
) {
385 GenericDocument
< UTF16
<> > json
;
386 json
.Parse
<kParseValidateEncodingFlag
>(L
"[{\"created_at\":\"Wed Oct 30 17:13:20 +0000 2012\"}]");
388 ASSERT_TRUE(json
.IsArray());
389 GenericValue
< UTF16
<> >& v
= json
[0];
390 ASSERT_TRUE(v
.IsObject());
392 GenericValue
< UTF16
<> >& s
= v
[L
"created_at"];
393 ASSERT_TRUE(s
.IsString());
395 EXPECT_EQ(0, memcmp(L
"Wed Oct 30 17:13:20 +0000 2012", s
.GetString(), (s
.GetStringLength() + 1) * sizeof(wchar_t)));
398 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
400 #if 0 // Many old compiler does not support these. Turn it off temporaily.
402 #include <type_traits>
404 TEST(Document
, Traits
) {
405 static_assert(std::is_constructible
<Document
>::value
, "");
406 static_assert(std::is_default_constructible
<Document
>::value
, "");
408 static_assert(!std::is_copy_constructible
<Document
>::value
, "");
410 static_assert(std::is_move_constructible
<Document
>::value
, "");
412 static_assert(!std::is_nothrow_constructible
<Document
>::value
, "");
413 static_assert(!std::is_nothrow_default_constructible
<Document
>::value
, "");
415 static_assert(!std::is_nothrow_copy_constructible
<Document
>::value
, "");
416 static_assert(std::is_nothrow_move_constructible
<Document
>::value
, "");
419 static_assert(std::is_assignable
<Document
,Document
>::value
, "");
421 static_assert(!std::is_copy_assignable
<Document
>::value
, "");
423 static_assert(std::is_move_assignable
<Document
>::value
, "");
426 static_assert(std::is_nothrow_assignable
<Document
, Document
>::value
, "");
428 static_assert(!std::is_nothrow_copy_assignable
<Document
>::value
, "");
430 static_assert(std::is_nothrow_move_assignable
<Document
>::value
, "");
433 static_assert( std::is_destructible
<Document
>::value
, "");
435 static_assert(std::is_nothrow_destructible
<Document
>::value
, "");
441 template <typename Allocator
>
442 struct DocumentMove
: public ::testing::Test
{
445 typedef ::testing::Types
< CrtAllocator
, MemoryPoolAllocator
<> > MoveAllocatorTypes
;
446 TYPED_TEST_CASE(DocumentMove
, MoveAllocatorTypes
);
448 TYPED_TEST(DocumentMove
, MoveConstructor
) {
449 typedef TypeParam Allocator
;
450 typedef GenericDocument
<UTF8
<>, Allocator
> D
;
454 a
.Parse("[\"one\", \"two\", \"three\"]");
455 EXPECT_FALSE(a
.HasParseError());
456 EXPECT_TRUE(a
.IsArray());
457 EXPECT_EQ(3u, a
.Size());
458 EXPECT_EQ(&a
.GetAllocator(), &allocator
);
460 // Document b(a); // does not compile (!is_copy_constructible)
462 EXPECT_TRUE(a
.IsNull());
463 EXPECT_TRUE(b
.IsArray());
464 EXPECT_EQ(3u, b
.Size());
465 EXPECT_THROW(a
.GetAllocator(), AssertException
);
466 EXPECT_EQ(&b
.GetAllocator(), &allocator
);
468 b
.Parse("{\"Foo\": \"Bar\", \"Baz\": 42}");
469 EXPECT_FALSE(b
.HasParseError());
470 EXPECT_TRUE(b
.IsObject());
471 EXPECT_EQ(2u, b
.MemberCount());
473 // Document c = a; // does not compile (!is_copy_constructible)
475 EXPECT_TRUE(b
.IsNull());
476 EXPECT_TRUE(c
.IsObject());
477 EXPECT_EQ(2u, c
.MemberCount());
478 EXPECT_THROW(b
.GetAllocator(), AssertException
);
479 EXPECT_EQ(&c
.GetAllocator(), &allocator
);
482 TYPED_TEST(DocumentMove
, MoveConstructorParseError
) {
483 typedef TypeParam Allocator
;
484 typedef GenericDocument
<UTF8
<>, Allocator
> D
;
489 ParseResult
error(a
.GetParseError(), a
.GetErrorOffset());
490 EXPECT_TRUE(a
.HasParseError());
491 EXPECT_NE(error
.Code(), noError
.Code());
492 EXPECT_NE(error
.Offset(), noError
.Offset());
495 EXPECT_FALSE(a
.HasParseError());
496 EXPECT_TRUE(b
.HasParseError());
497 EXPECT_EQ(a
.GetParseError(), noError
.Code());
498 EXPECT_EQ(b
.GetParseError(), error
.Code());
499 EXPECT_EQ(a
.GetErrorOffset(), noError
.Offset());
500 EXPECT_EQ(b
.GetErrorOffset(), error
.Offset());
503 EXPECT_FALSE(b
.HasParseError());
504 EXPECT_TRUE(c
.HasParseError());
505 EXPECT_EQ(b
.GetParseError(), noError
.Code());
506 EXPECT_EQ(c
.GetParseError(), error
.Code());
507 EXPECT_EQ(b
.GetErrorOffset(), noError
.Offset());
508 EXPECT_EQ(c
.GetErrorOffset(), error
.Offset());
511 // This test does not properly use parsing, just for testing.
512 // It must call ClearStack() explicitly to prevent memory leak.
513 // But here we cannot as ClearStack() is private.
515 TYPED_TEST(DocumentMove
, MoveConstructorStack
) {
516 typedef TypeParam Allocator
;
517 typedef UTF8
<> Encoding
;
518 typedef GenericDocument
<Encoding
, Allocator
> Document
;
521 size_t defaultCapacity
= a
.GetStackCapacity();
523 // Trick Document into getting GetStackCapacity() to return non-zero
524 typedef GenericReader
<Encoding
, Encoding
, Allocator
> Reader
;
525 Reader
reader(&a
.GetAllocator());
526 GenericStringStream
<Encoding
> is("[\"one\", \"two\", \"three\"]");
527 reader
.template Parse
<kParseDefaultFlags
>(is
, a
);
528 size_t capacity
= a
.GetStackCapacity();
529 EXPECT_GT(capacity
, 0u);
531 Document
b(std::move(a
));
532 EXPECT_EQ(a
.GetStackCapacity(), defaultCapacity
);
533 EXPECT_EQ(b
.GetStackCapacity(), capacity
);
535 Document c
= std::move(b
);
536 EXPECT_EQ(b
.GetStackCapacity(), defaultCapacity
);
537 EXPECT_EQ(c
.GetStackCapacity(), capacity
);
541 TYPED_TEST(DocumentMove
, MoveAssignment
) {
542 typedef TypeParam Allocator
;
543 typedef GenericDocument
<UTF8
<>, Allocator
> D
;
547 a
.Parse("[\"one\", \"two\", \"three\"]");
548 EXPECT_FALSE(a
.HasParseError());
549 EXPECT_TRUE(a
.IsArray());
550 EXPECT_EQ(3u, a
.Size());
551 EXPECT_EQ(&a
.GetAllocator(), &allocator
);
553 // Document b; b = a; // does not compile (!is_copy_assignable)
556 EXPECT_TRUE(a
.IsNull());
557 EXPECT_TRUE(b
.IsArray());
558 EXPECT_EQ(3u, b
.Size());
559 EXPECT_THROW(a
.GetAllocator(), AssertException
);
560 EXPECT_EQ(&b
.GetAllocator(), &allocator
);
562 b
.Parse("{\"Foo\": \"Bar\", \"Baz\": 42}");
563 EXPECT_FALSE(b
.HasParseError());
564 EXPECT_TRUE(b
.IsObject());
565 EXPECT_EQ(2u, b
.MemberCount());
567 // Document c; c = a; // does not compile (see static_assert)
570 EXPECT_TRUE(b
.IsNull());
571 EXPECT_TRUE(c
.IsObject());
572 EXPECT_EQ(2u, c
.MemberCount());
573 EXPECT_THROW(b
.GetAllocator(), AssertException
);
574 EXPECT_EQ(&c
.GetAllocator(), &allocator
);
577 TYPED_TEST(DocumentMove
, MoveAssignmentParseError
) {
578 typedef TypeParam Allocator
;
579 typedef GenericDocument
<UTF8
<>, Allocator
> D
;
584 ParseResult
error(a
.GetParseError(), a
.GetErrorOffset());
585 EXPECT_TRUE(a
.HasParseError());
586 EXPECT_NE(error
.Code(), noError
.Code());
587 EXPECT_NE(error
.Offset(), noError
.Offset());
591 EXPECT_FALSE(a
.HasParseError());
592 EXPECT_TRUE(b
.HasParseError());
593 EXPECT_EQ(a
.GetParseError(), noError
.Code());
594 EXPECT_EQ(b
.GetParseError(), error
.Code());
595 EXPECT_EQ(a
.GetErrorOffset(), noError
.Offset());
596 EXPECT_EQ(b
.GetErrorOffset(), error
.Offset());
600 EXPECT_FALSE(b
.HasParseError());
601 EXPECT_TRUE(c
.HasParseError());
602 EXPECT_EQ(b
.GetParseError(), noError
.Code());
603 EXPECT_EQ(c
.GetParseError(), error
.Code());
604 EXPECT_EQ(b
.GetErrorOffset(), noError
.Offset());
605 EXPECT_EQ(c
.GetErrorOffset(), error
.Offset());
608 // This test does not properly use parsing, just for testing.
609 // It must call ClearStack() explicitly to prevent memory leak.
610 // But here we cannot as ClearStack() is private.
612 TYPED_TEST(DocumentMove
, MoveAssignmentStack
) {
613 typedef TypeParam Allocator
;
614 typedef UTF8
<> Encoding
;
615 typedef GenericDocument
<Encoding
, Allocator
> D
;
618 size_t defaultCapacity
= a
.GetStackCapacity();
620 // Trick Document into getting GetStackCapacity() to return non-zero
621 typedef GenericReader
<Encoding
, Encoding
, Allocator
> Reader
;
622 Reader
reader(&a
.GetAllocator());
623 GenericStringStream
<Encoding
> is("[\"one\", \"two\", \"three\"]");
624 reader
.template Parse
<kParseDefaultFlags
>(is
, a
);
625 size_t capacity
= a
.GetStackCapacity();
626 EXPECT_GT(capacity
, 0u);
630 EXPECT_EQ(a
.GetStackCapacity(), defaultCapacity
);
631 EXPECT_EQ(b
.GetStackCapacity(), capacity
);
635 EXPECT_EQ(b
.GetStackCapacity(), defaultCapacity
);
636 EXPECT_EQ(c
.GetStackCapacity(), capacity
);
640 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
642 // Issue 22: Memory corruption via operator=
643 // Fixed by making unimplemented assignment operator private.
644 //TEST(Document, Assignment) {