Merge branch 'devel/master' into tizen
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Constraint.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-test-suite-utils.h>
19 #include <dali/public-api/dali-core.h>
20 #include <stdlib.h>
21
22 #include <iostream>
23
24 using namespace Dali;
25
26 ///////////////////////////////////////////////////////////////////////////////
27 void utc_dali_constraint_startup(void)
28 {
29   test_return_value = TET_UNDEF;
30 }
31
32 void utc_dali_constraint_cleanup(void)
33 {
34   test_return_value = TET_PASS;
35 }
36 ///////////////////////////////////////////////////////////////////////////////
37
38 ///////////////////////////////////////////////////////////////////////////////
39 namespace
40 {
41 /**
42  * A function to use for a constraint, no data collected.
43  */
44 template<typename T>
45 void BasicFunction(T& /* current */, const PropertyInputContainer& /* inputs */)
46 {
47 }
48
49 /**
50  * A functor which sets a given boolean when the functor is called.
51  */
52 template<typename T>
53 struct BasicCalledFunctor
54 {
55   BasicCalledFunctor(bool& functorCalled)
56   : mCalled(functorCalled)
57   {
58   }
59
60   void operator()(T& /* current */, const PropertyInputContainer& /* inputs */)
61   {
62     mCalled = true;
63   }
64
65   bool& mCalled;
66 };
67
68 /**
69  * A functor which increments a given integer when the functor is called.
70  */
71 template<typename T>
72 struct CalledCountFunctor
73 {
74   CalledCountFunctor(int& callCount)
75   : mCallCount(callCount)
76   {
77   }
78
79   void operator()(T& /* current */, const PropertyInputContainer& /* inputs */)
80   {
81     ++mCallCount;
82   }
83
84   int& mCallCount;
85 };
86
87 /**
88  * A functor which sets the given value as the value required when the functor is called.
89  */
90 template<typename T>
91 struct SetValueFunctor
92 {
93   SetValueFunctor(const T& value)
94   : mValue(value)
95   {
96   }
97
98   void operator()(T& current, const PropertyInputContainer& /* inputs */)
99   {
100     current = mValue;
101   }
102
103   T mValue;
104 };
105
106 } // unnamed namespace
107 ///////////////////////////////////////////////////////////////////////////////
108
109 ///////////////////////////////////////////////////////////////////////////////
110 // Constraint::New(
111 //   Handle,
112 //   Property::Index,
113 //   void( *function )( T&, const PropertyInputContainer& ) )
114 ///////////////////////////////////////////////////////////////////////////////
115 namespace UtcDaliConstraintNewFunction
116 {
117 bool gConstraintFunctionCalled = false;
118 void ConstraintFunction(Vector3& /* current */, const PropertyInputContainer& /* inputs */)
119 {
120   gConstraintFunctionCalled = true;
121 }
122 } // namespace UtcDaliConstraintNewFunction
123
124 int UtcDaliConstraintNewFunctionP(void)
125 {
126   // Ensure that we can create a constraint using a C function and that it is called.
127
128   TestApplication application;
129   UtcDaliConstraintNewFunction::gConstraintFunctionCalled = false;
130
131   Actor actor = Actor::New();
132   application.GetScene().Add(actor);
133
134   application.SendNotification();
135   application.Render();
136
137   DALI_TEST_EQUALS(UtcDaliConstraintNewFunction::gConstraintFunctionCalled, false, TEST_LOCATION);
138
139   // Add a constraint
140   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &UtcDaliConstraintNewFunction::ConstraintFunction);
141   DALI_TEST_CHECK(constraint);
142   constraint.Apply();
143
144   application.SendNotification();
145   application.Render();
146
147   DALI_TEST_EQUALS(UtcDaliConstraintNewFunction::gConstraintFunctionCalled, true, TEST_LOCATION);
148
149   END_TEST;
150 }
151
152 int UtcDaliConstraintNewFunctionN(void)
153 {
154   // Create a constraint with an uninitialised handle
155
156   TestApplication application;
157
158   // Add a constraint with an uninitialised handle
159   try
160   {
161     Constraint constraint = Constraint::New<Vector3>(Actor(), Actor::Property::POSITION, &UtcDaliConstraintNewFunction::ConstraintFunction);
162     DALI_TEST_CHECK(false); // Should not reach here
163   }
164   catch(...)
165   {
166     DALI_TEST_CHECK(true); // Should assert!
167   }
168
169   END_TEST;
170 }
171
172 // helper for next test
173 void StringConstraintFunction(std::string& /* current */, const PropertyInputContainer& /* inputs */)
174 {
175 }
176
177 int UtcDaliConstraintNewFunctionNonConstrainableTypeN(void)
178 {
179   // Ensure that we can create a constraint using a C function and that it is called.
180
181   TestApplication application;
182   UtcDaliConstraintNewFunction::gConstraintFunctionCalled = false;
183
184   Actor actor = Actor::New();
185   application.GetScene().Add(actor);
186
187   application.SendNotification();
188   application.Render();
189
190   try
191   {
192     // Add a constraint
193     Constraint constraint = Constraint::New<std::string>(actor, Actor::Property::COLOR_MODE, &StringConstraintFunction);
194     DALI_TEST_CHECK(constraint);
195     constraint.Apply();
196     tet_result(TET_FAIL);
197   }
198   catch(Dali::DaliException& e)
199   {
200     DALI_TEST_ASSERT(e, "Property not constrainable", TEST_LOCATION);
201   }
202
203   END_TEST;
204 }
205
206 ///////////////////////////////////////////////////////////////////////////////
207
208 ///////////////////////////////////////////////////////////////////////////////
209 // Constraint::New(
210 //   Handle,
211 //   Property::Index,
212 //   const T& object )
213 ///////////////////////////////////////////////////////////////////////////////
214 int UtcDaliConstraintNewFunctorP(void)
215 {
216   // Ensure that we can create a constraint using a functor and that it is called.
217
218   TestApplication application;
219   bool            functorCalled = false;
220
221   Actor actor = Actor::New();
222   application.GetScene().Add(actor);
223
224   application.SendNotification();
225   application.Render();
226
227   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
228
229   // Add a constraint
230   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, BasicCalledFunctor<Vector3>(functorCalled));
231   DALI_TEST_CHECK(constraint);
232   constraint.Apply();
233
234   application.SendNotification();
235   application.Render();
236
237   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
238
239   END_TEST;
240 }
241
242 int UtcDaliConstraintNewFunctorN(void)
243 {
244   // Create a constraint with an uninitialised handle
245
246   TestApplication application;
247   bool            functorCalled = false;
248
249   // Add a constraint with an uninitialised handle
250   try
251   {
252     Constraint constraint = Constraint::New<Vector3>(Actor(), Actor::Property::POSITION, BasicCalledFunctor<Vector3>(functorCalled));
253     DALI_TEST_CHECK(false); // Should not reach here
254   }
255   catch(...)
256   {
257     DALI_TEST_CHECK(true); // Should assert!
258   }
259
260   END_TEST;
261 }
262
263 ///////////////////////////////////////////////////////////////////////////////
264
265 ///////////////////////////////////////////////////////////////////////////////
266 // Constraint::New(
267 //   Handle,
268 //   Property::Index,
269 //   const T& object,
270 //   void ( T::*memberFunction ) ( P&, const PropertyInputContainer& ) )
271 ///////////////////////////////////////////////////////////////////////////////
272 namespace UtcDaliConstraintNewFunctorMember
273 {
274 struct Functor
275 {
276   Functor(bool& positionCalled, bool& scaleCalled)
277   : mPositionCalled(positionCalled),
278     mScaleCalled(scaleCalled)
279   {
280   }
281
282   void Position(Vector3& /* current */, const PropertyInputContainer& /* inputs */)
283   {
284     mPositionCalled = true;
285   }
286
287   void Scale(Vector3& /* current */, const PropertyInputContainer& /* inputs */)
288   {
289     mScaleCalled = true;
290   }
291
292   bool& mPositionCalled;
293   bool& mScaleCalled;
294 };
295 } // namespace UtcDaliConstraintNewFunctorMember
296
297 int UtcDaliConstraintNewFunctorMemberP(void)
298 {
299   // Ensure that we can create a constraint using a functor and that it is called.
300
301   TestApplication application;
302   bool            positionFunctorCalled = false;
303   bool            sizeFunctorCalled     = false;
304
305   Actor actor = Actor::New();
306   application.GetScene().Add(actor);
307
308   application.SendNotification();
309   application.Render();
310
311   DALI_TEST_EQUALS(positionFunctorCalled, false, TEST_LOCATION);
312   DALI_TEST_EQUALS(sizeFunctorCalled, false, TEST_LOCATION);
313
314   // Add a constraint that calls Functor::Position
315   Constraint constraint = Constraint::New<Vector3>(
316     actor,
317     Actor::Property::POSITION,
318     UtcDaliConstraintNewFunctorMember::Functor(positionFunctorCalled, sizeFunctorCalled),
319     &UtcDaliConstraintNewFunctorMember::Functor::Position);
320   DALI_TEST_CHECK(constraint);
321   constraint.Apply();
322
323   application.SendNotification();
324   application.Render();
325
326   DALI_TEST_EQUALS(positionFunctorCalled, true, TEST_LOCATION);
327   DALI_TEST_EQUALS(sizeFunctorCalled, false, TEST_LOCATION);
328
329   // Add another constraint that calls Functor::Size
330   Constraint constraint2 = Constraint::New<Vector3>(
331     actor,
332     Actor::Property::SCALE,
333     UtcDaliConstraintNewFunctorMember::Functor(positionFunctorCalled, sizeFunctorCalled),
334     &UtcDaliConstraintNewFunctorMember::Functor::Scale);
335   DALI_TEST_CHECK(constraint2);
336   constraint2.Apply();
337
338   application.SendNotification();
339   application.Render();
340
341   DALI_TEST_EQUALS(positionFunctorCalled, true, TEST_LOCATION);
342   DALI_TEST_EQUALS(sizeFunctorCalled, true, TEST_LOCATION);
343
344   END_TEST;
345 }
346
347 int UtcDaliConstraintNewFunctorMemberN(void)
348 {
349   // Create a constraint with an uninitialised handle
350
351   TestApplication application;
352   bool            positionFunctorCalled = false;
353   bool            sizeFunctorCalled     = false;
354
355   // Add a constraint with an uninitialised handle
356   try
357   {
358     Constraint constraint = Constraint::New<Vector3>(
359       Actor(),
360       Actor::Property::POSITION,
361       UtcDaliConstraintNewFunctorMember::Functor(positionFunctorCalled, sizeFunctorCalled),
362       &UtcDaliConstraintNewFunctorMember::Functor::Position);
363     DALI_TEST_CHECK(false); // Should not reach here
364   }
365   catch(Dali::DaliException& e)
366   {
367     DALI_TEST_CHECK(true); // Should assert!
368   }
369
370   END_TEST;
371 }
372 ///////////////////////////////////////////////////////////////////////////////
373
374 ///////////////////////////////////////////////////////////////////////////////
375 // Constraint::Clone
376 ///////////////////////////////////////////////////////////////////////////////
377 int UtcDaliConstraintCloneP(void)
378 {
379   // Ensure we can clone for another actor and it's called appropriately
380
381   TestApplication application;
382   int             calledCount = 0;
383
384   Actor actor = Actor::New();
385   Actor clone = Actor::New();
386
387   Integration::Scene stage = application.GetScene();
388   stage.Add(actor);
389   stage.Add(clone);
390
391   application.SendNotification();
392   application.Render();
393
394   DALI_TEST_EQUALS(calledCount, 0, TEST_LOCATION);
395
396   // Add a constraint to actor
397   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, CalledCountFunctor<Vector3>(calledCount));
398   DALI_TEST_CHECK(constraint);
399   constraint.Apply();
400
401   // Create a clone but don't apply
402   Constraint constraintClone = constraint.Clone(clone);
403
404   application.SendNotification();
405   application.Render();
406
407   DALI_TEST_EQUALS(calledCount, 1, TEST_LOCATION);
408
409   // Reset
410   calledCount = 0;
411
412   application.SendNotification();
413   application.Render();
414
415   DALI_TEST_EQUALS(calledCount, 1, TEST_LOCATION);
416
417   // Apply the clone constraint
418   constraintClone.Apply();
419
420   application.SendNotification();
421   application.Render();
422
423   // Should be called once for the new constraint clone and once for the original constraint
424   DALI_TEST_EQUALS(calledCount, 3, TEST_LOCATION);
425
426   // Reset
427   calledCount = 0;
428
429   // Change the position of both actors
430   actor.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
431   clone.SetProperty(Actor::Property::POSITION, Vector2(100.0f, 100.0f));
432
433   application.SendNotification();
434   application.Render();
435
436   // Functor should have been called twice
437   DALI_TEST_EQUALS(calledCount, 2, TEST_LOCATION);
438
439   END_TEST;
440 }
441
442 int UtcDaliConstraintCloneN(void)
443 {
444   // Attempt to clone an uninitialised constraint should cause an assert
445
446   TestApplication application;
447
448   Constraint constraint;
449
450   try
451   {
452     Actor      actor = Actor::New();
453     Constraint clone = constraint.Clone(actor);
454     DALI_TEST_CHECK(false);
455   }
456   catch(...)
457   {
458     DALI_TEST_CHECK(true);
459   }
460
461   END_TEST;
462 }
463
464 namespace UtcDaliConstraintClone
465 {
466 void Function(Vector3& /* current */, const PropertyInputContainer& inputs)
467 {
468   DALI_TEST_EQUALS(inputs[0]->GetType(), Property::VECTOR3, TEST_LOCATION);
469   DALI_TEST_EQUALS(inputs[1]->GetType(), Property::ROTATION, TEST_LOCATION);
470   DALI_TEST_EQUALS(inputs[2]->GetType(), Property::VECTOR4, TEST_LOCATION);
471   DALI_TEST_EQUALS(inputs[3]->GetType(), Property::BOOLEAN, TEST_LOCATION);
472 }
473 } // namespace UtcDaliConstraintClone
474
475 int UtcDaliConstraintCloneCheckSourcesAndSetters(void)
476 {
477   // Ensure all sources, the tag and remove-action are cloned appropriately
478
479   TestApplication application;
480
481   Actor actor = Actor::New();
482   Actor clone = Actor::New();
483
484   Integration::Scene stage = application.GetScene();
485   stage.Add(actor);
486   stage.Add(clone);
487
488   application.SendNotification();
489   application.Render();
490
491   // Create a constraint, DON'T Apply it though
492   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &UtcDaliConstraintClone::Function);
493   constraint.AddSource(LocalSource(Actor::Property::SIZE));
494   constraint.AddSource(LocalSource(Actor::Property::ORIENTATION));
495   constraint.AddSource(LocalSource(Actor::Property::COLOR));
496   constraint.AddSource(LocalSource(Actor::Property::VISIBLE));
497   constraint.SetRemoveAction(Constraint::DISCARD);
498   constraint.SetTag(123);
499
500   // Clone the constraint & apply the clone
501   Constraint constraintClone = constraint.Clone(clone);
502   constraintClone.Apply();
503
504   application.SendNotification();
505   application.Render();
506
507   DALI_TEST_EQUALS(constraint.GetRemoveAction(), constraintClone.GetRemoveAction(), TEST_LOCATION);
508   DALI_TEST_EQUALS(constraint.GetTag(), constraintClone.GetTag(), TEST_LOCATION);
509
510   END_TEST;
511 }
512 ///////////////////////////////////////////////////////////////////////////////
513
514 ///////////////////////////////////////////////////////////////////////////////
515 // Constraint::Constraint( const Constraint& )
516 // Constraint::operator=
517 ///////////////////////////////////////////////////////////////////////////////
518 int UtcDaliConstraintCopyAndAssignment(void)
519 {
520   // Ensure copy constructor & assignment operators work
521
522   TestApplication application;
523
524   Actor actor = Actor::New();
525   application.GetScene().Add(actor);
526
527   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
528   Constraint copied(constraint);
529   Constraint assigned;
530   DALI_TEST_CHECK(constraint == copied);
531   DALI_TEST_CHECK(copied != assigned);
532
533   assigned = constraint;
534   DALI_TEST_CHECK(constraint == assigned);
535
536   END_TEST;
537 }
538 ///////////////////////////////////////////////////////////////////////////////
539
540 int UtcDaliConstraintMoveConstructor(void)
541 {
542   // Ensure copy constructor & assignment operators work
543
544   TestApplication application;
545
546   Actor actor = Actor::New();
547   application.GetScene().Add(actor);
548
549   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
550   DALI_TEST_CHECK(constraint);
551   DALI_TEST_EQUALS(1, constraint.GetBaseObject().ReferenceCount(), TEST_LOCATION);
552   DALI_TEST_CHECK(constraint.GetTargetObject() == actor);
553
554   Constraint moved = std::move(constraint);
555   DALI_TEST_CHECK(moved);
556   DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
557   DALI_TEST_CHECK(moved.GetTargetObject() == actor);
558   DALI_TEST_CHECK(!constraint);
559
560   END_TEST;
561 }
562
563 int UtcDaliConstraintMoveAssignment(void)
564 {
565   // Ensure copy constructor & assignment operators work
566
567   TestApplication application;
568
569   Actor actor = Actor::New();
570   application.GetScene().Add(actor);
571
572   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
573   DALI_TEST_CHECK(constraint);
574   DALI_TEST_EQUALS(1, constraint.GetBaseObject().ReferenceCount(), TEST_LOCATION);
575   DALI_TEST_CHECK(constraint.GetTargetObject() == actor);
576
577   Constraint moved;
578   moved = std::move(constraint);
579   DALI_TEST_CHECK(moved);
580   DALI_TEST_EQUALS(1, moved.GetBaseObject().ReferenceCount(), TEST_LOCATION);
581   DALI_TEST_CHECK(moved.GetTargetObject() == actor);
582   DALI_TEST_CHECK(!constraint);
583
584   END_TEST;
585 }
586
587 ///////////////////////////////////////////////////////////////////////////////
588 // Constraint::DownCast
589 ///////////////////////////////////////////////////////////////////////////////
590 int UtcDaliConstraintDownCast(void)
591 {
592   // Ensure DownCast works as expected
593
594   TestApplication application;
595
596   Actor      actor      = Actor::New();
597   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
598
599   // Another BaseHandle type
600   Constraint downCast = Constraint::DownCast(actor);
601   DALI_TEST_CHECK(!downCast);
602
603   // A constraint
604   downCast = Constraint::DownCast(constraint);
605   DALI_TEST_CHECK(downCast);
606
607   // An empty constraint
608   downCast = Constraint::DownCast(Constraint());
609   DALI_TEST_CHECK(!downCast);
610
611   END_TEST;
612 }
613 ///////////////////////////////////////////////////////////////////////////////
614
615 ///////////////////////////////////////////////////////////////////////////////
616 // Constraint::GetTargetObject
617 ///////////////////////////////////////////////////////////////////////////////
618 int UtcDaliConstraintGetTargetObjectP(void)
619 {
620   TestApplication application;
621
622   Actor      actor      = Actor::New();
623   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
624   DALI_TEST_CHECK(constraint.GetTargetObject() == actor);
625
626   Actor actor2 = Actor::New();
627   DALI_TEST_CHECK(constraint.GetTargetObject() != actor2);
628
629   END_TEST;
630 }
631
632 int UtcDaliConstraintGetTargetObjectN(void)
633 {
634   // Attempt to retrieve from uninitialised constraint
635
636   TestApplication application;
637
638   Constraint constraint;
639   try
640   {
641     Handle handle = constraint.GetTargetObject();
642     DALI_TEST_CHECK(false); // Should not reach here!
643   }
644   catch(...)
645   {
646     DALI_TEST_CHECK(true);
647   }
648
649   END_TEST;
650 }
651 ///////////////////////////////////////////////////////////////////////////////
652
653 ///////////////////////////////////////////////////////////////////////////////
654 // Constraint::GetTargetProperty
655 ///////////////////////////////////////////////////////////////////////////////
656 int UtcDaliConstraintGetTargetPropertyP(void)
657 {
658   TestApplication application;
659
660   Actor      actor      = Actor::New();
661   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
662   DALI_TEST_EQUALS(constraint.GetTargetProperty(), (Property::Index)Actor::Property::POSITION, TEST_LOCATION);
663
664   END_TEST;
665 }
666
667 int UtcDaliConstraintGetTargetPropertyN(void)
668 {
669   // Attempt to retrieve from uninitialised constraint
670
671   TestApplication application;
672
673   Constraint constraint;
674   try
675   {
676     Property::Index propertyIndex = constraint.GetTargetProperty();
677     (void)propertyIndex;
678     DALI_TEST_CHECK(false); // Should not reach here!
679   }
680   catch(...)
681   {
682     DALI_TEST_CHECK(true);
683   }
684
685   END_TEST;
686 }
687 ///////////////////////////////////////////////////////////////////////////////
688
689 ///////////////////////////////////////////////////////////////////////////////
690 // Constraint::SetTag
691 // Constraint::GetTag
692 ///////////////////////////////////////////////////////////////////////////////
693 int UtcDaliConstraintTagP(void)
694 {
695   TestApplication application;
696
697   Actor      actor      = Actor::New();
698   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
699   DALI_TEST_EQUALS(constraint.GetTag(), 0u, TEST_LOCATION);
700
701   const unsigned int tag = 123;
702   constraint.SetTag(tag);
703   DALI_TEST_EQUALS(constraint.GetTag(), tag, TEST_LOCATION);
704
705   END_TEST;
706 }
707
708 int UtcDaliConstraintSetTagN(void)
709 {
710   // Attempt to set from uninitialised constraint
711
712   TestApplication application;
713
714   Constraint constraint;
715   try
716   {
717     constraint.SetTag(123);
718     DALI_TEST_CHECK(false); // Should not reach here!
719   }
720   catch(...)
721   {
722     DALI_TEST_CHECK(true);
723   }
724
725   END_TEST;
726 }
727
728 int UtcDaliConstraintGetTagN(void)
729 {
730   // Attempt to retrieve from uninitialised constraint
731
732   TestApplication application;
733
734   Constraint constraint;
735   try
736   {
737     int tag = constraint.GetTag();
738     (void)tag;
739     DALI_TEST_CHECK(false); // Should not reach here!
740   }
741   catch(...)
742   {
743     DALI_TEST_CHECK(true);
744   }
745
746   END_TEST;
747 }
748
749 ///////////////////////////////////////////////////////////////////////////////
750
751 ///////////////////////////////////////////////////////////////////////////////
752 // Constraint::SetRemoveAction
753 // Constraint::GetRemoveAction
754 ///////////////////////////////////////////////////////////////////////////////
755 int UtcDaliConstraintRemoveActionP(void)
756 {
757   TestApplication application;
758
759   Actor      actor      = Actor::New();
760   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &BasicFunction<Vector3>);
761   DALI_TEST_EQUALS(constraint.GetRemoveAction(), Constraint::DEFAULT_REMOVE_ACTION, TEST_LOCATION);
762
763   constraint.SetRemoveAction(Constraint::DISCARD);
764   DALI_TEST_EQUALS(constraint.GetRemoveAction(), Constraint::DISCARD, TEST_LOCATION);
765
766   constraint.SetRemoveAction(Constraint::BAKE);
767   DALI_TEST_EQUALS(constraint.GetRemoveAction(), Constraint::BAKE, TEST_LOCATION);
768
769   END_TEST;
770 }
771
772 int UtcDaliConstraintSetRemoveActionN(void)
773 {
774   // Attempt to set from uninitialised constraint
775
776   TestApplication application;
777
778   Constraint constraint;
779   try
780   {
781     constraint.SetRemoveAction(Constraint::DISCARD);
782     DALI_TEST_CHECK(false); // Should not reach here!
783   }
784   catch(...)
785   {
786     DALI_TEST_CHECK(true);
787   }
788
789   END_TEST;
790 }
791
792 int UtcDaliConstraintGetRemoveActionN(void)
793 {
794   // Attempt to retrieve from uninitialised constraint
795
796   TestApplication application;
797
798   Constraint constraint;
799   try
800   {
801     Constraint::RemoveAction removeAction = constraint.GetRemoveAction();
802     (void)removeAction;
803     DALI_TEST_CHECK(false); // Should not reach here!
804   }
805   catch(...)
806   {
807     DALI_TEST_CHECK(true);
808   }
809
810   END_TEST;
811 }
812
813 int UtcDaliConstraintBakeRemoveAction(void)
814 {
815   // Ensure value is baked when constraint is removed
816
817   TestApplication application;
818
819   Actor actor = Actor::New();
820   application.GetScene().Add(actor);
821
822   application.SendNotification();
823   application.Render();
824
825   // Should not equal position by default
826   Vector3 position(10.0f, 20.0f, 30.0f);
827   DALI_TEST_CHECK(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION) != position);
828
829   // Create a constraint that constrains to position
830   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, SetValueFunctor<Vector3>(position));
831   constraint.SetRemoveAction(Constraint::BAKE);
832   constraint.Apply();
833
834   application.SendNotification();
835   application.Render();
836
837   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), position, TEST_LOCATION);
838
839   // Remove the constraint, it should still be at position
840   constraint.Remove();
841
842   application.SendNotification();
843   application.Render();
844
845   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), position, TEST_LOCATION);
846
847   END_TEST;
848 }
849
850 int UtcDaliConstraintDiscardRemoveAction(void)
851 {
852   // Ensure value is baked when constraint is removed
853
854   TestApplication application;
855
856   Actor actor = Actor::New();
857   application.GetScene().Add(actor);
858
859   application.SendNotification();
860   application.Render();
861
862   // Get and store current position
863   Vector3 originalPosition = actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION);
864
865   // Should not equal position by default
866   Vector3 position(10.0f, 20.0f, 30.0f);
867   DALI_TEST_CHECK(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION) != position);
868
869   // Create a constraint that constrains to position
870   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, SetValueFunctor<Vector3>(position));
871   constraint.SetRemoveAction(Constraint::DISCARD);
872   constraint.Apply();
873
874   application.SendNotification();
875   application.Render();
876
877   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), position, TEST_LOCATION);
878
879   // Remove the constraint, it should still be at position
880   constraint.Remove();
881
882   application.SendNotification();
883   application.Render();
884
885   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), originalPosition, TEST_LOCATION);
886   DALI_TEST_CHECK(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION) != position);
887
888   END_TEST;
889 }
890
891 ///////////////////////////////////////////////////////////////////////////////
892
893 ///////////////////////////////////////////////////////////////////////////////
894 // Constraint::Apply
895 // Constraint::Remove
896 ///////////////////////////////////////////////////////////////////////////////
897 int UtcDaliConstraintApplyRemove(void)
898 {
899   // Ensure constraint functors are called appropriately
900
901   TestApplication application;
902   bool            functorCalled = false;
903
904   Actor actor = Actor::New();
905   application.GetScene().Add(actor);
906
907   application.SendNotification();
908   application.Render();
909
910   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
911
912   // Create a constraint and apply, functor should be called
913   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, BasicCalledFunctor<Vector3>(functorCalled));
914   constraint.Apply();
915
916   application.SendNotification();
917   application.Render();
918
919   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
920
921   // Reset
922   functorCalled = false;
923
924   // Remove the constraint, functor should not be called
925   constraint.Remove();
926
927   application.SendNotification();
928   application.Render();
929
930   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
931
932   // Re-apply the constraint, functor should be called again
933   constraint.Apply();
934
935   application.SendNotification();
936   application.Render();
937
938   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
939
940   END_TEST;
941 }
942
943 int UtcDaliConstraintApplyBeforeAddedToStage(void)
944 {
945   // Constraint gets applied to an off-stage actor.
946   // Constraint should be automatically applied when the actor is added to the stage and not before
947
948   TestApplication application;
949   bool            functorCalled = false;
950
951   // Create an actor and a constraint and apply, DON'T add to stage just yet
952   Actor      actor      = Actor::New();
953   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, BasicCalledFunctor<Vector3>(functorCalled));
954   constraint.Apply();
955
956   application.SendNotification();
957   application.Render();
958
959   // Should NOT be called
960   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
961
962   // Add actor to stage
963   application.GetScene().Add(actor);
964
965   application.SendNotification();
966   application.Render();
967
968   // Should now be called
969   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
970
971   END_TEST;
972 }
973
974 int UtcDaliConstraintApplyAndRemoveBeforeAddedToStage(void)
975 {
976   // Constraint gets applied to an off-stage actor, then gets removed before it's added to the stage
977   // Constraint should NOT be called at all
978
979   TestApplication application;
980   bool            functorCalled = false;
981
982   // Create an actor and a constraint and apply, DON'T add to stage just yet
983   Actor      actor      = Actor::New();
984   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, BasicCalledFunctor<Vector3>(functorCalled));
985   constraint.Apply();
986
987   application.SendNotification();
988   application.Render();
989
990   // Should NOT be called
991   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
992
993   // Remove the constraint
994   constraint.Remove();
995
996   // Add actor to stage
997   application.GetScene().Add(actor);
998
999   application.SendNotification();
1000   application.Render();
1001
1002   // Still should NOT be called
1003   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
1004
1005   END_TEST;
1006 }
1007
1008 int UtcDaliConstraintApplyActorStagedUnstaged(void)
1009 {
1010   // Apply a constraint to an actor which is staged and unstaged.
1011   // Functor should only be called while the actor is staged.
1012
1013   TestApplication application;
1014   bool            functorCalled = false;
1015
1016   // Create an actor and add to stage
1017   Actor              actor = Actor::New();
1018   Integration::Scene stage = application.GetScene();
1019   stage.Add(actor);
1020
1021   // Create a constraint and apply
1022   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, BasicCalledFunctor<Vector3>(functorCalled));
1023   constraint.Apply();
1024
1025   application.SendNotification();
1026   application.Render();
1027
1028   // Constraint should be called
1029   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
1030
1031   // Reset
1032   functorCalled = false;
1033
1034   // Remove actor from stage
1035   stage.Remove(actor);
1036
1037   application.SendNotification();
1038   application.Render();
1039
1040   // Constraint should NOT be called
1041   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
1042
1043   // Re-add to stage
1044   stage.Add(actor);
1045
1046   application.SendNotification();
1047   application.Render();
1048
1049   // Constraint should be called
1050   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
1051
1052   END_TEST;
1053 }
1054
1055 int UtcDaliConstraintApplySeveralTimes(void)
1056 {
1057   // Apply the same constraint several times.
1058   // Should not cause any problems (subsequent attempts should be no-ops)
1059
1060   TestApplication application;
1061   int             count = 0;
1062
1063   // Create an actor and add to stage
1064   Actor              actor = Actor::New();
1065   Integration::Scene stage = application.GetScene();
1066   stage.Add(actor);
1067
1068   // Create a constraint and apply
1069   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, CalledCountFunctor<Vector3>(count));
1070   constraint.Apply();
1071
1072   // Apply again
1073   constraint.Apply(); // no-op
1074
1075   application.SendNotification();
1076   application.Render();
1077
1078   // Should only have been called once
1079   DALI_TEST_EQUALS(count, 1, TEST_LOCATION);
1080
1081   // Reset
1082   count = 0;
1083
1084   // Apply again
1085   constraint.Apply(); // no-op
1086
1087   application.SendNotification();
1088   application.Render();
1089
1090   DALI_TEST_EQUALS(count, 1, TEST_LOCATION);
1091
1092   // Reset
1093   count = 0;
1094
1095   // Change the position property, apply again
1096   actor.SetProperty(Actor::Property::POSITION, Vector2(10.0f, 10.0f));
1097   constraint.Apply();
1098
1099   application.SendNotification();
1100   application.Render();
1101
1102   // Constraint should have been called once
1103   DALI_TEST_EQUALS(count, 1, TEST_LOCATION);
1104
1105   END_TEST;
1106 }
1107
1108 ///////////////////////////////////////////////////////////////////////////////
1109
1110 ///////////////////////////////////////////////////////////////////////////////
1111 // Constraint::AddSource
1112 ///////////////////////////////////////////////////////////////////////////////
1113 namespace UtcDaliConstraintAddSource
1114 {
1115 void Function(Vector3& /* current */, const PropertyInputContainer& inputs)
1116 {
1117   DALI_TEST_EQUALS(inputs.Size(), 4u, TEST_LOCATION);
1118   DALI_TEST_EQUALS(inputs[0]->GetType(), Property::VECTOR3, TEST_LOCATION);
1119   DALI_TEST_EQUALS(inputs[1]->GetType(), Property::ROTATION, TEST_LOCATION);
1120   DALI_TEST_EQUALS(inputs[2]->GetType(), Property::VECTOR4, TEST_LOCATION);
1121   DALI_TEST_EQUALS(inputs[3]->GetType(), Property::BOOLEAN, TEST_LOCATION);
1122 }
1123 } // namespace UtcDaliConstraintAddSource
1124
1125 int UtcDaliConstraintAddSourceP(void)
1126 {
1127   // Ensure all sources are in the correct order in the functor
1128
1129   TestApplication application;
1130
1131   Actor actor = Actor::New();
1132   application.GetScene().Add(actor);
1133
1134   // Create a constraint, add sources
1135   Constraint constraint = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &UtcDaliConstraintAddSource::Function);
1136   constraint.AddSource(LocalSource(Actor::Property::SIZE));
1137   constraint.AddSource(LocalSource(Actor::Property::ORIENTATION));
1138   constraint.AddSource(LocalSource(Actor::Property::COLOR));
1139   constraint.AddSource(LocalSource(Actor::Property::VISIBLE));
1140   constraint.Apply();
1141
1142   application.SendNotification();
1143   application.Render();
1144
1145   END_TEST;
1146 }
1147
1148 int UtcDaliConstraintAddSourceN(void)
1149 {
1150   // Attempt to set from uninitialised constraint
1151
1152   TestApplication application;
1153
1154   Constraint constraint;
1155   try
1156   {
1157     constraint.AddSource(LocalSource(Actor::Property::POSITION));
1158     DALI_TEST_CHECK(false); // Should not reach here!
1159   }
1160   catch(...)
1161   {
1162     DALI_TEST_CHECK(true);
1163   }
1164
1165   END_TEST;
1166 }
1167 ///////////////////////////////////////////////////////////////////////////////
1168
1169 ///////////////////////////////////////////////////////////////////////////////
1170 namespace TestChaining
1171 {
1172 const Vector3 gFunction1Output(Vector3::ONE);
1173 void          Function1(Vector3& current, const PropertyInputContainer& /* inputs */)
1174 {
1175   // current is original position
1176   DALI_TEST_EQUALS(current, Vector3::ZERO, TEST_LOCATION);
1177   current = gFunction1Output;
1178 }
1179
1180 const Vector3 gFunction2Output(10.0f, 20.0f, 30.0f);
1181 void          Function2(Vector3& current, const PropertyInputContainer& /* inputs */)
1182 {
1183   // current is output from Function1
1184   DALI_TEST_EQUALS(current, gFunction1Output, TEST_LOCATION);
1185
1186   current = gFunction2Output;
1187 }
1188
1189 const Vector3 gFunction3Output(10.0f, 20.0f, 30.0f);
1190 void          Function3(Vector3& current, const PropertyInputContainer& /* inputs */)
1191 {
1192   // current is output from Function2
1193   DALI_TEST_EQUALS(current, gFunction2Output, TEST_LOCATION);
1194
1195   current = gFunction3Output;
1196 }
1197
1198 const Vector3 gFunction4Output(10.0f, 20.0f, 30.0f);
1199 void          Function4(Vector3& current, const PropertyInputContainer& /* inputs */)
1200 {
1201   // current is output from Function3
1202   DALI_TEST_EQUALS(current, gFunction3Output, TEST_LOCATION);
1203
1204   current = gFunction4Output;
1205 }
1206
1207 void Function5(Vector3& current, const PropertyInputContainer& /* inputs */)
1208 {
1209   // current is output from Function4
1210   DALI_TEST_EQUALS(current, gFunction4Output, TEST_LOCATION);
1211
1212   current = Vector3::ZERO;
1213 }
1214
1215 } // namespace TestChaining
1216
1217 int UtcDaliConstraintChaining(void)
1218 {
1219   // Apply several constraints to the same property and ensure the functors are called in the correct order.
1220
1221   TestApplication application;
1222
1223   Actor actor = Actor::New();
1224   application.GetScene().Add(actor);
1225
1226   Constraint constraint1 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &TestChaining::Function1);
1227   Constraint constraint2 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &TestChaining::Function2);
1228   Constraint constraint3 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &TestChaining::Function3);
1229   Constraint constraint4 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &TestChaining::Function4);
1230   Constraint constraint5 = Constraint::New<Vector3>(actor, Actor::Property::POSITION, &TestChaining::Function5);
1231
1232   constraint1.Apply();
1233   constraint2.Apply();
1234   constraint3.Apply();
1235   constraint4.Apply();
1236   constraint5.Apply();
1237
1238   application.SendNotification();
1239   application.Render();
1240
1241   END_TEST;
1242 }
1243 ///////////////////////////////////////////////////////////////////////////////
1244
1245 ///////////////////////////////////////////////////////////////////////////////
1246 namespace TestPropertyTypes
1247 {
1248 template<typename T>
1249 void Execute(T value)
1250 {
1251   TestApplication application;
1252   bool            functorCalled = false;
1253
1254   Actor           actor = Actor::New();
1255   Property::Index index = actor.RegisterProperty("TEMP_PROPERTY_NAME", value);
1256
1257   application.GetScene().Add(actor);
1258
1259   application.SendNotification();
1260   application.Render();
1261
1262   DALI_TEST_EQUALS(functorCalled, false, TEST_LOCATION);
1263
1264   // Add a constraint
1265   Constraint constraint = Constraint::New<T>(actor, index, BasicCalledFunctor<T>(functorCalled));
1266   DALI_TEST_CHECK(constraint);
1267   constraint.Apply();
1268
1269   application.SendNotification();
1270   application.Render();
1271
1272   DALI_TEST_EQUALS(functorCalled, true, TEST_LOCATION);
1273 }
1274 } // namespace TestPropertyTypes
1275
1276 int UtcDaliConstraintTestPropertyTypesP(void)
1277 {
1278   // Ensure we can use a constraint functor with all supported property types
1279
1280   TestPropertyTypes::Execute<bool>(false);
1281   TestPropertyTypes::Execute<int>(0);
1282   TestPropertyTypes::Execute<float>(0.0f);
1283   TestPropertyTypes::Execute<Vector2>(Vector2::ZERO);
1284   TestPropertyTypes::Execute<Vector3>(Vector3::ZERO);
1285   TestPropertyTypes::Execute<Vector4>(Vector4::ZERO);
1286   TestPropertyTypes::Execute<Quaternion>(Quaternion::IDENTITY);
1287   TestPropertyTypes::Execute<Matrix>(Matrix::IDENTITY);
1288   TestPropertyTypes::Execute<Matrix3>(Matrix3::IDENTITY);
1289
1290   END_TEST;
1291 }
1292
1293 ///////////////////////////////////////////////////////////////////////////////
1294
1295 ///////////////////////////////////////////////////////////////////////////////
1296 namespace
1297 {
1298 void SetHalfOpacity(Vector4& current, const PropertyInputContainer& inputs)
1299 {
1300   current.a = 0.5f;
1301 }
1302 } // unnamed namespace
1303
1304 int UtcDaliConstraintEnsureResetterAppliedOnSceneRemoval(void)
1305 {
1306   // Ensure BOTH double-buffered values of our color property is reset when a constraint is applied to it.
1307
1308   TestApplication application;
1309
1310   Actor actor = Actor::New();
1311   application.GetScene().Add(actor);
1312
1313   // Check initial value is fully opaque
1314   application.SendNotification();
1315   application.Render();
1316   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1317
1318   // Create a constraint whose value is discarded when it is removed
1319   Constraint constraint = Constraint::New<Vector4>(actor, Actor::Property::COLOR, SetHalfOpacity);
1320   constraint.SetRemoveAction(Constraint::RemoveAction::DISCARD);
1321   constraint.Apply();
1322
1323   // Check value after one render, it should be constrained
1324   application.SendNotification();
1325   application.Render();
1326   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 0.5f, TEST_LOCATION);
1327
1328   // Render another frame, ensure the other value has also been updated
1329   application.SendNotification();
1330   application.Render();
1331   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 0.5f, TEST_LOCATION);
1332
1333   // Remove the actor from the stage and delete the constraint
1334   actor.Unparent();
1335   constraint.Remove();
1336   constraint.Reset();
1337
1338   // Check value while off-stage, it should be fully opaque
1339   application.SendNotification();
1340   application.Render();
1341   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1342
1343   // Add the actor back to the stage and check the value, it should be fully opaque again
1344   application.GetScene().Add(actor);
1345
1346   // Check value when back on-stage, it should be fully opaque as the constraint is no longer applied to it.
1347   application.SendNotification();
1348   application.Render();
1349   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1350
1351   // Render for another frame to ensure both buffers have the correct value
1352   application.SendNotification();
1353   application.Render();
1354   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1355
1356   END_TEST;
1357 }
1358
1359 int UtcDaliConstraintOnActorAddedAndRemoved(void)
1360 {
1361   // Ensure adding and removing an actor from stage with a constraint still has it applied when it is re-added back to the stage
1362
1363   TestApplication application;
1364
1365   Actor actor = Actor::New();
1366   application.GetScene().Add(actor);
1367
1368   // Check initial value is fully opaque
1369   application.SendNotification();
1370   application.Render();
1371   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1372
1373   // Create a constraint whose value is discarded when it is removed
1374   Constraint constraint = Constraint::New<Vector4>(actor, Actor::Property::COLOR, SetHalfOpacity);
1375   constraint.SetRemoveAction(Constraint::RemoveAction::DISCARD);
1376   constraint.Apply();
1377
1378   // Check value after one render, it should be constrained
1379   application.SendNotification();
1380   application.Render();
1381   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 0.5f, TEST_LOCATION);
1382
1383   // Render another frame, ensure the other value has also been updated
1384   application.SendNotification();
1385   application.Render();
1386   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 0.5f, TEST_LOCATION);
1387
1388   // Remove the actor from the stage
1389   actor.Unparent();
1390
1391   // Check value while off-stage, the constraint is no longer being applied as it's off-stage
1392   application.SendNotification();
1393   application.Render();
1394   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1395
1396   // Check the other buffer, the constraint should not be applied to this either.
1397   application.SendNotification();
1398   application.Render();
1399   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 1.0f, TEST_LOCATION);
1400
1401   // Add the actor back to the stage and check the value, the constraint should have been re-applied
1402   application.GetScene().Add(actor);
1403   application.SendNotification();
1404   application.Render();
1405   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 0.5f, TEST_LOCATION);
1406
1407   // Render for another frame to ensure both buffers have the correct value
1408   application.SendNotification();
1409   application.Render();
1410   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR).a, 0.5f, TEST_LOCATION);
1411
1412   END_TEST;
1413 }
1414
1415 ///////////////////////////////////////////////////////////////////////////////
1416
1417 int UtcDaliConstraintGetTargetObjectNegative(void)
1418 {
1419   TestApplication  application;
1420   Dali::Constraint instance;
1421   try
1422   {
1423     instance.GetTargetObject();
1424     DALI_TEST_CHECK(false); // Should not get here
1425   }
1426   catch(...)
1427   {
1428     DALI_TEST_CHECK(true); // We expect an assert
1429   }
1430   END_TEST;
1431 }
1432
1433 int UtcDaliConstraintSetRemoveActionNegative(void)
1434 {
1435   TestApplication  application;
1436   Dali::Constraint instance;
1437   try
1438   {
1439     Dali::Constraint::RemoveAction arg1(Constraint::BAKE);
1440     instance.SetRemoveAction(arg1);
1441     DALI_TEST_CHECK(false); // Should not get here
1442   }
1443   catch(...)
1444   {
1445     DALI_TEST_CHECK(true); // We expect an assert
1446   }
1447   END_TEST;
1448 }
1449
1450 int UtcDaliConstraintGetTargetPropertyNegative(void)
1451 {
1452   TestApplication  application;
1453   Dali::Constraint instance;
1454   try
1455   {
1456     instance.GetTargetProperty();
1457     DALI_TEST_CHECK(false); // Should not get here
1458   }
1459   catch(...)
1460   {
1461     DALI_TEST_CHECK(true); // We expect an assert
1462   }
1463   END_TEST;
1464 }
1465
1466 int UtcDaliConstraintApplyNegative(void)
1467 {
1468   TestApplication  application;
1469   Dali::Constraint instance;
1470   try
1471   {
1472     instance.Apply();
1473     DALI_TEST_CHECK(false); // Should not get here
1474   }
1475   catch(...)
1476   {
1477     DALI_TEST_CHECK(true); // We expect an assert
1478   }
1479   END_TEST;
1480 }
1481
1482 int UtcDaliConstraintCloneNegative(void)
1483 {
1484   TestApplication  application;
1485   Dali::Constraint instance;
1486   try
1487   {
1488     Dali::Handle arg1;
1489     instance.Clone(arg1);
1490     DALI_TEST_CHECK(false); // Should not get here
1491   }
1492   catch(...)
1493   {
1494     DALI_TEST_CHECK(true); // We expect an assert
1495   }
1496   END_TEST;
1497 }
1498
1499 int UtcDaliConstraintRemoveNegative(void)
1500 {
1501   TestApplication  application;
1502   Dali::Constraint instance;
1503   try
1504   {
1505     instance.Remove();
1506     DALI_TEST_CHECK(false); // Should not get here
1507   }
1508   catch(...)
1509   {
1510     DALI_TEST_CHECK(true); // We expect an assert
1511   }
1512   END_TEST;
1513 }
1514
1515 int UtcDaliConstraintSetTagNegative(void)
1516 {
1517   TestApplication  application;
1518   Dali::Constraint instance;
1519   try
1520   {
1521     unsigned int arg1(0u);
1522     instance.SetTag(arg1);
1523     DALI_TEST_CHECK(false); // Should not get here
1524   }
1525   catch(...)
1526   {
1527     DALI_TEST_CHECK(true); // We expect an assert
1528   }
1529   END_TEST;
1530 }
1531
1532 int UtcDaliConstraintGetRemoveActionNegative(void)
1533 {
1534   TestApplication  application;
1535   Dali::Constraint instance;
1536   try
1537   {
1538     instance.GetRemoveAction();
1539     DALI_TEST_CHECK(false); // Should not get here
1540   }
1541   catch(...)
1542   {
1543     DALI_TEST_CHECK(true); // We expect an assert
1544   }
1545   END_TEST;
1546 }
1547
1548 int UtcDaliConstraintGetTagNegative(void)
1549 {
1550   TestApplication  application;
1551   Dali::Constraint instance;
1552   try
1553   {
1554     instance.GetTag();
1555     DALI_TEST_CHECK(false); // Should not get here
1556   }
1557   catch(...)
1558   {
1559     DALI_TEST_CHECK(true); // We expect an assert
1560   }
1561   END_TEST;
1562 }
1563
1564 namespace ComponentTest
1565 {
1566 void CheckComponentProperty(TestApplication& application, Actor& actor, Property::Index property)
1567 {
1568   float value = actor.GetCurrentProperty<float>(property);
1569
1570   // Add a component 0 constraint
1571   RelativeToConstraintFloat relativeConstraint(2.0f);
1572   Constraint                constraint = Constraint::New<float>(actor, property, relativeConstraint);
1573   constraint.AddSource(Source{actor, property});
1574   DALI_TEST_CHECK(constraint);
1575   constraint.SetRemoveAction(Constraint::RemoveAction::DISCARD);
1576   constraint.Apply();
1577
1578   application.SendNotification();
1579   application.Render();
1580
1581   DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(property), value * 2.0f, TEST_LOCATION);
1582
1583   constraint.Remove();
1584
1585   application.SendNotification();
1586   application.Render();
1587
1588   DALI_TEST_EQUALS(actor.GetCurrentProperty<float>(property), value, TEST_LOCATION);
1589 }
1590 } // namespace ComponentTest
1591
1592 int UtcDaliConstraintComponentTransformPropertyConstraintP(void)
1593 {
1594   TestApplication application;
1595
1596   Actor actor = Actor::New();
1597   actor.SetProperty(Actor::Property::POSITION, Vector3(100.0f, 100.0f, 100.0f));
1598   application.GetScene().Add(actor);
1599
1600   application.SendNotification();
1601   application.Render();
1602
1603   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector3>(Actor::Property::POSITION), Vector3(100.0f, 100.0f, 100.0f), TEST_LOCATION);
1604
1605   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::POSITION_X); // Component 0
1606   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::POSITION_Y); // Component 1
1607   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::POSITION_Z); // Component 2
1608
1609   END_TEST;
1610 }
1611
1612 int UtcDaliConstraintComponentNonTransformPropertyConstraintP(void)
1613 {
1614   TestApplication application;
1615
1616   Actor actor = Actor::New();
1617   actor.SetProperty(Actor::Property::COLOR, Vector4(0.25f, 0.25f, 0.25f, 0.25f));
1618   application.GetScene().Add(actor);
1619
1620   application.SendNotification();
1621   application.Render();
1622
1623   DALI_TEST_EQUALS(actor.GetCurrentProperty<Vector4>(Actor::Property::COLOR), Vector4(0.25f, 0.25f, 0.25f, 0.25f), TEST_LOCATION);
1624
1625   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::COLOR_RED);   // Component 0
1626   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::COLOR_GREEN); // Component 1
1627   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::COLOR_BLUE);  // Component 2
1628   ComponentTest::CheckComponentProperty(application, actor, Actor::Property::COLOR_ALPHA); // Component 3
1629
1630   END_TEST;
1631 }