2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
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>
24 using namespace Dali::Toolkit;
26 void utc_json_parser_startup(void)
28 test_return_value = TET_UNDEF;
31 void utc_json_parser_cleanup(void)
33 test_return_value = TET_PASS;
39 std::string ReplaceQuotes(const std::string &in_s)
42 // wrong as no embedded quote but had regex link problems
43 std::replace(s.begin(), s.end(), '\'', '"');
47 void CompareTrees(const TreeNode& a, const TreeNode& b)
49 DALI_TEST_CHECK( a.GetType() == b.GetType() );
51 DALI_TEST_CHECK( a.Size() == b.Size() );
55 DALI_TEST_CHECK( std::string( a.GetName() ) == std::string( b.GetName() ) );
58 DALI_TEST_CHECK( a.HasSubstitution() == b.HasSubstitution() );
62 case TreeNode::OBJECT:
65 for( TreeNode::ConstIterator aiter = a.CBegin(), biter = b.CBegin();
66 aiter != a.CEnd() && biter != b.CEnd(); ++aiter, ++biter )
68 CompareTrees( (*aiter).second, (*biter).second );
72 case TreeNode::STRING:
74 DALI_TEST_CHECK( std::string( a.GetString() ) == std::string( b.GetString() ) );
79 DALI_TEST_CHECK( a.GetFloat() == b.GetFloat() );
82 case TreeNode::INTEGER:
84 DALI_TEST_CHECK( a.GetInteger() == b.GetInteger());
87 case TreeNode::BOOLEAN:
89 DALI_TEST_CHECK( a.GetBoolean() == b.GetBoolean() );
99 int UtcDaliJsonParserMethod01(void)
101 ToolkitTestApplication application;
103 tet_infoline("JSON basic test");
105 std::string s1( ReplaceQuotes(
113 'object':{'key':'value'} \
116 JsonParser parser = JsonParser::New();
120 if(parser.ParseError())
122 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
123 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
126 DALI_TEST_CHECK(!parser.ParseError());
128 const TreeNode* root = parser.GetRoot();
130 DALI_TEST_CHECK(root);
132 DALI_TEST_CHECK(root->Size());
134 TreeNode::ConstIterator iter = root->CBegin();
135 DALI_TEST_CHECK(iter != root->CEnd());
137 const TreeNode* node = NULL;
139 node = &((*iter).second);
140 DALI_TEST_CHECK(node);
141 DALI_TEST_CHECK(node->GetType() == TreeNode::STRING);
142 DALI_TEST_CHECK(std::string((*iter).first) == std::string("string"));
143 DALI_TEST_CHECK(std::string(node->GetString()) == std::string("value2"));
146 DALI_TEST_CHECK(iter != root->CEnd());
147 node = &((*iter).second);
148 DALI_TEST_CHECK(node);
149 DALI_TEST_CHECK(node->GetType() == TreeNode::INTEGER);
150 DALI_TEST_CHECK(std::string((*iter).first) == std::string("integer"));
151 DALI_TEST_CHECK(node->GetInteger() == 2);
154 DALI_TEST_CHECK(iter != root->CEnd());
155 node = &((*iter).second);
156 DALI_TEST_CHECK(node);
157 DALI_TEST_CHECK(node->GetType() == TreeNode::FLOAT);
158 DALI_TEST_CHECK(std::string((*iter).first) == std::string("float"));
159 DALI_TEST_CHECK(node->GetFloat() == 2.0);
162 DALI_TEST_CHECK(iter != root->CEnd());
163 node = &((*iter).second);
164 DALI_TEST_CHECK(node);
165 DALI_TEST_CHECK(node->GetType() == TreeNode::BOOLEAN);
166 DALI_TEST_CHECK(std::string((*iter).first) == std::string("boolean"));
167 DALI_TEST_CHECK(node->GetBoolean());
170 DALI_TEST_CHECK(iter != root->CEnd());
171 node = &((*iter).second);
172 DALI_TEST_CHECK(node);
173 DALI_TEST_CHECK(node->GetType() == TreeNode::IS_NULL);
174 DALI_TEST_CHECK(std::string((*iter).first) == std::string("nil"));
177 DALI_TEST_CHECK(iter != root->CEnd());
178 node = &((*iter).second);
179 DALI_TEST_CHECK(node);
180 DALI_TEST_CHECK(node->GetType() == TreeNode::ARRAY);
181 DALI_TEST_CHECK(node->Size() == 3);
182 TreeNode::ConstIterator iterArray = node->CBegin();
184 DALI_TEST_CHECK(iterArray != node->CEnd());
185 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
186 DALI_TEST_CHECK( (*iterArray).first == NULL );
187 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 1);
190 DALI_TEST_CHECK(iterArray != node->CEnd());
191 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
192 DALI_TEST_CHECK( (*iterArray).first == NULL );
193 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 2);
196 DALI_TEST_CHECK(iterArray != node->CEnd());
197 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
198 DALI_TEST_CHECK( (*iterArray).first == NULL );
199 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 3);
202 DALI_TEST_CHECK(iter != root->CEnd());
203 node = &((*iter).second);
204 DALI_TEST_CHECK(node);
205 DALI_TEST_CHECK(node->GetType() == TreeNode::OBJECT);
206 DALI_TEST_CHECK(node->Size() == 1);
208 TreeNode::ConstIterator iterObject = node->CBegin();
209 DALI_TEST_CHECK(iterObject != node->CEnd());
210 DALI_TEST_CHECK( ((*iterObject).second).GetType() == TreeNode::STRING);
211 DALI_TEST_CHECK( std::string((*iterObject).first) == std::string("key" ));
212 DALI_TEST_CHECK( std::string(((*iterObject).second).GetString()) == std::string("value"));
214 tet_result(TET_PASS);
218 int UtcDaliJsonParserMethod02(void)
220 ToolkitTestApplication application;
222 tet_infoline("JSON Comments");
224 std::string s1( ReplaceQuotes(" \
225 // some comments with empty line above \n\
227 // inline comments \n\
228 'key':'value', // endline comments \n\
229 // more inline comments \n\
234 JsonParser parser = JsonParser::New();
238 if(parser.ParseError())
240 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
241 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
244 DALI_TEST_CHECK(!parser.ParseError());
246 const TreeNode* root = parser.GetRoot();
248 DALI_TEST_CHECK(root);
250 DALI_TEST_CHECK(root->Size());
252 const TreeNode& node = (*root->CBegin()).second;
254 DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
256 DALI_TEST_CHECK(node.GetString() == std::string("value"));
258 DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
260 tet_result(TET_PASS);
265 int UtcDaliJsonParserMethod03(void)
267 ToolkitTestApplication application;
269 tet_infoline("JSON Empty line comment");
271 std::string s1( ReplaceQuotes(
275 "// next empty line comment\n"\
282 JsonParser parser = JsonParser::New();
286 if(parser.ParseError())
288 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
289 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
292 DALI_TEST_CHECK(!parser.ParseError());
294 const TreeNode* root = parser.GetRoot();
296 DALI_TEST_CHECK(root);
298 DALI_TEST_CHECK(root->Size());
300 const TreeNode& node = (*root->CBegin()).second;
302 DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
304 DALI_TEST_CHECK(node.GetString() == std::string("value"));
306 DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
308 tet_result(TET_PASS);
312 int UtcDaliJsonParserMethod04(void)
314 ToolkitTestApplication application;
316 tet_infoline("JSON Merge");
318 std::string s1( ReplaceQuotes(" \
327 'actor':'bump-image', \
328 'property':'uLightPosition', \
329 'value':[0.8, 0.0, -1.5], \
330 'alpha-function': 'BOUNCE', \
331 'time-period': { 'duration': 2.5 } \
339 std::string s2( ReplaceQuotes(" \
347 'end-action':'DISCARD' \
353 JsonParser parser = JsonParser::New();
357 if(parser.ParseError())
359 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
360 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
362 DALI_TEST_CHECK(!parser.ParseError());
366 if(parser.ParseError())
368 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
369 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
372 DALI_TEST_CHECK(!parser.ParseError());
374 const TreeNode* root = parser.GetRoot();
375 DALI_TEST_CHECK(root);
377 const TreeNode *node = root->Find("bump");
378 DALI_TEST_CHECK(node);
380 DALI_TEST_CHECK(static_cast<int>(node->Size()) == 4);
382 DALI_TEST_CHECK( node->GetChild("duration") );
383 DALI_TEST_CHECK( node->GetChild("loop") );
384 DALI_TEST_CHECK( node->GetChild("properties") );
387 tet_result(TET_PASS);
391 int UtcDaliJsonParserMethod05(void)
393 ToolkitTestApplication application;
395 tet_infoline("JSON Pack & Write");
397 std::string s1( ReplaceQuotes(" \
406 'actor':'bump-image', \
407 'property':'uLightPosition', \
408 'value':[0.8, 0.0, -1.5], \
409 'alpha-function': 'BOUNCE', \
410 'time-period': { 'duration': 2.5 } \
418 JsonParser parser = JsonParser::New();
422 if(parser.ParseError())
424 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
425 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
427 DALI_TEST_CHECK(!parser.ParseError());
437 DALI_TEST_CHECK( a.str() == b.str() );
439 tet_result(TET_PASS);
446 static const int NUMBER_OK_TESTS = 36;
447 const char *TEST_OK[NUMBER_OK_TESTS] = {
448 "{ 'hex': '\u0123\u4567\u89AB\uCDEF\uabcd\uef4A' }",
449 "{ 'special': '`1~!@#$%^&*()_+-={:[,]}|;.</>?' }",
450 "{ 'slash': '/ & \' }",
451 "{'object with 1 member':['array with 1 element']}",
452 "[{}, [], -42, true, false, null]",
453 "{ 'integer': 1234567890 }",
454 "{ 'integer': 1234567890 }",
455 "{ 'real': -9876.543210 }",
456 "{ 'e': 0.123456789e-12 }",
457 "{ 'E': 1.234567890E+34 }",
458 "{ '': 23456789012E66 }",
462 "{ 'backslash': '\' }",
463 "{ 'controls': '\\b\\f\\n\\r\\t' }",
464 "{ 'alpha': 'abcdefghijklmnopqrstuvwyz' }",
465 "{ 'ALPHA': 'ABCDEFGHIJKLMNOPQRSTUVWYZ' }",
466 "{ 'digit': '0123456789' }",
467 "{ '0123456789': 'digit' }",
469 "{ 'false': false }",
473 "{ 'address': '1 Communication Centre. South Street' }",
474 "{ 'url': 'http://www.JSON.org/' }",
475 "{ 'comment': '// /* <!-- --' }",
476 "{ '# -- --> */': ' ' }",
477 "{ ' s p a c e d ' :[1,2 , 3,4 , 5 , 6 ,7 ]}",
478 "{ 'compact':[1,2,3,4,5,6,7]}",
479 "{ 'quotes': '" \\u0022 %22 0x22 034 "' }",
480 "{ '\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:': 'A key can be any string'}",
481 "[ 0.5 ,98.6, 99.44,1066,1e1,0.1e1,1e-1,1e00,2e+00,2e-00, 'rosebud']",
482 "{'JSON Test Pattern pass3': { 'The outermost value': 'must be an object or array.', 'In this test': 'It is an object.' } }",
483 "[[[[[[[[[[[[[[[[[[['Not too deep']]]]]]]]]]]]]]]]]]]",
488 int UtcDaliJsonParserMethod06(void)
490 ToolkitTestApplication application;
492 tet_infoline("JSON Parse Success");
494 JsonParser parser = JsonParser::New();
496 for(int i = 0; i < NUMBER_OK_TESTS; ++i)
498 parser = JsonParser::New();
500 parser.Parse( ReplaceQuotes(TEST_OK[i]) );
502 if(parser.ParseError())
504 tet_printf("Valid JSON parse test %d Failed", i);
505 tet_printf("%s", ReplaceQuotes(TEST_OK[i]).c_str());
507 tet_printf("JSON Error %d:%d: %s (%d)", parser.GetErrorLineNumber(), parser.GetErrorColumn(), parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
510 DALI_TEST_CHECK(!parser.ParseError());
513 tet_result(TET_PASS);
520 static const int NUMBER_FAIL_TESTS = 34;
521 const char *TEST_FAIL[] = {
522 "[' tab\t character \t in\t string ']",
524 "['Colon instead of comma': false]",
525 "{'Numbers cannot have leading zeroes': 013}",
526 "['Bad value', truth]",
527 "['Illegal backslash escape: \017']",
528 "['Bad value', truth]['Illegal backslash escape: \017']",
529 "{'Comma instead if closing brace': true,",
530 "{'Double colon':: null}",
531 "{'Extra comma': true,}",
533 "{'Illegal invocation': alert()}",
534 "{'Missing colon' null}",
536 "{unquoted_key: 'keys must be quoted'}",
537 "'A JSON payload should be an object or array, not a string.'",
539 "{'Illegal expression': 1 + 2}",
540 "{'Extra value after close': true} 'misplaced quoted value'",
544 "['Comma after the close'],",
545 "['double extra comma',,]",
546 "['Illegal backslash escape: \x15']",
548 "{'Comma instead of colon', null}",
552 "{'Numbers cannot be hex': 0x14}",
553 "[ , '<-- missing value']",
554 "[{'no comma':1} {'b:2}]",
555 "{'extra comma':1,}",
559 int UtcDaliJsonParserMethod07(void)
561 ToolkitTestApplication application;
563 tet_infoline("JSON Fail");
565 JsonParser parser = JsonParser::New();
567 for(int i = 0; i < NUMBER_FAIL_TESTS; ++i)
569 parser = JsonParser::New();
571 parser.Parse( ReplaceQuotes(TEST_FAIL[i]) );
573 if(!parser.ParseError())
575 tet_printf("Invalid JSON parse test %d Failed", i);
576 tet_printf("%s", ReplaceQuotes(TEST_FAIL[i]).c_str());
577 tet_printf("JSON Error %d:%d %s (%s)", parser.GetErrorLineNumber(), parser.GetErrorColumn(),
578 parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
581 DALI_TEST_CHECK(parser.ParseError());
585 parser = JsonParser::New();
587 parser.Parse( "['single quote']" );
589 if(!parser.ParseError())
591 tet_printf("['single quote']");
594 DALI_TEST_CHECK(parser.ParseError());
596 tet_result(TET_PASS);
600 int UtcDaliJsonParserMethod08(void)
602 ToolkitTestApplication application;
604 tet_infoline("JSON error reporting");
606 std::string s1( ReplaceQuotes("\
612 JsonParser parser = JsonParser::New();
616 DALI_TEST_CHECK(parser.ParseError());
618 DALI_TEST_CHECK(1 == parser.GetErrorLineNumber());
619 DALI_TEST_CHECK(53 == parser.GetErrorPosition());
620 DALI_TEST_CHECK(11 == parser.GetErrorColumn());
622 tet_result(TET_PASS);
626 int UtcDaliJsonParserMethod09(void)
628 ToolkitTestApplication application;
630 tet_infoline("JSON Pack()");
632 std::string s1( ReplaceQuotes("\
640 'object':{'key':'value'} \
644 JsonParser parser = JsonParser::New();
648 std::stringstream ss1;
649 parser.Write(ss1, 2);
651 parser.Pack(); // Pack() moves strings
653 std::stringstream ss2;
654 parser.Write(ss2, 2);
656 DALI_TEST_CHECK(ss1.str() == ss2.str());
658 tet_result(TET_PASS);
662 int UtcDaliJsonParserMethod10(void)
664 ToolkitTestApplication application;
666 tet_infoline("JSON empty data");
668 std::string s1( "" );
670 JsonParser parser = JsonParser::New();
674 DALI_TEST_CHECK(parser.ParseError());
676 tet_result(TET_PASS);
680 int UtcDaliJsonParserMethod11(void)
682 ToolkitTestApplication application;
683 tet_infoline("JSON tree copy");
685 std::string s1( ReplaceQuotes(" \
694 'actor':'bump-image', \
695 'property':'uLightPosition', \
696 'value':[0.8, 0.0, -1.5], \
697 'alpha-function': 'BOUNCE', \
698 'time-period': { 'duration': 2.5 } \
706 JsonParser parser = JsonParser::New();
710 JsonParser parser2 = JsonParser::New(*parser.GetRoot());
712 DALI_TEST_CHECK(parser.GetRoot());
713 DALI_TEST_CHECK(parser2.GetRoot());
715 CompareTrees( *parser.GetRoot(), *parser2.GetRoot() );
717 tet_result(TET_PASS);