mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-21 09:35:27 -04:00
223 lines
8.4 KiB
C++
223 lines
8.4 KiB
C++
/*
|
|
* 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 serialization to JSON.
|
|
*/
|
|
#include "DummyPlatform.h"
|
|
#include "GDCore/CommonTools.h"
|
|
#include "GDCore/Events/Builtin/StandardEvent.h"
|
|
#include "GDCore/Events/Event.h"
|
|
#include "GDCore/Events/EventsList.h"
|
|
#include "GDCore/Events/Serialization.h"
|
|
#include "GDCore/Extensions/Platform.h"
|
|
#include "GDCore/Project/EventsFunctionsExtension.h"
|
|
#include "GDCore/Project/Layout.h"
|
|
#include "GDCore/Project/Object.h"
|
|
#include "GDCore/Project/ObjectsContainer.h"
|
|
#include "GDCore/Project/Project.h"
|
|
#include "GDCore/Project/Variable.h"
|
|
#include "GDCore/Serialization/Serializer.h"
|
|
#include "GDCore/Tools/SystemStats.h"
|
|
#include "GDCore/Tools/VersionWrapper.h"
|
|
#include "catch.hpp"
|
|
|
|
using namespace gd;
|
|
|
|
namespace {
|
|
|
|
void AddEventsBasedExtension(gd::Project &project) {
|
|
auto &eventsExtension =
|
|
project.InsertNewEventsFunctionsExtension("MyEventsExtension", 0);
|
|
|
|
auto &eventsBasedBehavior =
|
|
eventsExtension.GetEventsBasedBehaviors().InsertNew(
|
|
"MyEventsBasedBehavior", 0);
|
|
eventsBasedBehavior.SetFullName("My events based behavior");
|
|
eventsBasedBehavior.SetDescription("An events based behavior for test");
|
|
eventsBasedBehavior.SetObjectType("");
|
|
eventsBasedBehavior.GetPropertyDescriptors()
|
|
.InsertNew("MyProperty", 0)
|
|
.SetType("Number");
|
|
};
|
|
|
|
void AddAnotherEventsBasedExtensionWithDependency(gd::Project &project) {
|
|
auto &eventsExtension =
|
|
project.InsertNewEventsFunctionsExtension("MyOtherEventsExtension", 0);
|
|
|
|
auto &eventsBasedObject = eventsExtension.GetEventsBasedObjects().InsertNew(
|
|
"MyEventsBasedObject", 0);
|
|
eventsBasedObject.SetFullName("My events based object");
|
|
eventsBasedObject.SetDescription("An events based object for test");
|
|
|
|
gd::Object &object = eventsBasedObject.GetObjects().InsertNewObject(
|
|
project, "MyExtension::Sprite", "MyObject", 0);
|
|
gd::Behavior *behavior =
|
|
object.AddNewBehavior(project, "MyEventsExtension::MyEventsBasedBehavior",
|
|
"MyEventsBasedBehavior");
|
|
behavior->UpdateProperty("MyProperty", "481516");
|
|
};
|
|
|
|
void SetupProject(gd::Project &project, gd::Platform &platform) {
|
|
SetupProjectWithDummyPlatform(project, platform);
|
|
AddEventsBasedExtension(project);
|
|
|
|
gd::Layout &layout = project.InsertNewLayout("Scene", 0);
|
|
gd::Object &object = layout.GetObjects().InsertNewObject(
|
|
project, "MyExtension::Sprite", "MyObject", 0);
|
|
gd::Behavior *behavior =
|
|
object.AddNewBehavior(project, "MyEventsExtension::MyEventsBasedBehavior",
|
|
"MyEventsBasedBehavior");
|
|
behavior->UpdateProperty("MyProperty", "481516");
|
|
};
|
|
|
|
void CheckBehaviorPropertyInObjectContainerElement(
|
|
SerializerElement &objectContainerElement) {
|
|
REQUIRE(objectContainerElement.HasChild("objects"));
|
|
|
|
auto &objectsElement = objectContainerElement.GetChild("objects");
|
|
objectsElement.ConsiderAsArrayOf("object");
|
|
REQUIRE(objectsElement.GetChildrenCount() == 1);
|
|
auto &objectElement = objectsElement.GetChild(0);
|
|
|
|
REQUIRE(objectElement.GetStringAttribute("name") == "MyObject");
|
|
REQUIRE(objectElement.GetStringAttribute("type") == "MyExtension::Sprite");
|
|
REQUIRE(objectElement.HasChild("behaviors"));
|
|
|
|
auto &behaviorsElement = objectElement.GetChild("behaviors");
|
|
behaviorsElement.ConsiderAsArrayOf("behavior");
|
|
REQUIRE(behaviorsElement.GetChildrenCount() == 1);
|
|
auto &behaviorElement = behaviorsElement.GetChild(0);
|
|
|
|
REQUIRE(behaviorElement.GetStringAttribute("name") ==
|
|
"MyEventsBasedBehavior");
|
|
REQUIRE(behaviorElement.GetStringAttribute("type") ==
|
|
"MyEventsExtension::MyEventsBasedBehavior");
|
|
REQUIRE(behaviorElement.GetStringAttribute("MyProperty") == "481516");
|
|
};
|
|
|
|
void CheckBehaviorPropertyInElement(SerializerElement &projectElement) {
|
|
auto &layoutsElement = projectElement.GetChild("layouts");
|
|
layoutsElement.ConsiderAsArrayOf("layout");
|
|
REQUIRE(layoutsElement.GetChildrenCount() == 1);
|
|
auto &layoutElement = layoutsElement.GetChild(0);
|
|
|
|
REQUIRE(layoutElement.GetStringAttribute("name") == "Scene");
|
|
CheckBehaviorPropertyInObjectContainerElement(layoutElement);
|
|
};
|
|
|
|
void CheckBehaviorProperty(ObjectsContainer &container) {
|
|
auto &object = container.GetObject("MyObject");
|
|
REQUIRE(object.GetType() == "MyExtension::Sprite");
|
|
REQUIRE(object.HasBehaviorNamed("MyEventsBasedBehavior"));
|
|
|
|
auto &behavior = object.GetBehavior("MyEventsBasedBehavior");
|
|
REQUIRE(behavior.GetTypeName() == "MyEventsExtension::MyEventsBasedBehavior");
|
|
REQUIRE(behavior.GetProperties().size() == 1);
|
|
REQUIRE(behavior.GetProperties().at("MyProperty").GetValue() == "481516");
|
|
};
|
|
} // namespace
|
|
|
|
// TODO EBO Add similar test cases for events-based objects.
|
|
TEST_CASE("BehaviorSerialization", "[common]") {
|
|
|
|
SECTION("Save and load a project with a custom behavior property value") {
|
|
gd::Platform platform;
|
|
gd::Project writtenProject;
|
|
SetupProject(writtenProject, platform);
|
|
CheckBehaviorProperty(
|
|
writtenProject.GetLayout("Scene").GetObjects());
|
|
|
|
SerializerElement projectElement;
|
|
writtenProject.SerializeTo(projectElement);
|
|
CheckBehaviorPropertyInElement(projectElement);
|
|
|
|
gd::Project readProject;
|
|
readProject.AddPlatform(platform);
|
|
readProject.UnserializeFrom(projectElement);
|
|
CheckBehaviorProperty(readProject.GetLayout("Scene").GetObjects());
|
|
}
|
|
|
|
SECTION("Copy constructor of Behavior") {
|
|
gd::Platform platform;
|
|
gd::Project originalProject;
|
|
SetupProject(originalProject, platform);
|
|
CheckBehaviorProperty(originalProject.GetLayout("Scene").GetObjects());
|
|
|
|
auto clonedProject = originalProject;
|
|
|
|
CheckBehaviorProperty(clonedProject.GetLayout("Scene").GetObjects());
|
|
}
|
|
|
|
SECTION("Load a project with a property value on a custom behavior that no longer exists") {
|
|
gd::Platform platform;
|
|
gd::Project writtenProject;
|
|
SetupProject(writtenProject, platform);
|
|
|
|
// Remove the events-based behavior
|
|
writtenProject.RemoveEventsFunctionsExtension("MyEventsExtension");
|
|
|
|
SerializerElement projectElement;
|
|
writtenProject.SerializeTo(projectElement);
|
|
CheckBehaviorPropertyInElement(projectElement);
|
|
|
|
gd::Project readProject;
|
|
readProject.AddPlatform(platform);
|
|
readProject.UnserializeFrom(projectElement);
|
|
|
|
// Add the events-based behavior back
|
|
AddEventsBasedExtension(readProject);
|
|
|
|
CheckBehaviorProperty(readProject.GetLayout("Scene").GetObjects());
|
|
}
|
|
|
|
SECTION("Save and load a project with an event based extension dependency") {
|
|
gd::Platform platform;
|
|
gd::Project writtenProject;
|
|
SetupProject(writtenProject, platform);
|
|
AddAnotherEventsBasedExtensionWithDependency(writtenProject);
|
|
|
|
// It's important that the extension with the dependency is the first one.
|
|
REQUIRE(writtenProject.GetEventsFunctionsExtension(0).GetName() ==
|
|
"MyOtherEventsExtension");
|
|
REQUIRE(writtenProject.GetEventsFunctionsExtension(1).GetName() ==
|
|
"MyEventsExtension");
|
|
|
|
SerializerElement projectElement;
|
|
writtenProject.SerializeTo(projectElement);
|
|
|
|
auto &extensionsElement =
|
|
projectElement.GetChild("eventsFunctionsExtensions");
|
|
extensionsElement.ConsiderAsArrayOf("eventsFunctionsExtension");
|
|
REQUIRE(extensionsElement.GetChildrenCount() == 2);
|
|
|
|
auto &firstExtensionElement = extensionsElement.GetChild(0);
|
|
REQUIRE(firstExtensionElement.GetStringAttribute("name") ==
|
|
"MyOtherEventsExtension");
|
|
auto &eventsBasedObjectsElement =
|
|
firstExtensionElement.GetChild("eventsBasedObjects");
|
|
eventsBasedObjectsElement.ConsiderAsArrayOf("eventsBasedObject");
|
|
auto &eventsBasedObjectElement =
|
|
eventsBasedObjectsElement.GetChild(0);
|
|
CheckBehaviorPropertyInObjectContainerElement(eventsBasedObjectElement);
|
|
|
|
auto &secondExtensionElement = extensionsElement.GetChild(1);
|
|
REQUIRE(secondExtensionElement.GetStringAttribute("name") ==
|
|
"MyEventsExtension");
|
|
|
|
gd::Project readProject;
|
|
readProject.AddPlatform(platform);
|
|
readProject.UnserializeFrom(projectElement);
|
|
|
|
// The custom behavior is unserialized even though it depends on the other
|
|
// extension.
|
|
REQUIRE(readProject.HasEventsBasedObject(
|
|
"MyOtherEventsExtension::MyEventsBasedObject"));
|
|
CheckBehaviorProperty(
|
|
readProject
|
|
.GetEventsBasedObject("MyOtherEventsExtension::MyEventsBasedObject")
|
|
.GetObjects());
|
|
}
|
|
} |