2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <dali-toolkit-test-suite-utils.h>
21 #include <dali-toolkit/dali-toolkit.h>
22 #include <dali-toolkit/devel-api/builder/json-parser.h>
25 using namespace Dali::Toolkit;
27 void utc_json_parser_startup(void)
29 test_return_value = TET_UNDEF;
32 void utc_json_parser_cleanup(void)
34 test_return_value = TET_PASS;
40 std::string ReplaceQuotes(const std::string &in_s)
43 // wrong as no embedded quote but had regex link problems
44 std::replace(s.begin(), s.end(), '\'', '"');
48 void CompareTrees(const TreeNode& a, const TreeNode& b)
50 DALI_TEST_CHECK( a.GetType() == b.GetType() );
52 DALI_TEST_CHECK( a.Size() == b.Size() );
56 DALI_TEST_CHECK( std::string( a.GetName() ) == std::string( b.GetName() ) );
59 DALI_TEST_CHECK( a.HasSubstitution() == b.HasSubstitution() );
63 case TreeNode::OBJECT:
66 for( TreeNode::ConstIterator aiter = a.CBegin(), biter = b.CBegin();
67 aiter != a.CEnd() && biter != b.CEnd(); ++aiter, ++biter )
69 CompareTrees( (*aiter).second, (*biter).second );
73 case TreeNode::STRING:
75 DALI_TEST_CHECK( std::string( a.GetString() ) == std::string( b.GetString() ) );
80 DALI_TEST_CHECK( a.GetFloat() == b.GetFloat() );
83 case TreeNode::INTEGER:
85 DALI_TEST_CHECK( a.GetInteger() == b.GetInteger());
88 case TreeNode::BOOLEAN:
90 DALI_TEST_CHECK( a.GetBoolean() == b.GetBoolean() );
104 int UtcDaliJsonParserMethod01(void)
106 ToolkitTestApplication application;
108 tet_infoline("JSON basic test");
110 std::string s1( ReplaceQuotes(
118 'object':{'key':'value'} \
121 JsonParser parser = JsonParser::New();
125 if(parser.ParseError())
127 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
128 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
131 DALI_TEST_CHECK(!parser.ParseError());
133 const TreeNode* root = parser.GetRoot();
135 DALI_TEST_CHECK(root);
137 DALI_TEST_CHECK(root->Size());
139 TreeNode::ConstIterator iter = root->CBegin();
140 DALI_TEST_CHECK(iter != root->CEnd());
142 const TreeNode* node = NULL;
144 node = &((*iter).second);
145 DALI_TEST_CHECK(node);
146 DALI_TEST_CHECK(node->GetType() == TreeNode::STRING);
147 DALI_TEST_CHECK(std::string((*iter).first) == std::string("string"));
148 DALI_TEST_CHECK(std::string(node->GetString()) == std::string("value2"));
151 DALI_TEST_CHECK(iter != root->CEnd());
152 node = &((*iter).second);
153 DALI_TEST_CHECK(node);
154 DALI_TEST_CHECK(node->GetType() == TreeNode::INTEGER);
155 DALI_TEST_CHECK(std::string((*iter).first) == std::string("integer"));
156 DALI_TEST_CHECK(node->GetInteger() == 2);
159 DALI_TEST_CHECK(iter != root->CEnd());
160 node = &((*iter).second);
161 DALI_TEST_CHECK(node);
162 DALI_TEST_CHECK(node->GetType() == TreeNode::FLOAT);
163 DALI_TEST_CHECK(std::string((*iter).first) == std::string("float"));
164 DALI_TEST_CHECK(node->GetFloat() == 2.0);
167 DALI_TEST_CHECK(iter != root->CEnd());
168 node = &((*iter).second);
169 DALI_TEST_CHECK(node);
170 DALI_TEST_CHECK(node->GetType() == TreeNode::BOOLEAN);
171 DALI_TEST_CHECK(std::string((*iter).first) == std::string("boolean"));
172 DALI_TEST_CHECK(node->GetBoolean());
175 DALI_TEST_CHECK(iter != root->CEnd());
176 node = &((*iter).second);
177 DALI_TEST_CHECK(node);
178 DALI_TEST_CHECK(node->GetType() == TreeNode::IS_NULL);
179 DALI_TEST_CHECK(std::string((*iter).first) == std::string("nil"));
182 DALI_TEST_CHECK(iter != root->CEnd());
183 node = &((*iter).second);
184 DALI_TEST_CHECK(node);
185 DALI_TEST_CHECK(node->GetType() == TreeNode::ARRAY);
186 DALI_TEST_CHECK(node->Size() == 3);
187 TreeNode::ConstIterator iterArray = node->CBegin();
189 DALI_TEST_CHECK(iterArray != node->CEnd());
190 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
191 DALI_TEST_CHECK( (*iterArray).first == NULL );
192 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 1);
195 DALI_TEST_CHECK(iterArray != node->CEnd());
196 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
197 DALI_TEST_CHECK( (*iterArray).first == NULL );
198 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 2);
201 DALI_TEST_CHECK(iterArray != node->CEnd());
202 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
203 DALI_TEST_CHECK( (*iterArray).first == NULL );
204 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 3);
207 DALI_TEST_CHECK(iter != root->CEnd());
208 node = &((*iter).second);
209 DALI_TEST_CHECK(node);
210 DALI_TEST_CHECK(node->GetType() == TreeNode::OBJECT);
211 DALI_TEST_CHECK(node->Size() == 1);
213 TreeNode::ConstIterator iterObject = node->CBegin();
214 DALI_TEST_CHECK(iterObject != node->CEnd());
215 DALI_TEST_CHECK( ((*iterObject).second).GetType() == TreeNode::STRING);
216 DALI_TEST_CHECK( std::string((*iterObject).first) == std::string("key" ));
217 DALI_TEST_CHECK( std::string(((*iterObject).second).GetString()) == std::string("value"));
220 DALI_TEST_CHECK(!( iter != root->CEnd() ));
222 ++iter; // Go past the end
224 iter++; // Use the other operator using the post increment operator
226 tet_result(TET_PASS);
230 int UtcDaliJsonParserMethod02(void)
232 ToolkitTestApplication application;
234 tet_infoline("JSON Comments");
236 std::string s1( ReplaceQuotes(" \
237 // some comments with empty line above \n\
239 // inline comments \n\
240 'key':'value', // endline comments \n\
241 // more inline comments \n\
246 JsonParser parser = JsonParser::New();
250 if(parser.ParseError())
252 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
253 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
256 DALI_TEST_CHECK(!parser.ParseError());
258 const TreeNode* root = parser.GetRoot();
260 DALI_TEST_CHECK(root);
262 DALI_TEST_CHECK(root->Size());
264 const TreeNode& node = (*root->CBegin()).second;
266 DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
268 DALI_TEST_CHECK(node.GetString() == std::string("value"));
270 DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
272 tet_result(TET_PASS);
277 int UtcDaliJsonParserMethod03(void)
279 ToolkitTestApplication application;
281 tet_infoline("JSON Empty line comment");
283 std::string s1( ReplaceQuotes(
287 "// next empty line comment\n"\
294 JsonParser parser = JsonParser::New();
298 if(parser.ParseError())
300 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
301 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
304 DALI_TEST_CHECK(!parser.ParseError());
306 const TreeNode* root = parser.GetRoot();
308 DALI_TEST_CHECK(root);
310 DALI_TEST_CHECK(root->Size());
312 const TreeNode& node = (*root->CBegin()).second;
314 DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
316 DALI_TEST_CHECK(node.GetString() == std::string("value"));
318 DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
320 tet_result(TET_PASS);
324 int UtcDaliJsonParserMethod04(void)
326 ToolkitTestApplication application;
328 tet_infoline("JSON Merge");
330 std::string s1( ReplaceQuotes(" \
339 'actor':'bump-image', \
340 'property':'uLightPosition', \
341 'value':[0.8, 0.0, -1.5], \
342 'alphaFunction': 'BOUNCE', \
343 'timePeriod': { 'duration': 2.5 } \
351 std::string s2( ReplaceQuotes(" \
359 'endAction':'DISCARD' \
365 JsonParser parser = JsonParser::New();
369 if(parser.ParseError())
371 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
372 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
374 DALI_TEST_CHECK(!parser.ParseError());
378 if(parser.ParseError())
380 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
381 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
384 DALI_TEST_CHECK(!parser.ParseError());
386 const TreeNode* root = parser.GetRoot();
387 DALI_TEST_CHECK(root);
389 const TreeNode *node = root->Find("bump");
390 DALI_TEST_CHECK(node);
392 DALI_TEST_CHECK(static_cast<int>(node->Size()) == 4);
394 DALI_TEST_CHECK( node->GetChild("duration") );
395 DALI_TEST_CHECK( node->GetChild("loop") );
396 DALI_TEST_CHECK( node->GetChild("properties") );
399 tet_result(TET_PASS);
403 int UtcDaliJsonParserMethod05(void)
405 ToolkitTestApplication application;
407 tet_infoline("JSON Pack & Write");
409 std::string s1( ReplaceQuotes(" \
418 'actor':'bump-image', \
419 'property':'uLightPosition', \
420 'value':[0.8, 0.0, -1.5], \
421 'alphaFunction': 'BOUNCE', \
422 'timePeriod': { 'duration': 2.5 } \
430 JsonParser parser = JsonParser::New();
434 if(parser.ParseError())
436 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
437 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
439 DALI_TEST_CHECK(!parser.ParseError());
449 DALI_TEST_CHECK( a.str() == b.str() );
451 tet_result(TET_PASS);
458 static const int NUMBER_OK_TESTS = 36;
459 const char *TEST_OK[NUMBER_OK_TESTS] = {
460 "{ 'hex': '\u0123\u4567\u89AB\uCDEF\uabcd\uef4A' }",
461 "{ 'special': '`1~!@#$%^&*()_+-={:[,]}|;.</>?' }",
462 "{ 'slash': '/ & \' }",
463 "{'object with 1 member':['array with 1 element']}",
464 "[{}, [], -42, true, false, null]",
465 "{ 'integer': 1234567890 }",
466 "{ 'integer': 1234567890 }",
467 "{ 'real': -9876.543210 }",
468 "{ 'e': 0.123456789e-12 }",
469 "{ 'E': 1.234567890E+34 }",
470 "{ '': 23456789012E66 }",
474 "{ 'backslash': '\' }",
475 "{ 'controls': '\\b\\f\\n\\r\\t' }",
476 "{ 'alpha': 'abcdefghijklmnopqrstuvwyz' }",
477 "{ 'ALPHA': 'ABCDEFGHIJKLMNOPQRSTUVWYZ' }",
478 "{ 'digit': '0123456789' }",
479 "{ '0123456789': 'digit' }",
481 "{ 'false': false }",
485 "{ 'address': '1 Communication Centre. South Street' }",
486 "{ 'url': 'http://www.JSON.org/' }",
487 "{ 'comment': '// /* <!-- --' }",
488 "{ '# -- --> */': ' ' }",
489 "{ ' s p a c e d ' :[1,2 , 3,4 , 5 , 6 ,7 ]}",
490 "{ 'compact':[1,2,3,4,5,6,7]}",
491 "{ 'quotes': '" \\u0022 %22 0x22 034 "' }",
492 "{ '\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:': 'A key can be any string'}",
493 "[ 0.5 ,98.6, 99.44,1066,1e1,0.1e1,1e-1,1e00,2e+00,2e-00, 'rosebud']",
494 "{'JSON Test Pattern pass3': { 'The outermost value': 'must be an object or array.', 'In this test': 'It is an object.' } }",
495 "[[[[[[[[[[[[[[[[[[['Not too deep']]]]]]]]]]]]]]]]]]]",
500 int UtcDaliJsonParserMethod06(void)
502 ToolkitTestApplication application;
504 tet_infoline("JSON Parse Success");
506 JsonParser parser = JsonParser::New();
508 for(int i = 0; i < NUMBER_OK_TESTS; ++i)
510 parser = JsonParser::New();
512 parser.Parse( ReplaceQuotes(TEST_OK[i]) );
514 if(parser.ParseError())
516 tet_printf("Valid JSON parse test %d Failed", i);
517 tet_printf("%s", ReplaceQuotes(TEST_OK[i]).c_str());
519 tet_printf("JSON Error %d:%d: %s (%d)", parser.GetErrorLineNumber(), parser.GetErrorColumn(), parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
522 DALI_TEST_CHECK(!parser.ParseError());
525 tet_result(TET_PASS);
532 static const int NUMBER_FAIL_TESTS = 34;
533 const char *TEST_FAIL[] = {
534 "[' tab\t character \t in\t string ']",
536 "['Colon instead of comma': false]",
537 "{'Numbers cannot have leading zeroes': 013}",
538 "['Bad value', truth]",
539 "['Illegal backslash escape: \017']",
540 "['Bad value', truth]['Illegal backslash escape: \017']",
541 "{'Comma instead if closing brace': true,",
542 "{'Double colon':: null}",
543 "{'Extra comma': true,}",
545 "{'Illegal invocation': alert()}",
546 "{'Missing colon' null}",
548 "{unquoted_key: 'keys must be quoted'}",
549 "'A JSON payload should be an object or array, not a string.'",
551 "{'Illegal expression': 1 + 2}",
552 "{'Extra value after close': true} 'misplaced quoted value'",
556 "['Comma after the close'],",
557 "['double extra comma',,]",
558 "['Illegal backslash escape: \x15']",
560 "{'Comma instead of colon', null}",
564 "{'Numbers cannot be hex': 0x14}",
565 "[ , '<-- missing value']",
566 "[{'no comma':1} {'b:2}]",
567 "{'extra comma':1,}",
571 int UtcDaliJsonParserMethod07(void)
573 ToolkitTestApplication application;
575 tet_infoline("JSON Fail");
577 JsonParser parser = JsonParser::New();
579 for(int i = 0; i < NUMBER_FAIL_TESTS; ++i)
581 parser = JsonParser::New();
583 parser.Parse( ReplaceQuotes(TEST_FAIL[i]) );
585 if(!parser.ParseError())
587 tet_printf("Invalid JSON parse test %d Failed", i);
588 tet_printf("%s", ReplaceQuotes(TEST_FAIL[i]).c_str());
589 tet_printf("JSON Error %d:%d %s (%s)", parser.GetErrorLineNumber(), parser.GetErrorColumn(),
590 parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
593 DALI_TEST_CHECK(parser.ParseError());
597 parser = JsonParser::New();
599 parser.Parse( "['single quote']" );
601 if(!parser.ParseError())
603 tet_printf("['single quote']");
606 DALI_TEST_CHECK(parser.ParseError());
608 tet_result(TET_PASS);
612 int UtcDaliJsonParserMethod08(void)
614 ToolkitTestApplication application;
616 tet_infoline("JSON error reporting");
618 std::string s1( ReplaceQuotes("\
624 JsonParser parser = JsonParser::New();
628 DALI_TEST_CHECK(parser.ParseError());
630 DALI_TEST_CHECK(1 == parser.GetErrorLineNumber());
631 DALI_TEST_CHECK(53 == parser.GetErrorPosition());
632 DALI_TEST_CHECK(11 == parser.GetErrorColumn());
633 DALI_TEST_CHECK("Missing Value" == parser.GetErrorDescription());
635 tet_result(TET_PASS);
639 int UtcDaliJsonParserMethod09(void)
641 ToolkitTestApplication application;
643 tet_infoline("JSON Pack()");
645 std::string s1( ReplaceQuotes("\
653 'object':{'key':'value'} \
657 JsonParser parser = JsonParser::New();
661 std::stringstream ss1;
662 parser.Write(ss1, 2);
664 parser.Pack(); // Pack() moves strings
666 std::stringstream ss2;
667 parser.Write(ss2, 2);
669 DALI_TEST_CHECK(ss1.str() == ss2.str());
671 tet_result(TET_PASS);
675 int UtcDaliJsonParserMethod10(void)
677 ToolkitTestApplication application;
679 tet_infoline("JSON empty data");
681 std::string s1( "" );
683 JsonParser parser = JsonParser::New();
687 DALI_TEST_CHECK(parser.ParseError());
689 tet_result(TET_PASS);
693 int UtcDaliJsonParserMethod11(void)
695 ToolkitTestApplication application;
696 tet_infoline("JSON tree copy");
698 std::string s1( ReplaceQuotes(" \
707 'actor':'bump-image', \
708 'property':'uLightPosition', \
709 'value':[0.8, 0.0, -1.5], \
710 'alphaFunction': 'BOUNCE', \
711 'timePeriod': { 'duration': 2.5 } \
719 JsonParser parser = JsonParser::New();
723 JsonParser parser2 = JsonParser::New(*parser.GetRoot());
725 DALI_TEST_CHECK(parser.GetRoot());
726 DALI_TEST_CHECK(parser2.GetRoot());
728 CompareTrees( *parser.GetRoot(), *parser2.GetRoot() );
730 tet_result(TET_PASS);
735 int UtcDaliJsonParserMerge1(void)
737 ToolkitTestApplication application;
738 tet_infoline("JSON tree merge");
740 std::string s1( ReplaceQuotes(" \
746 'backgroundColor':[0.8, 0.0, 1.0, 1.0], \
747 'foregroundColor':[1, 1, 1, 1] \
753 JsonParser parser = JsonParser::New();
754 JsonParser testParser = JsonParser::New();
756 testParser.Parse( s1 );
759 parser.Parse( s1 ); // Merge the tree into itself. The value array should not grow.
761 DALI_TEST_CHECK(parser.GetRoot());
763 CompareTrees( *parser.GetRoot(), *testParser.GetRoot() );
768 int UtcDaliJsonParserDownCast(void)
770 BaseHandle handle = JsonParser::New();
771 JsonParser parser = JsonParser::DownCast( handle );
772 DALI_TEST_CHECK( parser );
776 int UtcDaliJsonParserTreeNodeCount(void)
778 std::string s1( ReplaceQuotes(" \
784 'backgroundColor':[0.8, 0.0, 1.0, 1.0], \
785 'foregroundColor':[1, 1, 1, 1] \
791 JsonParser parser = JsonParser::New();
794 const TreeNode* treeNode = parser.GetRoot();
795 DALI_TEST_EQUALS(1, treeNode->Count("styles"), TEST_LOCATION );
796 DALI_TEST_EQUALS(0, treeNode->Count("random"), TEST_LOCATION );
801 int UtcDaliJsonParserTreeNodeFind(void)
803 std::string s1( ReplaceQuotes("\
811 'object':{'key':'value'} \
815 JsonParser parser = JsonParser::New();
818 const TreeNode* treeNode = parser.GetRoot();
819 const TreeNode* childNode = treeNode->Find("string");
820 DALI_TEST_CHECK( childNode );
821 const TreeNode* sameNode = childNode->Find("string");
822 DALI_TEST_EQUALS( sameNode, childNode, TEST_LOCATION );