[dali_2.3.25] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Scripting.cpp
1 /*
2  * Copyright (c) 2024 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 #include <dali-test-suite-utils.h>
19 #include <dali/devel-api/scripting/scripting.h>
20 #include <dali/public-api/dali-core.h>
21 #include <stdlib.h>
22
23 #include <iostream>
24
25 using namespace Dali;
26 using namespace Dali::Scripting;
27
28 namespace
29 {
30 const StringEnum COLOR_MODE_VALUES[] =
31   {
32     {"USE_OWN_COLOR", USE_OWN_COLOR},
33     {"USE_PARENT_COLOR", USE_PARENT_COLOR},
34     {"USE_OWN_MULTIPLY_PARENT_COLOR", USE_OWN_MULTIPLY_PARENT_COLOR},
35     {"USE_OWN_MULTIPLY_PARENT_ALPHA", USE_OWN_MULTIPLY_PARENT_ALPHA},
36 };
37 const unsigned int COLOR_MODE_VALUES_COUNT = sizeof(COLOR_MODE_VALUES) / sizeof(COLOR_MODE_VALUES[0]);
38
39 const StringEnum DRAW_MODE_VALUES[] =
40   {
41     {"NORMAL", DrawMode::NORMAL},
42     {"OVERLAY_2D", DrawMode::OVERLAY_2D}};
43 const unsigned int DRAW_MODE_VALUES_COUNT = sizeof(DRAW_MODE_VALUES) / sizeof(DRAW_MODE_VALUES[0]);
44
45 ////////////////////////////////////////////////////////////////////////////////
46 // Helpers for string to enum comparisons for Image and Image loading parameters
47 ////////////////////////////////////////////////////////////////////////////////
48
49 /**
50  * Template to check enumerations of type T, with a class of type X
51  */
52 template<typename T, typename X>
53 void TestEnumStrings(
54   Property::Map&    map,               // The map used to create instance of type X
55   const char* const keyName,           // the name of the key to iterate through
56   const StringEnum* values,            // An array of string values
57   unsigned int      num,               // Number of items in the array
58   T (X::*method)() const,              // The member method of X to call to get the enum
59   X (*creator)(const Property::Value&) // The method which creates an instance of type X
60 )
61 {
62   // get the key reference so we can change its value
63   Property::Value* value = map.Find(keyName);
64   for(unsigned int i = 0; i < num; ++i)
65   {
66     *value = values[i].string;
67     tet_printf("Checking: %s: %s\n", keyName, values[i].string);
68     X instance = creator(map);
69     DALI_TEST_EQUALS(values[i].value, (int)(instance.*method)(), TEST_LOCATION);
70   }
71 }
72
73 //////////////////////////////////////////////////////////////////////////////
74 // Helpers for string to enum comparisons for Actor to Property::Map
75 //////////////////////////////////////////////////////////////////////////////
76
77 /**
78  * Template to check enumerations of type T
79  */
80 template<typename T>
81 void TestEnumStrings(
82   const char* const keyName,     // The name of the key to check
83   TestApplication&  application, // Reference to the application class
84   const StringEnum* values,      // An array of string values
85   unsigned int      num,         // Number of items in the array
86   void (Actor::*method)(T)       // The Actor member method to set the enumeration
87 )
88 {
89   for(unsigned int i = 0; i < num; ++i)
90   {
91     tet_printf("Checking: %s: %s\n", keyName, values[i].string);
92
93     Actor actor = Actor::New();
94     (actor.*method)((T)values[i].value);
95
96     application.GetScene().Add(actor);
97     application.SendNotification();
98     application.Render();
99
100     Property::Map map;
101     CreatePropertyMap(actor, map);
102
103     DALI_TEST_CHECK(0 < map.Count());
104     DALI_TEST_CHECK(NULL != map.Find(keyName));
105     DALI_TEST_EQUALS(map.Find(keyName)->Get<std::string>(), values[i].string, TEST_LOCATION);
106
107     application.GetScene().Remove(actor);
108   }
109 }
110
111 //////////////////////////////////////////////////////////////////////////////
112
113 } // namespace
114
115 int UtcDaliValueFromEnum(void)
116 {
117   enum class T
118   {
119     None,
120     V1 = 1,
121     V2 = 2
122   };
123
124   Property::Value v1 = T::V1;
125   Property::Value v2 = T::V2;
126
127   T t = T::None;
128   DALI_TEST_CHECK(v1.Get<T>() == T::V1);
129   DALI_TEST_CHECK(v2.Get<T>() == T::V2);
130   DALI_TEST_CHECK(v1.Get(t) && t == T::V1);
131   DALI_TEST_CHECK(v2.Get(t) && t == T::V2);
132
133   END_TEST;
134 }
135
136 int UtcDaliScriptingNewActorNegative(void)
137 {
138   TestApplication application;
139
140   // Empty map
141   {
142     Actor handle = NewActor(Property::Map());
143     DALI_TEST_CHECK(!handle);
144   }
145
146   // Map with only properties
147   {
148     Property::Map map;
149     map["parentOrigin"] = ParentOrigin::TOP_CENTER;
150     map["anchorPoint"]  = AnchorPoint::TOP_CENTER;
151     Actor handle        = NewActor(map);
152     DALI_TEST_CHECK(!handle);
153   }
154
155   // Add some signals to the map, we should have no signal connections as its not yet supported
156   {
157     Property::Map map;
158     map["type"]    = "Actor";
159     map["signals"] = Property::MAP;
160     Actor handle   = NewActor(map);
161     DALI_TEST_CHECK(handle);
162     DALI_TEST_CHECK(!handle.WheelEventSignal().GetConnectionCount());
163     DALI_TEST_CHECK(!handle.OffSceneSignal().GetConnectionCount());
164     DALI_TEST_CHECK(!handle.OnSceneSignal().GetConnectionCount());
165     DALI_TEST_CHECK(!handle.TouchedSignal().GetConnectionCount());
166   }
167   END_TEST;
168 }
169
170 int UtcDaliScriptingNewActorProperties(void)
171 {
172   TestApplication application;
173
174   Property::Map map;
175   map["type"]               = "Actor";
176   map["size"]               = Vector3::ONE;
177   map["position"]           = Vector3::XAXIS;
178   map["scale"]              = Vector3::ONE;
179   map["visible"]            = false;
180   map["color"]              = Color::MAGENTA;
181   map["name"]               = "MyActor";
182   map["colorMode"]          = "USE_PARENT_COLOR";
183   map["sensitive"]          = false;
184   map["leaveRequired"]      = true;
185   map["drawMode"]           = "OVERLAY_2D";
186   map["inheritOrientation"] = false;
187   map["inheritScale"]       = false;
188
189   // Default properties
190   {
191     Actor handle = NewActor(map);
192     DALI_TEST_CHECK(handle);
193
194     application.GetScene().Add(handle);
195     application.SendNotification();
196     application.Render();
197
198     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::SIZE), Vector3::ONE, TEST_LOCATION);
199     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3::XAXIS, TEST_LOCATION);
200     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::SCALE), Vector3::ONE, TEST_LOCATION);
201     DALI_TEST_EQUALS(handle.GetCurrentProperty<bool>(Actor::Property::VISIBLE), false, TEST_LOCATION);
202     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector4>(Actor::Property::COLOR), Color::MAGENTA, TEST_LOCATION);
203     DALI_TEST_EQUALS(handle.GetProperty<std::string>(Actor::Property::NAME), "MyActor", TEST_LOCATION);
204     DALI_TEST_EQUALS(handle.GetProperty<ColorMode>(Actor::Property::COLOR_MODE), USE_PARENT_COLOR, TEST_LOCATION);
205     DALI_TEST_EQUALS(handle.GetProperty<bool>(Actor::Property::SENSITIVE), false, TEST_LOCATION);
206     DALI_TEST_EQUALS(handle.GetProperty<bool>(Actor::Property::LEAVE_REQUIRED), true, TEST_LOCATION);
207     DALI_TEST_EQUALS(handle.GetProperty<DrawMode::Type>(Actor::Property::DRAW_MODE), DrawMode::OVERLAY_2D, TEST_LOCATION);
208     DALI_TEST_EQUALS(handle.GetProperty<bool>(Actor::Property::INHERIT_ORIENTATION), false, TEST_LOCATION);
209     DALI_TEST_EQUALS(handle.GetProperty<bool>(Actor::Property::INHERIT_SCALE), false, TEST_LOCATION);
210
211     application.GetScene().Remove(handle);
212   }
213
214   // Check Anchor point and parent origin vector3s
215   map["parentOrigin"] = ParentOrigin::TOP_CENTER;
216   map["anchorPoint"]  = AnchorPoint::TOP_LEFT;
217   {
218     Actor handle = NewActor(map);
219     DALI_TEST_CHECK(handle);
220
221     application.GetScene().Add(handle);
222     application.SendNotification();
223     application.Render();
224
225     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::PARENT_ORIGIN), ParentOrigin::TOP_CENTER, TEST_LOCATION);
226     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT), AnchorPoint::TOP_LEFT, TEST_LOCATION);
227
228     application.GetScene().Remove(handle);
229   }
230
231   // Check Anchor point and parent origin STRINGS
232   map["parentOrigin"] = "TOP_LEFT";
233   map["anchorPoint"]  = "CENTER_LEFT";
234   {
235     Actor handle = NewActor(map);
236     DALI_TEST_CHECK(handle);
237
238     application.GetScene().Add(handle);
239     application.SendNotification();
240     application.Render();
241
242     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::PARENT_ORIGIN), ParentOrigin::TOP_LEFT, TEST_LOCATION);
243     DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::ANCHOR_POINT), AnchorPoint::CENTER_LEFT, TEST_LOCATION);
244
245     application.GetScene().Remove(handle);
246   }
247   END_TEST;
248 }
249
250 int UtcDaliScriptingNewAnimation(void)
251 {
252   TestApplication application;
253
254   Property::Map map;
255   map["actor"]         = "Actor1";
256   map["property"]      = "color";
257   map["value"]         = Color::MAGENTA;
258   map["alphaFunction"] = "EASE_IN_OUT";
259
260   Property::Map timePeriod;
261   timePeriod["delay"]    = 0.5f;
262   timePeriod["duration"] = 1.0f;
263   map["timePeriod"]      = timePeriod;
264
265   Dali::AnimationData data;
266   Scripting::NewAnimation(map, data);
267
268   Actor actor = Actor::New();
269   actor.SetProperty(Actor::Property::NAME, "Actor1");
270   actor.SetProperty(Actor::Property::COLOR, Color::CYAN);
271   application.GetScene().Add(actor);
272
273   Animation anim = data.CreateAnimation(actor, 0.5f);
274   anim.Play();
275
276   application.SendNotification();
277   application.Render(0);
278   application.Render(500); // Start animation
279   application.Render(500); // Halfway thru anim
280   application.SendNotification();
281   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR), (Color::MAGENTA + Color::CYAN) * 0.5f, TEST_LOCATION);
282
283   application.Render(500); // Halfway thru anim
284   application.SendNotification();
285   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR), Color::MAGENTA, TEST_LOCATION);
286
287   END_TEST;
288 }
289
290 int UtcDaliScriptingNewActorChildren(void)
291 {
292   TestApplication application;
293
294   Property::Map map;
295   map["type"]     = "Actor";
296   map["position"] = Vector3::XAXIS;
297
298   Property::Map child1Map;
299   child1Map["type"]     = "Layer";
300   child1Map["position"] = Vector3::YAXIS;
301
302   Property::Array childArray;
303   childArray.PushBack(child1Map);
304   map["actors"] = childArray;
305
306   // Create
307   Actor handle = NewActor(map);
308   DALI_TEST_CHECK(handle);
309
310   application.GetScene().Add(handle);
311   application.SendNotification();
312   application.Render();
313
314   DALI_TEST_EQUALS(handle.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3::XAXIS, TEST_LOCATION);
315   DALI_TEST_EQUALS(handle.GetChildCount(), 1u, TEST_LOCATION);
316
317   Actor child1 = handle.GetChildAt(0);
318   DALI_TEST_CHECK(child1);
319   DALI_TEST_CHECK(Layer::DownCast(child1));
320   DALI_TEST_EQUALS(child1.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3::YAXIS, TEST_LOCATION);
321   DALI_TEST_EQUALS(child1.GetChildCount(), 0u, TEST_LOCATION);
322
323   application.GetScene().Remove(handle);
324   END_TEST;
325 }
326
327 int UtcDaliScriptingCreatePropertyMapActor(void)
328 {
329   TestApplication application;
330
331   // Actor Type
332   {
333     Actor actor = Actor::New();
334
335     Property::Map map;
336     CreatePropertyMap(actor, map);
337     DALI_TEST_CHECK(!map.Empty());
338     DALI_TEST_CHECK(NULL != map.Find("type"));
339     DALI_TEST_EQUALS(map.Find("type")->Get<std::string>(), "Actor", TEST_LOCATION);
340
341     application.GetScene().Remove(actor);
342   }
343
344   // Layer Type
345   {
346     Actor actor = Layer::New();
347
348     Property::Map map;
349     CreatePropertyMap(actor, map);
350     DALI_TEST_CHECK(!map.Empty());
351     DALI_TEST_CHECK(NULL != map.Find("type"));
352     DALI_TEST_EQUALS(map.Find("type")->Get<std::string>(), "Layer", TEST_LOCATION);
353
354     application.GetScene().Remove(actor);
355   }
356
357   // Default properties
358   {
359     Actor actor = Actor::New();
360     actor.SetProperty(Actor::Property::SIZE, Vector3::ONE);
361     actor.SetProperty(Actor::Property::POSITION, Vector3::XAXIS);
362     actor.SetProperty(Actor::Property::SCALE, Vector3::ZAXIS);
363     actor.SetProperty(Actor::Property::VISIBLE, false);
364     actor.SetProperty(Actor::Property::COLOR, Color::MAGENTA);
365     actor.SetProperty(Actor::Property::NAME, "MyActor");
366     actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT);
367     actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_RIGHT);
368     actor.SetProperty(Actor::Property::SENSITIVE, false);
369     actor.SetProperty(Actor::Property::LEAVE_REQUIRED, true);
370     actor.SetProperty(Actor::Property::INHERIT_ORIENTATION, false);
371     actor.SetProperty(Actor::Property::INHERIT_SCALE, false);
372     actor.SetProperty(Actor::Property::SIZE_MODE_FACTOR, Vector3::ONE);
373
374     application.GetScene().Add(actor);
375     application.SendNotification();
376     application.Render();
377
378     Property::Map map;
379     CreatePropertyMap(actor, map);
380
381     DALI_TEST_CHECK(!map.Empty());
382     DALI_TEST_CHECK(NULL != map.Find("size"));
383     DALI_TEST_EQUALS(map.Find("size")->Get<Vector3>(), Vector3::ONE, TEST_LOCATION);
384     DALI_TEST_CHECK(NULL != map.Find("position"));
385     DALI_TEST_EQUALS(map.Find("position")->Get<Vector3>(), Vector3::XAXIS, TEST_LOCATION);
386     DALI_TEST_CHECK(NULL != map.Find("scale"));
387     DALI_TEST_EQUALS(map.Find("scale")->Get<Vector3>(), Vector3::ZAXIS, TEST_LOCATION);
388     DALI_TEST_CHECK(NULL != map.Find("visible"));
389     DALI_TEST_EQUALS(map.Find("visible")->Get<bool>(), false, TEST_LOCATION);
390     DALI_TEST_CHECK(NULL != map.Find("color"));
391     DALI_TEST_EQUALS(map.Find("color")->Get<Vector4>(), Color::MAGENTA, TEST_LOCATION);
392     DALI_TEST_CHECK(NULL != map.Find("name"));
393     DALI_TEST_EQUALS(map.Find("name")->Get<std::string>(), "MyActor", TEST_LOCATION);
394     DALI_TEST_CHECK(NULL != map.Find("anchorPoint"));
395     DALI_TEST_EQUALS(map.Find("anchorPoint")->Get<Vector3>(), AnchorPoint::CENTER_LEFT, TEST_LOCATION);
396     DALI_TEST_CHECK(NULL != map.Find("parentOrigin"));
397     DALI_TEST_EQUALS(map.Find("parentOrigin")->Get<Vector3>(), ParentOrigin::TOP_RIGHT, TEST_LOCATION);
398     DALI_TEST_CHECK(NULL != map.Find("sensitive"));
399     DALI_TEST_EQUALS(map.Find("sensitive")->Get<bool>(), false, TEST_LOCATION);
400     DALI_TEST_CHECK(NULL != map.Find("leaveRequired"));
401     DALI_TEST_EQUALS(map.Find("leaveRequired")->Get<bool>(), true, TEST_LOCATION);
402     DALI_TEST_CHECK(NULL != map.Find("inheritOrientation"));
403     DALI_TEST_EQUALS(map.Find("inheritOrientation")->Get<bool>(), false, TEST_LOCATION);
404     DALI_TEST_CHECK(NULL != map.Find("inheritScale"));
405     DALI_TEST_EQUALS(map.Find("inheritScale")->Get<bool>(), false, TEST_LOCATION);
406     DALI_TEST_CHECK(NULL != map.Find("sizeModeFactor"));
407     DALI_TEST_EQUALS(map.Find("sizeModeFactor")->Get<Vector3>(), Vector3::ONE, TEST_LOCATION);
408
409     application.GetScene().Remove(actor);
410   }
411
412   // Children
413   {
414     Actor actor = Actor::New();
415     Actor child = Layer::New();
416     actor.Add(child);
417
418     application.GetScene().Add(actor);
419     application.SendNotification();
420     application.Render();
421
422     Property::Map map;
423     CreatePropertyMap(actor, map);
424     DALI_TEST_CHECK(!map.Empty());
425
426     DALI_TEST_CHECK(NULL != map.Find("type"));
427     DALI_TEST_EQUALS(map.Find("type")->Get<std::string>(), "Actor", TEST_LOCATION);
428
429     DALI_TEST_CHECK(NULL != map.Find("actors"));
430     Property::Array children(map.Find("actors")->Get<Property::Array>());
431     DALI_TEST_CHECK(!children.Empty());
432     Property::Map childMap(children[0].Get<Property::Map>());
433     DALI_TEST_CHECK(!childMap.Empty());
434     DALI_TEST_CHECK(childMap.Find("type"));
435     DALI_TEST_EQUALS(childMap.Find("type")->Get<std::string>(), "Layer", TEST_LOCATION);
436
437     application.GetScene().Remove(actor);
438   }
439   END_TEST;
440 }
441
442 int UtcDaliScriptingGetEnumerationTemplates(void)
443 {
444   const Scripting::StringEnum myTable[] =
445     {
446       {"ONE", 1},
447       {"TWO", 2},
448       {"THREE", 3},
449       {"FOUR", 4},
450       {"FIVE", 5},
451     };
452   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
453
454   for(unsigned int i = 0; i < myTableCount; ++i)
455   {
456     tet_printf("Checking: %s\n", myTable[i].string);
457     int value;
458     DALI_TEST_CHECK(GetEnumeration<int>(myTable[i].string, myTable, myTableCount, value));
459     DALI_TEST_EQUALS(myTable[i].value, value, TEST_LOCATION);
460   }
461
462   for(unsigned int i = 0; i < myTableCount; ++i)
463   {
464     tet_printf("Checking: %d\n", myTable[i].value);
465     DALI_TEST_EQUALS(myTable[i].string, GetEnumerationName(myTable[i].value, myTable, myTableCount), TEST_LOCATION);
466   }
467
468   END_TEST;
469 }
470
471 int UtcDaliScriptingGetEnumerationNameN(void)
472 {
473   const char* value = GetEnumerationName(10, NULL, 0);
474   DALI_TEST_CHECK(NULL == value);
475
476   value = GetEnumerationName(10, NULL, 1);
477   DALI_TEST_CHECK(NULL == value);
478
479   END_TEST;
480 }
481
482 int UtcDaliScriptingGetLinearEnumerationNameN(void)
483 {
484   const char* value = GetLinearEnumerationName(10, NULL, 0);
485   DALI_TEST_CHECK(NULL == value);
486
487   value = GetLinearEnumerationName(10, NULL, 1);
488   DALI_TEST_CHECK(NULL == value);
489
490   END_TEST;
491 }
492
493 int UtcDaliScriptingGetLinearEnumerationNameP(void)
494 {
495   const Scripting::StringEnum myTable[] =
496     {
497       {"ONE", 0},
498       {"TWO", 1},
499       {"THREE", 2},
500       {"FOUR", 3},
501       {"FIVE", 4},
502     };
503   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
504
505   for(uint32_t i = 0; i < myTableCount; ++i)
506   {
507     const char* value = GetLinearEnumerationName<int32_t>(static_cast<int32_t>(i), myTable, myTableCount);
508     // We know that myTable[i].string is result. But for make clear test, let we just iterate and found it
509     std::string expectName = "invalid";
510     for(uint32_t j = 0; j < myTableCount; ++j)
511     {
512       if(myTable[j].value == static_cast<int32_t>(i))
513       {
514         DALI_TEST_CHECK(i == j);
515         expectName = myTable[j].string;
516         break;
517       }
518     }
519     DALI_TEST_EQUALS(std::string(value), expectName, TEST_LOCATION);
520   }
521
522   // Invalid case check
523   {
524     const char* value = GetLinearEnumerationName<int32_t>(static_cast<int32_t>(myTableCount), myTable, myTableCount);
525     DALI_TEST_CHECK(NULL == value);
526   }
527   {
528     const char* value = GetLinearEnumerationName<int32_t>(-1, myTable, myTableCount);
529     DALI_TEST_CHECK(NULL == value);
530   }
531
532   END_TEST;
533 }
534
535 int UtcDaliScriptingGetEnumerationProperty(void)
536 {
537   /*
538    * This test function performs the following checks:
539    *  - An enum can be looked up from a Property::Value of type INTEGER.
540    *  - An enum can be looked up from a Property::Value of type STRING.
541    *  - An enum can NOT be looked up for other Property::Value types.
542    *  - The return value is "true" if the property can be successfully converted AND it has changed.
543    *  - The return value is "false" if the property can be successfully converted BUT it has NOT changed.
544    *  - The return value is "false" if the property can not be successfully converted.
545    *  - The result value is only updated if the return value is "true" (IE. successful conversion and property value has changed).
546    */
547
548   // String to Enum property table to test with (equivalent to ones used within DALi).
549   const Dali::Scripting::StringEnum testTable[] = {
550     {"NONE", FaceCullingMode::NONE},
551     {"FRONT", FaceCullingMode::FRONT},
552     {"BACK", FaceCullingMode::BACK},
553     {"FRONT_AND_BACK", FaceCullingMode::FRONT_AND_BACK}};
554   const unsigned int testTableCount = sizeof(testTable) / sizeof(testTable[0]);
555
556   // TEST: An enum can be looked up from a Property::Value of type INTEGER.
557   // Initialise to first element.
558   FaceCullingMode::Type result = FaceCullingMode::NONE;
559   // Set the input property value to a different value (to emulate a change).
560   Property::Value propertyValueInteger(FaceCullingMode::FRONT);
561
562   // Perform the lookup.
563   bool returnValue = GetEnumerationProperty<FaceCullingMode::Type>(propertyValueInteger, testTable, testTableCount, result);
564
565   // TEST: The return value is "true" if the property can be successfully converted AND it has changed
566   // Check the property could be converted.
567   DALI_TEST_CHECK(returnValue);
568
569   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::FRONT), TEST_LOCATION);
570
571   // Now emulate a property-set with the same value. false should be returned.
572   returnValue = GetEnumerationProperty<FaceCullingMode::Type>(propertyValueInteger, testTable, testTableCount, result);
573
574   // TEST: The return value is "false" if the property can be successfully converted BUT it has NOT changed.
575   DALI_TEST_CHECK(!returnValue);
576
577   // The result should remain the same.
578   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::FRONT), TEST_LOCATION);
579
580   // TEST: An enum can be looked up from a Property::Value of type STRING.
581   // Set the input property value to a different value (to emulate a change).
582   Property::Value propertyValueString("BACK");
583
584   returnValue = GetEnumerationProperty<FaceCullingMode::Type>(propertyValueString, testTable, testTableCount, result);
585
586   DALI_TEST_CHECK(returnValue);
587
588   // The result should remain the same.
589   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::BACK), TEST_LOCATION);
590
591   returnValue = GetEnumerationProperty<FaceCullingMode::Type>(propertyValueString, testTable, testTableCount, result);
592
593   DALI_TEST_CHECK(!returnValue);
594
595   // The result should remain the same.
596   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::BACK), TEST_LOCATION);
597
598   // TEST: An enum can NOT be looked up for other Property::Value types.
599   Property::Value propertyValueBoolean(true);
600
601   returnValue = GetEnumerationProperty<FaceCullingMode::Type>(propertyValueBoolean, testTable, testTableCount, result);
602
603   // TEST: The return value is "false" if the property can not be successfully converted.
604   // Return value should be false as Property::Value was of an unsupported type for enum properties.
605   DALI_TEST_CHECK(!returnValue);
606
607   // TEST: The result value is only updated if the return value is "true" (IE. successful conversion and property value has changed).
608   // The result should remain the same.
609   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::BACK), TEST_LOCATION);
610
611   END_TEST;
612 }
613
614 int UtcDaliScriptingGetBitmaskEnumerationProperty(void)
615 {
616   /*
617    * This test function performs the following checks:
618    *  - An enum can be looked up from a Property::Value of type INTEGER.
619    *  - An enum can be looked up from a Property::Value of type STRING.
620    *  - An enum can NOT be looked up from other Property::Value types.
621    *  - The return value is "true" if the property can be successfully converted AND it has changed.
622    *  - The return value is "false" if the property can not be successfully converted.
623    *  - The result value is only updated if the return value is "true" (IE. successful conversion and property value has changed).
624    *  PropertyArrays:
625    *  - The return value when checking an array with 2 INTEGERS is "true" if the properties can be successfully converted.
626    *  - The result value when checking an array with 2 INTEGERS is the ORd value of the 2 integers.
627    *  - The return value when checking an array with 2 STRINGS is "true" if the properties can be successfully converted.
628    *  - The result value when checking an array with 2 STRINGS is the ORd value of the 2 integer equivalents of the strings.
629    *  - The return value when checking an array with an INTEGER and a STRING is "true" if the properties can be successfully converted.
630    *  - The result value when checking an array with an INTEGER and a STRING is the ORd value of the 2 integer equivalents of the strings.
631    *  - The return value when checking an array with an INTEGER and a Vector3 is "false" as the properties can not be successfully converted.
632    *  - The result value when checking an array with an INTEGER and a Vector3 is unchanged.
633    */
634
635   // String to Enum property table to test with (equivalent to ones used within DALi).
636   const Dali::Scripting::StringEnum testTable[] = {
637     {"NONE", FaceCullingMode::NONE},
638     {"FRONT", FaceCullingMode::FRONT},
639     {"BACK", FaceCullingMode::BACK},
640     {"FRONT_AND_BACK", FaceCullingMode::FRONT_AND_BACK}};
641   const unsigned int testTableCount = sizeof(testTable) / sizeof(testTable[0]);
642
643   // TEST: An enum can be looked up from a Property::Value of type INTEGER.
644   // Initialise to first element.
645   FaceCullingMode::Type result = FaceCullingMode::NONE;
646   // Set the input property value to a different value (to emulate a change).
647   Property::Value propertyValueInteger(FaceCullingMode::FRONT);
648
649   // Perform the lookup.
650   bool returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyValueInteger, testTable, testTableCount, result);
651
652   // TEST: The return value is "true" if the property can be successfully converted AND it has changed
653   // Check the property could be converted.
654   DALI_TEST_CHECK(returnValue);
655
656   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::FRONT), TEST_LOCATION);
657
658   // TEST: An enum can be looked up from a Property::Value of type STRING.
659   // Set the input property value to a different value (to emulate a change).
660   Property::Value propertyValueString("BACK");
661
662   returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyValueString, testTable, testTableCount, result);
663
664   DALI_TEST_CHECK(returnValue);
665
666   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::BACK), TEST_LOCATION);
667
668   // TEST: An enum can NOT be looked up from other Property::Value types.
669   Property::Value propertyValueVector(Vector3::ZERO);
670
671   returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyValueVector, testTable, testTableCount, result);
672
673   // TEST: The return value is "false" if the property can not be successfully converted.
674   // Return value should be false as Property::Value was of an unsupported type for enum properties.
675   DALI_TEST_CHECK(!returnValue);
676
677   // TEST: The result value is only updated if the return value is "true" (IE. successful conversion and property value has changed).
678   // The result should remain the same.
679   DALI_TEST_EQUALS(static_cast<int>(result), static_cast<int>(FaceCullingMode::BACK), TEST_LOCATION);
680
681   // Test PropertyArrays:
682
683   // Property array of 2 integers.
684   Property::Array propertyArrayIntegers;
685   propertyArrayIntegers.PushBack(FaceCullingMode::FRONT);
686   propertyArrayIntegers.PushBack(FaceCullingMode::BACK);
687   result = FaceCullingMode::NONE;
688
689   returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyArrayIntegers, testTable, testTableCount, result);
690
691   // TEST: The return value when checking an array with 2 INTEGERS is "true" if the properties can be successfully converted.
692   DALI_TEST_CHECK(returnValue);
693   // TEST: The result value when checking an array with 2 INTEGERS is the ORd value of the 2 integers.
694   DALI_TEST_CHECK(result == (FaceCullingMode::FRONT | FaceCullingMode::BACK));
695
696   // Property array of 2 strings.
697   Property::Array propertyArrayStrings;
698   propertyArrayStrings.PushBack("FRONT");
699   propertyArrayStrings.PushBack("BACK");
700   result = FaceCullingMode::NONE;
701
702   returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyArrayStrings, testTable, testTableCount, result);
703
704   // TEST: The return value when checking an array with 2 STRINGS is "true" if the properties can be successfully converted.
705   DALI_TEST_CHECK(returnValue);
706   // TEST: The result value when checking an array with 2 STRINGS is the ORd value of the 2 integer equivalents of the strings.
707   DALI_TEST_CHECK(result == (FaceCullingMode::FRONT | FaceCullingMode::BACK));
708
709   // Property array of an int and a string.
710   Property::Array propertyArrayMixed;
711   propertyArrayMixed.PushBack(FaceCullingMode::FRONT);
712   propertyArrayMixed.PushBack("BACK");
713   result = FaceCullingMode::NONE;
714
715   returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyArrayMixed, testTable, testTableCount, result);
716
717   // TEST: The return value when checking an array with an INTEGER and a STRING is "true" if the properties can be successfully converted.
718   DALI_TEST_CHECK(returnValue);
719   // TEST: The result value when checking an array with an INTEGER and a STRING is the ORd value of the 2 integer equivalents of the strings.
720   DALI_TEST_CHECK(result == (FaceCullingMode::FRONT | FaceCullingMode::BACK));
721
722   // Property array of an int and a string.
723   Property::Array propertyArrayInvalid;
724   propertyArrayInvalid.PushBack(FaceCullingMode::FRONT);
725   propertyArrayInvalid.PushBack(Vector3::ZERO);
726
727   // Set the initial value to non-zero, so we can test it does not change.
728   result = FaceCullingMode::FRONT_AND_BACK;
729
730   returnValue = GetBitmaskEnumerationProperty<FaceCullingMode::Type>(propertyArrayInvalid, testTable, testTableCount, result);
731
732   // TEST: The return value when checking an array with an INTEGER and a Vector3 is "false" as the properties can not be successfully converted.
733   DALI_TEST_CHECK(!returnValue);
734   // TEST: The result value when checking an array with an INTEGER and a Vector3 is unchanged.
735   DALI_TEST_CHECK(result == FaceCullingMode::FRONT_AND_BACK);
736
737   END_TEST;
738 }
739
740 int UtcDaliScriptingFindEnumIndexN(void)
741 {
742   const Scripting::StringEnum myTable[] =
743     {
744       {"ONE", (1 << 1)},
745       {"TWO", (1 << 2)},
746       {"THREE", (1 << 3)},
747       {"FOUR", (1 << 4)},
748       {"FIVE", (1 << 5)},
749     };
750   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
751   DALI_TEST_EQUALS(myTableCount, FindEnumIndex("Foo", myTable, myTableCount), TEST_LOCATION);
752
753   END_TEST;
754 }
755
756 int UtcDaliScriptingEnumStringToIntegerP(void)
757 {
758   const Scripting::StringEnum myTable[] =
759     {
760       {"ONE", (1 << 1)},
761       {"TWO", (1 << 2)},
762       {"THREE", (1 << 3)},
763       {"FOUR", (1 << 4)},
764       {"FIVE", (1 << 5)},
765     };
766   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
767
768   int integerEnum = 0;
769   DALI_TEST_CHECK(EnumStringToInteger("ONE", myTable, myTableCount, integerEnum));
770
771   DALI_TEST_EQUALS(integerEnum, (1 << 1), TEST_LOCATION);
772
773   integerEnum = 0;
774   DALI_TEST_CHECK(EnumStringToInteger("ONE,TWO", myTable, myTableCount, integerEnum));
775   DALI_TEST_EQUALS(integerEnum, (1 << 1) | (1 << 2), TEST_LOCATION);
776
777   DALI_TEST_CHECK(EnumStringToInteger("ONE,,TWO", myTable, myTableCount, integerEnum));
778   DALI_TEST_EQUALS(integerEnum, (1 << 1) | (1 << 2), TEST_LOCATION);
779
780   DALI_TEST_CHECK(EnumStringToInteger("ONE,TWO,THREE", myTable, myTableCount, integerEnum));
781   DALI_TEST_EQUALS(integerEnum, (1 << 1) | (1 << 2) | (1 << 3), TEST_LOCATION);
782
783   DALI_TEST_CHECK(EnumStringToInteger("ONE,TWO,THREE,FOUR,FIVE", myTable, myTableCount, integerEnum));
784   DALI_TEST_EQUALS(integerEnum, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5), TEST_LOCATION);
785
786   DALI_TEST_CHECK(EnumStringToInteger("TWO,ONE", myTable, myTableCount, integerEnum));
787   DALI_TEST_EQUALS(integerEnum, (1 << 1) | (1 << 2), TEST_LOCATION);
788
789   DALI_TEST_CHECK(EnumStringToInteger("TWO,ONE,FOUR,THREE,FIVE", myTable, myTableCount, integerEnum));
790   DALI_TEST_EQUALS(integerEnum, (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5), TEST_LOCATION);
791
792   DALI_TEST_CHECK(EnumStringToInteger("ONE,SEVEN", myTable, myTableCount, integerEnum));
793   DALI_TEST_EQUALS(integerEnum, (1 << 1), TEST_LOCATION);
794
795   DALI_TEST_CHECK(EnumStringToInteger("ONE,", myTable, myTableCount, integerEnum));
796   DALI_TEST_EQUALS(integerEnum, (1 << 1), TEST_LOCATION);
797
798   END_TEST;
799 }
800
801 int UtcDaliScriptingEnumStringToIntegerN(void)
802 {
803   const Scripting::StringEnum myTable[] =
804     {
805       {"ONE", 1},
806       {"TWO", 2},
807       {"THREE", 3},
808       {"FOUR", 4},
809       {"FIVE", 5},
810     };
811   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
812
813   int integerEnum = 0;
814   DALI_TEST_CHECK(!EnumStringToInteger("Foo", myTable, myTableCount, integerEnum));
815
816   DALI_TEST_CHECK(!EnumStringToInteger("", myTable, myTableCount, integerEnum));
817
818   DALI_TEST_CHECK(!EnumStringToInteger(",", myTable, myTableCount, integerEnum));
819
820   DALI_TEST_CHECK(!EnumStringToInteger(",ONE,SEVEN", myTable, myTableCount, integerEnum));
821
822   DALI_TEST_CHECK(!EnumStringToInteger(",", myTable, myTableCount, integerEnum));
823
824   DALI_TEST_CHECK(!EnumStringToInteger("ONE", myTable, 0, integerEnum));
825
826   DALI_TEST_EQUALS(integerEnum, 0, TEST_LOCATION);
827
828   END_TEST;
829 }
830
831 int UtcDaliScriptingEnumStringToIntegerInvalidEnumP(void)
832 {
833   const Scripting::StringEnum myTable[] =
834     {
835       {"", 1},
836       {"", 2},
837       {"", 3},
838     };
839
840   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
841
842   int integerEnum = 0;
843   DALI_TEST_CHECK(EnumStringToInteger("", myTable, myTableCount, integerEnum));
844   DALI_TEST_EQUALS(integerEnum, 1, TEST_LOCATION);
845
846   END_TEST;
847 }
848
849 int UtcDaliScriptingEnumStringToIntegerInvalidEnumN(void)
850 {
851   const Scripting::StringEnum myTable[] =
852     {
853       {"", 1},
854       {"", 1},
855       {"", 1},
856     };
857
858   const unsigned int myTableCount = sizeof(myTable) / sizeof(myTable[0]);
859
860   int integerEnum = 0;
861   DALI_TEST_CHECK(!EnumStringToInteger(NULL, NULL, 0, integerEnum));
862
863   DALI_TEST_CHECK(!EnumStringToInteger("ONE", NULL, 0, integerEnum));
864
865   DALI_TEST_CHECK(!EnumStringToInteger(NULL, myTable, 0, integerEnum));
866
867   DALI_TEST_CHECK(!EnumStringToInteger(NULL, myTable, myTableCount, integerEnum));
868
869   DALI_TEST_CHECK(!EnumStringToInteger("ONE", NULL, myTableCount, integerEnum));
870
871   DALI_TEST_EQUALS(integerEnum, 0, TEST_LOCATION);
872
873   END_TEST;
874 }