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/public-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() );
100 int UtcDaliJsonParserMethod01(void)
102 ToolkitTestApplication application;
104 tet_infoline("JSON basic test");
106 std::string s1( ReplaceQuotes(
114 'object':{'key':'value'} \
117 JsonParser parser = JsonParser::New();
121 if(parser.ParseError())
123 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
124 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
127 DALI_TEST_CHECK(!parser.ParseError());
129 const TreeNode* root = parser.GetRoot();
131 DALI_TEST_CHECK(root);
133 DALI_TEST_CHECK(root->Size());
135 TreeNode::ConstIterator iter = root->CBegin();
136 DALI_TEST_CHECK(iter != root->CEnd());
138 const TreeNode* node = NULL;
140 node = &((*iter).second);
141 DALI_TEST_CHECK(node);
142 DALI_TEST_CHECK(node->GetType() == TreeNode::STRING);
143 DALI_TEST_CHECK(std::string((*iter).first) == std::string("string"));
144 DALI_TEST_CHECK(std::string(node->GetString()) == std::string("value2"));
147 DALI_TEST_CHECK(iter != root->CEnd());
148 node = &((*iter).second);
149 DALI_TEST_CHECK(node);
150 DALI_TEST_CHECK(node->GetType() == TreeNode::INTEGER);
151 DALI_TEST_CHECK(std::string((*iter).first) == std::string("integer"));
152 DALI_TEST_CHECK(node->GetInteger() == 2);
155 DALI_TEST_CHECK(iter != root->CEnd());
156 node = &((*iter).second);
157 DALI_TEST_CHECK(node);
158 DALI_TEST_CHECK(node->GetType() == TreeNode::FLOAT);
159 DALI_TEST_CHECK(std::string((*iter).first) == std::string("float"));
160 DALI_TEST_CHECK(node->GetFloat() == 2.0);
163 DALI_TEST_CHECK(iter != root->CEnd());
164 node = &((*iter).second);
165 DALI_TEST_CHECK(node);
166 DALI_TEST_CHECK(node->GetType() == TreeNode::BOOLEAN);
167 DALI_TEST_CHECK(std::string((*iter).first) == std::string("boolean"));
168 DALI_TEST_CHECK(node->GetBoolean());
171 DALI_TEST_CHECK(iter != root->CEnd());
172 node = &((*iter).second);
173 DALI_TEST_CHECK(node);
174 DALI_TEST_CHECK(node->GetType() == TreeNode::IS_NULL);
175 DALI_TEST_CHECK(std::string((*iter).first) == std::string("nil"));
178 DALI_TEST_CHECK(iter != root->CEnd());
179 node = &((*iter).second);
180 DALI_TEST_CHECK(node);
181 DALI_TEST_CHECK(node->GetType() == TreeNode::ARRAY);
182 DALI_TEST_CHECK(node->Size() == 3);
183 TreeNode::ConstIterator iterArray = node->CBegin();
185 DALI_TEST_CHECK(iterArray != node->CEnd());
186 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
187 DALI_TEST_CHECK( (*iterArray).first == NULL );
188 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 1);
191 DALI_TEST_CHECK(iterArray != node->CEnd());
192 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
193 DALI_TEST_CHECK( (*iterArray).first == NULL );
194 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 2);
197 DALI_TEST_CHECK(iterArray != node->CEnd());
198 DALI_TEST_CHECK( ((*iterArray).second).GetType() == TreeNode::INTEGER);
199 DALI_TEST_CHECK( (*iterArray).first == NULL );
200 DALI_TEST_CHECK( ((*iterArray).second).GetInteger() == 3);
203 DALI_TEST_CHECK(iter != root->CEnd());
204 node = &((*iter).second);
205 DALI_TEST_CHECK(node);
206 DALI_TEST_CHECK(node->GetType() == TreeNode::OBJECT);
207 DALI_TEST_CHECK(node->Size() == 1);
209 TreeNode::ConstIterator iterObject = node->CBegin();
210 DALI_TEST_CHECK(iterObject != node->CEnd());
211 DALI_TEST_CHECK( ((*iterObject).second).GetType() == TreeNode::STRING);
212 DALI_TEST_CHECK( std::string((*iterObject).first) == std::string("key" ));
213 DALI_TEST_CHECK( std::string(((*iterObject).second).GetString()) == std::string("value"));
215 tet_result(TET_PASS);
219 int UtcDaliJsonParserMethod02(void)
221 ToolkitTestApplication application;
223 tet_infoline("JSON Comments");
225 std::string s1( ReplaceQuotes(" \
226 // some comments with empty line above \n\
228 // inline comments \n\
229 'key':'value', // endline comments \n\
230 // more inline comments \n\
235 JsonParser parser = JsonParser::New();
239 if(parser.ParseError())
241 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
242 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
245 DALI_TEST_CHECK(!parser.ParseError());
247 const TreeNode* root = parser.GetRoot();
249 DALI_TEST_CHECK(root);
251 DALI_TEST_CHECK(root->Size());
253 const TreeNode& node = (*root->CBegin()).second;
255 DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
257 DALI_TEST_CHECK(node.GetString() == std::string("value"));
259 DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
261 tet_result(TET_PASS);
266 int UtcDaliJsonParserMethod03(void)
268 ToolkitTestApplication application;
270 tet_infoline("JSON Empty line comment");
272 std::string s1( ReplaceQuotes(
276 "// next empty line comment\n"\
283 JsonParser parser = JsonParser::New();
287 if(parser.ParseError())
289 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
290 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
293 DALI_TEST_CHECK(!parser.ParseError());
295 const TreeNode* root = parser.GetRoot();
297 DALI_TEST_CHECK(root);
299 DALI_TEST_CHECK(root->Size());
301 const TreeNode& node = (*root->CBegin()).second;
303 DALI_TEST_CHECK(node.GetType() == TreeNode::STRING);
305 DALI_TEST_CHECK(node.GetString() == std::string("value"));
307 DALI_TEST_CHECK((*root->CBegin()).first == std::string("key"));
309 tet_result(TET_PASS);
313 int UtcDaliJsonParserMethod04(void)
315 ToolkitTestApplication application;
317 tet_infoline("JSON Merge");
319 std::string s1( ReplaceQuotes(" \
328 'actor':'bump-image', \
329 'property':'uLightPosition', \
330 'value':[0.8, 0.0, -1.5], \
331 'alpha-function': 'BOUNCE', \
332 'time-period': { 'duration': 2.5 } \
340 std::string s2( ReplaceQuotes(" \
348 'end-action':'DISCARD' \
354 JsonParser parser = JsonParser::New();
358 if(parser.ParseError())
360 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
361 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
363 DALI_TEST_CHECK(!parser.ParseError());
367 if(parser.ParseError())
369 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
370 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
373 DALI_TEST_CHECK(!parser.ParseError());
375 const TreeNode* root = parser.GetRoot();
376 DALI_TEST_CHECK(root);
378 const TreeNode *node = root->Find("bump");
379 DALI_TEST_CHECK(node);
381 DALI_TEST_CHECK(static_cast<int>(node->Size()) == 4);
383 DALI_TEST_CHECK( node->GetChild("duration") );
384 DALI_TEST_CHECK( node->GetChild("loop") );
385 DALI_TEST_CHECK( node->GetChild("properties") );
388 tet_result(TET_PASS);
392 int UtcDaliJsonParserMethod05(void)
394 ToolkitTestApplication application;
396 tet_infoline("JSON Pack & Write");
398 std::string s1( ReplaceQuotes(" \
407 'actor':'bump-image', \
408 'property':'uLightPosition', \
409 'value':[0.8, 0.0, -1.5], \
410 'alpha-function': 'BOUNCE', \
411 'time-period': { 'duration': 2.5 } \
419 JsonParser parser = JsonParser::New();
423 if(parser.ParseError())
425 std::cout << "Error: " << parser.GetErrorDescription() << std::endl;
426 std::cout << " at: " << parser.GetErrorLineNumber() << "(" << parser.GetErrorPosition() << ")" << std::endl;
428 DALI_TEST_CHECK(!parser.ParseError());
438 DALI_TEST_CHECK( a.str() == b.str() );
440 tet_result(TET_PASS);
447 static const int NUMBER_OK_TESTS = 36;
448 const char *TEST_OK[NUMBER_OK_TESTS] = {
449 "{ 'hex': '\u0123\u4567\u89AB\uCDEF\uabcd\uef4A' }",
450 "{ 'special': '`1~!@#$%^&*()_+-={:[,]}|;.</>?' }",
451 "{ 'slash': '/ & \' }",
452 "{'object with 1 member':['array with 1 element']}",
453 "[{}, [], -42, true, false, null]",
454 "{ 'integer': 1234567890 }",
455 "{ 'integer': 1234567890 }",
456 "{ 'real': -9876.543210 }",
457 "{ 'e': 0.123456789e-12 }",
458 "{ 'E': 1.234567890E+34 }",
459 "{ '': 23456789012E66 }",
463 "{ 'backslash': '\' }",
464 "{ 'controls': '\\b\\f\\n\\r\\t' }",
465 "{ 'alpha': 'abcdefghijklmnopqrstuvwyz' }",
466 "{ 'ALPHA': 'ABCDEFGHIJKLMNOPQRSTUVWYZ' }",
467 "{ 'digit': '0123456789' }",
468 "{ '0123456789': 'digit' }",
470 "{ 'false': false }",
474 "{ 'address': '1 Communication Centre. South Street' }",
475 "{ 'url': 'http://www.JSON.org/' }",
476 "{ 'comment': '// /* <!-- --' }",
477 "{ '# -- --> */': ' ' }",
478 "{ ' s p a c e d ' :[1,2 , 3,4 , 5 , 6 ,7 ]}",
479 "{ 'compact':[1,2,3,4,5,6,7]}",
480 "{ 'quotes': '" \\u0022 %22 0x22 034 "' }",
481 "{ '\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t`1~!@#$%^&*()_+-=[]{}|;:': 'A key can be any string'}",
482 "[ 0.5 ,98.6, 99.44,1066,1e1,0.1e1,1e-1,1e00,2e+00,2e-00, 'rosebud']",
483 "{'JSON Test Pattern pass3': { 'The outermost value': 'must be an object or array.', 'In this test': 'It is an object.' } }",
484 "[[[[[[[[[[[[[[[[[[['Not too deep']]]]]]]]]]]]]]]]]]]",
489 int UtcDaliJsonParserMethod06(void)
491 ToolkitTestApplication application;
493 tet_infoline("JSON Parse Success");
495 JsonParser parser = JsonParser::New();
497 for(int i = 0; i < NUMBER_OK_TESTS; ++i)
499 parser = JsonParser::New();
501 parser.Parse( ReplaceQuotes(TEST_OK[i]) );
503 if(parser.ParseError())
505 tet_printf("Valid JSON parse test %d Failed", i);
506 tet_printf("%s", ReplaceQuotes(TEST_OK[i]).c_str());
508 tet_printf("JSON Error %d:%d: %s (%d)", parser.GetErrorLineNumber(), parser.GetErrorColumn(), parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
511 DALI_TEST_CHECK(!parser.ParseError());
514 tet_result(TET_PASS);
521 static const int NUMBER_FAIL_TESTS = 34;
522 const char *TEST_FAIL[] = {
523 "[' tab\t character \t in\t string ']",
525 "['Colon instead of comma': false]",
526 "{'Numbers cannot have leading zeroes': 013}",
527 "['Bad value', truth]",
528 "['Illegal backslash escape: \017']",
529 "['Bad value', truth]['Illegal backslash escape: \017']",
530 "{'Comma instead if closing brace': true,",
531 "{'Double colon':: null}",
532 "{'Extra comma': true,}",
534 "{'Illegal invocation': alert()}",
535 "{'Missing colon' null}",
537 "{unquoted_key: 'keys must be quoted'}",
538 "'A JSON payload should be an object or array, not a string.'",
540 "{'Illegal expression': 1 + 2}",
541 "{'Extra value after close': true} 'misplaced quoted value'",
545 "['Comma after the close'],",
546 "['double extra comma',,]",
547 "['Illegal backslash escape: \x15']",
549 "{'Comma instead of colon', null}",
553 "{'Numbers cannot be hex': 0x14}",
554 "[ , '<-- missing value']",
555 "[{'no comma':1} {'b:2}]",
556 "{'extra comma':1,}",
560 int UtcDaliJsonParserMethod07(void)
562 ToolkitTestApplication application;
564 tet_infoline("JSON Fail");
566 JsonParser parser = JsonParser::New();
568 for(int i = 0; i < NUMBER_FAIL_TESTS; ++i)
570 parser = JsonParser::New();
572 parser.Parse( ReplaceQuotes(TEST_FAIL[i]) );
574 if(!parser.ParseError())
576 tet_printf("Invalid JSON parse test %d Failed", i);
577 tet_printf("%s", ReplaceQuotes(TEST_FAIL[i]).c_str());
578 tet_printf("JSON Error %d:%d %s (%s)", parser.GetErrorLineNumber(), parser.GetErrorColumn(),
579 parser.GetErrorDescription().c_str(), parser.GetErrorPosition());
582 DALI_TEST_CHECK(parser.ParseError());
586 parser = JsonParser::New();
588 parser.Parse( "['single quote']" );
590 if(!parser.ParseError())
592 tet_printf("['single quote']");
595 DALI_TEST_CHECK(parser.ParseError());
597 tet_result(TET_PASS);
601 int UtcDaliJsonParserMethod08(void)
603 ToolkitTestApplication application;
605 tet_infoline("JSON error reporting");
607 std::string s1( ReplaceQuotes("\
613 JsonParser parser = JsonParser::New();
617 DALI_TEST_CHECK(parser.ParseError());
619 DALI_TEST_CHECK(1 == parser.GetErrorLineNumber());
620 DALI_TEST_CHECK(53 == parser.GetErrorPosition());
621 DALI_TEST_CHECK(11 == parser.GetErrorColumn());
623 tet_result(TET_PASS);
627 int UtcDaliJsonParserMethod09(void)
629 ToolkitTestApplication application;
631 tet_infoline("JSON Pack()");
633 std::string s1( ReplaceQuotes("\
641 'object':{'key':'value'} \
645 JsonParser parser = JsonParser::New();
649 std::stringstream ss1;
650 parser.Write(ss1, 2);
652 parser.Pack(); // Pack() moves strings
654 std::stringstream ss2;
655 parser.Write(ss2, 2);
657 DALI_TEST_CHECK(ss1.str() == ss2.str());
659 tet_result(TET_PASS);
663 int UtcDaliJsonParserMethod10(void)
665 ToolkitTestApplication application;
667 tet_infoline("JSON empty data");
669 std::string s1( "" );
671 JsonParser parser = JsonParser::New();
675 DALI_TEST_CHECK(parser.ParseError());
677 tet_result(TET_PASS);
681 int UtcDaliJsonParserMethod11(void)
683 ToolkitTestApplication application;
684 tet_infoline("JSON tree copy");
686 std::string s1( ReplaceQuotes(" \
695 'actor':'bump-image', \
696 'property':'uLightPosition', \
697 'value':[0.8, 0.0, -1.5], \
698 'alpha-function': 'BOUNCE', \
699 'time-period': { 'duration': 2.5 } \
707 JsonParser parser = JsonParser::New();
711 JsonParser parser2 = JsonParser::New(*parser.GetRoot());
713 DALI_TEST_CHECK(parser.GetRoot());
714 DALI_TEST_CHECK(parser2.GetRoot());
716 CompareTrees( *parser.GetRoot(), *parser2.GetRoot() );
718 tet_result(TET_PASS);