1 //
2 // JSONTest.cpp
3 //
4 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5 // and Contributors.
6 //
7 // SPDX-License-Identifier:	BSL-1.0
8 //
9 
10 
11 #include "JSONTest.h"
12 #include "CppUnit/TestCaller.h"
13 #include "CppUnit/TestSuite.h"
14 #include "Poco/Path.h"
15 #include "Poco/Environment.h"
16 #include "Poco/File.h"
17 #include "Poco/FileStream.h"
18 #include "Poco/Glob.h"
19 #include "Poco/UTF8Encoding.h"
20 #include "Poco/Latin1Encoding.h"
21 #include "Poco/TextConverter.h"
22 #include "Poco/Nullable.h"
23 #include "Poco/Dynamic/Struct.h"
24 #include "Poco/DateTime.h"
25 #include "Poco/DateTimeFormatter.h"
26 #include <set>
27 #include <iostream>
28 
29 
30 using namespace Poco::JSON;
31 using namespace Poco::Dynamic;
32 using Poco::DynamicStruct;
33 using Poco::DateTime;
34 using Poco::DateTimeFormatter;
35 
JSONTest(const std::string & name)36 JSONTest::JSONTest(const std::string& name): CppUnit::TestCase("JSON")
37 {
38 
39 }
40 
41 
~JSONTest()42 JSONTest::~JSONTest()
43 {
44 
45 }
46 
47 
setUp()48 void JSONTest::setUp()
49 {
50 }
51 
52 
tearDown()53 void JSONTest::tearDown()
54 {
55 }
56 
57 
testNullProperty()58 void JSONTest::testNullProperty()
59 {
60 	std::string json = "{ \"test\" : null }";
61 	Parser parser;
62 
63 	Var result;
64 	try
65 	{
66 		result = parser.parse(json);
67 	}
68 	catch(JSONException& jsone)
69 	{
70 		std::cout << jsone.message() << std::endl;
71 		assertTrue (false);
72 	}
73 	assertTrue (result.type() == typeid(Object::Ptr));
74 
75 	Object::Ptr object = result.extract<Object::Ptr>();
76 	assertTrue (object->isNull("test"));
77 	Var test = object->get("test");
78 	assertTrue (test.isEmpty());
79 
80 	Poco::Nullable<int> test2 = object->getNullableValue<int>("test");
81 	assertTrue (test2.isNull());
82 
83 	DynamicStruct ds = *object;
84 	assertTrue (ds["test"].isEmpty());
85 
86 	const DynamicStruct& rds = *object;
87 	assertTrue (rds["test"].isEmpty());
88 }
89 
90 
testTrueProperty()91 void JSONTest::testTrueProperty()
92 {
93 	std::string json = "{ \"test\" : true }";
94 	Parser parser;
95 	Var result;
96 
97 	try
98 	{
99 		result = parser.parse(json);
100 	}
101 	catch(JSONException& jsone)
102 	{
103 		std::cout << jsone.message() << std::endl;
104 		assertTrue (false);
105 	}
106 
107 	assertTrue (result.type() == typeid(Object::Ptr));
108 
109 	Object::Ptr object = result.extract<Object::Ptr>();
110 	Var test = object->get("test");
111 	assertTrue (test.type() == typeid(bool));
112 	bool value = test;
113 	assertTrue (value);
114 
115 	DynamicStruct ds = *object;
116 	assertTrue (!ds["test"].isEmpty());
117 	assertTrue (ds["test"]);
118 
119 	const DynamicStruct& rds = *object;
120 	assertTrue (!rds["test"].isEmpty());
121 	assertTrue (rds["test"]);
122 }
123 
124 
testFalseProperty()125 void JSONTest::testFalseProperty()
126 {
127 	std::string json = "{ \"test\" : false }";
128 	Parser parser;
129 	Var result;
130 
131 	try
132 	{
133 		result = parser.parse(json);
134 	}
135 	catch(JSONException& jsone)
136 	{
137 		std::cout << jsone.message() << std::endl;
138 		assertTrue (false);
139 	}
140 
141 	assertTrue (result.type() == typeid(Object::Ptr));
142 
143 	Object::Ptr object = result.extract<Object::Ptr>();
144 	Var test = object->get("test");
145 	assertTrue (test.type() == typeid(bool));
146 	bool value = test;
147 	assertTrue (!value);
148 
149 	DynamicStruct ds = *object;
150 	assertTrue (!ds["test"].isEmpty());
151 	assertTrue (!ds["test"]);
152 
153 	const DynamicStruct& rds = *object;
154 	assertTrue (!rds["test"].isEmpty());
155 	assertTrue (!rds["test"]);
156 }
157 
158 
testNumberProperty()159 void JSONTest::testNumberProperty()
160 {
161 	testNumber(1969);
162 	testNumber(-1969);
163 	testNumber(1969.5);
164 	testNumber(-1969.5);
165 }
166 
167 
testUnsignedNumberProperty()168 void JSONTest::testUnsignedNumberProperty()
169 {
170 	// 4294967295 == unsigned(-1)
171 	std::string json = "{ \"test\" : 4294967295 }";
172 	Parser parser;
173 	Var result;
174 
175 	try
176 	{
177 		result = parser.parse(json);
178 	}
179 	catch(JSONException& jsone)
180 	{
181 		std::cout << jsone.message() << std::endl;
182 		assertTrue (false);
183 	}
184 
185 	assertTrue (result.type() == typeid(Object::Ptr));
186 
187 	Object::Ptr object = result.extract<Object::Ptr>();
188 	Var test = object->get("test");
189 	assertTrue (test.isNumeric());
190 	assertTrue (test.isInteger());
191 	Poco::UInt32 value = test;
192 	assertTrue (value == -1);
193 
194 	DynamicStruct ds = *object;
195 	assertTrue (!ds["test"].isEmpty());
196 	assertTrue (ds["test"].isNumeric());
197 	assertTrue (ds["test"].isInteger());
198 	assertTrue (ds["test"] == 4294967295u);
199 	value = ds["test"];
200 	assertTrue (value == -1);
201 
202 	const DynamicStruct& rds = *object;
203 	assertTrue (!rds["test"].isEmpty());
204 	assertTrue (rds["test"].isNumeric());
205 	assertTrue (rds["test"].isInteger());
206 	assertTrue (rds["test"] == 4294967295u);
207 	value = rds["test"];
208 	assertTrue (value == -1);
209 }
210 
211 #if defined(POCO_HAVE_INT64)
212 
213 
testNumber64Property()214 void JSONTest::testNumber64Property()
215 {
216 	std::string json = "{ \"test\" : -5000000000000000 }";
217 	Parser parser;
218 	Var result;
219 
220 	try
221 	{
222 		result = parser.parse(json);
223 	}
224 	catch(JSONException& jsone)
225 	{
226 		std::cout << jsone.message() << std::endl;
227 		assertTrue (false);
228 	}
229 
230 	assertTrue (result.type() == typeid(Object::Ptr));
231 
232 	Object object = *result.extract<Object::Ptr>();
233 	Var test = object.get("test");
234 	assertTrue (test.isInteger());
235 	Poco::Int64 value = test;
236 	assertTrue (value == -5000000000000000ll);
237 
238 	DynamicStruct ds = object;
239 	assertTrue (!ds["test"].isEmpty());
240 	assertTrue (ds["test"].isNumeric());
241 	assertTrue (ds["test"].isInteger());
242 	assertTrue (ds["test"] == -5000000000000000ll);
243 	value = ds["test"];
244 	assertTrue (value == -5000000000000000ll);
245 
246 	const DynamicStruct& rds = object;
247 	assertTrue (!rds["test"].isEmpty());
248 	assertTrue (rds["test"].isNumeric());
249 	assertTrue (rds["test"].isInteger());
250 	assertTrue (rds["test"] == -5000000000000000ll);
251 	value = rds["test"];
252 	assertTrue (value == -5000000000000000ll);
253 }
254 
255 
testUnsignedNumber64Property()256 void JSONTest::testUnsignedNumber64Property()
257 {
258 	// 18446744073709551615 == UInt64(-1)
259 	std::string json = "{ \"test\" : 18446744073709551615 }";
260 	Parser parser;
261 	Var result;
262 
263 	try
264 	{
265 		result = parser.parse(json);
266 	}
267 	catch(JSONException& jsone)
268 	{
269 		std::cout << jsone.message() << std::endl;
270 		assertTrue (false);
271 	}
272 
273 	assertTrue (result.type() == typeid(Object::Ptr));
274 
275 	Object::Ptr object = result.extract<Object::Ptr>();
276 	Var test = object->get("test");
277 	assertTrue (test.isInteger());
278 	Poco::UInt64 value = test;
279 	assertTrue (value == -1);
280 	DynamicStruct ds = *object;
281 	assertTrue (!ds["test"].isEmpty());
282 	assertTrue (ds["test"].isNumeric());
283 	assertTrue (ds["test"].isInteger());
284 	assertTrue (ds["test"] == 18446744073709551615ull);
285 	value = ds["test"];
286 	assertTrue (value == -1);
287 
288 	const DynamicStruct& rds = *object;
289 	assertTrue (!rds["test"].isEmpty());
290 	assertTrue (rds["test"].isNumeric());
291 	assertTrue (rds["test"].isInteger());
292 	assertTrue (rds["test"] == 18446744073709551615ull);
293 	value = rds["test"];
294 	assertTrue (value == -1);
295 }
296 
297 #endif
298 
299 
testStringProperty()300 void JSONTest::testStringProperty()
301 {
302 	std::string json = "{ \"test\" : \"value\" }";
303 	Parser parser;
304 	Var result;
305 
306 	try
307 	{
308 		result = parser.parse(json);
309 	}
310 	catch(JSONException& jsone)
311 	{
312 		std::cout << jsone.message() << std::endl;
313 		assertTrue (false);
314 	}
315 
316 	assertTrue (result.type() == typeid(Object::Ptr));
317 
318 	Object object = *result.extract<Object::Ptr>();
319 	Var test = object.get("test");
320 	assertTrue (test.isString());
321 	std::string value = test.convert<std::string>();
322 	assertTrue (value.compare("value") == 0);
323 
324 	object.set("test2", 'a');
325 	std::ostringstream ostr;
326 	object.stringify(ostr);
327 	assertTrue (ostr.str() == "{\"test\":\"value\",\"test2\":\"a\"}");
328 
329 	DynamicStruct ds = object;
330 	assertTrue (!ds["test"].isEmpty());
331 	assertTrue (ds["test"].isString());
332 	assertTrue (!ds["test"].isInteger());
333 	assertTrue (ds["test"] == "value");
334 	value = ds["test"].toString();
335 	assertTrue (value == "value");
336 
337 	const DynamicStruct& rds = object;
338 	assertTrue (!rds["test"].isEmpty());
339 	assertTrue (rds["test"].isString());
340 	assertTrue (!rds["test"].isInteger());
341 	assertTrue (rds["test"] == "value");
342 	value = rds["test"].toString();
343 	assertTrue (value == "value");
344 }
345 
346 
testEmptyObject()347 void JSONTest::testEmptyObject()
348 {
349 	std::string json = "{}";
350 	Parser parser;
351 	Var result;
352 
353 	try
354 	{
355 		result = parser.parse(json);
356 	}
357 	catch(JSONException& jsone)
358 	{
359 		std::cout << jsone.message() << std::endl;
360 		assertTrue (false);
361 	}
362 
363 	assertTrue (result.type() == typeid(Object::Ptr));
364 
365 	Object::Ptr object = result.extract<Object::Ptr>();
366 	assertTrue (object->size() == 0);
367 
368 	DynamicStruct ds = *object;
369 	assertTrue (ds.size() == 0);
370 
371 	const DynamicStruct& rds = *object;
372 	assertTrue (rds.size() == 0);
373 }
374 
375 
testEmptyPropertyName()376 void JSONTest::testEmptyPropertyName()
377 {
378 	std::string json = "{\"\": 42}";
379 	Parser parser;
380 	Var result;
381 
382 	try
383 	{
384 		result = parser.parse(json);
385 	}
386 	catch(JSONException& jsone)
387 	{
388 		std::cout << jsone.message() << std::endl;
389 		assertTrue (false);
390 	}
391 
392 	assertTrue (result.type() == typeid(Object::Ptr));
393 
394 	Object::Ptr object = result.extract<Object::Ptr>();
395 	assertTrue (object->size() == 1);
396 
397 	DynamicStruct ds = *object;
398 	assertTrue (ds.size() == 1);
399 
400 	const DynamicStruct& rds = *object;
401 	assertTrue (rds.size() == 1);
402 
403 	assertTrue (ds[""] == 42);
404 }
405 
406 
testComplexObject()407 void JSONTest::testComplexObject()
408 {
409 	std::string json =
410 	"{"
411 		"\"id\": 1,"
412 		"\"jsonrpc\": \"2.0\","
413 		"\"total\": 1,"
414 		"\"result\": ["
415 			"{"
416 				"\"id\": 1,"
417 				"\"guid\": \"67acfb26-17eb-4a75-bdbd-f0669b7d8f73\","
418 				"\"picture\": \"http://placehold.it/32x32\","
419 				"\"age\": 40,"
420 				"\"name\": \"Angelina Crossman\","
421 				"\"gender\": \"female\","
422 				"\"company\": \"Raylog\","
423 				"\"phone\": \"892-470-2803\","
424 				"\"email\": \"angelina@raylog.com\","
425 				"\"address\": \"20726, CostaMesa, Horatio Streets\","
426 				"\"about\": \"Consectetuer suscipit volutpat eros dolor euismod, "
427 				"et dignissim in feugiat sed, ea tation exerci quis. Consectetuer, "
428 				"dolor dolore ad vero ullamcorper, tincidunt facilisis at in facilisi, "
429 				"iusto illum illum. Autem nibh, sed elit consequat volutpat tation, "
430 				"nisl lorem lorem sed tation, facilisis dolore. Augue odio molestie, "
431 				"dolor zzril nostrud aliquam sed, wisi dolor et ut iusto, ea. Magna "
432 				"ex qui facilisi, hendrerit quis in eros ut, zzril nibh dolore nisl "
433 				"suscipit, vulputate elit ut lobortis exerci, nulla dolore eros at "
434 				"aliquam, ullamcorper vero ad iusto. Adipiscing, nisl eros exerci "
435 				"nisl vel, erat in luptatum in duis, iusto.\","
436 				"\"registered\": \"2008-04-09T11:13:17 +05:00\","
437 				"\"tags\": ["
438 					"\"ut\","
439 					"\"accumsan\","
440 					"\"feugait\","
441 					"\"ex\","
442 					"\"odio\","
443 					"\"consequat\","
444 					"\"delenit\""
445 				"],"
446 				"\"friends\": ["
447 					"{"
448 						"\"id\": 1,"
449 						"\"name\": \"Hailey Hardman\""
450 					"},"
451 					"{"
452 						"\"id\": 2,"
453 						"\"name\": \"Bailey Oldridge\""
454 					"},"
455 					"{"
456 						"\"id\": 3,"
457 						"\"name\": \"Makayla Campbell\""
458 					"}"
459 				"]"
460 			"}"
461 		"]"
462 	"}";
463 
464 	Parser parser;
465 	Var result;
466 
467 	try
468 	{
469 		result = parser.parse(json);
470 	}
471 	catch(JSONException& jsone)
472 	{
473 		std::cout << jsone.message() << std::endl;
474 		assertTrue (false);
475 	}
476 
477 	assertTrue (result.type() == typeid(Object::Ptr));
478 
479 	Object::Ptr object = result.extract<Object::Ptr>();
480 	assertTrue (object->size() > 0);
481 
482 	Object::NameList names = object->getNames();
483 	assertTrue (names.size() == 4);
484 	assertTrue (names[0] == "id");
485 	assertTrue (names[1] == "jsonrpc");
486 	assertTrue (names[2] == "result");
487 	assertTrue (names[3] == "total");
488 
489 	DynamicStruct ds = *object;
490 	assertTrue (ds.size() > 0);
491 	assertTrue (ds["id"] == 1);
492 	assertTrue (ds["jsonrpc"] == 2.0);
493 
494 	assertTrue (ds["result"].isArray());
495 	assertTrue (ds["result"].size() == 1);
496 	assertTrue (ds["result"][0].isStruct());
497 	assertTrue (ds["result"][0]["id"] == 1);
498 	assertTrue (ds["result"][0]["guid"] == "67acfb26-17eb-4a75-bdbd-f0669b7d8f73");
499 	assertTrue (ds["result"][0]["age"] == 40);
500 	assertTrue (ds["result"][0]["name"] == "Angelina Crossman");
501 	assertTrue (ds["result"][0]["gender"] == "female");
502 	assertTrue (ds["result"][0]["company"] == "Raylog");
503 	assertTrue (ds["result"][0]["phone"] == "892-470-2803");
504 	assertTrue (ds["result"][0]["email"] == "angelina@raylog.com");
505 	assertTrue (ds["result"][0]["address"] == "20726, CostaMesa, Horatio Streets");
506 	assertTrue (ds["result"][0]["about"] == "Consectetuer suscipit volutpat eros dolor euismod, "
507 		"et dignissim in feugiat sed, ea tation exerci quis. Consectetuer, "
508 		"dolor dolore ad vero ullamcorper, tincidunt facilisis at in facilisi, "
509 		"iusto illum illum. Autem nibh, sed elit consequat volutpat tation, "
510 		"nisl lorem lorem sed tation, facilisis dolore. Augue odio molestie, "
511 		"dolor zzril nostrud aliquam sed, wisi dolor et ut iusto, ea. Magna "
512 		"ex qui facilisi, hendrerit quis in eros ut, zzril nibh dolore nisl "
513 		"suscipit, vulputate elit ut lobortis exerci, nulla dolore eros at "
514 		"aliquam, ullamcorper vero ad iusto. Adipiscing, nisl eros exerci "
515 		"nisl vel, erat in luptatum in duis, iusto.");
516 	assertTrue (ds["result"][0]["registered"] == "2008-04-09T11:13:17 +05:00");
517 
518 	assertTrue (ds["result"][0]["tags"].isArray());
519 	assertTrue (ds["result"][0]["tags"].size() == 7);
520 	assertTrue (ds["result"][0]["tags"][0] == "ut");
521 	assertTrue (ds["result"][0]["tags"][1] == "accumsan");
522 	assertTrue (ds["result"][0]["tags"][2] == "feugait");
523 	assertTrue (ds["result"][0]["tags"][3] == "ex");
524 	assertTrue (ds["result"][0]["tags"][4] == "odio");
525 	assertTrue (ds["result"][0]["tags"][5] == "consequat");
526 	assertTrue (ds["result"][0]["tags"][6] == "delenit");
527 
528 	assertTrue (ds["result"][0]["friends"][0].isStruct());
529 	assertTrue (ds["result"][0]["friends"][0]["id"] == 1);
530 	assertTrue (ds["result"][0]["friends"][0]["name"] == "Hailey Hardman");
531 	assertTrue (ds["result"][0]["friends"][1]["id"] == 2);
532 	assertTrue (ds["result"][0]["friends"][1]["name"] == "Bailey Oldridge");
533 	assertTrue (ds["result"][0]["friends"][2]["id"] == 3);
534 	assertTrue (ds["result"][0]["friends"][2]["name"] == "Makayla Campbell");
535 
536 	const DynamicStruct& rds = *object;
537 	assertTrue (rds.size() > 0);
538 }
539 
540 
testDoubleProperty()541 void JSONTest::testDoubleProperty()
542 {
543 	std::string json = "{ \"test\" : 1234.5 }";
544 	Parser parser;
545 	Var result;
546 
547 	try
548 	{
549 		result = parser.parse(json);
550 	}
551 	catch(JSONException& jsone)
552 	{
553 		std::cout << jsone.message() << std::endl;
554 		assertTrue (false);
555 	}
556 
557 	assertTrue (result.type() == typeid(Object::Ptr));
558 
559 	Object::Ptr object = result.extract<Object::Ptr>();
560 	Var test = object->get("test");
561 	assertTrue (test.isNumeric());
562 	double value = test;
563 	assertTrue (value == 1234.5);
564 
565 	DynamicStruct ds = *object;
566 	assertTrue (ds["test"] == 1234.5);
567 }
568 
569 
testDouble2Property()570 void JSONTest::testDouble2Property()
571 {
572 	std::string json = "{ \"test\" : 12e34 }";
573 	Parser parser;
574 	Var result;
575 
576 	try
577 	{
578 		result = parser.parse(json);
579 	}
580 	catch(JSONException& jsone)
581 	{
582 		std::cout << jsone.message() << std::endl;
583 		assertTrue (false);
584 	}
585 
586 	assertTrue (result.type() == typeid(Object::Ptr));
587 
588 	Object::Ptr object = result.extract<Object::Ptr>();
589 	Var test = object->get("test");
590 	assertTrue (test.isNumeric());
591 	double value = test;
592 	assertTrue (value >= 1.99e34 && value <= 12.01e34);
593 }
594 
595 
testDouble3Property()596 void JSONTest::testDouble3Property()
597 {
598 	std::string json = "{ \"test\" : 12e-34 }";
599 	Parser parser;
600 	Var result;
601 
602 	try
603 	{
604 		result = parser.parse(json);
605 	}
606 	catch(JSONException& jsone)
607 	{
608 		std::cout << jsone.message() << std::endl;
609 		assertTrue (false);
610 	}
611 
612 	assertTrue (result.type() == typeid(Object::Ptr));
613 
614 	Object::Ptr object = result.extract<Object::Ptr>();
615 	Var test = object->get("test");
616 	assertTrue (test.isNumeric());
617 	double value = test;
618 	assertTrue (value == 12e-34);
619 }
620 
621 
testObjectProperty()622 void JSONTest::testObjectProperty()
623 {
624 	std::string json = "{ \"test\" : { \"property\" : \"value\" } }";
625 	Parser parser;
626 	Var result;
627 
628 	try
629 	{
630 		result = parser.parse(json);
631 	}
632 	catch(JSONException& jsone)
633 	{
634 		std::cout << jsone.message() << std::endl;
635 		assertTrue (false);
636 	}
637 
638 	assertTrue (result.type() == typeid(Object::Ptr));
639 
640 	Object::Ptr object = result.extract<Object::Ptr>();
641 	assertTrue (object->isObject("test"));
642 	assertTrue (!object->isArray("test"));
643 
644 	assertTrue (!object->isArray("nonExistentKey"));
645 	assertTrue (!object->isObject("nonExistentKey"));
646 
647 	Var test = object->get("test");
648 	assertTrue (test.type() == typeid(Object::Ptr));
649 	Object::Ptr subObject = test.extract<Object::Ptr>();
650 
651 	test = subObject->get("property");
652 	assertTrue (test.isString());
653 	std::string value = test.convert<std::string>();
654 	assertTrue (value.compare("value") == 0);
655 
656 	DynamicStruct ds = *object;
657 	assertTrue (ds["test"].isStruct());
658 	assertTrue (ds["test"]["property"] == "value");
659 
660 	// make sure that Object is recognized as such
661 	{
662 		Object obj;
663 		Object inner;
664 		inner.set("some_number", 5);
665 		inner.set("some_string", "xyz");
666 		std::string key = "new_object";
667 		obj.set(key, inner);
668 		assertTrue (obj.isObject(key));
669 	}
670 
671 	// make sure that Object pointer is recognized as Object
672 	{
673 		Object obj;
674 		Poco::JSON::Object::Ptr inner = new Poco::JSON::Object;
675 		inner->set("some_number", 5);
676 		inner->set("some_string", "xyz");
677 		std::string key = "new_object";
678 		obj.set(key, inner);
679 		assertTrue (obj.isObject(key));
680 	}
681 }
682 
683 
testObjectArray()684 void JSONTest::testObjectArray()
685 {
686 	std::string json = "{ \"test\" : { \"test1\" : [1, 2, 3], \"test2\" : 4 } }";
687 	Parser parser;
688 	Var result;
689 
690 	try
691 	{
692 		result = parser.parse(json);
693 	}
694 	catch(JSONException& jsone)
695 	{
696 		std::cout << jsone.message() << std::endl;
697 		assertTrue (false);
698 	}
699 
700 	assertTrue (result.type() == typeid(Object::Ptr));
701 	Object::Ptr object = result.extract<Object::Ptr>();
702 	assertTrue (object->isObject("test"));
703 	Object::Ptr subObject = object->getObject("test");
704 	assertTrue (!subObject->isObject("test1"));
705 	assertTrue (subObject->isArray("test1"));
706 	assertTrue (!subObject->isObject("test2"));
707 	assertTrue (!subObject->isArray("test2"));
708 
709 	DynamicStruct ds = *object;
710 	assertTrue (ds.size() > 0);
711 	assertTrue (ds.size() == 1);
712 
713 	assertTrue (ds["test"].isStruct());
714 	assertTrue (ds["test"]["test1"].isArray());
715 	assertTrue (ds["test"]["test1"].size() == 3);
716 	assertTrue (ds["test"]["test1"][0] == 1);
717 	assertTrue (ds["test"]["test1"][1] == 2);
718 	assertTrue (ds["test"]["test1"][2] == 3);
719 	assertTrue (ds["test"]["test2"] == 4);
720 
721 	object->set("test3", "another top level value");
722 	ds = std::move(*object);
723 	assertTrue (ds.size() == 2);
724 	assertTrue (ds["test"].isStruct());
725 	assertTrue (ds["test"]["test1"].isArray());
726 	assertTrue (ds["test"]["test1"].size() == 3);
727 	assertTrue (ds["test"]["test1"][0] == 1);
728 	assertTrue (ds["test"]["test1"][1] == 2);
729 	assertTrue (ds["test"]["test1"][2] == 3);
730 	assertTrue (ds["test"]["test2"] == 4);
731 	assertTrue (ds["test3"] == "another top level value");
732 }
733 
734 
testArrayOfObjects()735 void JSONTest::testArrayOfObjects()
736 {
737 	std::string json = "[ {\"test\" : 0}, { \"test1\" : [1, 2, 3], \"test2\" : 4 } ]";
738 	Parser parser;
739 	Var result;
740 
741 	try
742 	{
743 		result = parser.parse(json);
744 	}
745 	catch(JSONException& jsone)
746 	{
747 		std::cout << jsone.message() << std::endl;
748 		assertTrue (false);
749 	}
750 
751 	assertTrue (result.isArray());
752 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
753 	Poco::JSON::Array::Ptr arr = result.extract<Poco::JSON::Array::Ptr>();
754 	Object::Ptr object = arr->getObject(0);
755 	assertTrue (object->getValue<int>("test") == 0);
756 	Object::Ptr subObject = arr->getObject(1);
757 	Poco::JSON::Array::Ptr subArr = subObject->getArray("test1");
758 	result = subArr->get(0);
759 	assertTrue (result == 1);
760 
761 	Poco::Dynamic::Array da = *arr;
762 	assertTrue (da.size() == 2);
763 	assertTrue (da[0].isStruct());
764 	assertTrue (da[0]["test"] == 0);
765 	assertTrue (da[1].isStruct());
766 	assertTrue (da[1]["test1"].isArray());
767 	assertTrue (da[1]["test1"][0] == 1);
768 	assertTrue (da[1]["test1"][1] == 2);
769 	assertTrue (da[1]["test1"][2] == 3);
770 	assertTrue (da[1]["test2"] == 4);
771 }
772 
773 
testEmptyArray()774 void JSONTest::testEmptyArray()
775 {
776 	std::string json = "[]";
777 	Parser parser;
778 	Var result;
779 
780 	try
781 	{
782 		result = parser.parse(json);
783 	}
784 	catch(JSONException& jsone)
785 	{
786 		std::cout << jsone.message() << std::endl;
787 		assertTrue (false);
788 	}
789 
790 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
791 
792 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
793 	assertTrue (array->size() == 0);
794 
795 	Poco::Dynamic::Array da = *array;
796 	assertTrue (da.size() == 0);
797 }
798 
799 
testNestedArray()800 void JSONTest::testNestedArray()
801 {
802 	std::string json = "[[[[]]]]";
803 	Parser parser;
804 	Var result;
805 
806 	try
807 	{
808 		result = parser.parse(json);
809 	}
810 	catch(JSONException& jsone)
811 	{
812 		std::cout << jsone.message() << std::endl;
813 		assertTrue (false);
814 	}
815 
816 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
817 
818 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
819 	assertTrue (array->size() == 1);
820 
821 	Poco::Dynamic::Array da = *array;
822 	assertTrue (da.size() == 1);
823 	assertTrue (da[0].size() == 1);
824 	assertTrue (da[0][0].size() == 1);
825 	assertTrue (da[0][0][0].size() == 0);
826 }
827 
828 
testNullElement()829 void JSONTest::testNullElement()
830 {
831 	std::string json = "[ null ]";
832 	Parser parser;
833 	Var result;
834 
835 	try
836 	{
837 		result = parser.parse(json);
838 	}
839 	catch(JSONException& jsone)
840 	{
841 		std::cout << jsone.message() << std::endl;
842 		assertTrue (false);
843 	}
844 
845 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
846 
847 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
848 	assertTrue (array->isNull(0));
849 	Var test = array->get(0);
850 	assertTrue (test.isEmpty());
851 
852 	Poco::Dynamic::Array da = *array;
853 	assertTrue (da.size() == 1);
854 	assertTrue (da[0].isEmpty());
855 }
856 
857 
testTrueElement()858 void JSONTest::testTrueElement()
859 {
860 	std::string json = "[ true ]";
861 	Parser parser;
862 	Var result;
863 
864 	try
865 	{
866 		result = parser.parse(json);
867 	}
868 	catch(JSONException& jsone)
869 	{
870 		std::cout << jsone.message() << std::endl;
871 		assertTrue (false);
872 	}
873 
874 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
875 
876 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
877 	Var test = array->get(0);
878 	assertTrue (test.type() == typeid(bool));
879 	bool value = test;
880 	assertTrue (value);
881 
882 	Poco::Dynamic::Array da = *array;
883 	assertTrue (da.size() == 1);
884 	assertTrue (da[0]);
885 }
886 
887 
testFalseElement()888 void JSONTest::testFalseElement()
889 {
890 	std::string json = "[ false ]";
891 	Parser parser;
892 	Var result;
893 
894 	try
895 	{
896 		result = parser.parse(json);
897 	}
898 	catch(JSONException& jsone)
899 	{
900 		std::cout << jsone.message() << std::endl;
901 		assertTrue (false);
902 	}
903 
904 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
905 
906 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
907 	Var test = array->get(0);
908 	assertTrue (test.type() == typeid(bool));
909 	bool value = test;
910 	assertTrue (!value);
911 
912 	Poco::Dynamic::Array da = *array;
913 	assertTrue (da.size() == 1);
914 	assertTrue (!da[0]);
915 }
916 
917 
testNumberElement()918 void JSONTest::testNumberElement()
919 {
920 	std::string json = "[ 1969 ]";
921 	Parser parser;
922 	Var result;
923 
924 	try
925 	{
926 		result = parser.parse(json);
927 	}
928 	catch(JSONException& jsone)
929 	{
930 		std::cout << jsone.message() << std::endl;
931 		assertTrue (false);
932 	}
933 
934 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
935 
936 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
937 	Var test = array->get(0);
938 	assertTrue (test.isInteger());
939 	int value = test;
940 	assertTrue (value == 1969);
941 
942 	Poco::Dynamic::Array da = *array;
943 	assertTrue (da.size() == 1);
944 	assertTrue (da[0] == 1969);
945 }
946 
947 
testStringElement()948 void JSONTest::testStringElement()
949 {
950 	std::string json = "[ \"value\" ]";
951 	Parser parser;
952 	Var result;
953 
954 	try
955 	{
956 		result = parser.parse(json);
957 	}
958 	catch(JSONException& jsone)
959 	{
960 		std::cout << jsone.message() << std::endl;
961 		assertTrue (false);
962 	}
963 
964 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
965 
966 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
967 	Var test = array->get(0);
968 	assertTrue (test.isString());
969 	std::string value = test.convert<std::string>();
970 	assertTrue (value.compare("value") == 0);
971 
972 	Poco::Dynamic::Array da = *array;
973 	assertTrue (da.size() == 1);
974 	assertTrue (da[0] == "value");
975 
976 	std::stringstream s;
977 	json = "[ \"\\u0017\" ]";
978 	Var v = Parser().parse(json);
979 	Stringifier::condense(v, s);
980 	std::string ss = s.str();
981 	assertTrue (s.str() == "[\"\\u0017\"]");
982 }
983 
984 
testEmptyObjectElement()985 void JSONTest::testEmptyObjectElement()
986 {
987 	std::string json = "[{}]";
988 	Parser parser;
989 	Var result;
990 
991 	try
992 	{
993 		result = parser.parse(json);
994 	}
995 	catch(JSONException& jsone)
996 	{
997 		std::cout << jsone.message() << std::endl;
998 		assertTrue (false);
999 	}
1000 
1001 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
1002 
1003 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
1004 	Object::Ptr object = array->getObject(0);
1005 	assertTrue (object->size() == 0);
1006 
1007 	Poco::Dynamic::Array da = *array;
1008 	assertTrue (da.size() == 1);
1009 	assertTrue (da[0].isStruct());
1010 	assertTrue (da[0].size() == 0);
1011 }
1012 
1013 
testDoubleElement()1014 void JSONTest::testDoubleElement()
1015 {
1016 	std::string json = "[ 1234.5 ]";
1017 	Parser parser;
1018 	Var result;
1019 
1020 	try
1021 	{
1022 		result = parser.parse(json);
1023 	}
1024 	catch(JSONException& jsone)
1025 	{
1026 		std::cout << jsone.message() << std::endl;
1027 		assertTrue (false);
1028 	}
1029 
1030 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
1031 
1032 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
1033 	Var test = array->get(0);
1034 	assertTrue (test.isNumeric());
1035 	double value = test;
1036 	assertTrue (value == 1234.5);
1037 
1038 	Poco::Dynamic::Array da = *array;
1039 	assertTrue (da.size() == 1);
1040 	assertTrue (da[0] == 1234.5);
1041 }
1042 
1043 
testSetArrayElement()1044 void JSONTest::testSetArrayElement()
1045 {
1046 	std::string json = "[]";
1047 	Parser parser;
1048 	Var result = parser.parse(json);
1049 	Poco::JSON::Array::Ptr array = result.extract<Poco::JSON::Array::Ptr>();
1050 
1051 	Poco::Dynamic::Array dynArray = *array;
1052 	assertTrue (dynArray.size() == 0);
1053 
1054 	// array[0] = 7
1055 	array->set(0, 7);
1056 	assertTrue (array->size() == 1);
1057 	assertTrue (array->getElement<int>(0) == 7);
1058 
1059 	dynArray = *array;
1060 	assertTrue (dynArray.size() == 1);
1061 	assertTrue (dynArray[0] == 7);
1062 
1063 	// array[2] = "foo"
1064 	array->set(2, std::string("foo"));
1065 	assertTrue (array->size() == 3);
1066 	assertTrue (array->getElement<int>(0) == 7);
1067 	assertTrue (array->isNull(1));
1068 	assertTrue (array->getElement<std::string>(2) == "foo");
1069 
1070 	dynArray = *array;
1071 	assertTrue (dynArray.size() == 3);
1072 	assertTrue (dynArray[0] == 7);
1073 	assertTrue (dynArray[1].isEmpty());
1074 	assertTrue (dynArray[2] == "foo");
1075 
1076 	// array[1] = 13
1077 	array->set(1, 13);
1078 	assertTrue (array->size() == 3);
1079 	assertTrue (array->getElement<int>(0) == 7);
1080 	assertTrue (array->getElement<int>(1) == 13);
1081 	assertTrue (array->getElement<std::string>(2) == "foo");
1082 
1083 	dynArray = std::move(*array);
1084 	assertTrue (dynArray.size() == 3);
1085 	assertTrue (dynArray[0] == 7);
1086 	assertTrue (dynArray[1] == 13);
1087 	assertTrue (dynArray[2] == "foo");
1088 
1089 	dynArray.clear();
1090 	assertTrue (dynArray.size() == 0);
1091 }
1092 
1093 
testOptValue()1094 void JSONTest::testOptValue()
1095 {
1096 	std::string json = "{ }";
1097 	Parser parser;
1098 	Var result;
1099 
1100 	try
1101 	{
1102 		result = parser.parse(json);
1103 	}
1104 	catch(JSONException& jsone)
1105 	{
1106 		std::cout << jsone.message() << std::endl;
1107 		assertTrue (false);
1108 	}
1109 
1110 	assertTrue (result.type() == typeid(Object::Ptr));
1111 
1112 	Object::Ptr object = result.extract<Object::Ptr>();
1113 	int n = object->optValue("test", 123);
1114 	assertTrue (n == 123);
1115 }
1116 
1117 
testQuery()1118 void JSONTest::testQuery()
1119 {
1120 	std::string json = "{ \"name\" : \"Franky\", \"children\" : [ \"Jonas\", \"Ellen\" ], \"address\": { \"street\": \"A Street\", \"number\": 123, \"city\":\"The City\"} }";
1121 	Parser parser;
1122 	Var result;
1123 
1124 	try
1125 	{
1126 		result = parser.parse(json);
1127 	}
1128 	catch(JSONException& jsone)
1129 	{
1130 		std::cout << jsone.message() << std::endl;
1131 		assertTrue (false);
1132 	}
1133 
1134 	assertTrue (result.type() == typeid(Object::Ptr));
1135 
1136 	Query query(result);
1137 
1138 	std::string firstChild = query.findValue("children[0]", "");
1139 	assertTrue (firstChild.compare("Jonas") == 0);
1140 
1141 	Poco::DynamicStruct ds = *result.extract<Object::Ptr>();
1142 	assertTrue (ds["name"] == "Franky");
1143 	assertTrue (ds["children"].size() == 2);
1144 	assertTrue (ds["children"][0] == "Jonas");
1145 	assertTrue (ds["children"][1] == "Ellen");
1146 
1147 	Object::Ptr pAddress = query.findObject("address");
1148 	assertTrue (pAddress->getValue<std::string>("street") == "A Street");
1149 	pAddress = query.findObject("bad address");
1150 	assertTrue (pAddress.isNull());
1151 
1152 	Object address;
1153 	address.set("dummy", 123);
1154 	query.findObject("bad address", address);
1155 	assertTrue (!address.has("dummy"));
1156 	Object& rAddress = query.findObject("address", address);
1157 	assertTrue (rAddress.getValue<int>("number") == 123);
1158 
1159 	Var badAddr = query.find("address.street.anotherObject");
1160 	assertTrue (badAddr.isEmpty());
1161 
1162 	using Poco::JSON::Array;
1163 
1164 	Array::Ptr pChildren = query.findArray("children");
1165 	assertTrue (pChildren->getElement<std::string>(0) == "Jonas");
1166 	pChildren = query.findArray("no children");
1167 	assertTrue (pChildren.isNull());
1168 
1169 	Array children;
1170 	children.add("dummy");
1171 	query.findArray("no children", children);
1172 	assertTrue (children.size() == 0);
1173 	Array& rChildren = query.findArray("children", children);
1174 	assertTrue (rChildren.getElement<std::string>(1) == "Ellen");
1175 
1176 	Object::Ptr pObj = new Poco::JSON::Object;
1177 	pObj->set("Id", 22);
1178 
1179 	Query queryPointer(pObj);
1180 	Var idQueryPointer = queryPointer.find("Id");
1181 	assertTrue (22 == idQueryPointer);
1182 
1183 	Query queryObj(*pObj);
1184 	Var idQueryObj = queryObj.find("Id");
1185 	assertTrue (22 == idQueryObj);
1186 
1187 	Var bad = 1;
1188 	try
1189 	{
1190 		Query badQuery(bad);
1191 		fail ("must throw");
1192 	}
1193 	catch (Poco::InvalidArgumentException&) { }
1194 }
1195 
1196 
testComment()1197 void JSONTest::testComment()
1198 {
1199 	std::string json = "{ \"name\" : \"Franky\" /* father */, \"children\" : [ \"Jonas\" /* son */ , \"Ellen\" /* daughter */ ] }";
1200 	Parser parser;
1201 	Var result;
1202 
1203 	try
1204 	{
1205 		parser.parse(json);
1206 		fail ("must fail");
1207 	}
1208 	catch(Poco::SyntaxException&)
1209 	{
1210 	}
1211 	catch (JSONException&)
1212 	{
1213 	}
1214 
1215 	parser.reset();
1216 	parser.setAllowComments(true);
1217 	try
1218 	{
1219 		result = parser.parse(json);
1220 	}
1221 	catch(JSONException& jsone)
1222 	{
1223 		std::cout << jsone.message() << std::endl;
1224 		assertTrue (false);
1225 	}
1226 
1227 	assertTrue (result.type() == typeid(Object::Ptr));
1228 
1229 	Query query(result);
1230 
1231 	std::string firstChild = query.findValue("children[0]", "");
1232 	assertTrue (firstChild.compare("Jonas") == 0);
1233 }
1234 
1235 
testPrintHandler()1236 void JSONTest::testPrintHandler()
1237 {
1238 	std::string json = "{ \"name\" : \"Homer\", \"age\" : 38, \"wife\" : \"Marge\", \"age\" : 36, \"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ] }";
1239 	Parser parser;
1240 	std::ostringstream ostr;
1241 	PrintHandler::Ptr pHandler = new PrintHandler(ostr);
1242 	parser.setHandler(pHandler);
1243 	parser.parse(json);
1244 	assertTrue (ostr.str() == "{\"name\":\"Homer\",\"age\":38,\"wife\":\"Marge\",\"age\":36,\"children\":[\"Bart\",\"Lisa\",\"Maggie\"]}");
1245 
1246 	pHandler->setIndent(1);
1247 	ostr.str("");
1248 	parser.reset();
1249 	parser.parse(json);
1250 	assertTrue (ostr.str() == "{\n"
1251 		" \"name\" : \"Homer\",\n"
1252 		" \"age\" : 38,\n"
1253 		" \"wife\" : \"Marge\",\n"
1254 		" \"age\" : 36,\n"
1255 		" \"children\" : [\n"
1256 		"  \"Bart\",\n"
1257 		"  \"Lisa\",\n"
1258 		"  \"Maggie\"\n"
1259 		" ]\n"
1260 		"}"
1261 	);
1262 
1263 	pHandler->setIndent(2);
1264 	ostr.str("");
1265 	parser.reset();
1266 	parser.parse(json);
1267 	assertTrue (ostr.str() == "{\n"
1268 		"  \"name\" : \"Homer\",\n"
1269 		"  \"age\" : 38,\n"
1270 		"  \"wife\" : \"Marge\",\n"
1271 		"  \"age\" : 36,\n"
1272 		"  \"children\" : [\n"
1273 		"    \"Bart\",\n"
1274 		"    \"Lisa\",\n"
1275 		"    \"Maggie\"\n"
1276 		"  ]\n"
1277 		"}"
1278 	);
1279 
1280 	pHandler->setIndent(4);
1281 	ostr.str("");
1282 	parser.reset();
1283 	parser.parse(json);
1284 	assertTrue (ostr.str() == "{\n"
1285 		"    \"name\" : \"Homer\",\n"
1286 		"    \"age\" : 38,\n"
1287 		"    \"wife\" : \"Marge\",\n"
1288 		"    \"age\" : 36,\n"
1289 		"    \"children\" : [\n"
1290 		"        \"Bart\",\n"
1291 		"        \"Lisa\",\n"
1292 		"        \"Maggie\"\n"
1293 		"    ]\n"
1294 		"}"
1295 	);
1296 
1297 	json =
1298 		"{"
1299 			"\"array\":"
1300 			"["
1301 				"{"
1302 					"\"key1\":"
1303 					"["
1304 						"1,2,3,"
1305 						"{"
1306 							"\"subkey\":"
1307 							"\"test\""
1308 						"}"
1309 					"]"
1310 				"},"
1311 				"{"
1312 					"\"key2\":"
1313 					"{"
1314 						"\"anotherSubKey\":"
1315 						"["
1316 							"1,"
1317 							"{"
1318 								"\"subSubKey\":"
1319 								"["
1320 									"4,5,6"
1321 								"]"
1322 							"}"
1323 						"]"
1324 					"}"
1325 				"}"
1326 			"]"
1327 		"}";
1328 
1329 
1330 	ostr.str("");
1331 	pHandler->setIndent(0);
1332 	parser.reset();
1333 	parser.parse(json);
1334 	assertTrue (json == ostr.str());
1335 
1336 	json="[[\"a\"],[\"b\"],[[\"c\"],[\"d\"]]]";
1337 	ostr.str("");
1338 	pHandler->setIndent(0);
1339 	parser.reset();
1340 	parser.parse(json);
1341 	assertTrue (json == ostr.str());
1342 
1343 	json="[{\"1\":\"one\",\"0\":[\"zero\",\"nil\"]}]";
1344 	ostr.str("");
1345 	pHandler->setIndent(0);
1346 	parser.reset();
1347 	parser.parse(json);
1348 	assertTrue (json == ostr.str());
1349 
1350 }
1351 
1352 
testStringify()1353 void JSONTest::testStringify()
1354 {
1355 	std::ostringstream os;
1356 	Var i = 123;
1357 	Stringifier::stringify(i, os);
1358 	assertTrue (os.str() == "123");
1359 
1360 	os.str("");
1361 	Var f = 123.456;
1362 	Stringifier::stringify(f, os);
1363 	assertTrue (os.str() == "123.456");
1364 
1365 	os.str("");
1366 	Var s = "abcdef";
1367 	Stringifier::stringify(s, os);
1368 	assertTrue (os.str() == "\"abcdef\"");
1369 
1370 	os.str("");
1371 	DateTime dt;
1372 	Var d = dt;
1373 	Stringifier::stringify(d, os);
1374 	assertTrue (os.str() == std::string("\"" + DateTimeFormatter::format(dt, Poco::DateTimeFormat::ISO8601_FORMAT) + "\""));
1375 
1376 	std::string str1 = "\r";
1377 	std::string str2 = "\n";
1378 	Object obj1, obj2;
1379 	obj1.set("payload", str1);
1380 	obj2.set("payload", str2);
1381 	std::ostringstream oss1, oss2;
1382 	Poco::JSON::Stringifier::stringify(obj1, oss1);
1383 	Poco::JSON::Stringifier::stringify(obj2, oss2);
1384 	assertTrue (oss1.str() == "{\"payload\":\"\\r\"}");
1385 	std::cout << "\"" << oss1.str() << "\"" << std::endl;
1386 	assertTrue (oss2.str() == "{\"payload\":\"\\n\"}");
1387 
1388 	Object jObj(false);
1389 	jObj.set("foo\\", 0);
1390 	jObj.set("bar/", 0);
1391 	jObj.set("baz", 0);
1392 	jObj.set("q\"uote\"d", 0);
1393 	jObj.set("backspace", "bs\b");
1394 	jObj.set("newline", "nl\n");
1395 	jObj.set("tab", "tb\t");
1396 
1397 	std::stringstream ss;
1398 	jObj.stringify(ss);
1399 
1400 	assertTrue (ss.str() == "{\"backspace\":\"bs\\b\",\"bar\\/\":0,\"baz\":0,\"foo\\\\\":0,"
1401 		"\"newline\":\"nl\\n\",\"q\\\"uote\\\"d\":0,\"tab\":\"tb\\t\"}");
1402 
1403 	std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
1404 						"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
1405 						"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" } } }";
1406 	Parser parser;
1407 	Var result;
1408 
1409 	try
1410 	{
1411 		result = parser.parse(json);
1412 	}
1413 	catch(JSONException& jsone)
1414 	{
1415 		std::cout << jsone.message() << std::endl;
1416 		assertTrue (false);
1417 	}
1418 
1419 	assertTrue (result.type() == typeid(Object::Ptr));
1420 	std::ostringstream ostr;
1421 
1422 	Stringifier::condense(result, ostr);
1423 	std::string str = "{"
1424 						"\"Simpsons\":{"
1425 						"\"address\":{"
1426 						"\"number\":742,"
1427 						"\"street\":\"Evergreen Terrace\","
1428 						"\"town\":\"Springfield\""
1429 						"},"
1430 						"\"children\":["
1431 						"\"Bart\","
1432 						"\"Lisa\","
1433 						"\"Maggie\"],"
1434 						"\"husband\":{"
1435 						"\"age\":38,"
1436 						"\"name\":\"Homer\""
1437 						"},"
1438 						"\"wife\":{"
1439 						"\"age\":36,\"name\":\"Marge\""
1440 						"}}}";
1441 
1442 	assertTrue (ostr.str() == str);
1443 
1444 	ostr.str("");
1445 	Stringifier::stringify(result, ostr);
1446 	assertTrue (ostr.str() == str);
1447 
1448 	ostr.str("");
1449 	Stringifier::stringify(result, ostr, 1);
1450 	str = "{\n"
1451 		" \"Simpsons\" : {\n"
1452 		"  \"address\" : {\n"
1453 		"   \"number\" : 742,\n"
1454 		"   \"street\" : \"Evergreen Terrace\",\n"
1455 		"   \"town\" : \"Springfield\"\n"
1456 		"  },\n"
1457 		"  \"children\" : [\n"
1458 		"   \"Bart\",\n"
1459 		"   \"Lisa\",\n"
1460 		"   \"Maggie\"\n"
1461 		"  ],\n"
1462 		"  \"husband\" : {\n"
1463 		"   \"age\" : 38,\n"
1464 		"   \"name\" : \"Homer\"\n"
1465 		"  },\n"
1466 		"  \"wife\" : {\n"
1467 		"   \"age\" : 36,\n"
1468 		"   \"name\" : \"Marge\"\n"
1469 		"  }\n"
1470 		" }\n"
1471 		"}";
1472 	assertTrue (ostr.str() == str);
1473 
1474 	ostr.str("");
1475 	Stringifier::stringify(result, ostr, 2);
1476 	str = "{\n"
1477 		"  \"Simpsons\" : {\n"
1478 		"    \"address\" : {\n"
1479 		"      \"number\" : 742,\n"
1480 		"      \"street\" : \"Evergreen Terrace\",\n"
1481 		"      \"town\" : \"Springfield\"\n"
1482 		"    },\n"
1483 		"    \"children\" : [\n"
1484 		"      \"Bart\",\n"
1485 		"      \"Lisa\",\n"
1486 		"      \"Maggie\"\n"
1487 		"    ],\n"
1488 		"    \"husband\" : {\n"
1489 		"      \"age\" : 38,\n"
1490 		"      \"name\" : \"Homer\"\n"
1491 		"    },\n"
1492 		"    \"wife\" : {\n"
1493 		"      \"age\" : 36,\n"
1494 		"      \"name\" : \"Marge\"\n"
1495 		"    }\n"
1496 		"  }\n"
1497 		"}";
1498 	assertTrue (ostr.str() == str);
1499 
1500 	ostr.str("");
1501 	Stringifier::stringify(result, ostr, 4);
1502 	str = "{\n"
1503 		"    \"Simpsons\" : {\n"
1504 		"        \"address\" : {\n"
1505 		"            \"number\" : 742,\n"
1506 		"            \"street\" : \"Evergreen Terrace\",\n"
1507 		"            \"town\" : \"Springfield\"\n"
1508 		"        },\n"
1509 		"        \"children\" : [\n"
1510 		"            \"Bart\",\n"
1511 		"            \"Lisa\",\n"
1512 		"            \"Maggie\"\n"
1513 		"        ],\n"
1514 		"        \"husband\" : {\n"
1515 		"            \"age\" : 38,\n"
1516 		"            \"name\" : \"Homer\"\n"
1517 		"        },\n"
1518 		"        \"wife\" : {\n"
1519 		"            \"age\" : 36,\n"
1520 		"            \"name\" : \"Marge\"\n"
1521 		"        }\n"
1522 		"    }\n"
1523 		"}";
1524 	assertTrue (ostr.str() == str);
1525 }
1526 
1527 
testStringifyPreserveOrder()1528 void JSONTest::testStringifyPreserveOrder()
1529 {
1530 	Object presObj(Poco::JSON_PRESERVE_KEY_ORDER);
1531 	presObj.set("foo", 0);
1532 	presObj.set("bar", 0);
1533 	presObj.set("baz", 0);
1534 	std::stringstream ss;
1535 	presObj.stringify(ss);
1536 	assertTrue (ss.str() == "{\"foo\":0,\"bar\":0,\"baz\":0}");
1537 	Object::NameList nl = presObj.getNames();
1538 	assertTrue (nl.size() == 3);
1539 	assertTrue (nl[0] == "foo");
1540 	assertTrue (nl[1] == "bar");
1541 	assertTrue (nl[2] == "baz");
1542 
1543 	ss.str("");
1544 	Stringifier::stringify(presObj, ss);
1545 	assertTrue (ss.str() == "{\"foo\":0,\"bar\":0,\"baz\":0}");
1546 
1547 	Object noPresObj;
1548 	noPresObj.set("foo", 0);
1549 	noPresObj.set("bar", 0);
1550 	noPresObj.set("baz", 0);
1551 	ss.str("");
1552 	noPresObj.stringify(ss);
1553 	assertTrue (ss.str() == "{\"bar\":0,\"baz\":0,\"foo\":0}");
1554 	ss.str("");
1555 	Stringifier::stringify(noPresObj, ss);
1556 	assertTrue (ss.str() == "{\"bar\":0,\"baz\":0,\"foo\":0}");
1557 
1558 	std::string json = "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\" , \"age\" : 38 }, \"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
1559 						"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
1560 						"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" } } }";
1561 
1562 	ParseHandler::Ptr pHandler = new ParseHandler(true);
1563 	Parser parser(pHandler);
1564 	Var result;
1565 
1566 	try
1567 	{
1568 		result = parser.parse(json);
1569 	}
1570 	catch(JSONException& jsone)
1571 	{
1572 		std::cout << jsone.message() << std::endl;
1573 		assertTrue (false);
1574 	}
1575 
1576 	assertTrue (result.type() == typeid(Object::Ptr));
1577 	std::ostringstream ostr;
1578 
1579 	Stringifier::condense(result, ostr);
1580 	assertTrue (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
1581 						"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
1582 						"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
1583 
1584 	ostr.str("");
1585 	Stringifier::stringify(result, ostr);
1586 	assertTrue (ostr.str() == "{\"Simpsons\":{\"husband\":{\"name\":\"Homer\",\"age\":38},\"wife\":{\"name\":\"Marge\",\"age\":36},"
1587 						"\"children\":[\"Bart\",\"Lisa\",\"Maggie\"],"
1588 						"\"address\":{\"number\":742,\"street\":\"Evergreen Terrace\",\"town\":\"Springfield\"}}}");
1589 
1590 	ostr.str("");
1591 	Stringifier::stringify(result, ostr, 1);
1592 	assertTrue (ostr.str() == "{\n"
1593 						" \"Simpsons\" : {\n"
1594 						"  \"husband\" : {\n"
1595 						"   \"name\" : \"Homer\",\n"
1596 						"   \"age\" : 38\n"
1597 						"  },\n"
1598 						"  \"wife\" : {\n"
1599 						"   \"name\" : \"Marge\",\n"
1600 						"   \"age\" : 36\n"
1601 						"  },\n"
1602 						"  \"children\" : [\n"
1603 						"   \"Bart\",\n"
1604 						"   \"Lisa\",\n"
1605 						"   \"Maggie\"\n"
1606 						"  ],\n"
1607 						"  \"address\" : {\n"
1608 						"   \"number\" : 742,\n"
1609 						"   \"street\" : \"Evergreen Terrace\",\n"
1610 						"   \"town\" : \"Springfield\"\n"
1611 						"  }\n"
1612 						" }\n"
1613 						"}");
1614 
1615 	ostr.str("");
1616 	Stringifier::stringify(result, ostr, 2);
1617 	assertTrue (ostr.str() == "{\n"
1618 						"  \"Simpsons\" : {\n"
1619 						"    \"husband\" : {\n"
1620 						"      \"name\" : \"Homer\",\n"
1621 						"      \"age\" : 38\n"
1622 						"    },\n"
1623 						"    \"wife\" : {\n"
1624 						"      \"name\" : \"Marge\",\n"
1625 						"      \"age\" : 36\n"
1626 						"    },\n"
1627 						"    \"children\" : [\n"
1628 						"      \"Bart\",\n"
1629 						"      \"Lisa\",\n"
1630 						"      \"Maggie\"\n"
1631 						"    ],\n"
1632 						"    \"address\" : {\n"
1633 						"      \"number\" : 742,\n"
1634 						"      \"street\" : \"Evergreen Terrace\",\n"
1635 						"      \"town\" : \"Springfield\"\n"
1636 						"    }\n"
1637 						"  }\n"
1638 						"}");
1639 
1640 	ostr.str("");
1641 	Stringifier::stringify(result, ostr, 4);
1642 	assertTrue (ostr.str() == "{\n"
1643 						"    \"Simpsons\" : {\n"
1644 						"        \"husband\" : {\n"
1645 						"            \"name\" : \"Homer\",\n"
1646 						"            \"age\" : 38\n"
1647 						"        },\n"
1648 						"        \"wife\" : {\n"
1649 						"            \"name\" : \"Marge\",\n"
1650 						"            \"age\" : 36\n"
1651 						"        },\n"
1652 						"        \"children\" : [\n"
1653 						"            \"Bart\",\n"
1654 						"            \"Lisa\",\n"
1655 						"            \"Maggie\"\n"
1656 						"        ],\n"
1657 						"        \"address\" : {\n"
1658 						"            \"number\" : 742,\n"
1659 						"            \"street\" : \"Evergreen Terrace\",\n"
1660 						"            \"town\" : \"Springfield\"\n"
1661 						"        }\n"
1662 						"    }\n"
1663 						"}");
1664 
1665 	Poco::DynamicStruct ds = *result.extract<Object::Ptr>();
1666 	assertTrue(ds.toString() == "{ \"Simpsons\" : { \"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", \"town\" : \"Springfield\" }, "
1667 		"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
1668 		"\"husband\" : { \"age\" : 38, \"name\" : \"Homer\" }, "
1669 		"\"wife\" : { \"age\" : 36, \"name\" : \"Marge\" } } }");
1670 	assertTrue (ds["Simpsons"].isStruct());
1671 	assertFalse(ds["Simpsons"].isOrdered());
1672 	assertTrue (ds["Simpsons"]["husband"].isStruct());
1673 	assertTrue (ds["Simpsons"]["husband"]["name"] == "Homer");
1674 	assertTrue (ds["Simpsons"]["husband"]["age"] == 38);
1675 
1676 	assertTrue (ds["Simpsons"]["wife"].isStruct());
1677 	assertTrue (ds["Simpsons"]["wife"]["name"] == "Marge");
1678 	assertTrue (ds["Simpsons"]["wife"]["age"] == 36);
1679 
1680 	assertTrue (ds["Simpsons"]["children"].isArray());
1681 	assertTrue (ds["Simpsons"]["children"][0] == "Bart");
1682 	assertTrue (ds["Simpsons"]["children"][1] == "Lisa");
1683 	assertTrue (ds["Simpsons"]["children"][2] == "Maggie");
1684 
1685 	assertTrue (ds["Simpsons"]["address"].isStruct());
1686 	assertTrue (ds["Simpsons"]["address"]["number"] == 742);
1687 	assertTrue (ds["Simpsons"]["address"]["street"] == "Evergreen Terrace");
1688 	assertTrue (ds["Simpsons"]["address"]["town"] == "Springfield");
1689 
1690 	Poco::OrderedDynamicStruct ods = *result.extract<Object::Ptr>();
1691 	assertTrue(ods["Simpsons"].isStruct());
1692 	assertTrue(ods["Simpsons"].isOrdered());
1693 	assertTrue(ods.toString() == "{ \"Simpsons\" : { \"husband\" : { \"name\" : \"Homer\", \"age\" : 38 }, "
1694 		"\"wife\" : { \"name\" : \"Marge\", \"age\" : 36 }, "
1695 		"\"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ], "
1696 		"\"address\" : { \"number\" : 742, \"street\" : \"Evergreen Terrace\", "
1697 		"\"town\" : \"Springfield\" } } }");
1698 }
1699 
1700 
testValidJanssonFiles()1701 void JSONTest::testValidJanssonFiles()
1702 {
1703 	Poco::Path pathPattern(getTestFilesPath("valid"));
1704 
1705 	std::set<std::string> paths;
1706 	Poco::Glob::glob(pathPattern, paths);
1707 
1708 	for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
1709 	{
1710 		Poco::Path filePath(*it, "input");
1711 
1712 		if ( filePath.isFile() )
1713 		{
1714 			Poco::File inputFile(filePath);
1715 			if ( inputFile.exists() )
1716 			{
1717 				Poco::FileInputStream fis(filePath.toString());
1718 				std::cout << filePath.toString() << " ... ";
1719 
1720 				Parser parser;
1721 				Var result;
1722 
1723 				try
1724 				{
1725 					parser.parse(fis);
1726 					result = parser.asVar();
1727 					std::cout << "Ok!" << std::endl;
1728 				}
1729 				catch(JSONException& jsone)
1730 				{
1731 					std::string err = jsone.displayText();
1732 					std::cout << "Failed:" << err << std::endl;
1733 					fail (err);
1734 				}
1735 				catch(Poco::Exception& e)
1736 				{
1737 					std::string err = e.displayText();
1738 					std::cout << "Failed:" << err << std::endl;
1739 					fail (err);
1740 				}
1741 			}
1742 		}
1743 	}
1744 }
1745 
1746 
testInvalidJanssonFiles()1747 void JSONTest::testInvalidJanssonFiles()
1748 {
1749 	Poco::Path pathPattern(getTestFilesPath("invalid"));
1750 
1751 	std::set<std::string> paths;
1752 	Poco::Glob::glob(pathPattern, paths);
1753 
1754 	for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
1755 	{
1756 		Poco::Path filePath(*it, "input");
1757 
1758 		if (filePath.isFile())
1759 		{
1760 			Poco::File inputFile(filePath);
1761 			if (inputFile.exists())
1762 			{
1763 				Poco::FileInputStream fis(filePath.toString());
1764 				std::cout << filePath.toString() << " ... ";
1765 
1766 				Parser parser;
1767 				parser.setAllowNullByte(false);
1768 				Var result;
1769 
1770 				try
1771 				{
1772 					parser.parse(fis);
1773 					result = parser.asVar();
1774 					// We shouldn't get here.
1775 					std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
1776 					fail(result.convert<std::string>());
1777 				}
1778 				catch(Poco::Exception& /*ex*/)
1779 				{
1780 					std::cout << /*" (" << ex.displayText() << ") " <<*/ "Ok!" << std::endl;
1781 				}
1782 			}
1783 		}
1784 	}
1785 }
1786 
1787 
testInvalidUnicodeJanssonFiles()1788 void JSONTest::testInvalidUnicodeJanssonFiles()
1789 {
1790 	Poco::Path pathPattern(getTestFilesPath("invalid-unicode"));
1791 
1792 	std::set<std::string> paths;
1793 	Poco::Glob::glob(pathPattern, paths);
1794 
1795 	for(std::set<std::string>::iterator it = paths.begin(); it != paths.end(); ++it)
1796 	{
1797 		Poco::Path filePath(*it, "input");
1798 
1799 		if ( filePath.isFile() )
1800 		{
1801 			Poco::File inputFile(filePath);
1802 			if ( inputFile.exists() )
1803 			{
1804 				Poco::FileInputStream fis(filePath.toString());
1805 				std::cout << filePath.toString() << " ... ";
1806 
1807 				Parser parser;
1808 				parser.setAllowNullByte(false);
1809 				Var result;
1810 
1811 				try
1812 				{
1813 					parser.parse(fis);
1814 					result = parser.asVar();
1815 					// We shouldn't get here.
1816 					std::cout << "We didn't get an exception. This is the result: " << result.convert<std::string>() << std::endl;
1817 					fail(result.convert<std::string>());
1818 				}
1819 				catch(Poco::Exception& /*ex*/)
1820 				{
1821 					std::cout << /*" (" << ex.displayText() << ") " <<*/ "Ok!" << std::endl;
1822 				}
1823 			}
1824 		}
1825 	}
1826 }
1827 
1828 
testTemplate()1829 void JSONTest::testTemplate()
1830 {
1831 	Template tpl;
1832 	tpl.parse("Hello world! From <?= person.name?>.\n<?if person.tooOld?>You're too old.<?endif?>");
1833 
1834 	Object::Ptr data = new Object();
1835 	Object::Ptr person = new Object();
1836 	data->set("person", person);
1837 	person->set("name", "Franky");
1838 	person->set("tooOld", true);
1839 	std::ostringstream ostr;
1840 	tpl.render(data, ostr);
1841 	std::cout << ostr.str();
1842 	assertTrue (ostr.str() == "Hello world! From Franky.\nYou're too old.");
1843 }
1844 
1845 
testUnicode()1846 void JSONTest::testUnicode()
1847 {
1848 	const unsigned char supp[] = {0x61, 0xE1, 0xE9, 0x78, 0xED, 0xF3, 0xFA, 0x0};
1849 	std::string text((const char*) supp);
1850 
1851 	std::string json = "{ \"test\" : \"a\\u00E1\\u00E9x\\u00ED\\u00F3\\u00FA\" }";
1852 	Parser parser;
1853 
1854 	Var result;
1855 	parser.parse(json);
1856 	result = parser.asVar();
1857 
1858 	assertTrue (result.type() == typeid(Object::Ptr));
1859 
1860 	Object::Ptr object = result.extract<Object::Ptr>();
1861 	Var test = object->get("test");
1862 
1863 	Poco::Latin1Encoding latin1;
1864 	Poco::UTF8Encoding utf8;
1865 	Poco::TextConverter converter(latin1, utf8);
1866 	std::string original;
1867 	converter.convert(text, original);
1868 
1869 	assertTrue (test.convert<std::string>() == original);
1870 
1871 	parser.reset();
1872 	std::ostringstream os;
1873 	os << '[' << (char) 0x92 << ']';
1874 	try
1875 	{
1876 		parser.parse(os.str());
1877 		fail("Invalid Unicode sequence, must fail.");
1878 	}
1879 	catch (JSONException&) {}
1880 
1881 	parser.reset();
1882 	os.str("");
1883 	os << "[\"" << (char)0xC2 << (char)0x92 << "\"]";
1884 	result = parser.parse(os.str());
1885 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
1886 
1887 	parser.reset();
1888 	os.str("");
1889 	os << "[\"" << (char)0xAC << "\"]";
1890 	try
1891 	{
1892 		parser.parse(os.str());
1893 		fail("Invalid Unicode sequence, must fail.");
1894 	}
1895 	catch (JSONException&) {}
1896 
1897 	parser.reset();
1898 	os.str("");
1899 	os << "[\"" << (char)0xE2 << (char)0x82 << (char)0xAC << "\"]";
1900 	result = parser.parse(os.str());
1901 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
1902 
1903 	parser.reset();
1904 	os.str("");
1905 	os << "[\"" << (char)0xA2 << "\"]";
1906 	try
1907 	{
1908 		parser.parse(os.str());
1909 		fail("Invalid Unicode sequence, must fail.");
1910 	}
1911 	catch (JSONException&){}
1912 
1913 	parser.reset();
1914 	os.str("");
1915 	os << "[\"" << (char)0xF0 << (char)0xA4 << (char)0xAD << (char)0xAD << "\"]";
1916 	result = parser.parse(os.str());
1917 	assertTrue (result.type() == typeid(Poco::JSON::Array::Ptr));
1918 }
1919 
1920 
testSmallBuffer()1921 void JSONTest::testSmallBuffer()
1922 {
1923 	Poco::JSON::Parser parser(new Poco::JSON::ParseHandler(), 4);
1924 	std::string jsonStr = "{ \"x\" : \"123456789012345678901234567890123456789012345678901234567890\" }";
1925 	parser.parse(jsonStr);
1926 }
1927 
testEscape0()1928 void JSONTest::testEscape0()
1929 {
1930 	Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
1931 
1932 	std::string nullString("B\0b", 3);
1933 	json->set("name", nullString);
1934 
1935 	std::stringstream ss;
1936 	json->stringify(ss);
1937 
1938 	assertTrue (ss.str().compare("{\"name\":\"B\\u0000b\"}") == 0);
1939 }
1940 
1941 
testNonEscapeUnicode()1942 void JSONTest::testNonEscapeUnicode()
1943 {
1944 	std::string chinese("{\"arr\":[{ \"name\" : \"\\u4e2d\" }]}");
1945 	Poco::JSON::Parser parser(new Poco::JSON::ParseHandler());
1946 	Var result = parser.parse(chinese);
1947 
1948 	assertTrue (result.type() == typeid(Object::Ptr));
1949 
1950 	Object::Ptr object = result.extract<Object::Ptr>();
1951 	object->setEscapeUnicode(false);
1952 
1953 	std::stringstream ss;
1954 	object->stringify(ss);
1955 	assertTrue (ss.str().compare("{\"arr\":[{\"name\":\"\xE4\xB8\xAD\"}]}") == 0);
1956 
1957 	const unsigned char utf8Chars[]   = {'{', '"', 'a', 'r', 'r', '"', ':', '[', '{', '"', 'n', 'a', 'm', 'e', '"', ':',
1958 										 '"', 'g', 0xC3, 0xBC, 'n', 't', 'e', 'r', '"', '}', ']', '}', 0};
1959 	std::string utf8Text((const char*) utf8Chars);
1960 	parser.reset();
1961 	result = parser.parse(utf8Text);
1962 	object = result.extract<Object::Ptr>();
1963 	object->setEscapeUnicode(false);
1964 
1965 	ss.str(""); object->stringify(ss);
1966 	assertTrue (ss.str() == "{\"arr\":[{\"name\":\"g\xC3\xBCnter\"}]}");
1967 
1968 	Poco::JSON::Object obj1;
1969 	std::string shortEscapeStr("String with \t");
1970 	std::string longEscapeStr("String with \a and \v plus \t for good measure");
1971 	obj1.set("shortEscape", shortEscapeStr);
1972 	obj1.set("longEscape", longEscapeStr);
1973 
1974 	ss.str("");
1975 	obj1.stringify(ss);
1976 
1977 	parser.reset();
1978 	parser.parse(ss.str());
1979 	result = parser.asVar();
1980 
1981 	assertTrue (result.type() == typeid(Object::Ptr));
1982 
1983 	object = result.extract<Object::Ptr>();
1984 	Var shortEscape = object->get("shortEscape");
1985 	Var longEscape = object->get("longEscape");
1986 	assertTrue (shortEscape.convert<std::string>() == shortEscapeStr);
1987 	assertTrue (longEscape.convert<std::string>() == longEscapeStr);
1988 }
1989 
1990 
testEscapeUnicode()1991 void JSONTest::testEscapeUnicode()
1992 {
1993 	Poco::JSON::Object::Ptr json = new Poco::JSON::Object();
1994 	std::string chinese("{ \"name\" : \"\\u4e2d\" }");
1995 	Poco::JSON::Parser parser(new Poco::JSON::ParseHandler());
1996 	Var result = parser.parse(chinese);
1997 
1998 	assertTrue (result.type() == typeid(Object::Ptr));
1999 
2000 	Object::Ptr object = result.extract<Object::Ptr>();
2001 	object->setEscapeUnicode(true);
2002 
2003 	std::stringstream ss;
2004 	object->stringify(ss, 0, -1);
2005 	assertTrue (ss.str().compare("{\"name\":\"\\u4E2D\"}") == 0);
2006 
2007 	const unsigned char utf8Chars[]   = {'{', '"', 'n', 'a', 'm', 'e', '"', ':',
2008 			'"', 'g', 0xC3, 0xBC, 'n', 't', 'e', 'r', '"', '}', 0};
2009 	std::string utf8Text((const char*) utf8Chars);
2010 	parser.reset();
2011 	result = parser.parse(utf8Text);
2012 	object = result.extract<Object::Ptr>();
2013 	object->setEscapeUnicode(true);
2014 	ss.str(""); object->stringify(ss, 0, -1);
2015 	assertTrue (ss.str() == "{\"name\":\"g\\u00FCnter\"}");
2016 }
2017 
2018 
getTestFilesPath(const std::string & type)2019 std::string JSONTest::getTestFilesPath(const std::string& type)
2020 {
2021 	std::ostringstream ostr;
2022 	ostr << "data/" << type << '/';
2023 	std::string validDir(ostr.str());
2024 	Poco::Path pathPattern(validDir);
2025 	if (Poco::File(pathPattern).exists())
2026 	{
2027 		validDir += '*';
2028 		return validDir;
2029 	}
2030 
2031 	ostr.str("");
2032 	ostr << "/JSON/testsuite/data/" << type << '/';
2033 	validDir = Poco::Environment::get("POCO_BASE") + ostr.str();
2034 	std::cout << validDir << std::endl;
2035 	pathPattern = validDir;
2036 
2037 	if (Poco::File(pathPattern).exists())
2038 		validDir += '*';
2039 	else
2040 	{
2041 		std::cout << "Can't find " << validDir << std::endl;
2042 		throw Poco::NotFoundException("cannot locate directory containing valid JSON test files");
2043 	}
2044 	return validDir;
2045 }
2046 
2047 
testCopy()2048 void JSONTest::testCopy()
2049 {
2050 	Object obj1(Poco::JSON_PRESERVE_KEY_ORDER);
2051 	obj1.set("foo", 0);
2052 	obj1.set("bar", 0);
2053 	obj1.set("baz", 0);
2054 
2055 	Object::NameList nl = obj1.getNames();
2056 	assertTrue (nl.size() == 3);
2057 	assertTrue (nl[0] == "foo");
2058 	assertTrue (nl[1] == "bar");
2059 	assertTrue (nl[2] == "baz");
2060 
2061 	Object obj2;
2062 	obj2 = obj1;
2063 	nl = obj2.getNames();
2064 	assertTrue (nl.size() == 3);
2065 	assertTrue (nl[0] == "foo");
2066 	assertTrue (nl[1] == "bar");
2067 	assertTrue (nl[2] == "baz");
2068 
2069 	Object obj3;
2070 	obj3.set("foo", 0);
2071 	obj3.set("bar", 0);
2072 	obj3.set("baz", 0);
2073 	nl = obj3.getNames();
2074 	assertTrue (nl.size() == 3);
2075 	assertTrue (nl[0] == "bar");
2076 	assertTrue (nl[1] == "baz");
2077 	assertTrue (nl[2] == "foo");
2078 
2079 	Object obj4;
2080 	obj4 = obj3;
2081 	nl = obj4.getNames();
2082 	assertTrue (nl.size() == 3);
2083 	assertTrue (nl[0] == "bar");
2084 	assertTrue (nl[1] == "baz");
2085 	assertTrue (nl[2] == "foo");
2086 
2087 	obj4 = obj1;
2088 	nl = obj4.getNames();
2089 	assertTrue (nl.size() == 3);
2090 	assertTrue (nl[0] == "foo");
2091 	assertTrue (nl[1] == "bar");
2092 	assertTrue (nl[2] == "baz");
2093 
2094 	Object obj5(obj1);
2095 	nl = obj5.getNames();
2096 	assertTrue (nl.size() == 3);
2097 	assertTrue (nl[0] == "foo");
2098 	assertTrue (nl[1] == "bar");
2099 	assertTrue (nl[2] == "baz");
2100 }
2101 
2102 
testMove()2103 void JSONTest::testMove()
2104 {
2105 	Object obj1(Poco::JSON_PRESERVE_KEY_ORDER);
2106 	obj1.set("foo", 0);
2107 	obj1.set("bar", 0);
2108 	obj1.set("baz", 0);
2109 
2110 	Object::NameList nl = obj1.getNames();
2111 	assertTrue (nl.size() == 3);
2112 	assertTrue (nl[0] == "foo");
2113 	assertTrue (nl[1] == "bar");
2114 	assertTrue (nl[2] == "baz");
2115 
2116 	Object obj2;
2117 	obj2 = std::move(obj1);
2118 	assertTrue (obj1.getNames().size() == 0);
2119 
2120 	nl = obj2.getNames();
2121 	assertTrue (nl.size() == 3);
2122 	assertTrue (nl[0] == "foo");
2123 	assertTrue (nl[1] == "bar");
2124 	assertTrue (nl[2] == "baz");
2125 
2126 	Object obj3;
2127 	obj3.set("foo", 0);
2128 	obj3.set("bar", 0);
2129 	obj3.set("baz", 0);
2130 	nl = obj3.getNames();
2131 	assertTrue (nl.size() == 3);
2132 	assertTrue (nl[0] == "bar");
2133 	assertTrue (nl[1] == "baz");
2134 	assertTrue (nl[2] == "foo");
2135 
2136 	Object obj4;
2137 	obj4 = std::move(obj3);
2138 	assertTrue (obj3.getNames().size() == 0);
2139 
2140 	nl = obj4.getNames();
2141 	assertTrue (nl.size() == 3);
2142 	assertTrue (nl[0] == "bar");
2143 	assertTrue (nl[1] == "baz");
2144 	assertTrue (nl[2] == "foo");
2145 
2146 	Object obj5(Poco::JSON_PRESERVE_KEY_ORDER);
2147 	obj5.set("foo", 0);
2148 	obj5.set("bar", 0);
2149 	obj5.set("baz", 0);
2150 	nl = obj5.getNames();
2151 	assertTrue (nl.size() == 3);
2152 	assertTrue (nl[0] == "foo");
2153 	assertTrue (nl[1] == "bar");
2154 	assertTrue (nl[2] == "baz");
2155 
2156 	obj4 = std::move(obj5);
2157 	assertTrue (obj5.getNames().size() == 0);
2158 
2159 	nl = obj4.getNames();
2160 	assertTrue (nl.size() == 3);
2161 	assertTrue (nl[0] == "foo");
2162 	assertTrue (nl[1] == "bar");
2163 	assertTrue (nl[2] == "baz");
2164 }
2165 
2166 
suite()2167 CppUnit::Test* JSONTest::suite()
2168 {
2169 	CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("JSONTest");
2170 
2171 	CppUnit_addTest(pSuite, JSONTest, testNullProperty);
2172 	CppUnit_addTest(pSuite, JSONTest, testTrueProperty);
2173 	CppUnit_addTest(pSuite, JSONTest, testFalseProperty);
2174 	CppUnit_addTest(pSuite, JSONTest, testNumberProperty);
2175 	CppUnit_addTest(pSuite, JSONTest, testUnsignedNumberProperty);
2176 #if defined(POCO_HAVE_INT64)
2177 	CppUnit_addTest(pSuite, JSONTest, testNumber64Property);
2178 	CppUnit_addTest(pSuite, JSONTest, testUnsignedNumber64Property);
2179 #endif
2180 	CppUnit_addTest(pSuite, JSONTest, testStringProperty);
2181 	CppUnit_addTest(pSuite, JSONTest, testEmptyObject);
2182 	CppUnit_addTest(pSuite, JSONTest, testEmptyPropertyName);
2183 	CppUnit_addTest(pSuite, JSONTest, testComplexObject);
2184 	CppUnit_addTest(pSuite, JSONTest, testDoubleProperty);
2185 	CppUnit_addTest(pSuite, JSONTest, testDouble2Property);
2186 	CppUnit_addTest(pSuite, JSONTest, testDouble3Property);
2187 	CppUnit_addTest(pSuite, JSONTest, testObjectProperty);
2188 	CppUnit_addTest(pSuite, JSONTest, testObjectArray);
2189 	CppUnit_addTest(pSuite, JSONTest, testArrayOfObjects);
2190 	CppUnit_addTest(pSuite, JSONTest, testEmptyArray);
2191 	CppUnit_addTest(pSuite, JSONTest, testNestedArray);
2192 	CppUnit_addTest(pSuite, JSONTest, testNullElement);
2193 	CppUnit_addTest(pSuite, JSONTest, testTrueElement);
2194 	CppUnit_addTest(pSuite, JSONTest, testFalseElement);
2195 	CppUnit_addTest(pSuite, JSONTest, testNumberElement);
2196 	CppUnit_addTest(pSuite, JSONTest, testStringElement);
2197 	CppUnit_addTest(pSuite, JSONTest, testEmptyObjectElement);
2198 	CppUnit_addTest(pSuite, JSONTest, testDoubleElement);
2199 	CppUnit_addTest(pSuite, JSONTest, testSetArrayElement);
2200 	CppUnit_addTest(pSuite, JSONTest, testOptValue);
2201 	CppUnit_addTest(pSuite, JSONTest, testQuery);
2202 	CppUnit_addTest(pSuite, JSONTest, testComment);
2203 	CppUnit_addTest(pSuite, JSONTest, testPrintHandler);
2204 	CppUnit_addTest(pSuite, JSONTest, testStringify);
2205 	CppUnit_addTest(pSuite, JSONTest, testStringifyPreserveOrder);
2206 	CppUnit_addTest(pSuite, JSONTest, testValidJanssonFiles);
2207 	CppUnit_addTest(pSuite, JSONTest, testInvalidJanssonFiles);
2208 	CppUnit_addTest(pSuite, JSONTest, testInvalidUnicodeJanssonFiles);
2209 	CppUnit_addTest(pSuite, JSONTest, testTemplate);
2210 	CppUnit_addTest(pSuite, JSONTest, testUnicode);
2211 	CppUnit_addTest(pSuite, JSONTest, testSmallBuffer);
2212 	CppUnit_addTest(pSuite, JSONTest, testEscape0);
2213 	CppUnit_addTest(pSuite, JSONTest, testNonEscapeUnicode);
2214 	CppUnit_addTest(pSuite, JSONTest, testEscapeUnicode);
2215 	CppUnit_addTest(pSuite, JSONTest, testCopy);
2216 	CppUnit_addTest(pSuite, JSONTest, testMove);
2217 
2218 	return pSuite;
2219 }
2220