/* * GDevelop Core * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights * reserved. This project is released under the MIT License. */ /** * @file Tests covering project refactoring */ #include "GDCore/IDE/WholeProjectRefactorer.h" #include "DummyPlatform.h" #include "GDCore/Events/Builtin/LinkEvent.h" #include "GDCore/Events/Builtin/StandardEvent.h" #include "GDCore/Events/Event.h" #include "GDCore/Extensions/Metadata/ParameterMetadataTools.h" #include "GDCore/Extensions/Platform.h" #include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Project/EventsFunctionsExtension.h" #include "GDCore/Project/ExternalEvents.h" #include "GDCore/Project/ExternalLayout.h" #include "GDCore/Project/Layout.h" #include "GDCore/Project/Object.h" #include "GDCore/Project/Project.h" #include "GDCore/Project/Variable.h" #include "catch.hpp" namespace { gd::StandardEvent &EnsureStandardEvent(gd::BaseEvent &baseEvent) { gd::StandardEvent *standardEvent = dynamic_cast(&baseEvent); INFO("The inspected event is " << (standardEvent ? "a standard event" : "not a standard event")); REQUIRE(standardEvent != nullptr); return *standardEvent; } const gd::String &GetEventFirstActionFirstParameterString( gd::BaseEvent &event) { auto &actions = EnsureStandardEvent(event).GetActions(); REQUIRE(actions.IsEmpty() == false); REQUIRE(actions.Get(0).GetParametersCount() != 0); return actions.Get(0).GetParameter(0).GetPlainString(); } const gd::String &GetEventFirstConditionType(gd::BaseEvent &event) { auto &conditions = EnsureStandardEvent(event).GetConditions(); REQUIRE(conditions.IsEmpty() == false); return conditions.Get(0).GetType(); } const gd::String &GetEventFirstActionType(gd::BaseEvent &event) { auto &actions = EnsureStandardEvent(event).GetActions(); REQUIRE(actions.IsEmpty() == false); return actions.Get(0).GetType(); } gd::EventsFunctionsExtension &SetupProjectWithEventsFunctionExtension( gd::Project &project) { auto &eventsExtension = project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0); // Add a (free) function and a (free) expression eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0); eventsExtension.InsertNewEventsFunction("MyEventsFunctionExpression", 1) .SetFunctionType(gd::EventsFunction::Expression); // Add some usage for them { auto &layout = project.InsertNewLayout("LayoutWithFreeFunctions", 0); auto &externalEvents = project.InsertNewExternalEvents("ExternalEventsWithFreeFunctions", 0); externalEvents.SetAssociatedLayout("LayoutWithFreeFunctions"); // Create an event in the layout referring to // MyEventsExtension::MyEventsFunction { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyEventsExtension::MyEventsFunction"); instruction.SetParametersCount(3); instruction.SetParameter(0, gd::Expression("First parameter")); instruction.SetParameter(1, gd::Expression("Second parameter")); instruction.SetParameter(2, gd::Expression("Third parameter")); event.GetActions().Insert(instruction); layout.GetEvents().InsertEvent(event); } // Create an event in the external events referring to // MyEventsExtension::MyEventsFunctionExpression { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyExtension::DoSomething"); instruction.SetParametersCount(1); instruction.SetParameter( 0, gd::Expression( "1 + MyEventsExtension::MyEventsFunctionExpression(123, 456)")); event.GetActions().Insert(instruction); externalEvents.GetEvents().InsertEvent(event); } } // Add a events based behavior { auto &eventsBasedBehavior = eventsExtension.GetEventsBasedBehaviors().InsertNew( "MyEventsBasedBehavior", 0); eventsBasedBehavior.SetFullName("My events based behavior"); eventsBasedBehavior.SetDescription("An events based behavior for test"); // Add functions auto &behaviorEventsFunctions = eventsBasedBehavior.GetEventsFunctions(); behaviorEventsFunctions.InsertNewEventsFunction("MyBehaviorEventsFunction", 0); behaviorEventsFunctions .InsertNewEventsFunction("MyBehaviorEventsFunctionExpression", 1) .SetFunctionType(gd::EventsFunction::Expression); // Add property eventsBasedBehavior.GetPropertyDescriptors() .InsertNew("MyProperty", 0) .SetType("Number"); } // Add some usage in events { auto &layout = project.InsertNewLayout("LayoutWithBehaviorFunctions", 0); auto &externalEvents = project.InsertNewExternalEvents( "ExternalEventsWithBehaviorFunctions", 0); externalEvents.SetAssociatedLayout("LayoutWithBehaviorFunctions"); auto &object = layout.InsertNewObject( project, "MyExtension::Sprite", "ObjectWithMyBehavior", 0); object.AddBehavior(gd::BehaviorContent( "MyBehavior", "MyEventsExtension::MyEventsBasedBehavior")); auto &globalObject = project.InsertNewObject( project, "MyExtension::Sprite", "GlobalObjectWithMyBehavior", 0); globalObject.AddBehavior(gd::BehaviorContent( "MyBehavior", "MyEventsExtension::MyEventsBasedBehavior")); // Create an event in the layout referring to // MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunction { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType( "MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunction"); instruction.SetParametersCount(3); instruction.SetParameter(0, gd::Expression("First parameter")); instruction.SetParameter(1, gd::Expression("Second parameter")); instruction.SetParameter(2, gd::Expression("Third parameter")); event.GetActions().Insert(instruction); layout.GetEvents().InsertEvent(event); } // Create an event in the layout using "MyProperty" action { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType( "MyEventsExtension::MyEventsBasedBehavior::" + gd::EventsBasedBehavior::GetPropertyActionName("MyProperty")); event.GetActions().Insert(instruction); layout.GetEvents().InsertEvent(event); } // Create an event in the layout using "MyProperty" condition { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType( "MyEventsExtension::MyEventsBasedBehavior::" + gd::EventsBasedBehavior::GetPropertyConditionName("MyProperty")); event.GetConditions().Insert(instruction); layout.GetEvents().InsertEvent(event); } // Create an event in the layout using "MyProperty" expression { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyExtension::DoSomething"); instruction.SetParametersCount(1); instruction.SetParameter( 0, gd::Expression( "ObjectWithMyBehavior.MyBehavior::" + gd::EventsBasedBehavior::GetPropertyExpressionName("MyProperty") + "()")); event.GetActions().Insert(instruction); layout.GetEvents().InsertEvent(event); } // Create an event in ExternalEvents1 referring to // MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunctionExpression { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyExtension::DoSomething"); instruction.SetParametersCount(1); instruction.SetParameter( 0, gd::Expression("1 + " "ObjectWithMyBehavior.MyBehavior::" "MyBehaviorEventsFunctionExpression(123, 456, 789)")); event.GetActions().Insert(instruction); externalEvents.GetEvents().InsertEvent(event); } // Create an event in ExternalEvents1 **wrongly** referring to // MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunctionExpression // (it's ill-named). { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyExtension::DoSomething"); instruction.SetParametersCount(1); instruction.SetParameter( 0, gd::Expression("2 + " "ObjectWithMyBehavior::MyBehavior." "MyBehaviorEventsFunctionExpression(123, 456, 789)")); event.GetActions().Insert(instruction); externalEvents.GetEvents().InsertEvent(event); } // Create an event in ExternalEvents1 referring to // MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunctionExpression // function name without calling the function. { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyExtension::DoSomething"); instruction.SetParametersCount(1); instruction.SetParameter( 0, gd::Expression("3 + " "ObjectWithMyBehavior.MyBehavior::" "MyBehaviorEventsFunctionExpression")); event.GetActions().Insert(instruction); externalEvents.GetEvents().InsertEvent(event); } // Create an event in ExternalEvents1 **wrongly** referring to // MyEventsExtension::MyEventsBasedBehavior::MyBehaviorEventsFunctionExpression // function name without calling the function (it's ill-named). { gd::StandardEvent event; gd::Instruction instruction; instruction.SetType("MyExtension::DoSomething"); instruction.SetParametersCount(1); instruction.SetParameter( 0, gd::Expression("4 + " "ObjectWithMyBehavior::MyBehavior." "MyBehaviorEventsFunctionExpression")); event.GetActions().Insert(instruction); externalEvents.GetEvents().InsertEvent(event); } } return eventsExtension; } } // namespace TEST_CASE("WholeProjectRefactorer", "[common]") { SECTION("Object deleted (in layout)") { SECTION("Groups") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &layout1 = project.InsertNewLayout("Layout1", 0); gd::ObjectGroup group1; group1.AddObject("Object1"); group1.AddObject("Object2"); group1.AddObject("NotExistingObject"); group1.AddObject("GlobalObject1"); layout1.GetObjectGroups().Insert(group1); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0); gd::WholeProjectRefactorer::ObjectOrGroupRemovedInLayout( project, layout1, "Object1", /* isObjectGroup =*/false); gd::WholeProjectRefactorer::GlobalObjectOrGroupRemoved( project, "GlobalObject1", /* isObjectGroup =*/false); REQUIRE(layout1.GetObjectGroups()[0].Find("Object1") == false); REQUIRE(layout1.GetObjectGroups()[0].Find("Object2") == true); REQUIRE(layout1.GetObjectGroups()[0].Find("NotExistingObject") == true); REQUIRE(layout1.GetObjectGroups()[0].Find("GlobalObject1") == false); } SECTION("Initial instances") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &layout1 = project.InsertNewLayout("Layout1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0); gd::InitialInstance instance1; instance1.SetObjectName("Object1"); gd::InitialInstance instance2; instance2.SetObjectName("Object2"); gd::InitialInstance instance3; instance3.SetObjectName("GlobalObject1"); layout1.GetInitialInstances().InsertInitialInstance(instance1); layout1.GetInitialInstances().InsertInitialInstance(instance2); layout1.GetInitialInstances().InsertInitialInstance(instance3); gd::WholeProjectRefactorer::ObjectOrGroupRemovedInLayout( project, layout1, "Object1", /* isObjectGroup =*/false); gd::WholeProjectRefactorer::GlobalObjectOrGroupRemoved( project, "GlobalObject1", /* isObjectGroup =*/false); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject("Object1") == false); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject("Object2") == true); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject( "GlobalObject1") == false); } SECTION("Initial instances in associated external layouts") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &layout1 = project.InsertNewLayout("Layout1", 0); auto &layout2 = project.InsertNewLayout("Layout2", 0); auto &externalLayout1 = project.InsertNewExternalLayout("ExternalLayout1", 0); auto &externalLayout2 = project.InsertNewExternalLayout("ExternalLayout2", 0); externalLayout1.SetAssociatedLayout("Layout1"); externalLayout2.SetAssociatedLayout("Layout2"); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0); gd::InitialInstance instance1; instance1.SetObjectName("Object1"); gd::InitialInstance instance2; instance2.SetObjectName("Object2"); gd::InitialInstance instance3; instance3.SetObjectName("GlobalObject1"); externalLayout1.GetInitialInstances().InsertInitialInstance(instance1); externalLayout1.GetInitialInstances().InsertInitialInstance(instance2); externalLayout1.GetInitialInstances().InsertInitialInstance(instance3); externalLayout2.GetInitialInstances().InsertInitialInstance(instance1); externalLayout2.GetInitialInstances().InsertInitialInstance(instance2); externalLayout2.GetInitialInstances().InsertInitialInstance(instance3); gd::WholeProjectRefactorer::ObjectOrGroupRemovedInLayout( project, layout1, "Object1", /* isObjectGroup =*/false); gd::WholeProjectRefactorer::GlobalObjectOrGroupRemoved( project, "GlobalObject1", /* isObjectGroup =*/false); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "Object1") == false); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "Object2") == true); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "GlobalObject1") == false); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "Object1") == true); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "Object2") == true); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "GlobalObject1") == false); } } SECTION("Object renamed (in layout)") { SECTION("Groups") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &layout1 = project.InsertNewLayout("Layout1", 0); gd::ObjectGroup group1; group1.AddObject("Object1"); group1.AddObject("Object2"); group1.AddObject("NotExistingObject"); group1.AddObject("GlobalObject1"); layout1.GetObjectGroups().Insert(group1); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0); gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout( project, layout1, "Object1", "Object3", /* isObjectGroup =*/false); gd::WholeProjectRefactorer::GlobalObjectOrGroupRenamed( project, "GlobalObject1", "GlobalObject3", /* isObjectGroup =*/false); REQUIRE(layout1.GetObjectGroups()[0].Find("Object1") == false); REQUIRE(layout1.GetObjectGroups()[0].Find("Object2") == true); REQUIRE(layout1.GetObjectGroups()[0].Find("Object3") == true); REQUIRE(layout1.GetObjectGroups()[0].Find("GlobalObject1") == false); REQUIRE(layout1.GetObjectGroups()[0].Find("GlobalObject3") == true); } SECTION("Initial instances") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &layout1 = project.InsertNewLayout("Layout1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0); gd::InitialInstance instance1; instance1.SetObjectName("Object1"); gd::InitialInstance instance2; instance2.SetObjectName("Object2"); gd::InitialInstance instance3; instance3.SetObjectName("GlobalObject1"); layout1.GetInitialInstances().InsertInitialInstance(instance1); layout1.GetInitialInstances().InsertInitialInstance(instance2); layout1.GetInitialInstances().InsertInitialInstance(instance3); gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout( project, layout1, "Object1", "Object3", /* isObjectGroup =*/false); gd::WholeProjectRefactorer::GlobalObjectOrGroupRenamed( project, "GlobalObject1", "GlobalObject3", /* isObjectGroup =*/false); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject("Object1") == false); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject("Object3") == true); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject( "GlobalObject1") == false); REQUIRE(layout1.GetInitialInstances().HasInstancesOfObject( "GlobalObject3") == true); } SECTION("Initial instances in associated external layouts") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &layout1 = project.InsertNewLayout("Layout1", 0); auto &layout2 = project.InsertNewLayout("Layout2", 0); auto &externalLayout1 = project.InsertNewExternalLayout("ExternalLayout1", 0); auto &externalLayout2 = project.InsertNewExternalLayout("ExternalLayout2", 0); externalLayout1.SetAssociatedLayout("Layout1"); externalLayout2.SetAssociatedLayout("Layout2"); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object1", 0); layout1.InsertNewObject(project, "MyExtension::Sprite", "Object2", 0); gd::InitialInstance instance1; instance1.SetObjectName("Object1"); gd::InitialInstance instance2; instance2.SetObjectName("Object2"); gd::InitialInstance instance3; instance3.SetObjectName("GlobalObject1"); externalLayout1.GetInitialInstances().InsertInitialInstance(instance1); externalLayout1.GetInitialInstances().InsertInitialInstance(instance2); externalLayout1.GetInitialInstances().InsertInitialInstance(instance3); externalLayout2.GetInitialInstances().InsertInitialInstance(instance1); externalLayout2.GetInitialInstances().InsertInitialInstance(instance2); externalLayout2.GetInitialInstances().InsertInitialInstance(instance3); gd::WholeProjectRefactorer::ObjectOrGroupRenamedInLayout( project, layout1, "Object1", "Object3", /* isObjectGroup =*/false); gd::WholeProjectRefactorer::GlobalObjectOrGroupRenamed( project, "GlobalObject1", "GlobalObject3", /* isObjectGroup =*/false); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "Object1") == false); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "Object2") == true); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "Object3") == true); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "GlobalObject1") == false); REQUIRE(externalLayout1.GetInitialInstances().HasInstancesOfObject( "GlobalObject3") == true); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "Object1") == true); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "Object2") == true); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "Object3") == false); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "GlobalObject1") == false); REQUIRE(externalLayout2.GetInitialInstances().HasInstancesOfObject( "GlobalObject3") == true); } } SECTION("Object renamed (in events function)") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0); // Add a (free) function with an object group gd::EventsFunction &eventsFunction = eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0); gd::ObjectGroup &objectGroup = eventsFunction.GetObjectGroups().InsertNew("MyGroup", 0); objectGroup.AddObject("Object1"); objectGroup.AddObject("Object2"); // In theory, we would add the object parameters, but we're not testing // events in this test. // Create the objects container for the events function gd::ObjectsContainer globalObjectsContainer; gd::ObjectsContainer objectsContainer; gd::ParameterMetadataTools::ParametersToObjectsContainer( project, eventsFunction.GetParameters(), objectsContainer); // (this is strictly not necessary because we're not testing events in this // test) // Trigger the refactoring after the renaming of an object gd::WholeProjectRefactorer::ObjectOrGroupRenamedInEventsFunction( project, eventsFunction, globalObjectsContainer, objectsContainer, "Object1", "RenamedObject1", /* isObjectGroup=*/false); REQUIRE(objectGroup.Find("Object1") == false); REQUIRE(objectGroup.Find("RenamedObject1") == true); REQUIRE(objectGroup.Find("Object2") == true); // Events are not tested } SECTION("Object deleted (in events function)") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0); // Add a (free) function with an object group gd::EventsFunction &eventsFunction = eventsExtension.InsertNewEventsFunction("MyEventsFunction", 0); gd::ObjectGroup &objectGroup = eventsFunction.GetObjectGroups().InsertNew("MyGroup", 0); objectGroup.AddObject("Object1"); objectGroup.AddObject("Object2"); // In theory, we would add the object parameters, but we're not testing // events in this test. // Create the objects container for the events function gd::ObjectsContainer globalObjectsContainer; gd::ObjectsContainer objectsContainer; gd::ParameterMetadataTools::ParametersToObjectsContainer( project, eventsFunction.GetParameters(), objectsContainer); // (this is strictly not necessary because we're not testing events in this // test) // Trigger the refactoring after the renaming of an object gd::WholeProjectRefactorer::ObjectOrGroupRemovedInEventsFunction( project, eventsFunction, globalObjectsContainer, objectsContainer, "Object1", /* isObjectGroup=*/false); REQUIRE(objectGroup.Find("Object1") == false); REQUIRE(objectGroup.Find("Object2") == true); // Events are not tested } SECTION("Events extension renamed") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); gd::WholeProjectRefactorer::RenameEventsFunctionsExtension( project, eventsExtension, "MyEventsExtension", "MyRenamedExtension"); // Check that events function calls in instructions have been renamed REQUIRE(GetEventFirstActionType(project.GetLayout("LayoutWithFreeFunctions") .GetEvents() .GetEvent(0)) == "MyRenamedExtension::MyEventsFunction"); // Check that events function calls in expressions have been renamed REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithFreeFunctions") .GetEvents() .GetEvent(0)) == "1 + MyRenamedExtension::MyEventsFunctionExpression(123, 456)"); // Check that the type of the behavior was changed in the behaviors of // objects. Name is *not* changed. REQUIRE(project.GetLayout("LayoutWithBehaviorFunctions") .GetObject("ObjectWithMyBehavior") .GetBehavior("MyBehavior") .GetTypeName() == "MyRenamedExtension::MyEventsBasedBehavior"); REQUIRE(project.GetObject("GlobalObjectWithMyBehavior") .GetBehavior("MyBehavior") .GetTypeName() == "MyRenamedExtension::MyEventsBasedBehavior"); // Check if events-based behavior methods have been renamed in // instructions REQUIRE( GetEventFirstActionType(project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "MyRenamedExtension::MyEventsBasedBehavior::" "MyBehaviorEventsFunction"); // Check if events-based behaviors properties have been renamed in // instructions REQUIRE( GetEventFirstActionType(project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(1)) == "MyRenamedExtension::MyEventsBasedBehavior::" "SetPropertyMyProperty"); // Check events-based behavior methods have *not* been renamed in // expressions REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "1 + " "ObjectWithMyBehavior.MyBehavior::" "MyBehaviorEventsFunctionExpression(123, 456, 789)"); REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(2)) == "3 + " "ObjectWithMyBehavior.MyBehavior::" "MyBehaviorEventsFunctionExpression"); } SECTION("(Free) events function renamed") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); gd::WholeProjectRefactorer::RenameEventsFunction(project, eventsExtension, "MyEventsFunction", "MyRenamedEventsFunction"); gd::WholeProjectRefactorer::RenameEventsFunction( project, eventsExtension, "MyEventsFunctionExpression", "MyRenamedFunctionExpression"); // Check that events function calls in instructions have been renamed REQUIRE(GetEventFirstActionType(project.GetLayout("LayoutWithFreeFunctions") .GetEvents() .GetEvent(0)) == "MyEventsExtension::MyRenamedEventsFunction"); // Check that events function calls in expressions have been renamed REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithFreeFunctions") .GetEvents() .GetEvent(0)) == "1 + MyEventsExtension::MyRenamedFunctionExpression(123, 456)"); } SECTION("(Free) events function parameter moved") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); gd::WholeProjectRefactorer::MoveEventsFunctionParameter( project, eventsExtension, "MyEventsFunction", 0, 2); gd::WholeProjectRefactorer::MoveEventsFunctionParameter( project, eventsExtension, "MyEventsFunctionExpression", 0, 1); // Check that events function calls in instructions have been updated auto &action = static_cast( project.GetLayout("LayoutWithFreeFunctions") .GetEvents() .GetEvent(0)) .GetActions() .Get(0); REQUIRE(action.GetParameter(0).GetPlainString() == "Second parameter"); REQUIRE(action.GetParameter(1).GetPlainString() == "Third parameter"); REQUIRE(action.GetParameter(2).GetPlainString() == "First parameter"); // Check that events function calls in expressions have been updated REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithFreeFunctions") .GetEvents() .GetEvent(0)) == "1 + MyEventsExtension::MyEventsFunctionExpression(456, 123)"); } SECTION("Events based Behavior type renamed") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); auto &eventsBasedBehavior = eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior"); gd::WholeProjectRefactorer::RenameEventsBasedBehavior( project, eventsExtension, "MyEventsBasedBehavior", "MyRenamedEventsBasedBehavior"); // Check that the type of the behavior was changed in the behaviors of // objects. Name is *not* changed. REQUIRE(project.GetLayout("LayoutWithBehaviorFunctions") .GetObject("ObjectWithMyBehavior") .GetBehavior("MyBehavior") .GetTypeName() == "MyEventsExtension::MyRenamedEventsBasedBehavior"); REQUIRE(project.GetObject("GlobalObjectWithMyBehavior") .GetBehavior("MyBehavior") .GetTypeName() == "MyEventsExtension::MyRenamedEventsBasedBehavior"); // Check if events-based behavior methods have been renamed in // instructions REQUIRE( GetEventFirstActionType(project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "MyEventsExtension::MyRenamedEventsBasedBehavior::" "MyBehaviorEventsFunction"); // Check if events-based behaviors properties have been renamed in // instructions REQUIRE( GetEventFirstActionType(project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(1)) == "MyEventsExtension::MyRenamedEventsBasedBehavior::" "SetPropertyMyProperty"); // Check events-based behavior methods have *not* been renamed in // expressions REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "1 + " "ObjectWithMyBehavior.MyBehavior::" "MyBehaviorEventsFunctionExpression(123, 456, 789)"); } SECTION("(Events based Behavior) events function renamed") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); auto &eventsBasedBehavior = eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior"); gd::WholeProjectRefactorer::RenameBehaviorEventsFunction( project, eventsExtension, eventsBasedBehavior, "MyBehaviorEventsFunction", "MyRenamedBehaviorEventsFunction"); gd::WholeProjectRefactorer::RenameBehaviorEventsFunction( project, eventsExtension, eventsBasedBehavior, "MyBehaviorEventsFunctionExpression", "MyRenamedBehaviorEventsFunctionExpression"); // Check if events-based behavior methods have been renamed in // instructions REQUIRE( GetEventFirstActionType(project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "MyEventsExtension::MyEventsBasedBehavior::" "MyRenamedBehaviorEventsFunction"); // Check events-based behavior methods have been renamed in // expressions REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "1 + " "ObjectWithMyBehavior.MyBehavior::" "MyRenamedBehaviorEventsFunctionExpression(123, 456, 789)"); // Check that a ill-named function that looks a bit like a behavior method // (but which is actually an object function) is *not* renamed. REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(1)) == "2 + " "ObjectWithMyBehavior::MyBehavior." "MyBehaviorEventsFunctionExpression(123, 456, 789)"); // Check events based behaviors functions have been renamed in // expressions referring to the function with just its name REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(2)) == "3 + " "ObjectWithMyBehavior.MyBehavior::" "MyRenamedBehaviorEventsFunctionExpression"); // Check that a ill-named function that looks a bit like a behavior method // (but which is actually an object function) is *not* renamed. REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(3)) == "4 + " "ObjectWithMyBehavior::MyBehavior." "MyBehaviorEventsFunctionExpression"); } SECTION("(Events based Behavior) events function parameter moved") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); auto &eventsBasedBehavior = eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior"); gd::WholeProjectRefactorer::MoveBehaviorEventsFunctionParameter( project, eventsExtension, eventsBasedBehavior, "MyBehaviorEventsFunction", 0, 2); gd::WholeProjectRefactorer::MoveBehaviorEventsFunctionParameter( project, eventsExtension, eventsBasedBehavior, "MyBehaviorEventsFunctionExpression", 0, 2); // Check if parameters of events-based behavior methods have been moved in // instructions auto &action = static_cast( project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(0)) .GetActions() .Get(0); REQUIRE(action.GetParameter(0).GetPlainString() == "Second parameter"); REQUIRE(action.GetParameter(1).GetPlainString() == "Third parameter"); REQUIRE(action.GetParameter(2).GetPlainString() == "First parameter"); // Check parameters of events-based behavior methods have been moved in // expressions REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(0)) == "1 + " "ObjectWithMyBehavior.MyBehavior::" "MyBehaviorEventsFunctionExpression(456, 789, 123)"); // Check that a ill-named function that looks a bit like a behavior method // (but which is actually a free function) has its parameter *not* moved. REQUIRE(GetEventFirstActionFirstParameterString( project.GetExternalEvents("ExternalEventsWithBehaviorFunctions") .GetEvents() .GetEvent(1)) == "2 + " "ObjectWithMyBehavior::MyBehavior." "MyBehaviorEventsFunctionExpression(123, 456, 789)"); } SECTION("(Events based Behavior) property renamed") { gd::Project project; gd::Platform platform; SetupProjectWithDummyPlatform(project, platform); auto &eventsExtension = SetupProjectWithEventsFunctionExtension(project); auto &eventsBasedBehavior = eventsExtension.GetEventsBasedBehaviors().Get("MyEventsBasedBehavior"); gd::WholeProjectRefactorer::RenameBehaviorProperty(project, eventsExtension, eventsBasedBehavior, "MyProperty", "MyRenamedProperty"); // Check if events-based behaviors property has been renamed in // instructions REQUIRE( GetEventFirstActionType(project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(1)) == "MyEventsExtension::MyEventsBasedBehavior::" "SetPropertyMyRenamedProperty"); REQUIRE(GetEventFirstConditionType( project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(2)) == "MyEventsExtension::MyEventsBasedBehavior::" "PropertyMyRenamedProperty"); REQUIRE(GetEventFirstActionFirstParameterString( project.GetLayout("LayoutWithBehaviorFunctions") .GetEvents() .GetEvent(3)) == "ObjectWithMyBehavior.MyBehavior::PropertyMyRenamedProperty()"); } }