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