aboutsummaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/AssetTest.cpp26
-rw-r--r--src/test/CMakeLists.txt6
-rw-r--r--src/test/DBTest.cpp28
-rw-r--r--src/test/EventTest.cpp254
-rw-r--r--src/test/OptionalRefTest.cpp42
-rw-r--r--src/test/ParticleTest.cpp4
-rw-r--r--src/test/SceneManagerTest.cpp8
-rw-r--r--src/test/ValueBrokerTest.cpp63
8 files changed, 427 insertions, 4 deletions
diff --git a/src/test/AssetTest.cpp b/src/test/AssetTest.cpp
new file mode 100644
index 0000000..8aa7629
--- /dev/null
+++ b/src/test/AssetTest.cpp
@@ -0,0 +1,26 @@
+#include <gtest/gtest.h>
+
+#include <crepe/api/Asset.h>
+#include <crepe/api/Config.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class AssetTest : public Test {
+public:
+ Config & cfg = Config::get_instance();
+ void SetUp() override { this->cfg.asset.root_pattern = ".crepe-root"; }
+};
+
+TEST_F(AssetTest, Existant) { ASSERT_NO_THROW(Asset{"asset/texture/img.png"}); }
+
+TEST_F(AssetTest, Nonexistant) { ASSERT_ANY_THROW(Asset{"asset/nonexistant"}); }
+
+TEST_F(AssetTest, Rootless) {
+ 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 14c5123..8be8252 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -4,7 +4,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
)
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/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..eee022f 100644
--- a/src/test/ParticleTest.cpp
+++ b/src/test/ParticleTest.cpp
@@ -28,8 +28,8 @@ public:
GameObject game_object = mgr.new_object("", "", Vector2{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,
+ Sprite & test_sprite = game_object.add_component<Sprite>(
+ make_shared<Texture>("asset/texture/img.png"), color,
FlipSettings{true, true});
game_object.add_component<ParticleEmitter>(ParticleEmitter::Data{
diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp
index 69e1171..1efcfb2 100644
--- a/src/test/SceneManagerTest.cpp
+++ b/src/test/SceneManagerTest.cpp
@@ -20,6 +20,8 @@ public:
GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1);
GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1);
}
+
+ string get_name() const { return "scene1"; }
};
class ConcreteScene2 : public Scene {
@@ -33,6 +35,8 @@ public:
GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1);
GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1);
}
+
+ string get_name() const { return "scene2"; }
};
class SceneManagerTest : public ::testing::Test {
@@ -42,8 +46,8 @@ public:
};
TEST_F(SceneManagerTest, loadScene) {
- scene_mgr.add_scene<ConcreteScene1>("scene1");
- scene_mgr.add_scene<ConcreteScene2>("scene2");
+ scene_mgr.add_scene<ConcreteScene1>();
+ scene_mgr.add_scene<ConcreteScene2>();
scene_mgr.load_next_scene();
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);
+}