Adding new test harness
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit-unmanaged / utc-Dali-JsonParser.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #include <iostream>
18 #include <stdlib.h>
19 #include <dali-toolkit-test-suite-utils.h>
20 #include <dali-toolkit/dali-toolkit.h>
21 #include <dali-toolkit/public-api/builder/json-parser.h>
22
23 using namespace Dali;
24 using namespace Dali::Toolkit;
25
26 void utc_json_parser_startup(void)
27 {
28   test_return_value = TET_UNDEF;
29 }
30
31 void utc_json_parser_cleanup(void)
32 {
33   test_return_value = TET_PASS;
34 }
35
36 namespace
37 {
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
48
49 int UtcDaliJsonParserMethod01(void)
50 {
51   ToolkitTestApplication application;
52
53   tet_infoline("JSON basic test");
54
55   std::string s1( ReplaceQuotes(
56 "{ \
57   'string':'value2', \
58   'integer':2, \
59   'float':2.0, \
60   'boolean':true, \
61   'nil':null, \
62   'array':[1,2,3], \
63   'object':{'key':'value'} \
64 END_TEST; \
65 }"));
66
67   JsonParser parser = JsonParser::New();
68
69   parser.Parse( s1 );
70
71   if(parser.ParseError())
72   {
73     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
74     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
75   }
76
77   DALI_TEST_CHECK(!parser.ParseError());
78
79   const TreeNode* root = parser.GetRoot();
80
81   DALI_TEST_CHECK(root);
82
83   DALI_TEST_CHECK(root->Size());
84
85   TreeNode::ConstIterator iter = root->CBegin();
86   DALI_TEST_CHECK(iter != root->CEnd());
87
88   const TreeNode* node = NULL;
89
90   node = &((*iter).second);
91   DALI_TEST_CHECK(node);
92   DALI_TEST_CHECK(node->GetType() == TreeNode::STRING);
93   DALI_TEST_CHECK(std::string((*iter).first) == std::string("string"));
94   DALI_TEST_CHECK(std::string(node->GetString()) == std::string("value2"));
95
96   ++iter;
97   DALI_TEST_CHECK(iter != root->CEnd());
98   node = &((*iter).second);
99   DALI_TEST_CHECK(node);
100   DALI_TEST_CHECK(node->GetType() == TreeNode::INTEGER);
101   DALI_TEST_CHECK(std::string((*iter).first) == std::string("integer"));
102   DALI_TEST_CHECK(node->GetInteger() == 2);
103
104   ++iter;
105   DALI_TEST_CHECK(iter != root->CEnd());
106   node = &((*iter).second);
107   DALI_TEST_CHECK(node);
108   DALI_TEST_CHECK(node->GetType() == TreeNode::FLOAT);
109   DALI_TEST_CHECK(std::string((*iter).first) == std::string("float"));
110   DALI_TEST_CHECK(node->GetFloat() == 2.0);
111
112   ++iter;
113   DALI_TEST_CHECK(iter != root->CEnd());
114   node = &((*iter).second);
115   DALI_TEST_CHECK(node);
116   DALI_TEST_CHECK(node->GetType() == TreeNode::BOOLEAN);
117   DALI_TEST_CHECK(std::string((*iter).first) == std::string("boolean"));
118   DALI_TEST_CHECK(node->GetBoolean());
119
120   ++iter;
121   DALI_TEST_CHECK(iter != root->CEnd());
122   node = &((*iter).second);
123   DALI_TEST_CHECK(node);
124   DALI_TEST_CHECK(node->GetType() == TreeNode::IS_NULL);
125   DALI_TEST_CHECK(std::string((*iter).first) == std::string("nil"));
126
127   ++iter;
128   DALI_TEST_CHECK(iter != root->CEnd());
129   node = &((*iter).second);
130   DALI_TEST_CHECK(node);
131   DALI_TEST_CHECK(node->GetType() == TreeNode::ARRAY);
132   DALI_TEST_CHECK(node->Size() == 3);
133   TreeNode::ConstIterator iterArray = node->CBegin();
134
135   DALI_TEST_CHECK(iterArray != node->CEnd());
136   DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
137   DALI_TEST_CHECK( (*iterArray).first == NULL );
138   DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 1);
139
140   ++iterArray;
141   DALI_TEST_CHECK(iterArray != node->CEnd());
142   DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
143   DALI_TEST_CHECK( (*iterArray).first == NULL );
144   DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 2);
145
146   ++iterArray;
147   DALI_TEST_CHECK(iterArray != node->CEnd());
148   DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
149   DALI_TEST_CHECK( (*iterArray).first == NULL );
150   DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 3);
151
152   ++iter;
153   DALI_TEST_CHECK(iter != root->CEnd());
154   node = &((*iter).second);
155   DALI_TEST_CHECK(node);
156   DALI_TEST_CHECK(node->GetType() == TreeNode::OBJECT);
157   DALI_TEST_CHECK(node->Size() == 1);
158
159   TreeNode::ConstIterator iterObject = node->CBegin();
160   DALI_TEST_CHECK(iterObject != node->CEnd());
161   DALI_TEST_CHECK( ((*iterObject).second).GetType() == TreeNode::STRING);
162   DALI_TEST_CHECK( std::string((*iterObject).first) == std::string("key" ));
163   DALI_TEST_CHECK( std::string(((*iterObject).second).GetString()) == std::string("value"));
164
165   tet_result(TET_PASS);
166   END_TEST;
167 }
168
169 int UtcDaliJsonParserMethod02(void)
170 {
171   ToolkitTestApplication application;
172
173   tet_infoline("JSON Comments");
174
175   std::string s1( ReplaceQuotes("         \
176 // some comments with empty line above  \n\
177 {                                         \
178   // inline comments                    \n\
179   'key':'value', // endline comments    \n\
180   // more inline comments               \n\
181   'key2':'value2'                         \
182 }                                         \
183 "));
184
185   JsonParser parser = JsonParser::New();
186
187   parser.Parse( s1 );
188
189   if(parser.ParseError())
190   {
191     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
192     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
193   }
194
195   DALI_TEST_CHECK(!parser.ParseError());
196
197   const TreeNode* root = parser.GetRoot();
198
199   DALI_TEST_CHECK(root);
200
201   DALI_TEST_CHECK(root->Size());
202
203   const TreeNode& node = (*root->CBegin()).second;
204
205   DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
206
207   DALI_TEST_CHECK(node.GetString() == std::string("value"));
208
209   DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
210
211   tet_result(TET_PASS);
212   END_TEST;
213 }
214
215
216 int UtcDaliJsonParserMethod03(void)
217 {
218   ToolkitTestApplication application;
219
220   tet_infoline("JSON Empty line comment");
221
222   std::string s1( ReplaceQuotes(
223 "/*\n" \
224 "c comment\n" \
225 "*/"\
226 "// next empty line comment\n"\
227 "//\n"\
228 "{\n"\
229 "  'key':'value'\n"\
230 "}\n"\
231 ));
232
233   JsonParser parser = JsonParser::New();
234
235   parser.Parse( s1 );
236
237   if(parser.ParseError())
238   {
239     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
240     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
241   }
242
243   DALI_TEST_CHECK(!parser.ParseError());
244
245   const TreeNode* root = parser.GetRoot();
246
247   DALI_TEST_CHECK(root);
248
249   DALI_TEST_CHECK(root->Size());
250
251   const TreeNode& node = (*root->CBegin()).second;
252
253   DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
254
255   DALI_TEST_CHECK(node.GetString() == std::string("value"));
256
257   DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
258
259   tet_result(TET_PASS);
260   END_TEST;
261 }
262
263 int UtcDaliJsonParserMethod04(void)
264 {
265   ToolkitTestApplication application;
266
267   tet_infoline("JSON Merge");
268
269   std::string s1( ReplaceQuotes("                                       \
270 {                                                                       \
271   'animations':                                                         \
272   {                                                                     \
273     'bump':                                                             \
274     {                                                                   \
275       'properties':                                                     \
276       [                                                                 \
277         {                                                               \
278           'actor':'bump-image',                                         \
279           'property':'uLightPosition',                                  \
280           'value':[0.8, 0.0, -1.5],                                     \
281           'alpha-function': 'BOUNCE',                                   \
282           'time-period': { 'duration': 2.5 }                            \
283         }                                                               \
284       ]                                                                 \
285     }                                                                   \
286   }                                                                     \
287 }                                                                       \
288 "));
289
290   std::string s2( ReplaceQuotes("                                       \
291 {                                                                       \
292   'animations':                                                         \
293   {                                                                     \
294     'bump':                                                             \
295     {                                                                   \
296       'duration': 5.0,                                                  \
297       'loop': true,                                                     \
298       'end-action':'DISCARD'                                            \
299     }                                                                   \
300   }                                                                     \
301 }                                                                       \
302 "));
303
304   JsonParser parser = JsonParser::New();
305
306   parser.Parse( s1 );
307
308   if(parser.ParseError())
309   {
310     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
311     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
312   }
313   DALI_TEST_CHECK(!parser.ParseError());
314
315   parser.Parse( s2 );
316
317   if(parser.ParseError())
318   {
319     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
320     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
321   }
322
323   DALI_TEST_CHECK(!parser.ParseError());
324
325   const TreeNode* root = parser.GetRoot();
326   DALI_TEST_CHECK(root);
327
328   const TreeNode *node = root->Find("bump");
329   DALI_TEST_CHECK(node);
330
331   DALI_TEST_CHECK(static_cast<int>(node->Size()) == 4);
332
333   DALI_TEST_CHECK( node->GetChild("duration") );
334   DALI_TEST_CHECK( node->GetChild("loop") );
335   DALI_TEST_CHECK( node->GetChild("properties") );
336
337
338   tet_result(TET_PASS);
339   END_TEST;
340 }
341
342 int UtcDaliJsonParserMethod05(void)
343 {
344   ToolkitTestApplication application;
345
346   tet_infoline("JSON Pack & Write");
347
348   std::string s1( ReplaceQuotes("                                       \
349 {                                                                       \
350   'animations':                                                         \
351   {                                                                     \
352     'bump':                                                             \
353     {                                                                   \
354       'properties':                                                     \
355       [                                                                 \
356         {                                                               \
357           'actor':'bump-image',                                         \
358           'property':'uLightPosition',                                  \
359           'value':[0.8, 0.0, -1.5],                                     \
360           'alpha-function': 'BOUNCE',                                   \
361           'time-period': { 'duration': 2.5 }                            \
362         }                                                               \
363       ]                                                                 \
364     }                                                                   \
365   }                                                                     \
366 }                                                                       \
367 "));
368
369   JsonParser parser = JsonParser::New();
370
371   parser.Parse( s1 );
372
373   if(parser.ParseError())
374   {
375     std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
376     std::cout << "   at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
377   }
378   DALI_TEST_CHECK(!parser.ParseError());
379
380   std::stringstream a;
381   parser.Write(a, 2);
382
383   parser.Pack();
384
385   std::stringstream b;
386   parser.Write(b, 2);
387
388   DALI_TEST_CHECK( a.str() == b.str() );
389
390   tet_result(TET_PASS);
391   END_TEST;
392 }
393
394 namespace
395 {
396
397 static const int NUMBER_OK_TESTS = 36;
398 const char *TEST_OK[NUMBER_OK_TESTS] = {
399   "{ 'hex': '\u0123\u4567\u89AB\uCDEF\uabcd\uef4A' }",
400   "{ 'special': '`1~!@#$%^&*()_+-={:[,]}|;.</>?' }",
401   "{ 'slash': '/ & \' }",
402   "{'object with 1 member':['array with 1 element']}",
403   "[{}, [], -42, true, false, null]",
404   "{ 'integer': 1234567890 }",
405   "{ 'integer': 1234567890 }",
406   "{ 'real': -9876.543210 }",
407   "{ 'e': 0.123456789e-12 }",
408   "{ 'E': 1.234567890E+34 }",
409   "{ '':  23456789012E66 }",
410   "{ 'zero': 0 }",
411   "{ 'one': 1 }",
412   "{ 'space': ' ' }",
413   "{ 'backslash': '\' }",
414   "{ 'controls': '\\b\\f\\n\\r\\t' }",
415   "{ 'alpha': 'abcdefghijklmnopqrstuvwyz' }",
416   "{ 'ALPHA': 'ABCDEFGHIJKLMNOPQRSTUVWYZ' }",
417   "{ 'digit': '0123456789' }",
418   "{ '0123456789': 'digit' }",
419   "{ 'true': true }",
420   "{ 'false': false }",
421   "{ 'null': null }",
422   "{ 'array':[  ] }",
423   "{ 'object':{  } }",
424   "{ 'address': '1 Communication Centre. South Street' }",
425   "{ 'url': 'http://www.JSON.org/' }",
426   "{ 'comment': '// /* <!-- --' }",
427   "{ '# -- --> */': ' ' }",
428   "{ ' s p a c e d ' :[1,2 , 3,4 , 5        ,          6           ,7        ]}",
429   "{ 'compact':[1,2,3,4,5,6,7]}",
430   "{ 'quotes': '&#34; \\u0022 %22 0x22 034 &#x22;' }",
431   "{ '\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:': 'A key can be any string'}",
432   "[ 0.5 ,98.6, 99.44,1066,1e1,0.1e1,1e-1,1e00,2e+00,2e-00, 'rosebud']",
433   "{'JSON Test Pattern pass3': { 'The outermost value': 'must be an object or array.', 'In this test': 'It is an object.' } }",
434   "[[[[[[[[[[[[[[[[[[['Not too deep']]]]]]]]]]]]]]]]]]]",
435 };
436 }
437
438
439 int UtcDaliJsonParserMethod06(void)
440 {
441   ToolkitTestApplication application;
442
443   tet_infoline("JSON Parse Success");
444
445   JsonParser parser = JsonParser::New();
446
447   for(int i = 0; i < NUMBER_OK_TESTS; ++i)
448   {
449     parser = JsonParser::New();
450
451     parser.Parse( ReplaceQuotes(TEST_OK[i]) );
452
453     if(parser.ParseError())
454     {
455       tet_printf("Valid JSON parse test %d Failed", i);
456       tet_printf("%s", ReplaceQuotes(TEST_OK[i]).c_str());
457
458       tet_printf("JSON Error %d:%d: %s (%d)", parser.GetErrorLineNumber(), parser.GetErrorColumn(), parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
459     }
460
461     DALI_TEST_CHECK(!parser.ParseError());
462   }
463
464   tet_result(TET_PASS);
465   END_TEST;
466 }
467
468 namespace
469 {
470
471 static const int NUMBER_FAIL_TESTS = 32;
472 const char *TEST_FAIL[] = {
473   "[' tab\t   character  \t in\t string   ']",
474   "['Extra close']]",
475   "['Colon instead of comma': false]",
476   "{'Numbers cannot have leading zeroes': 013}",
477   "['Bad value', truth]",
478   "['Illegal backslash escape: \017']",
479   "['Bad value', truth]['Illegal backslash escape: \017']",
480   "{'Comma instead if closing brace': true,",
481   "{'Double colon':: null}",
482   "{'Extra comma': true,}",
483   "['Unclosed array'",
484   "{'Illegal invocation': alert()}",
485   "{'Missing colon' null}",
486   "[0e]",
487   "{unquoted_key: 'keys must be quoted'}",
488   "'A JSON payload should be an object or array, not a string.'",
489   "[\naked]",
490   "{'Illegal expression': 1 + 2}",
491   "{'Extra value after close': true} 'misplaced quoted value'",
492   "[0e+]",
493   "[+23456789012E66]",
494   "['extra comma',]",
495   "['Comma after the close'],",
496   "['double extra comma',,]",
497   "['Illegal backslash escape: \x15']",
498   "['line\nbreak']",
499   "{'Comma instead of colon', null}",
500   "['mismatch'}",
501   "['line\nbreak']",
502   "[0e+-1]",
503   "{'Numbers cannot be hex': 0x14}",
504   "[   , '<-- missing value']",
505 };
506 }
507
508 int UtcDaliJsonParserMethod07(void)
509 {
510   ToolkitTestApplication application;
511
512   tet_infoline("JSON Fail");
513
514   JsonParser parser = JsonParser::New();
515
516   for(int i = 0; i < NUMBER_FAIL_TESTS; ++i)
517   {
518     parser = JsonParser::New();
519
520     parser.Parse( ReplaceQuotes(TEST_FAIL[i]) );
521
522     if(!parser.ParseError())
523     {
524       tet_printf("Invalid JSON parse test %d Failed", i);
525       tet_printf("%s", ReplaceQuotes(TEST_FAIL[i]).c_str());
526       tet_printf("JSON Error %d:%d %s (%s)", parser.GetErrorLineNumber(), parser.GetErrorColumn(),
527                  parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
528     }
529
530     DALI_TEST_CHECK(parser.ParseError());
531   }
532
533
534   parser = JsonParser::New();
535
536   parser.Parse( "['single quote']" );
537
538   if(!parser.ParseError())
539   {
540     tet_printf("['single quote']");
541   }
542
543   DALI_TEST_CHECK(parser.ParseError());
544
545   tet_result(TET_PASS);
546   END_TEST;
547 }
548
549 int UtcDaliJsonParserMethod08(void)
550 {
551   ToolkitTestApplication application;
552
553   tet_infoline("JSON error reporting");
554
555   std::string s1( ReplaceQuotes("\
556 {                                         \n\
557   'float':,],                             \n\
558 }                                         \n\
559 "));
560
561   JsonParser parser = JsonParser::New();
562
563   parser.Parse( s1 );
564
565   DALI_TEST_CHECK(parser.ParseError());
566
567   DALI_TEST_CHECK(1  == parser.GetErrorLineNumber());
568   DALI_TEST_CHECK(53 == parser.GetErrorPosition());
569   DALI_TEST_CHECK(11 == parser.GetErrorColumn());
570
571   tet_result(TET_PASS);
572   END_TEST;
573 }
574
575 int UtcDaliJsonParserMethod09(void)
576 {
577   ToolkitTestApplication application;
578
579   tet_infoline("JSON Pack()");
580
581   std::string s1( ReplaceQuotes("\
582 {                                         \
583   'string':'value2',                      \
584   'integer':2,                            \
585   'float':2.3,                            \
586   'boolean':true,                         \
587   'nil':null,                             \
588   'array':[1,2,3],                        \
589   'object':{'key':'value'}                \
590 }                                         \
591 "));
592
593   JsonParser parser = JsonParser::New();
594
595   parser.Parse( s1 );
596
597   std::stringstream ss1;
598   parser.Write(ss1, 2);
599
600   parser.Pack(); // Pack() moves strings
601
602   std::stringstream ss2;
603   parser.Write(ss2, 2);
604
605   DALI_TEST_CHECK(ss1.str() == ss2.str());
606
607   tet_result(TET_PASS);
608   END_TEST;
609 }
610
611 int UtcDaliJsonParserMethod10(void)
612 {
613   ToolkitTestApplication application;
614
615   tet_infoline("JSON basic test");
616
617   std::string s1( "" );
618
619   JsonParser parser = JsonParser::New();
620
621   parser.Parse( s1 );
622
623   DALI_TEST_CHECK(parser.ParseError());
624
625   tet_result(TET_PASS);
626   END_TEST;
627 }