[dali_2.3.19] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / utc-Dali-JsonParser.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <dali-toolkit-test-suite-utils.h>
19 #include <dali-toolkit/dali-toolkit.h>
20 #include <dali-toolkit/devel-api/builder/json-parser.h>
21 #include <stdlib.h>
22 #include <iostream>
23
24 using namespace Dali;
25 using namespace Dali::Toolkit;
26
27 void utc_json_parser_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_json_parser_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36
37 namespace
38 {
39 std::string ReplaceQuotes(const std::string& in_s)
40 {
41   std::string s(in_s);
42   // wrong as no embedded quote but had regex link problems
43   std::replace(s.begin(), s.end(), '\'', '"');
44   return s;
45 }
46
47 void CompareTrees(const TreeNode& a, const TreeNode& b)
48 {
49   DALI_TEST_CHECK(a.GetType() == b.GetType());
50
51   DALI_TEST_CHECK(a.Size() == b.Size());
52
53   if(a.GetName())
54   {
55     DALI_TEST_CHECK(std::string(a.GetName()) == std::string(b.GetName()));
56   }
57
58   DALI_TEST_CHECK(a.HasSubstitution() == b.HasSubstitution());
59
60   switch(a.GetType())
61   {
62     case TreeNode::OBJECT:
63     case TreeNode::ARRAY:
64     {
65       for(TreeNode::ConstIterator aiter = a.CBegin(), biter = b.CBegin();
66           aiter != a.CEnd() && biter != b.CEnd();
67           ++aiter, ++biter)
68       {
69         CompareTrees((*aiter).second, (*biter).second);
70       }
71       break;
72     }
73     case TreeNode::STRING:
74     {
75       DALI_TEST_CHECK(std::string(a.GetString()) == std::string(b.GetString()));
76       break;
77     }
78     case TreeNode::FLOAT:
79     {
80       DALI_TEST_CHECK(a.GetFloat() == b.GetFloat());
81       break;
82     }
83     case TreeNode::INTEGER:
84     {
85       DALI_TEST_CHECK(a.GetInteger() == b.GetInteger());
86       break;
87     }
88     case TreeNode::BOOLEAN:
89     {
90       DALI_TEST_CHECK(a.GetBoolean() == b.GetBoolean());
91       break;
92     }
93     default:
94     {
95       break;
96     }
97   }
98 }
99
100 } // namespace
101
102 int UtcDaliJsonParserMethod01(void)
103 {
104   ToolkitTestApplication application;
105
106   tet_infoline("JSON basic test");
107
108   std::string s1(ReplaceQuotes(
109     "{ \
110   'string':'value2', \
111   'integer':2, \
112   'float':2.0, \
113   'boolean':true, \
114   'nil':null, \
115   'array':[1,2,3], \
116   'object':{'key':'value'} \
117 }"));
118
119   JsonParser parser = JsonParser::New();
120
121   parser.Parse(s1);
122
123   if(parser.ParseError())
124   {
125     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
126     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
127   }
128
129   DALI_TEST_CHECK(!parser.ParseError());
130
131   const TreeNode* root = parser.GetRoot();
132
133   DALI_TEST_CHECK(root);
134
135   DALI_TEST_CHECK(root->Size());
136
137   TreeNode::ConstIterator iter = root->CBegin();
138   DALI_TEST_CHECK(iter != root->CEnd());
139
140   const TreeNode* node = NULL;
141
142   node = &((*iter).second);
143   DALI_TEST_CHECK(node);
144   DALI_TEST_CHECK(node->GetType() == TreeNode::STRING);
145   DALI_TEST_CHECK(std::string((*iter).first) == std::string("string"));
146   DALI_TEST_CHECK(std::string(node->GetString()) == std::string("value2"));
147
148   ++iter;
149   DALI_TEST_CHECK(iter != root->CEnd());
150   node = &((*iter).second);
151   DALI_TEST_CHECK(node);
152   DALI_TEST_CHECK(node->GetType() == TreeNode::INTEGER);
153   DALI_TEST_CHECK(std::string((*iter).first) == std::string("integer"));
154   DALI_TEST_CHECK(node->GetInteger() == 2);
155
156   ++iter;
157   DALI_TEST_CHECK(iter != root->CEnd());
158   node = &((*iter).second);
159   DALI_TEST_CHECK(node);
160   DALI_TEST_CHECK(node->GetType() == TreeNode::FLOAT);
161   DALI_TEST_CHECK(std::string((*iter).first) == std::string("float"));
162   DALI_TEST_CHECK(node->GetFloat() == 2.0);
163
164   ++iter;
165   DALI_TEST_CHECK(iter != root->CEnd());
166   node = &((*iter).second);
167   DALI_TEST_CHECK(node);
168   DALI_TEST_CHECK(node->GetType() == TreeNode::BOOLEAN);
169   DALI_TEST_CHECK(std::string((*iter).first) == std::string("boolean"));
170   DALI_TEST_CHECK(node->GetBoolean());
171
172   ++iter;
173   DALI_TEST_CHECK(iter != root->CEnd());
174   node = &((*iter).second);
175   DALI_TEST_CHECK(node);
176   DALI_TEST_CHECK(node->GetType() == TreeNode::IS_NULL);
177   DALI_TEST_CHECK(std::string((*iter).first) == std::string("nil"));
178
179   ++iter;
180   DALI_TEST_CHECK(iter != root->CEnd());
181   node = &((*iter).second);
182   DALI_TEST_CHECK(node);
183   DALI_TEST_CHECK(node->GetType() == TreeNode::ARRAY);
184   DALI_TEST_CHECK(node->Size() == 3);
185   TreeNode::ConstIterator iterArray = node->CBegin();
186
187   DALI_TEST_CHECK(iterArray != node->CEnd());
188   DALI_TEST_CHECK(((*iterArray).second).GetType() == TreeNode::INTEGER);
189   DALI_TEST_CHECK((*iterArray).first == NULL);
190   DALI_TEST_CHECK(((*iterArray).second).GetInteger() == 1);
191
192   ++iterArray;
193   DALI_TEST_CHECK(iterArray != node->CEnd());
194   DALI_TEST_CHECK(((*iterArray).second).GetType() == TreeNode::INTEGER);
195   DALI_TEST_CHECK((*iterArray).first == NULL);
196   DALI_TEST_CHECK(((*iterArray).second).GetInteger() == 2);
197
198   ++iterArray;
199   DALI_TEST_CHECK(iterArray != node->CEnd());
200   DALI_TEST_CHECK(((*iterArray).second).GetType() == TreeNode::INTEGER);
201   DALI_TEST_CHECK((*iterArray).first == NULL);
202   DALI_TEST_CHECK(((*iterArray).second).GetInteger() == 3);
203
204   ++iter;
205   DALI_TEST_CHECK(iter != root->CEnd());
206   node = &((*iter).second);
207   DALI_TEST_CHECK(node);
208   DALI_TEST_CHECK(node->GetType() == TreeNode::OBJECT);
209   DALI_TEST_CHECK(node->Size() == 1);
210
211   TreeNode::ConstIterator iterObject = node->CBegin();
212   DALI_TEST_CHECK(iterObject != node->CEnd());
213   DALI_TEST_CHECK(((*iterObject).second).GetType() == TreeNode::STRING);
214   DALI_TEST_CHECK(std::string((*iterObject).first) == std::string("key"));
215   DALI_TEST_CHECK(std::string(((*iterObject).second).GetString()) == std::string("value"));
216
217   ++iter;
218   DALI_TEST_CHECK(!(iter != root->CEnd()));
219
220   ++iter; // Go past the end
221
222   iter++; // Use the other operator using the post increment operator
223
224   tet_result(TET_PASS);
225   END_TEST;
226 }
227
228 int UtcDaliJsonParserMethod02(void)
229 {
230   ToolkitTestApplication application;
231
232   tet_infoline("JSON Comments");
233
234   std::string s1(ReplaceQuotes(
235     "         \
236 // some comments with empty line above  \n\
237 {                                         \
238   // inline comments                    \n\
239   'key':'value', // endline comments    \n\
240   // more inline comments               \n\
241   'key2':'value2'                         \
242 }                                         \
243 "));
244
245   JsonParser parser = JsonParser::New();
246
247   parser.Parse(s1);
248
249   if(parser.ParseError())
250   {
251     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
252     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
253   }
254
255   DALI_TEST_CHECK(!parser.ParseError());
256
257   const TreeNode* root = parser.GetRoot();
258
259   DALI_TEST_CHECK(root);
260
261   DALI_TEST_CHECK(root->Size());
262
263   const TreeNode& node = (*root->CBegin()).second;
264
265   DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
266
267   DALI_TEST_CHECK(node.GetString() == std::string("value"));
268
269   DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
270
271   tet_result(TET_PASS);
272   END_TEST;
273 }
274
275 int UtcDaliJsonParserMethod03(void)
276 {
277   ToolkitTestApplication application;
278
279   tet_infoline("JSON Empty line comment");
280
281   std::string s1(ReplaceQuotes(
282     "/*\n"
283     "c comment\n"
284     "*/"
285     "// next empty line comment\n"
286     "//\n"
287     "{\n"
288     "  'key':'value'\n"
289     "}\n"));
290
291   JsonParser parser = JsonParser::New();
292
293   parser.Parse(s1);
294
295   if(parser.ParseError())
296   {
297     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
298     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
299   }
300
301   DALI_TEST_CHECK(!parser.ParseError());
302
303   const TreeNode* root = parser.GetRoot();
304
305   DALI_TEST_CHECK(root);
306
307   DALI_TEST_CHECK(root->Size());
308
309   const TreeNode& node = (*root->CBegin()).second;
310
311   DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
312
313   DALI_TEST_CHECK(node.GetString() == std::string("value"));
314
315   DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
316
317   tet_result(TET_PASS);
318   END_TEST;
319 }
320
321 int UtcDaliJsonParserMethod04(void)
322 {
323   ToolkitTestApplication application;
324
325   tet_infoline("JSON Merge");
326
327   std::string s1(ReplaceQuotes(
328     "                                       \
329 {                                                                       \
330   'animations':                                                         \
331   {                                                                     \
332     'bump':                                                             \
333     {                                                                   \
334       'properties':                                                     \
335       [                                                                 \
336         {                                                               \
337           'actor':'bump-image',                                         \
338           'property':'uLightPosition',                                  \
339           'value':[0.8, 0.0, -1.5],                                     \
340           'alphaFunction': 'BOUNCE',                                    \
341           'timePeriod': { 'duration': 2.5 }                            \
342         }                                                               \
343       ]                                                                 \
344     }                                                                   \
345   }                                                                     \
346 }                                                                       \
347 "));
348
349   std::string s2(ReplaceQuotes(
350     "                                       \
351 {                                                                       \
352   'animations':                                                         \
353   {                                                                     \
354     'bump':                                                             \
355     {                                                                   \
356       'duration': 5.0,                                                  \
357       'loop': true,                                                     \
358       'endAction':'DISCARD'                                            \
359     }                                                                   \
360   }                                                                     \
361 }                                                                       \
362 "));
363
364   JsonParser parser = JsonParser::New();
365
366   parser.Parse(s1);
367
368   if(parser.ParseError())
369   {
370     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
371     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
372   }
373   DALI_TEST_CHECK(!parser.ParseError());
374
375   parser.Parse(s2);
376
377   if(parser.ParseError())
378   {
379     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
380     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
381   }
382
383   DALI_TEST_CHECK(!parser.ParseError());
384
385   const TreeNode* root = parser.GetRoot();
386   DALI_TEST_CHECK(root);
387
388   const TreeNode* node = root->Find("bump");
389   DALI_TEST_CHECK(node);
390
391   DALI_TEST_CHECK(static_cast<int>(node->Size()) == 4);
392
393   DALI_TEST_CHECK(node->GetChild("duration"));
394   DALI_TEST_CHECK(node->GetChild("loop"));
395   DALI_TEST_CHECK(node->GetChild("properties"));
396
397   tet_result(TET_PASS);
398   END_TEST;
399 }
400
401 int UtcDaliJsonParserMethod05(void)
402 {
403   ToolkitTestApplication application;
404
405   tet_infoline("JSON Pack & Write");
406
407   std::string s1(ReplaceQuotes(
408     "                                       \
409 {                                                                       \
410   'animations':                                                         \
411   {                                                                     \
412     'bump':                                                             \
413     {                                                                   \
414       'properties':                                                     \
415       [                                                                 \
416         {                                                               \
417           'actor':'bump-image',                                         \
418           'property':'uLightPosition',                                  \
419           'value':[0.8, 0.0, -1.5],                                     \
420           'alphaFunction': 'BOUNCE',                                    \
421           'timePeriod': { 'duration': 2.5 }                            \
422         }                                                               \
423       ]                                                                 \
424     }                                                                   \
425   }                                                                     \
426 }                                                                       \
427 "));
428
429   JsonParser parser = JsonParser::New();
430
431   parser.Parse(s1);
432
433   if(parser.ParseError())
434   {
435     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
436     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
437   }
438   DALI_TEST_CHECK(!parser.ParseError());
439
440   std::stringstream a;
441   parser.Write(a, 2);
442
443   parser.Pack();
444
445   std::stringstream b;
446   parser.Write(b, 2);
447
448   DALI_TEST_CHECK(a.str() == b.str());
449
450   tet_result(TET_PASS);
451   END_TEST;
452 }
453
454 namespace
455 {
456 static const int NUMBER_OK_TESTS          = 36;
457 const char*      TEST_OK[NUMBER_OK_TESTS] = {
458   "{ 'hex': '\u0123\u4567\u89AB\uCDEF\uabcd\uef4A' }",
459   "{ 'special': '`1~!@#$%^&*()_+-={:[,]}|;.</>?' }",
460   "{ 'slash': '/ & \' }",
461   "{'object with 1 member':['array with 1 element']}",
462   "[{}, [], -42, true, false, null]",
463   "{ 'integer': 1234567890 }",
464   "{ 'integer': 1234567890 }",
465   "{ 'real': -9876.543210 }",
466   "{ 'e': 0.123456789e-12 }",
467   "{ 'E': 1.234567890E+34 }",
468   "{ '':  23456789012E66 }",
469   "{ 'zero': 0 }",
470   "{ 'one': 1 }",
471   "{ 'space': ' ' }",
472   "{ 'backslash': '\' }",
473   "{ 'controls': '\\b\\f\\n\\r\\t' }",
474   "{ 'alpha': 'abcdefghijklmnopqrstuvwyz' }",
475   "{ 'ALPHA': 'ABCDEFGHIJKLMNOPQRSTUVWYZ' }",
476   "{ 'digit': '0123456789' }",
477   "{ '0123456789': 'digit' }",
478   "{ 'true': true }",
479   "{ 'false': false }",
480   "{ 'null': null }",
481   "{ 'array':[  ] }",
482   "{ 'object':{  } }",
483   "{ 'address': '1 Communication Centre. South Street' }",
484   "{ 'url': 'http://www.JSON.org/' }",
485   "{ 'comment': '// /* <!-- --' }",
486   "{ '# -- --> */': ' ' }",
487   "{ ' s p a c e d ' :[1,2 , 3,4 , 5        ,          6           ,7        ]}",
488   "{ 'compact':[1,2,3,4,5,6,7]}",
489   "{ 'quotes': '&#34; \\u0022 %22 0x22 034 &#x22;' }",
490   "{ '\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:': 'A key can be any string'}",
491   "[ 0.5 ,98.6, 99.44,1066,1e1,0.1e1,1e-1,1e00,2e+00,2e-00, 'rosebud']",
492   "{'JSON Test Pattern pass3': { 'The outermost value': 'must be an object or array.', 'In this test': 'It is an object.' } }",
493   "[[[[[[[[[[[[[[[[[[['Not too deep']]]]]]]]]]]]]]]]]]]",
494 };
495 } // namespace
496
497 int UtcDaliJsonParserMethod06(void)
498 {
499   ToolkitTestApplication application;
500
501   tet_infoline("JSON Parse Success");
502
503   JsonParser parser = JsonParser::New();
504
505   for(int i = 0; i < NUMBER_OK_TESTS; ++i)
506   {
507     parser = JsonParser::New();
508
509     parser.Parse(ReplaceQuotes(TEST_OK[i]));
510
511     if(parser.ParseError())
512     {
513       tet_printf("Valid JSON parse test %d Failed", i);
514       tet_printf("%s", ReplaceQuotes(TEST_OK[i]).c_str());
515
516       tet_printf("JSON Error %d:%d: %s (%d)", parser.GetErrorLineNumber(), parser.GetErrorColumn(), parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
517     }
518
519     DALI_TEST_CHECK(!parser.ParseError());
520   }
521
522   tet_result(TET_PASS);
523   END_TEST;
524 }
525
526 namespace
527 {
528 static const int NUMBER_FAIL_TESTS = 34;
529 const char*      TEST_FAIL[]       = {
530   "[' tab\t   character  \t in\t string   ']",
531   "['Extra close']]",
532   "['Colon instead of comma': false]",
533   "{'Numbers cannot have leading zeroes': 013}",
534   "['Bad value', truth]",
535   "['Illegal backslash escape: \017']",
536   "['Bad value', truth]['Illegal backslash escape: \017']",
537   "{'Comma instead if closing brace': true,",
538   "{'Double colon':: null}",
539   "{'Extra comma': true,}",
540   "['Unclosed array'",
541   "{'Illegal invocation': alert()}",
542   "{'Missing colon' null}",
543   "[0e]",
544   "{unquoted_key: 'keys must be quoted'}",
545   "'A JSON payload should be an object or array, not a string.'",
546   "[\naked]",
547   "{'Illegal expression': 1 + 2}",
548   "{'Extra value after close': true} 'misplaced quoted value'",
549   "[0e+]",
550   "[+23456789012E66]",
551   "['extra comma',]",
552   "['Comma after the close'],",
553   "['double extra comma',,]",
554   "['Illegal backslash escape: \x15']",
555   "['line\nbreak']",
556   "{'Comma instead of colon', null}",
557   "['mismatch'}",
558   "['line\nbreak']",
559   "[0e+-1]",
560   "{'Numbers cannot be hex': 0x14}",
561   "[   , '<-- missing value']",
562   "[{'no comma':1} {'b:2}]",
563   "{'extra comma':1,}",
564 };
565 } // namespace
566
567 int UtcDaliJsonParserMethod07(void)
568 {
569   ToolkitTestApplication application;
570
571   tet_infoline("JSON Fail");
572
573   JsonParser parser = JsonParser::New();
574
575   for(int i = 0; i < NUMBER_FAIL_TESTS; ++i)
576   {
577     parser = JsonParser::New();
578
579     parser.Parse(ReplaceQuotes(TEST_FAIL[i]));
580
581     if(!parser.ParseError())
582     {
583       tet_printf("Invalid JSON parse test %d Failed", i);
584       tet_printf("%s", ReplaceQuotes(TEST_FAIL[i]).c_str());
585       tet_printf("JSON Error %d:%d %s (%s)", parser.GetErrorLineNumber(), parser.GetErrorColumn(), parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
586     }
587
588     DALI_TEST_CHECK(parser.ParseError());
589   }
590
591   parser = JsonParser::New();
592
593   parser.Parse("['single quote']");
594
595   if(!parser.ParseError())
596   {
597     tet_printf("['single quote']");
598   }
599
600   DALI_TEST_CHECK(parser.ParseError());
601
602   tet_result(TET_PASS);
603   END_TEST;
604 }
605
606 int UtcDaliJsonParserMethod08(void)
607 {
608   ToolkitTestApplication application;
609
610   tet_infoline("JSON error reporting");
611
612   std::string s1(ReplaceQuotes(
613     "\
614 {                                         \n\
615   'float':,],                             \n\
616 }                                         \n\
617 "));
618
619   JsonParser parser = JsonParser::New();
620
621   parser.Parse(s1);
622
623   DALI_TEST_CHECK(parser.ParseError());
624
625   DALI_TEST_CHECK(1 == parser.GetErrorLineNumber());
626   DALI_TEST_CHECK(53 == parser.GetErrorPosition());
627   DALI_TEST_CHECK(11 == parser.GetErrorColumn());
628   DALI_TEST_CHECK("Missing Value" == parser.GetErrorDescription());
629
630   tet_result(TET_PASS);
631   END_TEST;
632 }
633
634 int UtcDaliJsonParserMethod09(void)
635 {
636   ToolkitTestApplication application;
637
638   tet_infoline("JSON Pack()");
639
640   std::string s1(ReplaceQuotes(
641     "\
642 {                                         \
643   'string':'value2',                      \
644   'integer':2,                            \
645   'float':2.3,                            \
646   'boolean':true,                         \
647   'nil':null,                             \
648   'array':[1,2,3],                        \
649   'object':{'key':'value'}                \
650 }                                         \
651 "));
652
653   JsonParser parser = JsonParser::New();
654
655   parser.Parse(s1);
656
657   std::stringstream ss1;
658   parser.Write(ss1, 2);
659
660   parser.Pack(); // Pack() moves strings
661
662   std::stringstream ss2;
663   parser.Write(ss2, 2);
664
665   DALI_TEST_CHECK(ss1.str() == ss2.str());
666
667   tet_result(TET_PASS);
668   END_TEST;
669 }
670
671 int UtcDaliJsonParserMethod10(void)
672 {
673   ToolkitTestApplication application;
674
675   tet_infoline("JSON empty data");
676
677   std::string s1("");
678
679   JsonParser parser = JsonParser::New();
680
681   parser.Parse(s1);
682
683   DALI_TEST_CHECK(parser.ParseError());
684
685   tet_result(TET_PASS);
686   END_TEST;
687 }
688
689 int UtcDaliJsonParserMethod11(void)
690 {
691   ToolkitTestApplication application;
692   tet_infoline("JSON tree copy");
693
694   std::string s1(ReplaceQuotes(
695     "                                       \
696 {                                                                       \
697   'animations':                                                         \
698   {                                                                     \
699     'bump':                                                             \
700     {                                                                   \
701       'properties':                                                     \
702       [                                                                 \
703         {                                                               \
704           'actor':'bump-image',                                         \
705           'property':'uLightPosition',                                  \
706           'value':[0.8, 0.0, -1.5],                                     \
707           'alphaFunction': 'BOUNCE',                                    \
708           'timePeriod': { 'duration': 2.5 }                            \
709         }                                                               \
710       ]                                                                 \
711     }                                                                   \
712   }                                                                     \
713 }                                                                       \
714 "));
715
716   JsonParser parser = JsonParser::New();
717
718   parser.Parse(s1);
719
720   JsonParser parser2 = JsonParser::New(*parser.GetRoot());
721
722   DALI_TEST_CHECK(parser.GetRoot());
723   DALI_TEST_CHECK(parser2.GetRoot());
724
725   CompareTrees(*parser.GetRoot(), *parser2.GetRoot());
726
727   tet_result(TET_PASS);
728   END_TEST;
729 }
730
731 int UtcDaliJsonParserMerge1(void)
732 {
733   ToolkitTestApplication application;
734   tet_infoline("JSON tree merge");
735
736   std::string s1(ReplaceQuotes(
737     "                                       \
738 {                                                                       \
739   'styles':                                                             \
740   {                                                                     \
741     'button':                                                           \
742     {                                                                   \
743       'backgroundColor':[0.8, 0.0, 1.0, 1.0],                           \
744       'foregroundColor':[1, 1, 1, 1]                                    \
745     }                                                                   \
746   }                                                                     \
747 }                                                                       \
748 "));
749
750   JsonParser parser     = JsonParser::New();
751   JsonParser testParser = JsonParser::New();
752
753   testParser.Parse(s1);
754
755   parser.Parse(s1);
756   parser.Parse(s1); // Merge the tree into itself. The value array should not grow.
757
758   DALI_TEST_CHECK(parser.GetRoot());
759
760   CompareTrees(*parser.GetRoot(), *testParser.GetRoot());
761
762   END_TEST;
763 }
764
765 int UtcDaliJsonParserDownCast(void)
766 {
767   BaseHandle handle = JsonParser::New();
768   JsonParser parser = JsonParser::DownCast(handle);
769   DALI_TEST_CHECK(parser);
770   END_TEST;
771 }
772
773 int UtcDaliJsonParserTreeNodeCount(void)
774 {
775   std::string s1(ReplaceQuotes(
776     "                                       \
777 {                                                                       \
778   'styles':                                                             \
779   {                                                                     \
780     'button':                                                           \
781     {                                                                   \
782       'backgroundColor':[0.8, 0.0, 1.0, 1.0],                           \
783       'foregroundColor':[1, 1, 1, 1]                                    \
784     }                                                                   \
785   }                                                                     \
786 }                                                                       \
787 "));
788
789   JsonParser parser = JsonParser::New();
790   parser.Parse(s1);
791
792   const TreeNode* treeNode = parser.GetRoot();
793   DALI_TEST_EQUALS(1, treeNode->Count("styles"), TEST_LOCATION);
794   DALI_TEST_EQUALS(0, treeNode->Count("random"), TEST_LOCATION);
795
796   END_TEST;
797 }
798
799 int UtcDaliJsonParserTreeNodeFind(void)
800 {
801   std::string s1(ReplaceQuotes(
802     "\
803 {                                         \
804   'string':'value2',                      \
805   'integer':2,                            \
806   'float':2.3,                            \
807   'boolean':true,                         \
808   'nil':null,                             \
809   'array':[1,2,3],                        \
810   'object':{'key':'value'}                \
811 }                                         \
812 "));
813
814   JsonParser parser = JsonParser::New();
815   parser.Parse(s1);
816
817   const TreeNode* treeNode  = parser.GetRoot();
818   const TreeNode* childNode = treeNode->Find("string");
819   DALI_TEST_CHECK(childNode);
820   const TreeNode* sameNode = childNode->Find("string");
821   DALI_TEST_EQUALS(sameNode, childNode, TEST_LOCATION);
822
823   END_TEST;
824 }