Ensure resetters reset both values when a property-owner is disconnected
[platform/core/uifw/dali-core.git] / automated-tests / src / dali / utc-Dali-Constraint.cpp
index 02818eb..f8f8ac5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -160,6 +160,41 @@ int UtcDaliConstraintNewFunctionN(void)
 
   END_TEST;
 }
+
+// helper for next test
+void StringConstraintFunction( std::string& /* current */, const PropertyInputContainer& /* inputs */ )
+{
+}
+
+int UtcDaliConstraintNewFunctionNonConstrainableTypeN(void)
+{
+  // Ensure that we can create a constraint using a C function and that it is called.
+
+  TestApplication application;
+  UtcDaliConstraintNewFunction::gConstraintFunctionCalled = false;
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  try
+  {
+    // Add a constraint
+    Constraint constraint = Constraint::New< std::string >( actor, Actor::Property::COLOR_MODE, &StringConstraintFunction );
+    DALI_TEST_CHECK( constraint );
+    constraint.Apply();
+    tet_result(TET_FAIL);
+  }
+  catch ( Dali::DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "Property not constrainable", TEST_LOCATION );
+  }
+
+  END_TEST;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -365,11 +400,10 @@ int UtcDaliConstraintCloneP(void)
   // Reset
   calledCount = 0;
 
-  // Ensure constraint isn't called again if scene doesn't change
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS( calledCount, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( calledCount, 1, TEST_LOCATION );
 
   // Apply the clone constraint
   constraintClone.Apply();
@@ -377,8 +411,8 @@ int UtcDaliConstraintCloneP(void)
   application.SendNotification();
   application.Render();
 
-  // Should only be called once for the new constraint clone ONLY
-  DALI_TEST_EQUALS( calledCount, 1, TEST_LOCATION );
+  // Should be called once for the new constraint clone and once for the original constraint
+  DALI_TEST_EQUALS( calledCount, 3, TEST_LOCATION );
 
   // Reset
   calledCount = 0;
@@ -569,7 +603,7 @@ int UtcDaliConstraintGetTargetPropertyP(void)
 
   Actor actor = Actor::New();
   Constraint constraint = Constraint::New< Vector3 >( actor, Actor::Property::POSITION, &BasicFunction< Vector3 > );
-  DALI_TEST_EQUALS( constraint.GetTargetProperty(), Actor::Property::POSITION, TEST_LOCATION );
+  DALI_TEST_EQUALS( constraint.GetTargetProperty(), (Property::Index)Actor::Property::POSITION, TEST_LOCATION );
 
   END_TEST;
 }
@@ -997,8 +1031,7 @@ int UtcDaliConstraintApplySeveralTimes(void)
   application.SendNotification();
   application.Render();
 
-  // Constraint should not have been called as the input-properties (none) have not changed for the constraint
-  DALI_TEST_EQUALS( count, 0, TEST_LOCATION );
+  DALI_TEST_EQUALS( count, 1, TEST_LOCATION );
 
   // Reset
   count = 0;
@@ -1202,22 +1235,126 @@ int UtcDaliConstraintTestPropertyTypesP(void)
   END_TEST;
 }
 
-int UtcDaliConstraintTestPropertyTypesN(void)
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+namespace
+{
+void SetHalfOpacity( Vector4& current, const PropertyInputContainer& inputs )
 {
-  // unsigned int not supported so we should assert
+  current.a = 0.5f;
+}
+} // unnamed namespace
 
-  try
-  {
-    TestPropertyTypes::Execute< unsigned int >( 0u );
-    DALI_TEST_CHECK( false ); // Should not come here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
+int UtcDaliConstraintEnsureResetterAppliedOnStageRemoval(void)
+{
+  // Ensure BOTH double-buffered values of our color property is reset when a constraint is applied to it.
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add( actor );
+
+  // Check initial value is fully opaque
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
+
+  // Create a constraint whose value is discarded when it is removed
+  Constraint constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, SetHalfOpacity );
+  constraint.SetRemoveAction( Constraint::RemoveAction::Discard );
+  constraint.Apply();
 
+  // Check value after one render, it should be constrained
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION );
+
+  // Render another frame, ensure the other value has also been updated
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION );
+
+  // Remove the actor from the stage and delete the constraint
+  actor.Unparent();
+  constraint.Remove();
+  constraint.Reset();
+
+  // Check value while off-stage, it should be fully opaque
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
+
+  // Add the actor back to the stage and check the value, it should be fully opaque again
+  Stage::GetCurrent().Add( actor );
+
+  // Check value when back on-stage, it should be fully opaque as the constraint is no longer applied to it.
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
+
+  // Render for another frame to ensure both buffers have the correct value
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
 
   END_TEST;
 }
-///////////////////////////////////////////////////////////////////////////////
 
+int UtcDaliConstraintOnActorAddedAndRemoved(void)
+{
+  // Ensure adding and removing an actor from stage with a constraint still has it applied when it is re-added back to the stage
+
+  TestApplication application;
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add( actor );
+
+  // Check initial value is fully opaque
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
+
+  // Create a constraint whose value is discarded when it is removed
+  Constraint constraint = Constraint::New< Vector4 >( actor, Actor::Property::COLOR, SetHalfOpacity );
+  constraint.SetRemoveAction( Constraint::RemoveAction::Discard );
+  constraint.Apply();
+
+  // Check value after one render, it should be constrained
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION );
+
+  // Render another frame, ensure the other value has also been updated
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION );
+
+  // Remove the actor from the stage
+  actor.Unparent();
+
+  // Check value while off-stage, the constraint is no longer being applied as it's off-stage
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
+
+  // Check the other buffer, the constraint should not be applied to this either.
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 1.0f, TEST_LOCATION );
+
+  // Add the actor back to the stage and check the value, the constraint should have been re-applied
+  Stage::GetCurrent().Add( actor );
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION );
+
+  // Render for another frame to ensure both buffers have the correct value
+  application.SendNotification();
+  application.Render();
+  DALI_TEST_EQUALS( actor.GetCurrentColor().a, 0.5f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+///////////////////////////////////////////////////////////////////////////////