[dali_2.0.7] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-scene-loader-internal / utc-Dali-JsonUtil.cpp
1 /*
2  * Copyright (c) 2020 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 // Enable debug log for test coverage
19 #define DEBUG_ENABLED 1
20
21 #include "dali-scene-loader/internal/json-util.h"
22 #include "dali-toolkit/devel-api/builder/json-parser.h"
23 #include <dali-test-suite-utils.h>
24 #include <string>
25
26 #define STRINGIFY(x) #x
27
28 using namespace Dali;
29 using namespace Dali::Toolkit;
30 using namespace Dali::SceneLoader;
31
32 namespace
33 {
34 const std::string TEST_JSON =
35   "{ \"int\": 17834,"
36   "\"float\": 3.1415628,"
37   "\"bool\": true,"
38   "\"null\": null,"
39   "\"string\": \"hello\","
40   "\"floatArray\": [ 0.0, 0.25, 1.0, 0.75 ],"
41   "\"intArray\": [ 1, 2, 3, 5, 7, 11, 13, -1, -5 ],"
42   "\"mixedArray\": [ 1.99, \"the\", 6, \"brown\", \"fox\" ],"
43   "\"stringArray\": [ \"lorem\", \"ipsum\", \"dolor\", \"sic\", \"amet\" ],"
44   "\"object\": { \"duration\": 4.0, \"delay\": 1.0 },"
45   "\"rgb\": [ 0.5, 0.8, 0.25 ],"
46   "\"disambiguatedFloat\": { \"type\": \"float\", \"value\": 15.8 },"
47   "\"rotation1\": { \"type\": \"rotation\", \"value\": [ 15.0, 90.0, -45.0 ] },"
48   "\"rotation2\": { \"type\": \"rotation\", \"value\": [ 0.707, 0.0, 0.707, 0.0 ] },"
49   "\"matrix\": [ 1.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 1.0, 2.0, 3.0, 4.0 ],"
50   "\"matrix3\": [ 2.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 1.0, 2.0 ],"
51   "\"vector2\": [ 2.0, 1.0 ]"
52   "}";
53
54 template <typename T>
55 struct Item
56 {
57   std::string name;
58   bool readResult;
59   T result;
60 };
61
62 struct Document
63 {
64   Document(const std::string& json)
65   : parser(JsonParser::New())
66   {
67     //DALI_TEST_CHECK(parser.Parse(json));
68     if (!parser.Parse(json))
69     {
70       auto error = parser.GetErrorDescription();
71       printf("Error: %s in {%d, %d}\n", error.c_str(), parser.GetErrorLineNumber(), parser.GetErrorColumn());
72     }
73     root = parser.GetRoot();
74   }
75
76   JsonParser parser;
77   const TreeNode* root;
78 };
79
80 template <typename T, size_t N>
81 bool CompareArrays(const T (&array)[N], const T* p, T epsilon = T(0))
82 {
83   for (auto& i: array)
84   {
85     if (std::abs(i - *p) > epsilon)
86     {
87       printf("Element %d mismatched.\n", int32_t(std::distance(array, &i)));
88       return false;
89     }
90     ++p;
91   }
92   return true;
93 }
94
95 }
96
97 int UtcDaliJsonUtilReadBool(void)
98 {
99   bool value = false;
100   DALI_TEST_CHECK(!ReadBool(nullptr, value));
101   DALI_TEST_EQUAL(value, false); // unchanged
102
103   Document doc{ TEST_JSON };
104
105   for (auto& i : {
106     Item<bool>{ "bool",       true, true },
107     Item<bool>{ "int",        false, true }, // value unchanged
108     Item<bool>{ "float",      false, true },
109     Item<bool>{ "null",       false, true },
110     Item<bool>{ "floatArray", false, true },
111     Item<bool>{ "intArray",   false, true },
112     Item<bool>{ "object",     false, true },
113   })
114   {
115     bool readResult = ReadBool(doc.root->GetChild(i.name), value);
116     DALI_TEST_EQUAL(readResult, i.readResult);
117     if (readResult)
118     {
119       DALI_TEST_EQUAL(value, i.result);
120     }
121   }
122
123   END_TEST;
124 }
125
126 int UtcDaliJsonUtilReadInt(void)
127 {
128   int value = 0xbadbeef;
129   DALI_TEST_CHECK(!ReadInt(nullptr, value));
130   DALI_TEST_EQUAL(value, 0xbadbeef);
131
132   Document doc{ TEST_JSON };
133
134   for (auto& i : {
135     Item<int>{ "bool",       false, 0xbadbeef }, // unchanged from initial
136     Item<int>{ "int",        true, 17834 },
137     Item<int>{ "float",      true, 3 },
138     Item<int>{ "null",       false, 3 },
139     Item<int>{ "floatArray", false, 3 },
140     Item<int>{ "intArray",   false, 3 },
141     Item<int>{ "object",     false, 3 },
142   })
143   {
144     bool readResult = ReadInt(doc.root->GetChild(i.name), value);
145     DALI_TEST_EQUAL(readResult, i.readResult);
146     if (readResult)
147     {
148       DALI_TEST_EQUAL(value, i.result);
149     }
150   }
151
152   END_TEST;
153 }
154
155 int UtcDaliJsonUtilReadFloat(void)
156 {
157   float value = 10.101f;
158   DALI_TEST_CHECK(!ReadFloat(nullptr, value));
159   DALI_TEST_EQUAL(value, 10.101f);
160
161   Document doc{ TEST_JSON };
162
163   for (auto& i : {
164     Item<float>{ "bool",       false, 10.101f }, // unchanged from initial
165     Item<float>{ "int",        true, 17834.f },
166     Item<float>{ "float",      true, 3.1415628f },
167     Item<float>{ "null",       false, 3.1415628f },
168     Item<float>{ "floatArray", false, 3.1415628f },
169     Item<float>{ "intArray",   false, 3.1415628f },
170     Item<float>{ "object",     false, 3.1415628f },
171   })
172   {
173     bool readResult = ReadFloat(doc.root->GetChild(i.name), value);
174     DALI_TEST_EQUAL(readResult, i.readResult);
175     if (readResult)
176     {
177       DALI_TEST_EQUAL(value, i.result);
178     }
179   }
180
181   END_TEST;
182 }
183
184 int UtcDaliJsonUtilNumericalArrays(void)
185 {
186   Document doc{ TEST_JSON };
187
188   DALI_TEST_EQUAL(4u, GetNumericalArraySize(doc.root->GetChild("floatArray")));
189   DALI_TEST_EQUAL(9u, GetNumericalArraySize(doc.root->GetChild("intArray")));
190   DALI_TEST_EQUAL(1u, GetNumericalArraySize(doc.root->GetChild("mixedArray")));
191
192   END_TEST;
193 }
194
195 int UtcDaliJsonUtilReadVectorInt(void)
196 {
197   DALI_TEST_CHECK(!ReadVector(nullptr, static_cast<int*>(nullptr), 0));
198
199   Document doc{ TEST_JSON };
200
201   int ints[9];
202   DALI_TEST_CHECK(ReadVector(doc.root->GetChild("floatArray"), ints, 4u));
203   DALI_TEST_CHECK(CompareArrays<int>({ 0, 0, 1, 0 }, ints));
204
205   DALI_TEST_CHECK(ReadVector(doc.root->GetChild("intArray"), ints, 9u));
206   DALI_TEST_CHECK(CompareArrays<int>({ 1, 2, 3, 5, 7, 11, 13, -1, -5 }, ints));
207
208   DALI_TEST_CHECK(ReadVector(doc.root->GetChild("mixedArray"), ints, 1u));
209   DALI_TEST_CHECK(CompareArrays<int>({ 1 }, ints));
210
211   END_TEST;
212 }
213
214 int UtcDaliJsonUtilReadVectorFloat(void)
215 {
216   DALI_TEST_CHECK(!ReadVector(nullptr, static_cast<int*>(nullptr), 0));
217
218   Document doc{ TEST_JSON };
219
220   constexpr float e = 1e-6f;
221   float floats[9];
222   DALI_TEST_CHECK(ReadVector(doc.root->GetChild("floatArray"), floats, 4u));
223   DALI_TEST_CHECK(CompareArrays<float>({ 0.f, 0.25f, 1.f, 0.75f }, floats, e));
224
225   DALI_TEST_CHECK(ReadVector(doc.root->GetChild("intArray"), floats, 9u));
226   DALI_TEST_CHECK(CompareArrays<float>({ 1.f, 2.f, 3.f, 5.f, 7.f, 11.f, 13.f, -1.f, -5.f }, floats, e));
227
228   DALI_TEST_CHECK(ReadVector(doc.root->GetChild("mixedArray"), floats, 1u));
229   DALI_TEST_CHECK(CompareArrays<float>({ 1.99f }, floats, e));
230
231   END_TEST;
232 }
233
234 int UtcDaliJsonUtilReadColor(void)
235 {
236   Vector4 color;
237   DALI_TEST_CHECK(!ReadColor(nullptr, color));
238
239   Document doc{ TEST_JSON };
240   DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("bool"), color));
241   DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("int"), color));
242   DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("float"), color));
243   DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("string"), color));
244   DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("object"), color));
245
246   constexpr float e = 1e-6f;
247   DALI_TEST_CHECK(ReadColor(doc.root->GetChild("floatArray"), color));
248   DALI_TEST_CHECK(CompareArrays<float>({ 0.f, 0.25f, 1.0f, 0.75f }, color.AsFloat(), e));
249
250   DALI_TEST_CHECK(ReadColor(doc.root->GetChild("intArray"), color));
251   DALI_TEST_CHECK(CompareArrays<float>({ 1.f, 2.f, 3.f, 5.f }, color.AsFloat(), e));
252
253   DALI_TEST_CHECK(ReadColor(doc.root->GetChild("rgb"), color));
254   DALI_TEST_CHECK(CompareArrays<float>({ .5f, .8f, .25f, 1.f }, color.AsFloat(), e));
255
256   END_TEST;
257 }
258
259 int UtcDaliJsonUtilReadTimePeriod(void)
260 {
261   TimePeriod value(60.f);
262   DALI_TEST_CHECK(!ReadTimePeriod(nullptr, value));
263   DALI_TEST_EQUAL(value.durationSeconds, 60.f);
264   DALI_TEST_EQUAL(value.delaySeconds, 0.f);
265
266   Document doc{ TEST_JSON };
267   DALI_TEST_CHECK(ReadTimePeriod(doc.root->GetChild("object"), value));
268   DALI_TEST_EQUAL(value.durationSeconds, 4.f);
269   DALI_TEST_EQUAL(value.delaySeconds, 1.f);
270
271   END_TEST;
272 }
273
274 int UtcDaliJsonUtilReadString(void)
275 {
276   std::string value = "bye";
277   DALI_TEST_CHECK(!ReadString(nullptr, value));
278   DALI_TEST_EQUAL(value, "bye");
279
280   Document doc{ TEST_JSON };
281
282   for (auto& i : {
283     Item<std::string>{ "bool",       false, "bye"}, // unchanged from initial
284     Item<std::string>{ "int",        false, "bye"},
285     Item<std::string>{ "float",      false, "bye"},
286     Item<std::string>{ "null",       false, "bye"},
287     Item<std::string>{ "string",     true, "hello"},
288     Item<std::string>{ "floatArray", false, "hello"}, // unchanged
289     Item<std::string>{ "object",     false, "hello"},
290   })
291   {
292     bool readResult = ReadString(doc.root->GetChild(i.name), value);
293     DALI_TEST_EQUAL(readResult, i.readResult);
294     if (readResult)
295     {
296       DALI_TEST_EQUAL(value, i.result);
297     }
298   }
299
300   END_TEST;
301 }
302
303 int UtcDaliJsonUtilReadStringVector(void)
304 {
305   std::vector<std::string> strings;
306   DALI_TEST_CHECK(!ReadStringVector(nullptr, strings));
307   DALI_TEST_CHECK(strings.empty());
308
309   Document doc{ TEST_JSON };
310
311   DALI_TEST_CHECK(!ReadStringVector(doc.root->GetChild("floatArray"), strings));
312   DALI_TEST_CHECK(strings.empty());
313
314   DALI_TEST_CHECK(!ReadStringVector(doc.root->GetChild("intArray"), strings));
315   DALI_TEST_CHECK(strings.empty());
316
317   DALI_TEST_CHECK(!ReadStringVector(doc.root->GetChild("mixedArray"), strings));
318   DALI_TEST_CHECK(strings.empty());
319
320   DALI_TEST_CHECK(ReadStringVector(doc.root->GetChild("stringArray"), strings));
321   DALI_TEST_EQUAL(strings.size(), 5u);
322
323   auto iStrings = strings.begin();
324   for (auto& i : { "lorem", "ipsum", "dolor", "sic", "amet" })
325   {
326     DALI_TEST_EQUAL(*iStrings, i);
327     ++iStrings;
328   }
329
330   END_TEST;
331 }
332
333 int UtcDaliJsonUtilReadAndReturnPropertyValue(void)
334 {
335   Document doc{ TEST_JSON };
336   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("disambiguatedFloat")).Get<float>(), 15.8f);
337
338   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("rotation1")).Get<Quaternion>(),
339     Quaternion(Radian(Degree(15.0)), Radian(Degree(90.0)), Radian(Degree(-45.f))));
340   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("rotation2")).Get<Quaternion>(),
341     Quaternion(Vector4(0.707f, 0.f, 0.707f, 0.f)));
342
343   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("bool")).Get<bool>(), true);
344   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("int")).Get<int32_t>(), 17834);
345
346   const float floats[]{ 1.f, 0.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f, 0.f, 0.f, 3.f, 0.f, 1.f, 2.f, 3.f, 4.f };
347   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("matrix")).Get<Matrix>(), Matrix(floats));
348   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("matrix3")).Get<Matrix3>(), Matrix3(floats[5],
349     floats[6], floats[7], floats[8], floats[9], floats[10], floats[11], floats[12], floats[13]));
350   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("floatArray")).Get<Vector4>(),
351     Vector4(0.f, .25f, 1.f, .75f));
352   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("rgb")).Get<Vector3>(),
353     Vector3(.5f, .8f, .25f));
354   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("vector2")).Get<Vector2>(),
355     Vector2(2.f, 1.f));
356   DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("object")->GetChild("duration")).Get<float>(), 4.f );
357
358   END_TEST;
359 }
360
361 namespace
362 {
363 template <typename T>
364 void CheckEqualityAs(Property::Value lhs, Property::Value rhs)
365 {
366   DALI_TEST_EQUAL(lhs.Get<T>(), rhs.Get<T>());
367 }
368
369 }
370
371 int UtcDaliJsonUtilReadPropertyValue(void)
372 {
373   struct TypeNameValue
374   {
375     Property::Type type;
376     std::string name;
377     Property::Value value;
378     void(*compareFn)(Property::Value, Property::Value);
379   };
380
381   Document doc{ TEST_JSON };
382
383   const float floats[]{ 1.f, 0.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f, 0.f, 0.f, 3.f, 0.f, 1.f, 2.f, 3.f, 4.f };
384   const TypeNameValue typeNameValues[] {
385     { Property::BOOLEAN, "bool", true, CheckEqualityAs<bool> },
386     { Property::FLOAT, "float", 3.1415628f, CheckEqualityAs<float> },
387     { Property::INTEGER, "int", 17834, CheckEqualityAs<int32_t> },
388     { Property::VECTOR2, "vector2", Vector2(2.f, 1.f), CheckEqualityAs<Vector2> },
389     { Property::VECTOR3, "rgb", Vector3(.5f, .8f, .25f), CheckEqualityAs<Vector3> },
390     { Property::VECTOR4, "floatArray", Vector4(.0f, .25f, 1.f, .75f), CheckEqualityAs<Vector4> },
391     { Property::MATRIX3, "matrix3", Matrix3(2.f, 0.f, 0.f, 0.f, 0.f, 3.f, 0.f, 1.f, 2.f),
392       CheckEqualityAs<Matrix3> },
393     { Property::MATRIX, "matrix", Matrix(floats), CheckEqualityAs<Matrix> },
394     { Property::RECTANGLE, "intArray", Rect<int>(1, 2, 3, 5), CheckEqualityAs<Rect<int>> },
395     { Property::EXTENTS, "intArray", Extents(1, 2, 3, 5), CheckEqualityAs<Extents> },
396   };
397   for(auto& i: typeNameValues)
398   {
399     std::cout << i.value << std::endl;
400     i.compareFn(ReadPropertyValue(i.type, *doc.root->GetChild(i.name)), i.value);
401   }
402
403   END_TEST;
404 }