aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/AssetTest.cpp21
-rw-r--r--src/test/CMakeLists.txt10
-rw-r--r--src/test/DBTest.cpp28
-rw-r--r--src/test/ECSTest.cpp387
-rw-r--r--src/test/EventTest.cpp254
-rw-r--r--src/test/OptionalRefTest.cpp42
-rw-r--r--src/test/ParticleTest.cpp18
-rw-r--r--src/test/PhysicsTest.cpp4
-rw-r--r--src/test/RenderSystemTest.cpp166
-rw-r--r--src/test/SceneManagerTest.cpp160
-rw-r--r--src/test/ScriptTest.cpp99
-rw-r--r--src/test/ValueBrokerTest.cpp63
-rw-r--r--src/test/Vector2Test.cpp384
-rw-r--r--src/test/main.cpp23
14 files changed, 1622 insertions, 37 deletions
diff --git a/src/test/AssetTest.cpp b/src/test/AssetTest.cpp
new file mode 100644
index 0000000..93fd6a9
--- /dev/null
+++ b/src/test/AssetTest.cpp
@@ -0,0 +1,21 @@
+#include <gtest/gtest.h>
+
+#include <crepe/api/Asset.h>
+#include <crepe/api/Config.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+TEST(AssetTest, Existant) { ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); }
+
+TEST(AssetTest, Nonexistant) { ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); }
+
+TEST(AssetTest, Rootless) {
+ Config & cfg = Config::get_instance();
+ cfg.asset.root_pattern.clear();
+
+ string arbitrary = "\\/this is / /../passed through as-is";
+ Asset asset{arbitrary};
+ ASSERT_EQ(arbitrary, asset.get_path());
+}
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 49c8151..d310f6a 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -3,5 +3,13 @@ target_sources(test_main PUBLIC
PhysicsTest.cpp
ScriptTest.cpp
ParticleTest.cpp
+ AssetTest.cpp
+ OptionalRefTest.cpp
+ RenderSystemTest.cpp
+ EventTest.cpp
+ ECSTest.cpp
+ SceneManagerTest.cpp
+ ValueBrokerTest.cpp
+ DBTest.cpp
+ Vector2Test.cpp
)
-
diff --git a/src/test/DBTest.cpp b/src/test/DBTest.cpp
new file mode 100644
index 0000000..e80814c
--- /dev/null
+++ b/src/test/DBTest.cpp
@@ -0,0 +1,28 @@
+#include <crepe/facade/DB.h>
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class DBTest : public Test {
+public:
+ DB db;
+};
+
+TEST_F(DBTest, ReadWrite) {
+ db.set("foo", "bar");
+ EXPECT_EQ(db.get("foo"), "bar");
+}
+
+TEST_F(DBTest, Nonexistant) {
+ EXPECT_THROW(db.get("foo"), std::out_of_range);
+ db.set("foo", "bar");
+ EXPECT_NO_THROW(db.get("foo"));
+}
+
+TEST_F(DBTest, Has) {
+ EXPECT_EQ(db.has("foo"), false);
+ db.set("foo", "bar");
+ EXPECT_EQ(db.has("foo"), true);
+}
diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp
new file mode 100644
index 0000000..af9d6f2
--- /dev/null
+++ b/src/test/ECSTest.cpp
@@ -0,0 +1,387 @@
+#include <gtest/gtest.h>
+
+#define protected public
+
+#include <crepe/ComponentManager.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Metadata.h>
+#include <crepe/api/Transform.h>
+#include <crepe/api/Vector2.h>
+
+using namespace std;
+using namespace crepe;
+
+class ECSTest : public ::testing::Test {
+public:
+ ComponentManager mgr{};
+};
+
+TEST_F(ECSTest, createGameObject) {
+ GameObject obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().name, "body");
+ EXPECT_EQ(metadata[0].get().tag, "person");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+ EXPECT_EQ(transform[0].get().rotation, 0);
+ EXPECT_EQ(transform[0].get().scale, 1);
+}
+
+TEST_F(ECSTest, deleteAllGameObjects) {
+ GameObject obj0 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+ GameObject obj1 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+
+ mgr.delete_all_components();
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 0);
+ EXPECT_EQ(transform.size(), 0);
+
+ GameObject obj2 = mgr.new_object("body2", "person2", vec2{1, 0}, 5, 1);
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "body2");
+ EXPECT_EQ(metadata[0].get().tag, "person2");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+
+ EXPECT_EQ(transform[0].get().game_object_id, 0);
+ EXPECT_EQ(transform[0].get().position.x, 1);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+ EXPECT_EQ(transform[0].get().rotation, 5);
+ EXPECT_EQ(transform[0].get().scale, 1);
+}
+
+TEST_F(ECSTest, deleteGameObject) {
+ GameObject obj0 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+ GameObject obj1 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+
+ mgr.delete_all_components_of_id(0);
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 1);
+ EXPECT_EQ(metadata[0].get().name, "body");
+ EXPECT_EQ(metadata[0].get().tag, "person");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+
+ EXPECT_EQ(transform[0].get().game_object_id, 1);
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+ EXPECT_EQ(transform[0].get().rotation, 0);
+ EXPECT_EQ(transform[0].get().scale, 1);
+}
+
+TEST_F(ECSTest, manyGameObjects) {
+ for (int i = 0; i < 5000; i++) {
+ GameObject obj = mgr.new_object("body", "person", vec2{0, 0}, 0, i);
+ }
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 5000);
+ EXPECT_EQ(transform.size(), 5000);
+ for (int i = 0; i < 5000; i++) {
+ EXPECT_EQ(metadata[i].get().game_object_id, i);
+ EXPECT_EQ(metadata[i].get().name, "body");
+ EXPECT_EQ(metadata[i].get().tag, "person");
+ EXPECT_EQ(metadata[i].get().parent, -1);
+ EXPECT_EQ(metadata[i].get().children.size(), 0);
+
+ EXPECT_EQ(transform[i].get().game_object_id, i);
+ EXPECT_EQ(transform[i].get().position.x, 0);
+ EXPECT_EQ(transform[i].get().position.y, 0);
+ EXPECT_EQ(transform[i].get().rotation, 0);
+ EXPECT_EQ(transform[i].get().scale, i);
+ }
+
+ mgr.delete_components<Metadata>();
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 0);
+ EXPECT_EQ(transform.size(), 5000);
+
+ for (int i = 0; i < 10000 - 5000; i++) {
+ string tag = "person" + to_string(i);
+ GameObject obj = mgr.new_object("body", tag, vec2{0, 0}, i, 0);
+ }
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 10000 - 5000);
+ EXPECT_EQ(transform.size(), 10000);
+
+ for (int i = 0; i < 10000 - 5000; i++) {
+ EXPECT_EQ(metadata[i].get().game_object_id, i + 5000);
+ EXPECT_EQ(metadata[i].get().name, "body");
+ EXPECT_EQ(metadata[i].get().tag, "person" + to_string(i));
+ EXPECT_EQ(metadata[i].get().parent, -1);
+ EXPECT_EQ(metadata[i].get().children.size(), 0);
+
+ EXPECT_EQ(transform[i].get().game_object_id, i);
+ EXPECT_EQ(transform[i].get().position.x, 0);
+ EXPECT_EQ(transform[i].get().position.y, 0);
+ EXPECT_EQ(transform[i].get().rotation, 0);
+ EXPECT_EQ(transform[i].get().scale, i);
+ }
+
+ mgr.delete_all_components();
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 0);
+ EXPECT_EQ(transform.size(), 0);
+
+ for (int i = 0; i < 10000; i++) {
+ string name = "body" + to_string(i);
+ GameObject obj = mgr.new_object(name, "person", vec2{0, 0}, 0, 0);
+ }
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 10000);
+ EXPECT_EQ(transform.size(), 10000);
+
+ for (int i = 0; i < 10000; i++) {
+ EXPECT_EQ(metadata[i].get().game_object_id, i);
+ EXPECT_EQ(metadata[i].get().name, "body" + to_string(i));
+ EXPECT_EQ(metadata[i].get().tag, "person");
+ EXPECT_EQ(metadata[i].get().parent, -1);
+ EXPECT_EQ(metadata[i].get().children.size(), 0);
+
+ EXPECT_EQ(transform[i].get().game_object_id, i);
+ EXPECT_EQ(transform[i].get().position.x, 0);
+ EXPECT_EQ(transform[i].get().position.y, 0);
+ EXPECT_EQ(transform[i].get().rotation, 0);
+ EXPECT_EQ(transform[i].get().scale, 0);
+ }
+}
+
+TEST_F(ECSTest, getComponentsByID) {
+ GameObject obj0 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+ GameObject obj1 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_id<Metadata>(0);
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_id<Transform>(1);
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "body");
+ EXPECT_EQ(metadata[0].get().tag, "person");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+
+ EXPECT_EQ(transform[0].get().game_object_id, 1);
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+ EXPECT_EQ(transform[0].get().rotation, 0);
+ EXPECT_EQ(transform[0].get().scale, 1);
+}
+
+TEST_F(ECSTest, tooMuchComponents) {
+ try {
+ GameObject obj0 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+ obj0.add_component<Transform>(vec2{10, 10}, 0, 1);
+ } catch (const exception & e) {
+ EXPECT_EQ(e.what(),
+ string("Exceeded maximum number of instances for this component type"));
+ }
+
+ try {
+ GameObject obj1 = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+ obj1.add_component<Metadata>("body", "person");
+ } catch (const exception & e) {
+ EXPECT_EQ(e.what(),
+ string("Exceeded maximum number of instances for this component type"));
+ }
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+
+ EXPECT_EQ(metadata.size(), 2);
+ EXPECT_EQ(metadata[0].get().name, "body");
+ EXPECT_EQ(metadata[1].get().name, "body");
+}
+
+TEST_F(ECSTest, partentChild) {
+ {
+ GameObject body = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);
+ GameObject right_leg = mgr.new_object("rightLeg", "person", vec2{1, 1}, 0, 1);
+ GameObject left_leg = mgr.new_object("leftLeg", "person", vec2{1, 1}, 0, 1);
+ GameObject right_foot = mgr.new_object("rightFoot", "person", vec2{2, 2}, 0, 1);
+ GameObject left_foot = mgr.new_object("leftFoot", "person", vec2{2, 2}, 0, 1);
+
+ // Set the parent of each GameObject
+ right_foot.set_parent(right_leg);
+ left_foot.set_parent(left_leg);
+ right_leg.set_parent(body);
+ left_leg.set_parent(body);
+ }
+
+ // Get the Metadata and Transform components of each GameObject
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+
+ // Check IDs
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[1].get().game_object_id, 1);
+ EXPECT_EQ(metadata[2].get().game_object_id, 2);
+ EXPECT_EQ(metadata[3].get().game_object_id, 3);
+ EXPECT_EQ(metadata[4].get().game_object_id, 4);
+
+ // Check the parent-child relationships
+ EXPECT_EQ(metadata[0].get().name, "body");
+ EXPECT_EQ(metadata[1].get().name, "rightLeg");
+ EXPECT_EQ(metadata[2].get().name, "leftLeg");
+ EXPECT_EQ(metadata[3].get().name, "rightFoot");
+ EXPECT_EQ(metadata[4].get().name, "leftFoot");
+
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[1].get().parent, 0);
+ EXPECT_EQ(metadata[2].get().parent, 0);
+ EXPECT_EQ(metadata[3].get().parent, 1);
+ EXPECT_EQ(metadata[4].get().parent, 2);
+
+ EXPECT_EQ(metadata[0].get().children.size(), 2);
+ EXPECT_EQ(metadata[1].get().children.size(), 1);
+ EXPECT_EQ(metadata[2].get().children.size(), 1);
+ EXPECT_EQ(metadata[3].get().children.size(), 0);
+ EXPECT_EQ(metadata[4].get().children.size(), 0);
+
+ EXPECT_EQ(metadata[0].get().children[0], 1);
+ EXPECT_EQ(metadata[0].get().children[1], 2);
+ EXPECT_EQ(metadata[1].get().children[0], 3);
+ EXPECT_EQ(metadata[2].get().children[0], 4);
+}
+
+TEST_F(ECSTest, persistent) {
+ GameObject obj0 = mgr.new_object("obj0", "obj0", vec2{0, 0}, 0, 1);
+ GameObject obj1 = mgr.new_object("obj1", "obj1", vec2{0, 0}, 0, 1);
+ obj1.set_persistent();
+ GameObject obj2 = mgr.new_object("obj2", "obj2", vec2{0, 0}, 0, 1);
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 3);
+ EXPECT_EQ(transform.size(), 3);
+
+ mgr.delete_components_by_id<Metadata>(1);
+ mgr.delete_components<Metadata>();
+ mgr.delete_all_components_of_id(1);
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 3);
+
+ mgr.delete_all_components();
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 1);
+ EXPECT_EQ(metadata[0].get().name, "obj1");
+ EXPECT_EQ(metadata[0].get().tag, "obj1");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+
+ EXPECT_EQ(transform[0].get().game_object_id, 1);
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+
+ GameObject obj3 = mgr.new_object("obj3", "obj3", vec2{0, 0}, 0, 5);
+ GameObject obj4 = mgr.new_object("obj4", "obj4", vec2{0, 0}, 0, 5);
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 3);
+ EXPECT_EQ(transform.size(), 3);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "obj3");
+
+ EXPECT_EQ(metadata[1].get().game_object_id, 1);
+ EXPECT_EQ(metadata[1].get().name, "obj1");
+
+ EXPECT_EQ(metadata[2].get().game_object_id, 2);
+ EXPECT_EQ(metadata[2].get().name, "obj4");
+
+ EXPECT_EQ(transform[0].get().game_object_id, 0);
+ EXPECT_EQ(transform[0].get().scale, 5);
+
+ EXPECT_EQ(transform[1].get().game_object_id, 1);
+ EXPECT_EQ(transform[1].get().scale, 1);
+
+ EXPECT_EQ(transform[2].get().game_object_id, 2);
+ EXPECT_EQ(transform[2].get().scale, 5);
+}
+
+TEST_F(ECSTest, resetPersistent) {
+ GameObject obj0 = mgr.new_object("obj0", "obj0", vec2{0, 0}, 0, 1);
+ GameObject obj1 = mgr.new_object("obj1", "obj1", vec2{0, 0}, 0, 1);
+ obj1.set_persistent();
+ GameObject obj2 = mgr.new_object("obj2", "obj2", vec2{0, 0}, 0, 1);
+
+ vector<reference_wrapper<Metadata>> metadata = mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 3);
+ EXPECT_EQ(transform.size(), 3);
+
+ mgr.delete_all_components();
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ vector<reference_wrapper<Metadata>> metadata_id = mgr.get_components_by_id<Metadata>(1);
+
+ EXPECT_EQ(metadata_id.size(), 1);
+ EXPECT_EQ(metadata_id[0].get().game_object_id, 1);
+ EXPECT_EQ(metadata_id[0].get().name, "obj1");
+
+ mgr.set_persistent(1, false);
+ mgr.delete_all_components();
+
+ metadata = mgr.get_components_by_type<Metadata>();
+ transform = mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 0);
+ EXPECT_EQ(transform.size(), 0);
+}
diff --git a/src/test/EventTest.cpp b/src/test/EventTest.cpp
new file mode 100644
index 0000000..b0e6c9c
--- /dev/null
+++ b/src/test/EventTest.cpp
@@ -0,0 +1,254 @@
+
+#include "api/Event.h"
+#include "api/EventManager.h"
+#include "api/IKeyListener.h"
+#include "api/IMouseListener.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+using namespace std;
+using namespace std::chrono_literals;
+using namespace crepe;
+
+class EventManagerTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Clear any existing subscriptions or events before each test
+ EventManager::get_instance().clear();
+ }
+
+ void TearDown() override {
+ // Ensure cleanup after each test
+ EventManager::get_instance().clear();
+ }
+};
+class MockKeyListener : public IKeyListener {
+public:
+ MOCK_METHOD(bool, on_key_pressed, (const KeyPressEvent & event), (override));
+ MOCK_METHOD(bool, on_key_released, (const KeyReleaseEvent & event), (override));
+};
+
+class MockMouseListener : public IMouseListener {
+public:
+ MOCK_METHOD(bool, on_mouse_clicked, (const MouseClickEvent & event), (override));
+ MOCK_METHOD(bool, on_mouse_pressed, (const MousePressEvent & event), (override));
+ MOCK_METHOD(bool, on_mouse_released, (const MouseReleaseEvent & event), (override));
+ MOCK_METHOD(bool, on_mouse_moved, (const MouseMoveEvent & event), (override));
+};
+
+TEST_F(EventManagerTest, EventSubscription) {
+ EventHandler<KeyPressEvent> key_handler = [](const KeyPressEvent & e) {
+ std::cout << "Key Event Triggered" << std::endl;
+ return true;
+ };
+
+ // Subscribe to KeyPressEvent
+ EventManager::get_instance().subscribe<KeyPressEvent>(key_handler, 1);
+
+ // Verify subscription (not directly verifiable; test by triggering event)
+
+ EventManager::get_instance().trigger_event<KeyPressEvent>(
+ KeyPressEvent{
+ .repeat = true,
+ .key = Keycode::A,
+ },
+ 1);
+ EventManager::get_instance().trigger_event<KeyPressEvent>(
+ KeyPressEvent{
+ .repeat = true,
+ .key = Keycode::A,
+
+ },
+ EventManager::CHANNEL_ALL);
+}
+TEST_F(EventManagerTest, EventManagerTest_trigger_all_channels) {
+ bool triggered = false;
+
+ EventHandler<MouseClickEvent> mouse_handler = [&](const MouseClickEvent & e) {
+ triggered = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false;
+ };
+ EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler,
+ EventManager::CHANNEL_ALL);
+
+ MouseClickEvent click_event{
+ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};
+ EventManager::get_instance().trigger_event<MouseClickEvent>(click_event,
+ EventManager::CHANNEL_ALL);
+
+ EXPECT_TRUE(triggered);
+}
+TEST_F(EventManagerTest, EventManagerTest_trigger_one_channel) {
+ bool triggered = false;
+ int test_channel = 1;
+ EventHandler<MouseClickEvent> mouse_handler = [&](const MouseClickEvent & e) {
+ triggered = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false;
+ };
+ EventManager::get_instance().subscribe<MouseClickEvent>(mouse_handler, test_channel);
+
+ MouseClickEvent click_event{
+ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};
+ EventManager::get_instance().trigger_event<MouseClickEvent>(click_event,
+ EventManager::CHANNEL_ALL);
+
+ EXPECT_FALSE(triggered);
+ EventManager::get_instance().trigger_event<MouseClickEvent>(click_event, test_channel);
+}
+
+TEST_F(EventManagerTest, EventManagerTest_callback_propagation) {
+ EventManager & event_manager = EventManager::get_instance();
+
+ // Flags to track handler calls
+ bool triggered_true = false;
+ bool triggered_false = false;
+
+ // Handlers
+ EventHandler<MouseClickEvent> mouse_handler_true = [&](const MouseClickEvent & e) {
+ triggered_true = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return true; // Stops propagation
+ };
+
+ EventHandler<MouseClickEvent> mouse_handler_false = [&](const MouseClickEvent & e) {
+ triggered_false = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false; // Allows propagation
+ };
+
+ // Test event
+ MouseClickEvent click_event{
+ .mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE};
+ event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL);
+ event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL);
+
+ // Trigger event
+ event_manager.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);
+
+ // Check that only the true handler was triggered
+ EXPECT_TRUE(triggered_true);
+ EXPECT_FALSE(triggered_false);
+
+ // Reset and clear
+ triggered_true = false;
+ triggered_false = false;
+ event_manager.clear();
+ event_manager.subscribe<MouseClickEvent>(mouse_handler_false, EventManager::CHANNEL_ALL);
+ event_manager.subscribe<MouseClickEvent>(mouse_handler_true, EventManager::CHANNEL_ALL);
+
+ // Trigger event again
+ event_manager.trigger_event<MouseClickEvent>(click_event, EventManager::CHANNEL_ALL);
+
+ // Check that both handlers were triggered
+ EXPECT_TRUE(triggered_true);
+ EXPECT_TRUE(triggered_false);
+}
+
+TEST_F(EventManagerTest, EventManagerTest_queue_dispatch) {
+ EventManager & event_manager = EventManager::get_instance();
+ bool triggered1 = false;
+ bool triggered2 = false;
+ int test_channel = 1;
+ EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent & e) {
+ triggered1 = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false; // Allows propagation
+ };
+ EventHandler<MouseClickEvent> mouse_handler2 = [&](const MouseClickEvent & e) {
+ triggered2 = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false; // Allows propagation
+ };
+ event_manager.subscribe<MouseClickEvent>(mouse_handler1);
+ event_manager.subscribe<MouseClickEvent>(mouse_handler2, test_channel);
+
+ event_manager.queue_event<MouseClickEvent>(
+ MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+ event_manager.queue_event<MouseClickEvent>(
+ MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE},
+ test_channel);
+ event_manager.dispatch_events();
+ EXPECT_TRUE(triggered1);
+ EXPECT_TRUE(triggered2);
+}
+
+TEST_F(EventManagerTest, EventManagerTest_unsubscribe) {
+ EventManager & event_manager = EventManager::get_instance();
+
+ // Flags to track if handlers are triggered
+ bool triggered1 = false;
+ bool triggered2 = false;
+
+ // Define EventHandlers
+ EventHandler<MouseClickEvent> mouse_handler1 = [&](const MouseClickEvent & e) {
+ triggered1 = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false; // Allows propagation
+ };
+
+ EventHandler<MouseClickEvent> mouse_handler2 = [&](const MouseClickEvent & e) {
+ triggered2 = true;
+ EXPECT_EQ(e.mouse_x, 100);
+ EXPECT_EQ(e.mouse_y, 200);
+ EXPECT_EQ(e.button, MouseButton::LEFT_MOUSE);
+ return false; // Allows propagation
+ };
+ // Subscribe handlers
+ subscription_t handler1_id = event_manager.subscribe<MouseClickEvent>(mouse_handler1);
+ subscription_t handler2_id = event_manager.subscribe<MouseClickEvent>(mouse_handler2);
+
+ // Queue events
+ event_manager.queue_event<MouseClickEvent>(
+ MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+
+ // Dispatch events - both handlers should be triggered
+ event_manager.dispatch_events();
+ EXPECT_TRUE(triggered1); // Handler 1 should be triggered
+ EXPECT_TRUE(triggered2); // Handler 2 should be triggered
+
+ // Reset flags
+ triggered1 = false;
+ triggered2 = false;
+
+ // Unsubscribe handler1
+ event_manager.unsubscribe(handler1_id);
+
+ // Queue the same event again
+ event_manager.queue_event<MouseClickEvent>(
+ MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+
+ // Dispatch events - only handler 2 should be triggered, handler 1 should NOT
+ event_manager.dispatch_events();
+ EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered
+ EXPECT_TRUE(triggered2); // Handler 2 should be triggered
+
+ // Reset flags
+ triggered2 = false;
+
+ // Unsubscribe handler2
+ event_manager.unsubscribe(handler2_id);
+
+ // Queue the event again
+ event_manager.queue_event<MouseClickEvent>(
+ MouseClickEvent{.mouse_x = 100, .mouse_y = 200, .button = MouseButton::LEFT_MOUSE});
+
+ // Dispatch events - no handler should be triggered
+ event_manager.dispatch_events();
+ EXPECT_FALSE(triggered1); // Handler 1 should NOT be triggered
+ EXPECT_FALSE(triggered2); // Handler 2 should NOT be triggered
+}
diff --git a/src/test/OptionalRefTest.cpp b/src/test/OptionalRefTest.cpp
new file mode 100644
index 0000000..83f7b23
--- /dev/null
+++ b/src/test/OptionalRefTest.cpp
@@ -0,0 +1,42 @@
+#include <gtest/gtest.h>
+
+#include <crepe/util/OptionalRef.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+TEST(OptionalRefTest, Normal) {
+ string value = "foo";
+ OptionalRef<string> ref = value;
+
+ EXPECT_TRUE(ref);
+ ASSERT_NO_THROW({
+ string & value_ref = ref;
+ EXPECT_EQ(value_ref, value);
+ });
+
+ ref.clear();
+ EXPECT_FALSE(ref);
+ ASSERT_THROW({ string & value_ref = ref; }, runtime_error);
+}
+
+TEST(OptionalRefTest, Empty) {
+ string value = "foo";
+ OptionalRef<string> ref;
+
+ EXPECT_FALSE(ref);
+ ASSERT_THROW({ string & value_ref = ref; }, runtime_error);
+}
+
+TEST(OptionalRefTest, Chain) {
+ string value = "foo";
+ OptionalRef<string> ref1 = value;
+ OptionalRef<string> ref2 = ref1;
+
+ EXPECT_TRUE(ref2);
+ string & value_ref = ref2;
+ EXPECT_EQ(value_ref, value);
+ value_ref = "bar";
+ EXPECT_EQ(value_ref, value);
+}
diff --git a/src/test/ParticleTest.cpp b/src/test/ParticleTest.cpp
index 4e655a9..976f9a1 100644
--- a/src/test/ParticleTest.cpp
+++ b/src/test/ParticleTest.cpp
@@ -1,4 +1,4 @@
-#include "api/Vector2.h"
+#include "api/Texture.h"
#include <crepe/ComponentManager.h>
#include <crepe/Particle.h>
#include <crepe/api/Config.h>
@@ -25,12 +25,12 @@ public:
std::vector<std::reference_wrapper<Transform>> transforms
= mgr.get_components_by_id<Transform>(0);
if (transforms.empty()) {
- GameObject game_object = mgr.new_object("", "", Vector2{0, 0}, 0, 0);
+ GameObject game_object = mgr.new_object("", "", vec2{0, 0}, 0, 0);
Color color(0, 0, 0, 0);
- Sprite test_sprite = game_object.add_component<Sprite>(
- make_shared<Texture>("../asset/texture/img.png"), color,
- FlipSettings{true, true});
+ auto s1 = Texture("asset/texture/img.png");
+ Sprite & test_sprite = game_object.add_component<Sprite>(
+ s1, color, Sprite::FlipSettings{true, true}, 1, 1, 100);
game_object.add_component<ParticleEmitter>(ParticleEmitter::Data{
.position = {0, 0},
@@ -42,11 +42,11 @@ public:
.max_angle = 0,
.begin_lifespan = 0,
.end_lifespan = 0,
- .force_over_time = Vector2{0, 0},
+ .force_over_time = vec2{0, 0},
.boundary{
.width = 0,
.height = 0,
- .offset = Vector2{0, 0},
+ .offset = vec2{0, 0},
.reset_on_exit = false,
},
.sprite = test_sprite,
@@ -68,8 +68,8 @@ public:
emitter.data.max_angle = 0;
emitter.data.begin_lifespan = 0;
emitter.data.end_lifespan = 0;
- emitter.data.force_over_time = Vector2{0, 0};
- emitter.data.boundary = {0, 0, Vector2{0, 0}, false};
+ emitter.data.force_over_time = vec2{0, 0};
+ emitter.data.boundary = {0, 0, vec2{0, 0}, false};
for (auto & particle : emitter.data.particles) {
particle.active = false;
}
diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp
index 1e37c26..33b6020 100644
--- a/src/test/PhysicsTest.cpp
+++ b/src/test/PhysicsTest.cpp
@@ -20,12 +20,12 @@ public:
vector<reference_wrapper<Transform>> transforms
= mgr.get_components_by_id<Transform>(0);
if (transforms.empty()) {
- auto entity = mgr.new_object("", "", Vector2{0, 0}, 0, 0);
+ auto entity = mgr.new_object("", "", vec2{0, 0}, 0, 0);
entity.add_component<Rigidbody>(Rigidbody::Data{
.mass = 1,
.gravity_scale = 1,
.body_type = Rigidbody::BodyType::DYNAMIC,
- .max_linear_velocity = Vector2{10, 10},
+ .max_linear_velocity = vec2{10, 10},
.max_angular_velocity = 10,
.constraints = {0, 0},
.use_gravity = true,
diff --git a/src/test/RenderSystemTest.cpp b/src/test/RenderSystemTest.cpp
new file mode 100644
index 0000000..bb5b81a
--- /dev/null
+++ b/src/test/RenderSystemTest.cpp
@@ -0,0 +1,166 @@
+#include "types.h"
+#include <functional>
+#include <gtest/gtest.h>
+#include <memory>
+#include <vector>
+
+#define private public
+#define protected public
+
+#include "crepe/api/Camera.h"
+#include <crepe/ComponentManager.h>
+#include <crepe/api/Color.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Sprite.h>
+#include <crepe/api/Texture.h>
+
+#include <crepe/system/RenderSystem.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class RenderSystemTest : public Test {
+public:
+ ComponentManager mgr{};
+ RenderSystem sys{mgr};
+ GameObject entity1 = this->mgr.new_object("name");
+ GameObject entity2 = this->mgr.new_object("name");
+ GameObject entity3 = this->mgr.new_object("name");
+ GameObject entity4 = this->mgr.new_object("name");
+
+ void SetUp() override {
+ auto s1 = Texture("asset/texture/img.png");
+ auto s2 = Texture("asset/texture/img.png");
+ auto s3 = Texture("asset/texture/img.png");
+ auto s4 = Texture("asset/texture/img.png");
+ auto & sprite1 = entity1.add_component<Sprite>(
+ s1, Color(0, 0, 0, 0), Sprite::FlipSettings{false, false}, 5, 5, 100);
+ ASSERT_NE(sprite1.sprite_image.texture.get(), nullptr);
+ EXPECT_EQ(sprite1.order_in_layer, 5);
+ EXPECT_EQ(sprite1.sorting_in_layer, 5);
+ auto & sprite2 = entity2.add_component<Sprite>(
+ s2, Color(0, 0, 0, 0), Sprite::FlipSettings{false, false}, 2, 1, 100);
+ ASSERT_NE(sprite2.sprite_image.texture.get(), nullptr);
+ EXPECT_EQ(sprite2.sorting_in_layer, 2);
+ EXPECT_EQ(sprite2.order_in_layer, 1);
+
+ auto & sprite3 = entity3.add_component<Sprite>(
+ s3, Color(0, 0, 0, 0), Sprite::FlipSettings{false, false}, 1, 2, 100);
+ ASSERT_NE(sprite3.sprite_image.texture.get(), nullptr);
+ EXPECT_EQ(sprite3.sorting_in_layer, 1);
+ EXPECT_EQ(sprite3.order_in_layer, 2);
+
+ auto & sprite4 = entity4.add_component<Sprite>(
+ s4, Color(0, 0, 0, 0), Sprite::FlipSettings{false, false}, 1, 1, 100);
+ ASSERT_NE(sprite4.sprite_image.texture.get(), nullptr);
+ EXPECT_EQ(sprite4.sorting_in_layer, 1);
+ EXPECT_EQ(sprite4.order_in_layer, 1);
+ }
+};
+
+TEST_F(RenderSystemTest, expected_throws) {
+ GameObject entity1 = this->mgr.new_object("NAME");
+
+ // no texture img
+ EXPECT_ANY_THROW({
+ auto test = Texture("");
+ entity1.add_component<Sprite>(test, Color(0, 0, 0, 0),
+ Sprite::FlipSettings{false, false}, 1, 1, 100);
+ });
+
+ // No camera
+ EXPECT_ANY_THROW({ this->sys.update(); });
+}
+
+TEST_F(RenderSystemTest, make_sprites) {}
+
+TEST_F(RenderSystemTest, sorting_sprites) {
+ vector<reference_wrapper<Sprite>> sprites = this->mgr.get_components_by_type<Sprite>();
+ ASSERT_EQ(sprites.size(), 4);
+
+ vector<reference_wrapper<Sprite>> sorted_sprites = this->sys.sort(sprites);
+ ASSERT_EQ(sorted_sprites.size(), 4);
+
+ // Expected order after sorting:
+ // 1. sorting_in_layer: 1, order_in_layer: 1 (entity4)
+ // 2. sorting_in_layer: 1, order_in_layer: 2 (entity3)
+ // 3. sorting_in_layer: 2, order_in_layer: 1 (entity2)
+ // 4. sorting_in_layer: 5, order_in_layer: 5 (entity1)
+
+ EXPECT_EQ(sorted_sprites[0].get().sorting_in_layer, 1);
+ EXPECT_EQ(sorted_sprites[0].get().order_in_layer, 1);
+
+ EXPECT_EQ(sorted_sprites[1].get().sorting_in_layer, 1);
+ EXPECT_EQ(sorted_sprites[1].get().order_in_layer, 2);
+
+ EXPECT_EQ(sorted_sprites[2].get().sorting_in_layer, 2);
+ EXPECT_EQ(sorted_sprites[2].get().order_in_layer, 1);
+
+ EXPECT_EQ(sorted_sprites[3].get().sorting_in_layer, 5);
+ EXPECT_EQ(sorted_sprites[3].get().order_in_layer, 5);
+
+ for (size_t i = 1; i < sorted_sprites.size(); ++i) {
+ const Sprite & prev = sorted_sprites[i - 1].get();
+ const Sprite & curr = sorted_sprites[i].get();
+
+ if (prev.sorting_in_layer == curr.sorting_in_layer) {
+ EXPECT_LE(prev.order_in_layer, curr.order_in_layer);
+ } else {
+ EXPECT_LE(prev.sorting_in_layer, curr.sorting_in_layer);
+ }
+ }
+}
+
+TEST_F(RenderSystemTest, Update) {
+ entity1.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{2000, 2000}, 1.0f);
+ {
+ vector<reference_wrapper<Sprite>> sprites = this->mgr.get_components_by_type<Sprite>();
+ ASSERT_EQ(sprites.size(), 4);
+
+ EXPECT_EQ(sprites[0].get().game_object_id, 0);
+ EXPECT_EQ(sprites[1].get().game_object_id, 1);
+ EXPECT_EQ(sprites[2].get().game_object_id, 2);
+ EXPECT_EQ(sprites[3].get().game_object_id, 3);
+ }
+ this->sys.update();
+ {
+ vector<reference_wrapper<Sprite>> sprites = this->mgr.get_components_by_type<Sprite>();
+ ASSERT_EQ(sprites.size(), 4);
+
+ EXPECT_EQ(sprites[0].get().game_object_id, 0);
+ EXPECT_EQ(sprites[1].get().game_object_id, 1);
+ EXPECT_EQ(sprites[2].get().game_object_id, 2);
+ EXPECT_EQ(sprites[3].get().game_object_id, 3);
+ }
+}
+
+TEST_F(RenderSystemTest, Camera) {
+ {
+ auto cameras = this->mgr.get_components_by_type<Camera>();
+ EXPECT_NE(cameras.size(), 1);
+ }
+ {
+ entity1.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{2000, 2000}, 1.0f);
+ auto cameras = this->mgr.get_components_by_type<Camera>();
+ EXPECT_EQ(cameras.size(), 1);
+ }
+
+ //TODO improve with newer version
+}
+TEST_F(RenderSystemTest, Color) {
+ entity1.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{2000, 2000}, 1.0f);
+ auto & sprite = this->mgr.get_components_by_id<Sprite>(entity1.id).front().get();
+ ASSERT_NE(sprite.sprite_image.texture.get(), nullptr);
+
+ sprite.color = Color::GREEN;
+ EXPECT_EQ(sprite.color.r, Color::GREEN.r);
+ EXPECT_EQ(sprite.color.g, Color::GREEN.g);
+ EXPECT_EQ(sprite.color.b, Color::GREEN.b);
+ EXPECT_EQ(sprite.color.a, Color::GREEN.a);
+ this->sys.update();
+ EXPECT_EQ(sprite.color.r, Color::GREEN.r);
+ EXPECT_EQ(sprite.color.g, Color::GREEN.g);
+ EXPECT_EQ(sprite.color.b, Color::GREEN.b);
+ EXPECT_EQ(sprite.color.a, Color::GREEN.a);
+}
diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp
new file mode 100644
index 0000000..62b7d33
--- /dev/null
+++ b/src/test/SceneManagerTest.cpp
@@ -0,0 +1,160 @@
+#include "types.h"
+#include <crepe/ComponentManager.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Metadata.h>
+#include <crepe/api/Scene.h>
+#include <crepe/api/SceneManager.h>
+#include <crepe/api/Transform.h>
+#include <crepe/api/Vector2.h>
+#include <gtest/gtest.h>
+
+using namespace std;
+using namespace crepe;
+
+class ConcreteScene1 : public Scene {
+public:
+ void load_scene() {
+ ComponentManager & mgr = this->component_manager;
+ GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", vec2{0, 0}, 0, 1);
+ GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", vec2{1, 0}, 0, 1);
+ GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", vec2{2, 0}, 0, 1);
+ }
+
+ string get_name() const { return "scene1"; }
+};
+
+class ConcreteScene2 : public Scene {
+public:
+ void load_scene() {
+ ComponentManager & mgr = this->component_manager;
+ GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 0}, 0, 1);
+ GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 1}, 0, 1);
+ GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 2}, 0, 1);
+ GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 3}, 0, 1);
+ }
+
+ string get_name() const { return "scene2"; }
+};
+
+class ConcreteScene3 : public Scene {
+public:
+ ConcreteScene3(const string & name) : name(name) {}
+
+ void load_scene() {
+ ComponentManager & mgr = this->component_manager;
+ GameObject object1 = mgr.new_object("scene_3", "tag_scene_3", vec2{0, 0}, 0, 1);
+ }
+
+ string get_name() const { return name; }
+
+private:
+ const string name;
+};
+
+class SceneManagerTest : public ::testing::Test {
+public:
+ ComponentManager component_mgr{};
+ SceneManager scene_mgr{component_mgr};
+};
+
+TEST_F(SceneManagerTest, loadScene) {
+ scene_mgr.add_scene<ConcreteScene1>();
+ scene_mgr.add_scene<ConcreteScene2>();
+
+ scene_mgr.load_next_scene();
+
+ vector<reference_wrapper<Metadata>> metadata
+ = component_mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform
+ = component_mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 3);
+ EXPECT_EQ(transform.size(), 3);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "scene_1");
+ EXPECT_EQ(metadata[0].get().tag, "tag_scene_1");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+
+ EXPECT_EQ(metadata[1].get().game_object_id, 1);
+ EXPECT_EQ(metadata[1].get().name, "scene_1");
+ EXPECT_EQ(metadata[1].get().tag, "tag_scene_1");
+ EXPECT_EQ(metadata[1].get().parent, -1);
+ EXPECT_EQ(metadata[1].get().children.size(), 0);
+ EXPECT_EQ(transform[1].get().position.x, 1);
+ EXPECT_EQ(transform[1].get().position.y, 0);
+
+ EXPECT_EQ(metadata[2].get().game_object_id, 2);
+ EXPECT_EQ(metadata[2].get().name, "scene_1");
+ EXPECT_EQ(metadata[2].get().tag, "tag_scene_1");
+ EXPECT_EQ(metadata[2].get().parent, -1);
+ EXPECT_EQ(metadata[2].get().children.size(), 0);
+ EXPECT_EQ(transform[2].get().position.x, 2);
+ EXPECT_EQ(transform[2].get().position.y, 0);
+
+ scene_mgr.set_next_scene("scene2");
+ scene_mgr.load_next_scene();
+
+ metadata = component_mgr.get_components_by_type<Metadata>();
+ transform = component_mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 4);
+ EXPECT_EQ(transform.size(), 4);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "scene_2");
+ EXPECT_EQ(metadata[0].get().tag, "tag_scene_2");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+
+ EXPECT_EQ(metadata[1].get().game_object_id, 1);
+ EXPECT_EQ(metadata[1].get().name, "scene_2");
+ EXPECT_EQ(metadata[1].get().tag, "tag_scene_2");
+ EXPECT_EQ(metadata[1].get().parent, -1);
+ EXPECT_EQ(metadata[1].get().children.size(), 0);
+ EXPECT_EQ(transform[1].get().position.x, 0);
+ EXPECT_EQ(transform[1].get().position.y, 1);
+
+ EXPECT_EQ(metadata[2].get().game_object_id, 2);
+ EXPECT_EQ(metadata[2].get().name, "scene_2");
+ EXPECT_EQ(metadata[2].get().tag, "tag_scene_2");
+ EXPECT_EQ(metadata[2].get().parent, -1);
+ EXPECT_EQ(metadata[2].get().children.size(), 0);
+ EXPECT_EQ(transform[2].get().position.x, 0);
+ EXPECT_EQ(transform[2].get().position.y, 2);
+
+ EXPECT_EQ(metadata[3].get().game_object_id, 3);
+ EXPECT_EQ(metadata[3].get().name, "scene_2");
+ EXPECT_EQ(metadata[3].get().tag, "tag_scene_2");
+ EXPECT_EQ(metadata[3].get().parent, -1);
+ EXPECT_EQ(metadata[3].get().children.size(), 0);
+ EXPECT_EQ(transform[3].get().position.x, 0);
+ EXPECT_EQ(transform[3].get().position.y, 3);
+}
+
+TEST_F(SceneManagerTest, perfectForwarding) {
+ scene_mgr.add_scene<ConcreteScene3>("scene3");
+
+ scene_mgr.load_next_scene();
+
+ vector<reference_wrapper<Metadata>> metadata
+ = component_mgr.get_components_by_type<Metadata>();
+ vector<reference_wrapper<Transform>> transform
+ = component_mgr.get_components_by_type<Transform>();
+
+ EXPECT_EQ(metadata.size(), 1);
+ EXPECT_EQ(transform.size(), 1);
+
+ EXPECT_EQ(metadata[0].get().game_object_id, 0);
+ EXPECT_EQ(metadata[0].get().name, "scene_3");
+ EXPECT_EQ(metadata[0].get().tag, "tag_scene_3");
+ EXPECT_EQ(metadata[0].get().parent, -1);
+ EXPECT_EQ(metadata[0].get().children.size(), 0);
+ EXPECT_EQ(transform[0].get().position.x, 0);
+ EXPECT_EQ(transform[0].get().position.y, 0);
+}
diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp
index 19fef6d..78d5061 100644
--- a/src/test/ScriptTest.cpp
+++ b/src/test/ScriptTest.cpp
@@ -6,6 +6,8 @@
#include <crepe/ComponentManager.h>
#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Event.h>
+#include <crepe/api/EventManager.h>
#include <crepe/api/GameObject.h>
#include <crepe/api/Script.h>
#include <crepe/api/Vector2.h>
@@ -15,58 +17,113 @@ using namespace std;
using namespace crepe;
using namespace testing;
+class MyEvent : public Event {};
+
class ScriptTest : public Test {
public:
ComponentManager component_manager{};
ScriptSystem system{component_manager};
+ EventManager & event_manager = EventManager::get_instance();
class MyScript : public Script {
// NOTE: default (private) visibility of init and update shouldn't cause
// issues!
- void init() { this->init_count++; }
+ void init() {
+ this->init_count++;
+
+ subscribe<MyEvent>([this](const MyEvent &) {
+ this->event_count++;
+ return true;
+ });
+
+ // init should never be called more than once
+ EXPECT_LE(this->init_count, 1);
+ }
void update() { this->update_count++; }
public:
unsigned init_count = 0;
unsigned update_count = 0;
+ unsigned event_count = 0;
};
- BehaviorScript * behaviorscript_ref = nullptr;
- MyScript * script_ref = nullptr;
+ OptionalRef<BehaviorScript> behaviorscript;
+ OptionalRef<MyScript> script;
void SetUp() override {
auto & mgr = this->component_manager;
GameObject entity = mgr.new_object("name");
BehaviorScript & component = entity.add_component<BehaviorScript>();
- this->behaviorscript_ref = &component;
- EXPECT_EQ(this->behaviorscript_ref->script.get(), nullptr);
+ this->behaviorscript = component;
+ ASSERT_TRUE(this->behaviorscript);
+ EXPECT_EQ(component.script.get(), nullptr);
component.set_script<MyScript>();
- ASSERT_NE(this->behaviorscript_ref->script.get(), nullptr);
+ ASSERT_NE(component.script.get(), nullptr);
- this->script_ref = (MyScript *) this->behaviorscript_ref->script.get();
- ASSERT_NE(this->script_ref, nullptr);
+ this->script = *(MyScript *) component.script.get();
+ ASSERT_TRUE(this->script);
+
+ // sanity
+ MyScript & script = this->script;
+ ASSERT_EQ(script.init_count, 0);
+ ASSERT_EQ(script.update_count, 0);
+ ASSERT_EQ(script.event_count, 0);
}
};
TEST_F(ScriptTest, Default) {
- EXPECT_EQ(0, this->script_ref->init_count);
- EXPECT_EQ(0, this->script_ref->update_count);
+ MyScript & script = this->script;
+ EXPECT_EQ(0, script.init_count);
+ EXPECT_EQ(0, script.update_count);
+ EXPECT_EQ(0, script.event_count);
}
TEST_F(ScriptTest, UpdateOnce) {
- EXPECT_EQ(0, this->script_ref->init_count);
- EXPECT_EQ(0, this->script_ref->update_count);
+ MyScript & script = this->script;
- this->system.update();
- EXPECT_EQ(1, this->script_ref->init_count);
- EXPECT_EQ(1, this->script_ref->update_count);
+ system.update();
+ EXPECT_EQ(1, script.init_count);
+ EXPECT_EQ(1, script.update_count);
+ EXPECT_EQ(0, script.event_count);
}
-TEST_F(ScriptTest, ListScripts) {
- size_t script_count = 0;
- for (auto & _ : this->system.get_scripts()) {
- script_count++;
- }
- ASSERT_EQ(1, script_count);
+TEST_F(ScriptTest, UpdateInactive) {
+ BehaviorScript & behaviorscript = this->behaviorscript;
+ MyScript & script = this->script;
+
+ behaviorscript.active = false;
+ system.update();
+ EXPECT_EQ(0, script.init_count);
+ EXPECT_EQ(0, script.update_count);
+ EXPECT_EQ(0, script.event_count);
+
+ behaviorscript.active = true;
+ system.update();
+ EXPECT_EQ(1, script.init_count);
+ EXPECT_EQ(1, script.update_count);
+ EXPECT_EQ(0, script.event_count);
+}
+
+TEST_F(ScriptTest, EventInactive) {
+ BehaviorScript & behaviorscript = this->behaviorscript;
+ MyScript & script = this->script;
+ EventManager & evmgr = this->event_manager;
+
+ system.update();
+ behaviorscript.active = false;
+ EXPECT_EQ(1, script.init_count);
+ EXPECT_EQ(1, script.update_count);
+ EXPECT_EQ(0, script.event_count);
+
+ evmgr.trigger_event<MyEvent>();
+ EXPECT_EQ(1, script.init_count);
+ EXPECT_EQ(1, script.update_count);
+ EXPECT_EQ(0, script.event_count);
+
+ behaviorscript.active = true;
+ evmgr.trigger_event<MyEvent>();
+ EXPECT_EQ(1, script.init_count);
+ EXPECT_EQ(1, script.update_count);
+ EXPECT_EQ(1, script.event_count);
}
diff --git a/src/test/ValueBrokerTest.cpp b/src/test/ValueBrokerTest.cpp
new file mode 100644
index 0000000..e6bb058
--- /dev/null
+++ b/src/test/ValueBrokerTest.cpp
@@ -0,0 +1,63 @@
+#include <gtest/gtest.h>
+
+#include <crepe/ValueBroker.h>
+#include <crepe/util/Proxy.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class ValueBrokerTest : public Test {
+public:
+ int read_count = 0;
+ int write_count = 0;
+ int value = 0;
+
+ ValueBroker<int> broker{
+ [this](const int & target) -> void {
+ this->write_count++;
+ this->value = target;
+ },
+ [this]() -> const int & {
+ this->read_count++;
+ return this->value;
+ },
+ };
+ Proxy<int> proxy{broker};
+
+ void SetUp() override {
+ ASSERT_EQ(read_count, 0);
+ ASSERT_EQ(write_count, 0);
+ }
+};
+
+TEST_F(ValueBrokerTest, BrokerWrite) {
+ broker.set(0);
+ EXPECT_EQ(read_count, 0);
+ EXPECT_EQ(write_count, 1);
+}
+
+TEST_F(ValueBrokerTest, BrokerRead) {
+ broker.get();
+ EXPECT_EQ(read_count, 1);
+ EXPECT_EQ(write_count, 0);
+}
+
+TEST_F(ValueBrokerTest, ProxyWrite) {
+ proxy = 0;
+ EXPECT_EQ(read_count, 0);
+ EXPECT_EQ(write_count, 1);
+}
+
+void dummy(int) {}
+TEST_F(ValueBrokerTest, ProxyRead) {
+ dummy(proxy);
+ EXPECT_EQ(read_count, 1);
+ EXPECT_EQ(write_count, 0);
+}
+
+TEST_F(ValueBrokerTest, ProxyReadWrite) {
+ proxy = proxy;
+ ASSERT_EQ(read_count, 1);
+ ASSERT_EQ(write_count, 1);
+}
diff --git a/src/test/Vector2Test.cpp b/src/test/Vector2Test.cpp
new file mode 100644
index 0000000..17bca41
--- /dev/null
+++ b/src/test/Vector2Test.cpp
@@ -0,0 +1,384 @@
+#include <gtest/gtest.h>
+
+#include <crepe/api/Vector2.h>
+
+using namespace crepe;
+
+class Vector2Test : public ::testing::Test {
+public:
+ Vector2<int> int_vec1;
+ Vector2<int> int_vec2;
+ Vector2<double> double_vec1;
+ Vector2<double> double_vec2;
+ Vector2<long> long_vec1;
+ Vector2<long> long_vec2;
+ Vector2<float> float_vec1;
+ Vector2<float> float_vec2;
+
+ void SetUp() override {
+ int_vec1 = {1, 2};
+ int_vec2 = {3, 4};
+ double_vec1 = {1.0, 2.0};
+ double_vec2 = {3.0, 4.0};
+ long_vec1 = {1, 2};
+ long_vec2 = {3, 4};
+ float_vec1 = {1.0f, 2.0f};
+ float_vec2 = {3.0f, 4.0f};
+ }
+};
+
+TEST_F(Vector2Test, Subtract) {
+ Vector2<int> result = int_vec1 - int_vec2;
+ EXPECT_EQ(result.x, -2);
+ EXPECT_EQ(result.y, -2);
+
+ Vector2<double> result2 = double_vec1 - double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, -2.0);
+ EXPECT_FLOAT_EQ(result2.y, -2.0);
+
+ Vector2<long> result3 = long_vec1 - long_vec2;
+ EXPECT_EQ(result3.x, -2);
+ EXPECT_EQ(result3.y, -2);
+
+ Vector2<float> result4 = float_vec1 - float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, -2.0f);
+ EXPECT_FLOAT_EQ(result4.y, -2.0f);
+}
+
+TEST_F(Vector2Test, SubtractScalar) {
+ Vector2<int> result = int_vec1 - 1;
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 1);
+
+ Vector2<double> result2 = double_vec1 - 1.0;
+ EXPECT_FLOAT_EQ(result2.x, 0.0);
+ EXPECT_FLOAT_EQ(result2.y, 1.0);
+
+ Vector2<long> result3 = long_vec1 - 1;
+ EXPECT_EQ(result3.x, 0);
+ EXPECT_EQ(result3.y, 1);
+
+ Vector2<float> result4 = float_vec1 - 1.0f;
+ EXPECT_FLOAT_EQ(result4.x, 0.0f);
+ EXPECT_FLOAT_EQ(result4.y, 1.0f);
+}
+
+TEST_F(Vector2Test, Add) {
+ Vector2<int> result = int_vec1 + int_vec2;
+ EXPECT_EQ(result.x, 4);
+ EXPECT_EQ(result.y, 6);
+
+ Vector2<double> result2 = double_vec1 + double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, 4.0);
+ EXPECT_FLOAT_EQ(result2.y, 6.0);
+
+ Vector2<long> result3 = long_vec1 + long_vec2;
+ EXPECT_EQ(result3.x, 4);
+ EXPECT_EQ(result3.y, 6);
+
+ Vector2<float> result4 = float_vec1 + float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, 4.0f);
+ EXPECT_FLOAT_EQ(result4.y, 6.0f);
+}
+
+TEST_F(Vector2Test, AddScalar) {
+ Vector2<int> result = int_vec1 + 1;
+ EXPECT_EQ(result.x, 2);
+ EXPECT_EQ(result.y, 3);
+
+ Vector2<double> result2 = double_vec1 + 1.0;
+ EXPECT_FLOAT_EQ(result2.x, 2.0);
+ EXPECT_FLOAT_EQ(result2.y, 3.0);
+
+ Vector2<long> result3 = long_vec1 + 1;
+ EXPECT_EQ(result3.x, 2);
+ EXPECT_EQ(result3.y, 3);
+
+ Vector2<float> result4 = float_vec1 + 1.0f;
+ EXPECT_FLOAT_EQ(result4.x, 2.0f);
+ EXPECT_FLOAT_EQ(result4.y, 3.0f);
+}
+
+TEST_F(Vector2Test, Multiply) {
+ Vector2<int> result = int_vec1 * int_vec2;
+ EXPECT_EQ(result.x, 3);
+ EXPECT_EQ(result.y, 8);
+
+ Vector2<double> result2 = double_vec1 * double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, 3.0);
+ EXPECT_FLOAT_EQ(result2.y, 8.0);
+
+ Vector2<long> result3 = long_vec1 * long_vec2;
+ EXPECT_EQ(result3.x, 3);
+ EXPECT_EQ(result3.y, 8);
+
+ Vector2<float> result4 = float_vec1 * float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, 3.0f);
+ EXPECT_FLOAT_EQ(result4.y, 8.0f);
+}
+
+TEST_F(Vector2Test, MultiplyScalar) {
+ Vector2<int> result = int_vec1 * 2;
+ EXPECT_EQ(result.x, 2);
+ EXPECT_EQ(result.y, 4);
+
+ Vector2<double> result2 = double_vec1 * 2.0;
+ EXPECT_FLOAT_EQ(result2.x, 2.0);
+ EXPECT_FLOAT_EQ(result2.y, 4.0);
+
+ Vector2<long> result3 = long_vec1 * 2;
+ EXPECT_EQ(result3.x, 2);
+ EXPECT_EQ(result3.y, 4);
+
+ Vector2<float> result4 = float_vec1 * 2.0f;
+ EXPECT_FLOAT_EQ(result4.x, 2.0f);
+ EXPECT_FLOAT_EQ(result4.y, 4.0f);
+}
+
+TEST_F(Vector2Test, Divide) {
+ Vector2<int> result = int_vec1 / int_vec2;
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 0);
+
+ Vector2<double> result2 = double_vec1 / double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, 0.33333333333333331);
+ EXPECT_FLOAT_EQ(result2.y, 0.5);
+
+ Vector2<long> result3 = long_vec1 / long_vec2;
+ EXPECT_EQ(result3.x, 0);
+ EXPECT_EQ(result3.y, 0);
+
+ Vector2<float> result4 = float_vec1 / float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, 0.333333343f);
+ EXPECT_FLOAT_EQ(result4.y, 0.5f);
+}
+
+TEST_F(Vector2Test, DivideScalar) {
+ Vector2<int> result = int_vec1 / 2;
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 1);
+
+ Vector2<double> result2 = double_vec1 / 2.0;
+ EXPECT_FLOAT_EQ(result2.x, 0.5);
+ EXPECT_FLOAT_EQ(result2.y, 1.0);
+
+ Vector2<long> result3 = long_vec1 / 2;
+ EXPECT_EQ(result3.x, 0);
+ EXPECT_EQ(result3.y, 1);
+
+ Vector2<float> result4 = float_vec1 / 2.0f;
+ EXPECT_FLOAT_EQ(result4.x, 0.5f);
+ EXPECT_FLOAT_EQ(result4.y, 1.0f);
+}
+
+TEST_F(Vector2Test, AddChain) {
+ Vector2<int> result = int_vec1;
+ result += int_vec2;
+ EXPECT_EQ(result.x, 4);
+ EXPECT_EQ(result.y, 6);
+
+ Vector2<double> result2 = double_vec1;
+ result2 += double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, 4.0);
+ EXPECT_FLOAT_EQ(result2.y, 6.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 += long_vec2;
+ EXPECT_EQ(result3.x, 4);
+ EXPECT_EQ(result3.y, 6);
+
+ Vector2<float> result4 = float_vec1;
+ result4 += float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, 4.0f);
+ EXPECT_FLOAT_EQ(result4.y, 6.0f);
+}
+
+TEST_F(Vector2Test, AddScalarChain) {
+ Vector2<int> result = int_vec1;
+ result += 1;
+ EXPECT_EQ(result.x, 2);
+ EXPECT_EQ(result.y, 3);
+
+ Vector2<double> result2 = double_vec1;
+ result2 += 1.0;
+ EXPECT_FLOAT_EQ(result2.x, 2.0);
+ EXPECT_FLOAT_EQ(result2.y, 3.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 += 1;
+ EXPECT_EQ(result3.x, 2);
+ EXPECT_EQ(result3.y, 3);
+
+ Vector2<float> result4 = float_vec1;
+ result4 += 1.0f;
+ EXPECT_FLOAT_EQ(result4.x, 2.0f);
+ EXPECT_FLOAT_EQ(result4.y, 3.0f);
+}
+
+TEST_F(Vector2Test, SubtractChain) {
+ Vector2<int> result = int_vec1;
+ result -= int_vec2;
+ EXPECT_EQ(result.x, -2);
+ EXPECT_EQ(result.y, -2);
+
+ Vector2<double> result2 = double_vec1;
+ result2 -= double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, -2.0);
+ EXPECT_FLOAT_EQ(result2.y, -2.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 -= long_vec2;
+ EXPECT_EQ(result3.x, -2);
+ EXPECT_EQ(result3.y, -2);
+
+ Vector2<float> result4 = float_vec1;
+ result4 -= float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, -2.0f);
+ EXPECT_FLOAT_EQ(result4.y, -2.0f);
+}
+
+TEST_F(Vector2Test, SubtractScalarChain) {
+ Vector2<int> result = int_vec1;
+ result -= 1;
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 1);
+
+ Vector2<double> result2 = double_vec1;
+ result2 -= 1.0;
+ EXPECT_FLOAT_EQ(result2.x, 0.0);
+ EXPECT_FLOAT_EQ(result2.y, 1.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 -= 1;
+ EXPECT_EQ(result3.x, 0);
+ EXPECT_EQ(result3.y, 1);
+
+ Vector2<float> result4 = float_vec1;
+ result4 -= 1.0f;
+ EXPECT_FLOAT_EQ(result4.x, 0.0f);
+ EXPECT_FLOAT_EQ(result4.y, 1.0f);
+}
+
+TEST_F(Vector2Test, MultiplyChain) {
+ Vector2<int> result = int_vec1;
+ result *= int_vec2;
+ EXPECT_EQ(result.x, 3);
+ EXPECT_EQ(result.y, 8);
+
+ Vector2<double> result2 = double_vec1;
+ result2 *= double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, 3.0);
+ EXPECT_FLOAT_EQ(result2.y, 8.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 *= long_vec2;
+ EXPECT_EQ(result3.x, 3);
+ EXPECT_EQ(result3.y, 8);
+
+ Vector2<float> result4 = float_vec1;
+ result4 *= float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, 3.0f);
+ EXPECT_FLOAT_EQ(result4.y, 8.0f);
+}
+
+TEST_F(Vector2Test, MultiplyScalarChain) {
+ Vector2<int> result = int_vec1;
+ result *= 2;
+ EXPECT_EQ(result.x, 2);
+ EXPECT_EQ(result.y, 4);
+
+ Vector2<double> result2 = double_vec1;
+ result2 *= 2.0;
+ EXPECT_FLOAT_EQ(result2.x, 2.0);
+ EXPECT_FLOAT_EQ(result2.y, 4.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 *= 2;
+ EXPECT_EQ(result3.x, 2);
+ EXPECT_EQ(result3.y, 4);
+
+ Vector2<float> result4 = float_vec1;
+ result4 *= 2.0f;
+ EXPECT_FLOAT_EQ(result4.x, 2.0f);
+ EXPECT_FLOAT_EQ(result4.y, 4.0f);
+}
+
+TEST_F(Vector2Test, DivideChain) {
+ Vector2<int> result = int_vec1;
+ result /= int_vec2;
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 0);
+
+ Vector2<double> result2 = double_vec1;
+ result2 /= double_vec2;
+ EXPECT_FLOAT_EQ(result2.x, 0.33333333333333331);
+ EXPECT_FLOAT_EQ(result2.y, 0.5);
+
+ Vector2<long> result3 = long_vec1;
+ result3 /= long_vec2;
+ EXPECT_EQ(result3.x, 0);
+ EXPECT_EQ(result3.y, 0);
+
+ Vector2<float> result4 = float_vec1;
+ result4 /= float_vec2;
+ EXPECT_FLOAT_EQ(result4.x, 0.333333343f);
+ EXPECT_FLOAT_EQ(result4.y, 0.5f);
+}
+
+TEST_F(Vector2Test, DivideScalarChain) {
+ Vector2<int> result = int_vec1;
+ result /= 2;
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 1);
+
+ Vector2<double> result2 = double_vec1;
+ result2 /= 2.0;
+ EXPECT_FLOAT_EQ(result2.x, 0.5);
+ EXPECT_FLOAT_EQ(result2.y, 1.0);
+
+ Vector2<long> result3 = long_vec1;
+ result3 /= 2;
+ EXPECT_EQ(result3.x, 0);
+ EXPECT_EQ(result3.y, 1);
+
+ Vector2<float> result4 = float_vec1;
+ result4 /= 2.0f;
+ EXPECT_FLOAT_EQ(result4.x, 0.5f);
+ EXPECT_FLOAT_EQ(result4.y, 1.0f);
+}
+
+TEST_F(Vector2Test, Negatation) {
+ Vector2<int> result = -int_vec1;
+ EXPECT_EQ(result.x, -1);
+ EXPECT_EQ(result.y, -2);
+
+ Vector2<double> result2 = -double_vec1;
+ EXPECT_FLOAT_EQ(result2.x, -1.0);
+ EXPECT_FLOAT_EQ(result2.y, -2.0);
+
+ Vector2<long> result3 = -long_vec1;
+ EXPECT_EQ(result3.x, -1);
+ EXPECT_EQ(result3.y, -2);
+
+ Vector2<float> result4 = -float_vec1;
+ EXPECT_FLOAT_EQ(result4.x, -1.0f);
+ EXPECT_FLOAT_EQ(result4.y, -2.0f);
+}
+
+TEST_F(Vector2Test, Equals) {
+ EXPECT_TRUE(int_vec1 == int_vec1);
+ EXPECT_FALSE(int_vec1 == int_vec2);
+ EXPECT_TRUE(double_vec1 == double_vec1);
+ EXPECT_FALSE(double_vec1 == double_vec2);
+ EXPECT_TRUE(long_vec1 == long_vec1);
+ EXPECT_FALSE(long_vec1 == long_vec2);
+}
+
+TEST_F(Vector2Test, NotEquals) {
+ EXPECT_FALSE(int_vec1 != int_vec1);
+ EXPECT_TRUE(int_vec1 != int_vec2);
+ EXPECT_FALSE(double_vec1 != double_vec1);
+ EXPECT_TRUE(double_vec1 != double_vec2);
+ EXPECT_FALSE(long_vec1 != long_vec1);
+ EXPECT_TRUE(long_vec1 != long_vec2);
+}
diff --git a/src/test/main.cpp b/src/test/main.cpp
index 241015d..aece72d 100644
--- a/src/test/main.cpp
+++ b/src/test/main.cpp
@@ -1,15 +1,30 @@
-#include <crepe/api/Config.h>
-
#include <gtest/gtest.h>
+#define protected public
+#define private public
+
+#include <crepe/api/Config.h>
+
using namespace crepe;
using namespace testing;
+class GlobalConfigReset : public EmptyTestEventListener {
+public:
+ Config & cfg = Config::get_instance();
+ Config cfg_default = Config();
+
+ // This function is called before each test
+ void OnTestStart(const TestInfo &) override {
+ cfg = cfg_default;
+ cfg.log.level = Log::Level::WARNING;
+ }
+};
+
int main(int argc, char ** argv) {
InitGoogleTest(&argc, argv);
- auto & cfg = Config::get_instance();
- cfg.log.level = Log::Level::ERROR;
+ UnitTest & ut = *UnitTest::GetInstance();
+ ut.listeners().Append(new GlobalConfigReset);
return RUN_ALL_TESTS();
}