/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace CommandAdjustSimulatedObjectTests { namespace AZStd { using namespace ::AZStd; } // namespace AZStd namespace AZ { using namespace ::AZ; } // namespace AZ namespace EMotionFX { // Import real types from the production namespace using ::EMotionFX::AnimGraphConnectionId; using ::EMotionFX::AnimGraphNodeId; using ::EMotionFX::AnimGraphObject; using ::EMotionFX::BlendTreeConnection; using ::EMotionFX::ValueParameter; using ::EMotionFX::CommandAllocator; using ::EMotionFX::PhysicsSetup; // Forward-declare types that will be mocked class Actor; class ActorManager; class AnimGraph; class AnimGraphInstance; class AnimGraphManager; class AnimGraphNode; class AnimGraphStateTransition; class EMotionFXManager; class GroupParameter; class Parameter; class SimulatedJoint; class SimulatedObject; class SimulatedObjectSetup; } // namespace EMotionFX namespace EMotionFX { typedef AZStd::vector GroupParameterVector; typedef AZStd::vector ParameterVector; typedef AZStd::vector ValueParameterVector; } #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include } // namespace CommandAdjustSimulatedObjectTests namespace EMotionFX { namespace UnderTest { using namespace ::CommandAdjustSimulatedObjectTests::EMotionFX; } // namespace UnderTest /////////////////////////////////////////////////////////////////////////// // CommandAdjustSimulatedObject tests /////////////////////////////////////////////////////////////////////////// struct CommandAdjustSimulatedObjectTestsParam { AZStd::optional objectName; AZStd::optional gravityFactor; AZStd::optional stiffnessFactor; AZStd::optional dampingFactor; AZStd::optional> colliderTags; void (*setExecuteExpectations)(UnderTest::SimulatedObject*); void (*setUndoExpectations)(UnderTest::SimulatedObject*); }; class CommandAdjustSimulatedObjectTestsFixture : public UnitTest::AllocatorsTestFixture , public ::testing::WithParamInterface<::testing::tuple> { public: static std::string buildCommandLineFromTestParam(const CommandAdjustSimulatedObjectTestsParam& param) { std::string string; std::stringstream stream(string); if (param.objectName.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedObject::s_objectNameParameterName << ' ' << param.objectName.value(); } if (param.gravityFactor.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedObject::s_gravityFactorParameterName << ' ' << param.gravityFactor.value(); } if (param.stiffnessFactor.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedObject::s_stiffnessFactorParameterName << ' ' << param.stiffnessFactor.value(); } if (param.dampingFactor.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedObject::s_dampingFactorParameterName << ' ' << param.dampingFactor.value(); } if (param.colliderTags.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedObject::s_colliderTagsParameterName << ' '; for (const std::string& val : *param.colliderTags) { stream << val; if (&val != std::addressof(*(param.colliderTags->end() - 1))) { stream << ";"; } } } return stream.str(); } }; TEST_P(CommandAdjustSimulatedObjectTestsFixture, TestExecute) { using ::testing::Return; using ::testing::ReturnRef; const AZStd::string nameString {"Old name"}; UnderTest::EMotionFXManager& manager = UnderTest::GetEMotionFX(); UnderTest::ActorManager actorManager; UnderTest::Actor actor; auto simulatedObjectSetup = AZStd::make_shared(); UnderTest::SimulatedObject simulatedObject; EXPECT_CALL(manager, GetActorManager()) .WillRepeatedly(Return(&actorManager)); EXPECT_CALL(actorManager, FindActorByID(0)) .WillRepeatedly(Return(&actor)); EXPECT_CALL(actor, GetSimulatedObjectSetup()) .WillRepeatedly(ReturnRef(simulatedObjectSetup)); EXPECT_CALL(actor, GetDirtyFlag()) .WillOnce(Return(false)); EXPECT_CALL(*simulatedObjectSetup, GetSimulatedObject(0)) .WillRepeatedly(Return(&simulatedObject)); // GetName returns a reference, so the return value for it has to be // defined in a place where that reference will exist EXPECT_CALL(simulatedObject, GetName()) .WillRepeatedly(::testing::ReturnRef(nameString)); AZStd::vector defaultColliderTags; EXPECT_CALL(simulatedObject, GetColliderTags()) .WillRepeatedly(testing::ReturnRef(defaultColliderTags)); const bool doExecuteOnly = ::testing::get<0>(GetParam()); const bool useCommandString = ::testing::get<1>(GetParam()); const CommandAdjustSimulatedObjectTestsParam& testParams = ::testing::get<2>(GetParam()); if (doExecuteOnly) { EXPECT_CALL(actor, SetDirtyFlag(true)); testParams.setExecuteExpectations(&simulatedObject); } else { { testing::InSequence sequence; EXPECT_CALL(actor, SetDirtyFlag(true)) .RetiresOnSaturation(); EXPECT_CALL(actor, SetDirtyFlag(false)) .RetiresOnSaturation(); } testParams.setUndoExpectations(&simulatedObject); } AZStd::string paramString {"-actorId 0 -objectIndex 0"}; paramString += AZStd::string(buildCommandLineFromTestParam(testParams).c_str()); MCore::CommandLine parameters(paramString); AZStd::string outResult; UnderTest::CommandAdjustSimulatedObject command(/*actorId=*/0, /*objectIndex=*/0); if (useCommandString) { EXPECT_TRUE(command.SetCommandParameters(parameters)); } else { if (testParams.objectName) { command.SetObjectName(AZStd::string(testParams.objectName->c_str(), testParams.objectName->size())); } command.SetGravityFactor(testParams.gravityFactor); command.SetStiffnessFactor(testParams.stiffnessFactor); command.SetDampingFactor(testParams.dampingFactor); if (testParams.colliderTags) { AZStd::vector value; for (const std::string& stdstring : testParams.colliderTags.value()) { value.emplace_back(stdstring.c_str(), stdstring.size()); } command.SetColliderTags(value); } } EXPECT_TRUE(command.Execute(parameters, outResult)) << outResult.c_str(); if (!doExecuteOnly) { EXPECT_TRUE(command.Undo(parameters, outResult)) << outResult.c_str(); } } INSTANTIATE_TEST_CASE_P(TestCommandAdjustSimulatedObject, CommandAdjustSimulatedObjectTestsFixture, ::testing::Combine( ::testing::Bool(), // Test execute or test undo ::testing::Bool(), // Use command strings or not ::testing::ValuesIn({ CommandAdjustSimulatedObjectTestsParam { "New name", AZStd::nullopt, AZStd::nullopt, AZStd::nullopt, AZStd::nullopt, [](UnderTest::SimulatedObject* simulatedObject) { EXPECT_CALL(*simulatedObject, SetName(StrEq("New name"))) .Times(1); }, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, SetName(StrEq("New name"))) .Times(1); EXPECT_CALL(*simulatedObject, SetName(StrEq("Old name"))) .Times(1); } }, CommandAdjustSimulatedObjectTestsParam { AZStd::nullopt, 2.2f, AZStd::nullopt, AZStd::nullopt, AZStd::nullopt, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, GetGravityFactor()) .Times(1) .WillOnce(::testing::Return(1.2f)); EXPECT_CALL(*simulatedObject, SetGravityFactor(::testing::FloatEq(2.2f))) .Times(1); }, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, GetGravityFactor()) .Times(1) .WillOnce(::testing::Return(1.2f)); EXPECT_CALL(*simulatedObject, SetGravityFactor(::testing::FloatEq(2.2f))) .Times(1); EXPECT_CALL(*simulatedObject, SetGravityFactor(::testing::FloatEq(1.2f))) .Times(1); } }, CommandAdjustSimulatedObjectTestsParam { AZStd::nullopt, AZStd::nullopt, 3.2f, AZStd::nullopt, AZStd::nullopt, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, GetStiffnessFactor()) .Times(1) .WillOnce(::testing::Return(2.2f)); EXPECT_CALL(*simulatedObject, SetStiffnessFactor(::testing::FloatEq(3.2f))) .Times(1); }, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, GetStiffnessFactor()) .Times(1) .WillOnce(::testing::Return(2.2f)); EXPECT_CALL(*simulatedObject, SetStiffnessFactor(::testing::FloatEq(3.2f))) .Times(1); EXPECT_CALL(*simulatedObject, SetStiffnessFactor(::testing::FloatEq(2.2f))) .Times(1); } }, CommandAdjustSimulatedObjectTestsParam { AZStd::nullopt, AZStd::nullopt, AZStd::nullopt, 4.2f, AZStd::nullopt, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, GetDampingFactor()) .Times(1) .WillOnce(::testing::Return(3.2f)); EXPECT_CALL(*simulatedObject, SetDampingFactor(::testing::FloatEq(4.2f))) .Times(1); }, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, GetDampingFactor()) .Times(1) .WillOnce(::testing::Return(3.2f)); EXPECT_CALL(*simulatedObject, SetDampingFactor(::testing::FloatEq(4.2f))) .Times(1); EXPECT_CALL(*simulatedObject, SetDampingFactor(::testing::FloatEq(3.2f))) .Times(1); } }, CommandAdjustSimulatedObjectTestsParam { AZStd::nullopt, AZStd::nullopt, AZStd::nullopt, AZStd::nullopt, std::vector{"left_knee", "right_knee"}, [](UnderTest::SimulatedObject* simulatedObject) { EXPECT_CALL(*simulatedObject, SetColliderTags(::testing::Pointwise(StrEq(), std::vector {"left_knee", "right_knee"}))) .Times(1); }, [](UnderTest::SimulatedObject* simulatedObject) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedObject, SetColliderTags(::testing::Pointwise(StrEq(), std::vector {"left_knee", "right_knee"}))) .Times(1); EXPECT_CALL(*simulatedObject, SetColliderTags(::testing::Pointwise(StrEq(), std::vector {}))) .Times(1); } }, }) ), [](const ::testing::TestParamInfo<::testing::tuple>& info) { std::string cmdline = (::testing::get<0>(info.param) ? std::string {"Execute_"} : std::string {"Undo_"}) + (::testing::get<1>(info.param) ? std::string {"UseCommandString"} : std::string {"UseSetters"}) + CommandAdjustSimulatedObjectTestsFixture::buildCommandLineFromTestParam(::testing::get<2>(info.param)); std::replace(cmdline.begin(), cmdline.end(), ' ', '_'); std::replace(cmdline.begin(), cmdline.end(), ';', '_'); cmdline.erase(std::remove(cmdline.begin(), cmdline.end(), '-'), cmdline.end()); cmdline.erase(std::remove(cmdline.begin(), cmdline.end(), '.'), cmdline.end()); return cmdline; } ); /////////////////////////////////////////////////////////////////////////// // CommandAdjustSimulatedJoint tests /////////////////////////////////////////////////////////////////////////// struct CommandAdjustSimulatedJointTestsParam { AZStd::optional coneAngleLimit; AZStd::optional mass; AZStd::optional stiffness; AZStd::optional damping; AZStd::optional gravityFactor; AZStd::optional friction; AZStd::optional pinned; AZStd::optional> colliderExclusionTags; AZStd::optional autoExcludeMode; AZStd::optional geometricAutoExclusion; void (*setExecuteExpectations)(UnderTest::SimulatedJoint*); void (*setUndoExpectations)(UnderTest::SimulatedJoint*); }; class CommandAdjustSimulatedJointTestsFixture : public UnitTest::AllocatorsTestFixture , public ::testing::WithParamInterface<::testing::tuple> { public: void SetUp() override { UnitTest::AllocatorsTestFixture::SetUp(); } static std::string buildCommandLineFromTestParam(const CommandAdjustSimulatedJointTestsParam& param) { std::string string; std::stringstream stream(string); if (param.coneAngleLimit.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_coneAngleLimitParameterName << ' ' << param.coneAngleLimit.value(); } if (param.mass.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_massParameterName << ' ' << param.mass.value(); } if (param.stiffness.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_stiffnessParameterName << ' ' << param.stiffness.value(); } if (param.damping.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_dampingParameterName << ' ' << param.damping.value(); } if (param.gravityFactor.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_gravityFactorParameterName << ' ' << param.gravityFactor.value(); } if (param.friction.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_frictionParameterName << ' ' << param.friction.value(); } if (param.pinned.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_pinnedParameterName << ' ' << (param.pinned.value() ? "true" : "false"); } if (param.colliderExclusionTags.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_colliderExclusionTagsParameterName << ' '; for (const std::string& val : *param.colliderExclusionTags) { stream << val; if (&val != std::addressof(*(param.colliderExclusionTags->end() - 1))) { stream << ";"; } } } if (param.autoExcludeMode.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_autoExcludeModeParameterName << ' '; switch (param.autoExcludeMode.value()) { case SimulatedJoint::AutoExcludeMode::None: stream << "None"; break; case SimulatedJoint::AutoExcludeMode::Self: stream << "Self"; break; case SimulatedJoint::AutoExcludeMode::SelfAndNeighbors: stream << "SelfAndNeighbors"; break; case SimulatedJoint::AutoExcludeMode::All: stream << "All"; break; }; } if (param.geometricAutoExclusion.has_value()) { stream << " -" << UnderTest::CommandAdjustSimulatedJoint::s_geometricAutoExclusionParameterName << ' ' << (param.geometricAutoExclusion.value() ? "true" : "false"); } return stream.str(); } }; TEST_P(CommandAdjustSimulatedJointTestsFixture, TestExecute) { using ::testing::Return; using ::testing::ReturnRef; UnderTest::EMotionFXManager& manager = UnderTest::GetEMotionFX(); UnderTest::ActorManager actorManager; UnderTest::Actor actor; auto simulatedObjectSetup = AZStd::make_shared(); UnderTest::SimulatedObject simulatedObject; UnderTest::SimulatedJoint simulatedJoint; EXPECT_CALL(manager, GetActorManager()) .WillRepeatedly(Return(&actorManager)); EXPECT_CALL(actorManager, FindActorByID(0)) .WillRepeatedly(Return(&actor)); EXPECT_CALL(actor, GetSimulatedObjectSetup()) .WillRepeatedly(ReturnRef(simulatedObjectSetup)); EXPECT_CALL(actor, GetDirtyFlag()) .WillOnce(Return(false)); EXPECT_CALL(*simulatedObjectSetup, GetSimulatedObject(0)) .WillRepeatedly(Return(&simulatedObject)); EXPECT_CALL(simulatedObject, GetSimulatedJoint(0)) .WillRepeatedly(Return(&simulatedJoint)); AZStd::vector defaultColliderExclusionTags; EXPECT_CALL(simulatedJoint, GetColliderExclusionTags()) .WillRepeatedly(testing::ReturnRef(defaultColliderExclusionTags)); const bool doExecuteOnly = ::testing::get<0>(GetParam()); const bool useCommandString = ::testing::get<1>(GetParam()); const auto& testParams = ::testing::get<2>(GetParam()); if (doExecuteOnly) { EXPECT_CALL(actor, SetDirtyFlag(true)); testParams.setExecuteExpectations(&simulatedJoint); } else { { testing::InSequence sequence; EXPECT_CALL(actor, SetDirtyFlag(true)) .RetiresOnSaturation(); EXPECT_CALL(actor, SetDirtyFlag(false)) .RetiresOnSaturation(); } testParams.setUndoExpectations(&simulatedJoint); } AZStd::string paramString {"-actorId 0 -objectIndex 0 -jointIndex 0"}; paramString += AZStd::string(buildCommandLineFromTestParam(testParams).c_str()); MCore::CommandLine parameters(paramString); AZStd::string outResult; UnderTest::CommandAdjustSimulatedJoint command(/*actorId=*/0, /*objectIndex=*/0, /*jointIndex=*/0); if (useCommandString) { EXPECT_TRUE(command.SetCommandParameters(parameters)); } else { if (testParams.coneAngleLimit.has_value()) { command.SetConeAngleLimit(testParams.coneAngleLimit.value()); } if (testParams.mass.has_value()) { command.SetMass(testParams.mass.value()); } if (testParams.stiffness.has_value()) { command.SetStiffness(testParams.stiffness.value()); } if (testParams.damping.has_value()) { command.SetDamping(testParams.damping.value()); } if (testParams.gravityFactor.has_value()) { command.SetGravityFactor(testParams.gravityFactor.value()); } if (testParams.friction.has_value()) { command.SetFriction(testParams.friction.value()); } if (testParams.pinned.has_value()) { command.SetPinned(testParams.pinned.value()); } if (testParams.colliderExclusionTags.has_value()) { AZStd::vector value; for (const std::string& stdstring : testParams.colliderExclusionTags.value()) { value.emplace_back(stdstring.c_str(), stdstring.size()); } command.SetColliderExclusionTags(value); } if (testParams.autoExcludeMode.has_value()) { command.SetAutoExcludeMode(testParams.autoExcludeMode.value()); } if (testParams.geometricAutoExclusion.has_value()) { command.SetGeometricAutoExclusion(testParams.geometricAutoExclusion.has_value()); } } EXPECT_TRUE(command.Execute(parameters, outResult)) << outResult.c_str(); if (!doExecuteOnly) { EXPECT_TRUE(command.Undo(parameters, outResult)) << outResult.c_str(); } } INSTANTIATE_TEST_CASE_P(TestCommandAdjustSimulatedJoint, CommandAdjustSimulatedJointTestsFixture, ::testing::Combine( ::testing::Bool(), // Test execute or test undo ::testing::Bool(), // Use command strings or not ::testing::ValuesIn( { CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ 0.3f, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetConeAngleLimit()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetConeAngleLimit(::testing::FloatEq(0.3f))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetConeAngleLimit()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetConeAngleLimit(::testing::FloatEq(0.3f))) .Times(1); EXPECT_CALL(*simulatedJoint, SetConeAngleLimit(::testing::FloatEq(0.8f))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ 0.3f, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetMass()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetMass(::testing::FloatEq(0.3f))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetMass()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetMass(::testing::FloatEq(0.3f))) .Times(1); EXPECT_CALL(*simulatedJoint, SetMass(::testing::FloatEq(0.8f))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ 0.3f, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetStiffness()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetStiffness(::testing::FloatEq(0.3f))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetStiffness()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetStiffness(::testing::FloatEq(0.3f))) .Times(1); EXPECT_CALL(*simulatedJoint, SetStiffness(::testing::FloatEq(0.8f))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ 0.3f, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetDamping()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetDamping(::testing::FloatEq(0.3f))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetDamping()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetDamping(::testing::FloatEq(0.3f))) .Times(1); EXPECT_CALL(*simulatedJoint, SetDamping(::testing::FloatEq(0.8f))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ 0.3f, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetGravityFactor()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetGravityFactor(::testing::FloatEq(0.3f))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetGravityFactor()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetGravityFactor(::testing::FloatEq(0.3f))) .Times(1); EXPECT_CALL(*simulatedJoint, SetGravityFactor(::testing::FloatEq(0.8f))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ 0.3f, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetFriction()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetFriction(::testing::FloatEq(0.3f))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetFriction()) .Times(1) .WillOnce(::testing::Return(0.8f)); EXPECT_CALL(*simulatedJoint, SetFriction(::testing::FloatEq(0.3f))) .Times(1); EXPECT_CALL(*simulatedJoint, SetFriction(::testing::FloatEq(0.8f))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ true, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, IsPinned()) .Times(1) .WillOnce(::testing::Return(false)); EXPECT_CALL(*simulatedJoint, SetPinned(true)) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint* simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, IsPinned()) .Times(1) .WillOnce(::testing::Return(false)); EXPECT_CALL(*simulatedJoint, SetPinned(true)) .Times(1); EXPECT_CALL(*simulatedJoint, SetPinned(false)) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ std::vector{"left_knee", "right_knee"}, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint * simulatedJoint) { EXPECT_CALL(*simulatedJoint, SetColliderExclusionTags(::testing::Pointwise(StrEq(), std::vector {"left_knee", "right_knee"}))) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint * simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, SetColliderExclusionTags(::testing::Pointwise(StrEq(), std::vector {"left_knee", "right_knee"}))) .Times(1); EXPECT_CALL(*simulatedJoint, SetColliderExclusionTags(::testing::Pointwise(StrEq(), std::vector {}))) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ SimulatedJoint::AutoExcludeMode::All, /* geometricAutoExclusion = */ AZStd::nullopt, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint * simulatedJoint) { EXPECT_CALL(*simulatedJoint, GetAutoExcludeMode()) .Times(1) .WillOnce(::testing::Return(SimulatedJoint::AutoExcludeMode::None)); EXPECT_CALL(*simulatedJoint, SetAutoExcludeMode(SimulatedJoint::AutoExcludeMode::All)) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint * simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, GetAutoExcludeMode()) .Times(1) .WillOnce(::testing::Return(SimulatedJoint::AutoExcludeMode::None)); EXPECT_CALL(*simulatedJoint, SetAutoExcludeMode(SimulatedJoint::AutoExcludeMode::All)) .Times(1); EXPECT_CALL(*simulatedJoint, SetAutoExcludeMode(SimulatedJoint::AutoExcludeMode::None)) .Times(1); } }, CommandAdjustSimulatedJointTestsParam { /* coneAngleLimit = */ AZStd::nullopt, /* mass = */ AZStd::nullopt, /* stiffness = */ AZStd::nullopt, /* damping = */ AZStd::nullopt, /* gravityFactor = */ AZStd::nullopt, /* friction = */ AZStd::nullopt, /* pinned = */ AZStd::nullopt, /* colliderExclusionTags = */ AZStd::nullopt, /* autoExcludeMode = */ AZStd::nullopt, /* geometricAutoExclusion = */ true, /* setExecuteExpectations = */ [](UnderTest::SimulatedJoint * simulatedJoint) { EXPECT_CALL(*simulatedJoint, IsGeometricAutoExclusion()) .Times(1) .WillOnce(::testing::Return(false)); EXPECT_CALL(*simulatedJoint, SetGeometricAutoExclusion(true)) .Times(1); }, /* setUndoExpectations = */ [](UnderTest::SimulatedJoint * simulatedJoint) { ::testing::InSequence sequence; EXPECT_CALL(*simulatedJoint, IsGeometricAutoExclusion()) .Times(1) .WillOnce(::testing::Return(false)); EXPECT_CALL(*simulatedJoint, SetGeometricAutoExclusion(true)) .Times(1); EXPECT_CALL(*simulatedJoint, SetGeometricAutoExclusion(false)) .Times(1); } }, }) ), [](const ::testing::TestParamInfo<::testing::tuple>& info) { std::string cmdline = (::testing::get<0>(info.param) ? std::string {"Execute_"} : std::string {"Undo_"}) + (::testing::get<1>(info.param) ? std::string {"UseCommandString"} : std::string {"UseSetters"}) + CommandAdjustSimulatedJointTestsFixture::buildCommandLineFromTestParam(::testing::get<2>(info.param)); std::replace(cmdline.begin(), cmdline.end(), ' ', '_'); std::replace(cmdline.begin(), cmdline.end(), ';', '_'); cmdline.erase(std::remove(cmdline.begin(), cmdline.end(), '-'), cmdline.end()); cmdline.erase(std::remove(cmdline.begin(), cmdline.end(), '.'), cmdline.end()); return cmdline; } ); } // namespace EMotionFX