Make Dali::InstrusivePtr able to compare with nullptr
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-BaseHandle.cpp
1 /*
2  * Copyright (c) 2022 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/integration-api/events/touch-event-integ.h>
19 #include <dali/public-api/dali-core.h>
20 #include <stdlib.h>
21
22 #include <iostream>
23
24 #include "dali-test-suite-utils/dali-test-suite-utils.h"
25
26 using namespace Dali;
27
28 void utc_base_handle_startup(void)
29 {
30   test_return_value = TET_UNDEF;
31 }
32
33 // Called after each test
34 void utc_base_handle_cleanup(void)
35 {
36   test_return_value = TET_PASS;
37 }
38
39 namespace
40 {
41 // Functor to test whether an animation finish signal is emitted
42 struct AnimationFinishCheck
43 {
44   AnimationFinishCheck(bool& signalReceived)
45   : mSignalReceived(signalReceived)
46   {
47   }
48
49   void operator()()
50   {
51     mSignalReceived = true;
52   }
53
54   void Reset()
55   {
56     mSignalReceived = false;
57   }
58
59   void CheckSignalReceived()
60   {
61     if(!mSignalReceived)
62     {
63       tet_printf("Expected Finish signal was not received\n");
64       tet_result(TET_FAIL);
65     }
66     else
67     {
68       tet_result(TET_PASS);
69     }
70   }
71
72   bool& mSignalReceived; // owned by individual tests
73 };
74
75 BaseHandle ImplicitCopyConstructor(BaseHandle passedByValue)
76 {
77   // object + copy + passedByValue, ref count == 3
78   DALI_TEST_CHECK(passedByValue);
79   if(passedByValue)
80   {
81     DALI_TEST_EQUALS(3, passedByValue.GetBaseObject().ReferenceCount(), TEST_LOCATION);
82   }
83
84   return passedByValue;
85 }
86
87 static bool gTouchCallBackCalled;
88
89 struct TestCallback
90 {
91   void operator()()
92   {
93     gTouchCallBackCalled = true;
94   }
95 };
96
97 // Used for testing BaseObject::GetTypeName with an object that is not registered
98 class FakeObject : public BaseObject
99 {
100 };
101 } // namespace
102
103 int UtcDaliBaseHandleConstructorVoid(void)
104 {
105   TestApplication application;
106   tet_infoline("Testing Dali::BaseHandle::BaseHandle()");
107
108   BaseHandle object;
109
110   DALI_TEST_CHECK(!object);
111   END_TEST;
112 }
113
114 int UtcDaliBaseHandleCopyConstructor(void)
115 {
116   TestApplication application;
117   tet_infoline("Testing Dali::BaseHandle::BaseHandle(const BaseHandle&)");
118
119   // Initialize an object, ref count == 1
120   BaseHandle object = Actor::New();
121
122   DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
123
124   // Copy the object, ref count == 2
125   BaseHandle copy(object);
126   DALI_TEST_CHECK(copy);
127   if(copy)
128   {
129     DALI_TEST_EQUALS(2, copy.GetBaseObject().ReferenceCount(), TEST_LOCATION);
130   }
131
132   {
133     // Pass by value, and return another copy, ref count == 3
134     BaseHandle anotherCopy = ImplicitCopyConstructor(copy);
135
136     DALI_TEST_CHECK(anotherCopy);
137     if(anotherCopy)
138     {
139       DALI_TEST_EQUALS(3, anotherCopy.GetBaseObject().ReferenceCount(), TEST_LOCATION);
140     }
141   }
142
143   // anotherCopy out of scope, ref count == 2
144   DALI_TEST_CHECK(copy);
145   if(copy)
146   {
147     DALI_TEST_EQUALS(2, copy.GetBaseObject().ReferenceCount(), TEST_LOCATION);
148   }
149   END_TEST;
150 }
151
152 int UtcDaliBaseHandleAssignmentOperator(void)
153 {
154   TestApplication application;
155   tet_infoline("Testing Dali::BaseHandle::operator=");
156
157   BaseHandle object = Actor::New();
158
159   DALI_TEST_CHECK(object);
160   if(object)
161   {
162     DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
163   }
164
165   BaseHandle copy = object;
166
167   DALI_TEST_CHECK(copy);
168   if(copy)
169   {
170     DALI_TEST_EQUALS(2, copy.GetBaseObject().ReferenceCount(), TEST_LOCATION);
171   }
172   END_TEST;
173 }
174
175 int UtcDaliBaseHandleMoveConstructor(void)
176 {
177   TestApplication application;
178
179   // Initialize an object, ref count == 1
180   BaseHandle object = Actor::New();
181
182   DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
183
184   // Move the object, ref count == 1
185   BaseHandle move = std::move(object);
186   DALI_TEST_CHECK(move);
187
188   // Check that object is moved (not copied, so ref count keeps the same)
189   if(move)
190   {
191     DALI_TEST_EQUALS(1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION);
192   }
193   DALI_TEST_CHECK(!object);
194
195   END_TEST;
196 }
197
198 int UtcDaliBaseHandleMoveAssignment(void)
199 {
200   TestApplication application;
201
202   // Initialize an object, ref count == 1
203   BaseHandle object = Actor::New();
204
205   DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
206
207   // Move the object, ref count == 1
208   BaseHandle move;
209   move = std::move(object);
210   DALI_TEST_CHECK(move);
211
212   // Check that object is moved (not copied, so ref count keeps the same)
213   if(move)
214   {
215     DALI_TEST_EQUALS(1, move.GetBaseObject().ReferenceCount(), TEST_LOCATION);
216   }
217   DALI_TEST_CHECK(!object);
218
219   END_TEST;
220 }
221
222 int UtcDaliBaseHandleGetBaseObject(void)
223 {
224   TestApplication application;
225   tet_infoline("Testing Dali::BaseHandle::GetBaseObject()");
226
227   BaseHandle object = Actor::New();
228
229   BaseObject& handle = object.GetBaseObject();
230
231   DALI_TEST_EQUALS(1, handle.ReferenceCount(), TEST_LOCATION);
232   END_TEST;
233 }
234
235 int UtcDaliBaseHandleReset(void)
236 {
237   TestApplication application;
238   tet_infoline("Testing Dali::BaseHandle::Reset()");
239
240   // Initialize an object, ref count == 1
241   BaseHandle object = Actor::New();
242
243   DALI_TEST_EQUALS(1, object.GetBaseObject().ReferenceCount(), TEST_LOCATION);
244
245   object.Reset();
246
247   DALI_TEST_CHECK(!object);
248   END_TEST;
249 }
250
251 int UtcDaliBaseHandleEqualityOperator01(void)
252 {
253   TestApplication application;
254   tet_infoline("Positive Test Dali::BaseHandle::operator==");
255
256   BaseHandle object = Actor::New();
257
258   DALI_TEST_CHECK(object);
259
260   BaseHandle theSameBaseHandle = object;
261
262   DALI_TEST_CHECK(object == theSameBaseHandle);
263   END_TEST;
264 }
265
266 int UtcDaliBaseHandleEqualityOperator02(void)
267 {
268   TestApplication application;
269   tet_infoline("Negative Test Dali::BaseHandle::operator==");
270
271   BaseHandle object = Actor::New();
272
273   DALI_TEST_CHECK(object);
274
275   BaseHandle aDifferentBaseHandle = Actor::New();
276
277   DALI_TEST_CHECK(!(object == aDifferentBaseHandle));
278   END_TEST;
279 }
280
281 int UtcDaliBaseHandleInequalityOperator01(void)
282 {
283   TestApplication application;
284   tet_infoline("Positive Test Dali::BaseHandle::operator!=");
285
286   BaseHandle object = Actor::New();
287
288   DALI_TEST_CHECK(object);
289
290   BaseHandle aDifferentBaseHandle = Actor::New();
291
292   DALI_TEST_CHECK(object != aDifferentBaseHandle);
293   END_TEST;
294 }
295
296 int UtcDaliBaseHandleInequalityOperator02(void)
297 {
298   TestApplication application;
299   tet_infoline("Negative Test Dali::BaseHandle::operator!=");
300
301   BaseHandle object = Actor::New();
302
303   DALI_TEST_CHECK(object);
304
305   BaseHandle theSameBaseHandle = object;
306
307   DALI_TEST_CHECK(!(object != theSameBaseHandle));
308   END_TEST;
309 }
310
311 int UtcDaliBaseHandleInequalityWithNullptr(void)
312 {
313   TestApplication application;
314   tet_infoline("Test for Dali::BaseHandle::operator == nullptr");
315
316   BaseHandle object;
317
318   // object is nullptr.
319   DALI_TEST_CHECK(object == nullptr);
320   DALI_TEST_CHECK(nullptr == object);
321   DALI_TEST_CHECK(!(object != nullptr));
322   DALI_TEST_CHECK(!(nullptr != object));
323
324   object = Actor::New();
325
326   // object is not nullptr.
327   DALI_TEST_CHECK(!(object == nullptr));
328   DALI_TEST_CHECK(!(nullptr == object));
329   DALI_TEST_CHECK(object != nullptr);
330   DALI_TEST_CHECK(nullptr != object);
331
332   END_TEST;
333 }
334
335 int UtcDaliBaseHandleStlVector(void)
336 {
337   TestApplication application;
338   tet_infoline("Testing Dali::BaseHandle compatibility with std::vector");
339
340   const int TargetVectorSize(5);
341
342   std::vector<Actor> myVector;
343
344   for(int i = 0; i < TargetVectorSize; ++i)
345   {
346     Actor actor = Actor::New();
347
348     std::stringstream stream;
349     stream << "Actor " << i + 1;
350     actor.SetProperty(Actor::Property::NAME, stream.str());
351
352     myVector.push_back(actor);
353   }
354
355   DALI_TEST_EQUALS(TargetVectorSize, static_cast<int>(myVector.size()), TEST_LOCATION);
356
357   DALI_TEST_CHECK(myVector[0].GetProperty<std::string>(Actor::Property::NAME) == "Actor 1");
358   DALI_TEST_CHECK(myVector[1].GetProperty<std::string>(Actor::Property::NAME) == "Actor 2");
359   DALI_TEST_CHECK(myVector[2].GetProperty<std::string>(Actor::Property::NAME) == "Actor 3");
360   DALI_TEST_CHECK(myVector[3].GetProperty<std::string>(Actor::Property::NAME) == "Actor 4");
361   DALI_TEST_CHECK(myVector[4].GetProperty<std::string>(Actor::Property::NAME) == "Actor 5");
362   END_TEST;
363 }
364
365 int UtcDaliBaseHandleDoAction(void)
366 {
367   TestApplication application;
368   tet_infoline("Positive Test Dali::BaseHandle::UtcDaliBaseHandleDoAction");
369
370   Actor      actor       = Actor::New();
371   BaseHandle actorObject = actor;
372
373   DALI_TEST_CHECK(actorObject);
374
375   // Check that an invalid command is not performed
376   Property::Map attributes;
377   DALI_TEST_CHECK(actorObject.DoAction("invalidCommand", attributes) == false);
378
379   // Check that the actor is visible
380   actor.SetProperty(Actor::Property::VISIBLE, true);
381   DALI_TEST_CHECK(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == true);
382
383   // Check the actor performed an action to hide itself
384   DALI_TEST_CHECK(actorObject.DoAction("hide", attributes) == true);
385
386   // flush the queue and render once
387   application.SendNotification();
388   application.Render();
389
390   // Check that the actor is now invisible
391   DALI_TEST_CHECK(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == false);
392
393   // Check the actor performed an action to show itself
394   DALI_TEST_CHECK(actorObject.DoAction("show", attributes) == true);
395
396   // flush the queue and render once
397   application.SendNotification();
398   application.Render();
399
400   // Check that the actor is now visible
401   DALI_TEST_CHECK(actor.GetCurrentProperty<bool>(Actor::Property::VISIBLE) == true);
402
403   application.GetScene().Add(actor);
404
405   // Build an animation with initial duration of 1 second
406   float      durationSeconds(1.0f);
407   Animation  animation       = Animation::New(durationSeconds);
408   BaseHandle animationObject = animation;
409
410   DALI_TEST_CHECK(animationObject);
411
412   // Check the current animation duration is 1 second
413   DALI_TEST_EQUALS(animation.GetDuration(), durationSeconds, TEST_LOCATION);
414
415   Vector3 targetPosition(100.0f, 100.0f, 100.0f);
416   animation.AnimateTo(Property(actor, Actor::Property::POSITION), targetPosition, AlphaFunction::LINEAR);
417
418   // Set the new duration to be 2 seconds
419   float           newDurationSeconds(2.0f);
420   Property::Value newDurationSecondsValue = Property::Value(newDurationSeconds);
421   attributes["duration"]                  = newDurationSecondsValue;
422
423   // Check the animation performed an action to play itself with the specified duration of 2 seconds
424   animationObject.DoAction("play", attributes);
425
426   bool                 signalReceived(false);
427   AnimationFinishCheck finishCheck(signalReceived);
428   // use the handle API to connect the signal
429   animation.ConnectSignal(&application, "finished", finishCheck);
430   // just for coverage connect to non-existant signal as well
431   animation.ConnectSignal(&application, "foo", finishCheck);
432   DALI_TEST_EQUALS(signalReceived, false, TEST_LOCATION);
433
434   application.SendNotification();
435   application.Render(static_cast<uint32_t>(newDurationSeconds * 500.0f) /* half of time */);
436   DALI_TEST_EQUALS(signalReceived, false, TEST_LOCATION);
437
438   // pause
439   animationObject.DoAction("pause", attributes);
440   application.SendNotification();
441   application.Render(static_cast<uint32_t>(newDurationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
442   DALI_TEST_EQUALS(signalReceived, false, TEST_LOCATION);
443
444   // continue
445   animationObject.DoAction("play", attributes);
446   application.SendNotification();
447   application.Render(static_cast<uint32_t>(newDurationSeconds * 500.0f) + 1u /*just beyond the animation duration*/);
448
449   // We expect the animation to finish
450   application.SendNotification();
451   finishCheck.CheckSignalReceived();
452   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), targetPosition, TEST_LOCATION);
453
454   // play again
455   signalReceived = false;
456   animationObject.DoAction("play", attributes);
457   DALI_TEST_EQUALS(animation.GetCurrentProgress(), 0.f, TEST_LOCATION);
458   application.SendNotification();
459   application.Render(static_cast<uint32_t>(newDurationSeconds * 500.0f) /* half of time */);
460   animationObject.DoAction("stop", attributes);
461   application.SendNotification();
462   application.Render(static_cast<uint32_t>(newDurationSeconds * 1000.0f) /* full time */);
463   DALI_TEST_EQUALS(signalReceived, false, TEST_LOCATION);
464
465   // Check the new animation duration is 2 seconds
466   DALI_TEST_EQUALS(animation.GetDuration(), newDurationSeconds, TEST_LOCATION);
467   END_TEST;
468 }
469
470 int UtcDaliBaseHandleConnectSignal(void)
471 {
472   TestApplication application;
473   tet_infoline("Testing Dali::BaseHandle::ConnectSignal");
474
475   gTouchCallBackCalled = false;
476
477   // get the root layer
478   Actor actor = Actor::New();
479   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
480   actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
481   actor.SetProperty(Actor::Property::POSITION, Vector2(240, 400));
482   actor.SetProperty(Actor::Property::SIZE, Vector2(100, 100));
483
484   application.GetScene().Add(actor);
485
486   DALI_TEST_CHECK(gTouchCallBackCalled == false);
487
488   // connect to its touch signal
489   actor.ConnectSignal(&application, "touched", TestCallback());
490
491   application.SendNotification();
492   application.Render(1000);
493   application.SendNotification();
494   application.Render(1000);
495
496   // simulate a touch event
497   Dali::Integration::Point point;
498   point.SetState(PointState::DOWN);
499   point.SetScreenPosition(Vector2(240, 400));
500   Dali::Integration::TouchEvent event;
501   event.AddPoint(point);
502   application.ProcessEvent(event);
503
504   application.SendNotification();
505   application.Render(1000);
506   application.SendNotification();
507   application.Render(1000);
508
509   DALI_TEST_CHECK(application.GetConnectionCount() > 0);
510   DALI_TEST_CHECK(gTouchCallBackCalled == true);
511
512   gTouchCallBackCalled = false;
513   application.DisconnectAll();
514
515   // simulate another touch event
516   application.ProcessEvent(event);
517
518   DALI_TEST_CHECK(gTouchCallBackCalled == false);
519   END_TEST;
520 }
521
522 int UtcDaliBaseHandleGetTypeNameP(void)
523 {
524   TestApplication application;
525   tet_infoline("Testing Dali::BaseHandle::GetTypeName");
526
527   // get the root layer
528   Actor actor = Actor::New();
529
530   std::string typeName = actor.GetTypeName();
531
532   DALI_TEST_CHECK(typeName.size());
533   DALI_TEST_CHECK(typeName == std::string("Actor"));
534   END_TEST;
535 }
536
537 int UtcDaliBaseHandleGetTypeNameN(void)
538 {
539   TestApplication application;
540   tet_infoline("Testing Dali::BaseObject::GetTypeName");
541   FakeObject  object;
542   std::string typeName = object.GetTypeName();
543
544   DALI_TEST_CHECK(typeName.empty());
545   END_TEST;
546 }
547
548 int UtcDaliBaseHandleGetTypeInfoP(void)
549 {
550   TestApplication application;
551   tet_infoline("Testing Dali::BaseHandle::GetTypeInfo");
552
553   Dali::TypeInfo info;
554   Actor          actor = Actor::New();
555
556   bool ok = actor.GetTypeInfo(info);
557   DALI_TEST_CHECK(ok);
558   END_TEST;
559 }
560
561 int UtcDaliBaseHandleGetTypeInfoN(void)
562 {
563   TestApplication application;
564   tet_infoline("Testing Dali::BaseHandle::GetTypeInfo");
565
566   Dali::TypeInfo info;
567   FakeObject     object;
568
569   bool ok = object.GetTypeInfo(info);
570   DALI_TEST_CHECK(!ok);
571   END_TEST;
572 }
573
574 int UtcDaliBaseHandleGetObjectPtr(void)
575 {
576   TestApplication application;
577   tet_infoline("Testing Dali::BaseHandle::GetObjectPtr");
578
579   // get the root layer
580   Actor actor = Actor::New();
581
582   Dali::RefObject* p = actor.GetObjectPtr();
583
584   DALI_TEST_CHECK(p != NULL);
585   END_TEST;
586 }
587
588 int UtcDaliBaseHandleBooleanCast(void)
589 {
590   TestApplication application;
591   tet_infoline("Testing Dali::BaseHandle::operator bool");
592
593   // get the root layer
594   BaseHandle handle = Actor::New();
595
596   DALI_TEST_CHECK(static_cast<bool>(handle));
597   END_TEST;
598 }
599
600 int UtcDaliBaseHandleCompareOperatorN(void)
601 {
602   TestApplication application;
603   BaseHandle      handle1 = Actor::New();
604   BaseHandle      handle2 = handle1;
605
606   DALI_TEST_CHECK((handle1 < handle2) == false);
607
608   END_TEST;
609 }
610
611 int UtcDaliBaseHandleDoActionNegative(void)
612 {
613   TestApplication  application;
614   Dali::BaseHandle instance;
615   try
616   {
617     std::string         arg1;
618     Dali::Property::Map arg2;
619     instance.DoAction(arg1, arg2);
620     DALI_TEST_CHECK(false); // Should not get here
621   }
622   catch(...)
623   {
624     DALI_TEST_CHECK(true); // We expect an assert
625   }
626   END_TEST;
627 }
628
629 int UtcDaliBaseHandleGetTypeInfoNegative(void)
630 {
631   TestApplication  application;
632   Dali::BaseHandle instance;
633   try
634   {
635     Dali::TypeInfo arg1;
636     instance.GetTypeInfo(arg1);
637     DALI_TEST_CHECK(false); // Should not get here
638   }
639   catch(...)
640   {
641     DALI_TEST_CHECK(true); // We expect an assert
642   }
643   END_TEST;
644 }
645
646 int UtcDaliBaseHandleGetTypeNameNegative(void)
647 {
648   TestApplication  application;
649   Dali::BaseHandle instance;
650   try
651   {
652     instance.GetTypeName();
653     DALI_TEST_CHECK(false); // Should not get here
654   }
655   catch(...)
656   {
657     DALI_TEST_CHECK(true); // We expect an assert
658   }
659   END_TEST;
660 }