From d9a51069366650051e644453f5d3ac90f2ab29b5 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 16:29:48 +0100 Subject: turn examples into unit tests --- src/crepe/util/Proxy.h | 2 ++ src/crepe/util/Proxy.hpp | 6 +++++ src/example/CMakeLists.txt | 3 --- src/example/log.cpp | 28 ------------------- src/example/proxy.cpp | 45 ------------------------------- src/example/script.cpp | 49 --------------------------------- src/test/CMakeLists.txt | 1 + src/test/ValueBrokerTest.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 73 insertions(+), 125 deletions(-) delete mode 100644 src/example/log.cpp delete mode 100644 src/example/proxy.cpp delete mode 100644 src/example/script.cpp create mode 100644 src/test/ValueBrokerTest.cpp diff --git a/src/crepe/util/Proxy.h b/src/crepe/util/Proxy.h index b34f7c6..789144a 100644 --- a/src/crepe/util/Proxy.h +++ b/src/crepe/util/Proxy.h @@ -15,6 +15,8 @@ namespace crepe { template class Proxy { public: + //! Set operator + Proxy & operator=(Proxy &); //! Set operator Proxy & operator=(const T &); //! Get operator diff --git a/src/crepe/util/Proxy.hpp b/src/crepe/util/Proxy.hpp index b9923db..ef2b69f 100644 --- a/src/crepe/util/Proxy.hpp +++ b/src/crepe/util/Proxy.hpp @@ -13,6 +13,12 @@ Proxy & Proxy::operator=(const T & val) { return *this; } +template +Proxy & Proxy::operator=(Proxy & proxy) { + this->broker.set(T(proxy)); + return *this; +} + template Proxy::operator const T &() { return this->broker.get(); diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 30432e5..f21bd24 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -17,13 +17,10 @@ function(add_example target_name) endfunction() add_example(audio_internal) -add_example(script) -add_example(log) add_example(rendering) add_example(asset_manager) add_example(physics) add_example(savemgr) -add_example(proxy) add_example(db) add_example(particles) add_example(gameloop) diff --git a/src/example/log.cpp b/src/example/log.cpp deleted file mode 100644 index 5baa021..0000000 --- a/src/example/log.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/** \file - * - * Standalone example for usage of the logging functions - */ - -#include -#include - -using namespace crepe; - -// unrelated setup code -int _ = []() { - // make sure all log messages get printed - auto & cfg = Config::get_instance(); - cfg.log.level = Log::Level::TRACE; - - return 0; // satisfy compiler -}(); - -int main() { - dbg_trace(); - dbg_log("debug message"); - Log::logf("info message with variable: {}", 3); - Log::logf(Log::Level::WARNING, "warning"); - Log::logf(Log::Level::ERROR, "error"); - - return 0; -} diff --git a/src/example/proxy.cpp b/src/example/proxy.cpp deleted file mode 100644 index 69451f8..0000000 --- a/src/example/proxy.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/** \file - * - * Standalone example for usage of the proxy type - */ - -#include -#include -#include -#include - -using namespace std; -using namespace crepe; - -void test_ro_ref(const int & val) {} -void test_rw_ref(int & val) {} -void test_ro_val(int val) {} - -int main() { - auto & cfg = Config::get_instance(); - cfg.log.level = Log::Level::DEBUG; - - int real_value = 0; - - ValueBroker broker{ - [&real_value](const int & target) { - dbg_logf("set {} to {}", real_value, target); - real_value = target; - }, - [&real_value]() -> const int & { - dbg_logf("get {}", real_value); - return real_value; - }, - }; - - Proxy proxy{broker}; - - broker.set(54); - proxy = 84; - - test_ro_ref(proxy); // this is allowed - // test_rw_ref(proxy); // this should throw a compile error - test_ro_val(proxy); - - return 0; -} diff --git a/src/example/script.cpp b/src/example/script.cpp deleted file mode 100644 index a23295b..0000000 --- a/src/example/script.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/** \file - * - * Standalone example for usage of the script component and system - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -using namespace crepe; -using namespace std; - -// Unrelated stuff that is not part of this POC -int _ = []() { - // Show dbg_trace() output - auto & cfg = Config::get_instance(); - cfg.log.level = Log::Level::TRACE; - - return 0; // satisfy compiler -}(); - -// User-defined script: -class MyScript : public Script { - void update() { - // Retrieve component from the same GameObject this script is on - Transform & test = get_component(); - dbg_logf("Transform({:.2f}, {:.2f})", test.position.x, test.position.y); - } -}; - -int main() { - ComponentManager component_manager{}; - ScriptSystem system{component_manager}; - - // Create game object with Transform and BehaviorScript components - GameObject obj = component_manager.new_object("name"); - obj.add_component().set_script(); - - // Update all scripts. This should result in MyScript::update being called - system.update(); - - return EXIT_SUCCESS; -} diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index d56d80f..c1f935d 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -5,5 +5,6 @@ target_sources(test_main PUBLIC ParticleTest.cpp ECSTest.cpp SceneManagerTest.cpp + ValueBrokerTest.cpp ) diff --git a/src/test/ValueBrokerTest.cpp b/src/test/ValueBrokerTest.cpp new file mode 100644 index 0000000..10a4654 --- /dev/null +++ b/src/test/ValueBrokerTest.cpp @@ -0,0 +1,64 @@ +#include + +#include +#include + +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 broker { + [this](const int & target) -> void { + this->write_count++; + this->value = target; + }, + [this]() -> const int & { + this->read_count++; + return this->value; + }, + }; + Proxy 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); +} + -- cgit v1.2.3 From fdf91122ddc1fa9942c8790d2c8c845f877df11d Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Wed, 20 Nov 2024 16:46:00 +0100 Subject: convert more examples to unit tests --- src/crepe/facade/DB.cpp | 4 +-- src/crepe/facade/DB.h | 4 ++- src/example/CMakeLists.txt | 5 --- src/example/audio_internal.cpp | 56 -------------------------------- src/example/db.cpp | 30 ------------------ src/example/particles.cpp | 43 ------------------------- src/example/physics.cpp | 24 -------------- src/example/rendering.cpp | 72 ------------------------------------------ src/test/CMakeLists.txt | 1 + src/test/DBTest.cpp | 29 +++++++++++++++++ 10 files changed, 35 insertions(+), 233 deletions(-) delete mode 100644 src/example/audio_internal.cpp delete mode 100644 src/example/db.cpp delete mode 100644 src/example/particles.cpp delete mode 100644 src/example/physics.cpp delete mode 100644 src/example/rendering.cpp create mode 100644 src/test/DBTest.cpp diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp index d5d19dc..95cf606 100644 --- a/src/crepe/facade/DB.cpp +++ b/src/crepe/facade/DB.cpp @@ -18,8 +18,8 @@ DB::DB(const string & path) { this->db = {db, [](libdb::DB * db) { db->close(db, 0); }}; // load or create database file - ret = this->db->open(this->db.get(), NULL, path.c_str(), NULL, libdb::DB_BTREE, DB_CREATE, - 0); + const char * file = path.empty() ? NULL : path.c_str(); + ret = this->db->open(this->db.get(), NULL, file, NULL, libdb::DB_BTREE, DB_CREATE, 0); if (ret != 0) throw runtime_error(format("db->open: {}", libdb::db_strerror(ret))); // create cursor diff --git a/src/crepe/facade/DB.h b/src/crepe/facade/DB.h index 629b0eb..115c0f1 100644 --- a/src/crepe/facade/DB.h +++ b/src/crepe/facade/DB.h @@ -22,8 +22,10 @@ class DB { public: /** * \param path The path of the database (created if nonexistant) + * + * \note If \p path is empty, the database is entirely in-memory */ - DB(const std::string & path); + DB(const std::string & path = ""); virtual ~DB() = default; public: diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index f21bd24..c75a4b5 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -16,12 +16,7 @@ function(add_example target_name) add_dependencies(examples ${target_name}) endfunction() -add_example(audio_internal) -add_example(rendering) add_example(asset_manager) -add_example(physics) add_example(savemgr) -add_example(db) -add_example(particles) add_example(gameloop) diff --git a/src/example/audio_internal.cpp b/src/example/audio_internal.cpp deleted file mode 100644 index 661161a..0000000 --- a/src/example/audio_internal.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** \file - * - * Standalone example for usage of the internal \c Sound class. - */ - -#include -#include -#include - -#include - -using namespace crepe; -using namespace std; -using namespace std::chrono_literals; -using std::make_unique; - -// Unrelated stuff that is not part of this POC -int _ = []() { - // Show dbg_trace() output - auto & cfg = Config::get_instance(); - cfg.log.level = Log::Level::TRACE; - - return 0; // satisfy compiler -}(); - -int main() { - // Load a background track (Ogg Vorbis) - auto bgm = Sound("../mwe/audio/bgm.ogg"); - // Load three short samples (WAV) - auto sfx1 = Sound("../mwe/audio/sfx1.wav"); - auto sfx2 = Sound("../mwe/audio/sfx2.wav"); - auto sfx3 = Sound("../mwe/audio/sfx3.wav"); - - // Start the background track - bgm.play(); - - // Play each sample sequentially while pausing and resuming the background track - this_thread::sleep_for(500ms); - sfx1.play(); - this_thread::sleep_for(500ms); - sfx2.play(); - bgm.pause(); - this_thread::sleep_for(500ms); - sfx3.play(); - bgm.play(); - this_thread::sleep_for(500ms); - - // Play all samples simultaniously - sfx1.play(); - sfx2.play(); - sfx3.play(); - this_thread::sleep_for(1000ms); - - // Stop all audio and exit - return EXIT_SUCCESS; -} diff --git a/src/example/db.cpp b/src/example/db.cpp deleted file mode 100644 index ee4e8fc..0000000 --- a/src/example/db.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -using namespace crepe; -using namespace std; - -// run before main -static auto _ = []() { - auto & cfg = Config::get_instance(); - cfg.log.level = Log::Level::TRACE; - return 0; -}(); - -int main() { - dbg_trace(); - - DB db("file.db"); - - const char * test_key = "test-key"; - string test_data = "Hello world!"; - - dbg_logf("DB has key = {}", db.has(test_key)); - - db.set(test_key, test_data); - - dbg_logf("key = \"{}\"", db.get(test_key)); - - return 0; -} diff --git a/src/example/particles.cpp b/src/example/particles.cpp deleted file mode 100644 index 3d5f676..0000000 --- a/src/example/particles.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace crepe; -using namespace std; - -int main(int argc, char * argv[]) { - ComponentManager mgr{}; - GameObject game_object = mgr.new_object("", "", Vector2{0, 0}, 0, 0); - Color color(0, 0, 0, 0); - Sprite test_sprite = game_object.add_component( - make_shared("../asset/texture/img.png"), color, FlipSettings{true, true}); - game_object.add_component(ParticleEmitter::Data{ - .position = {0, 0}, - .max_particles = 100, - .emission_rate = 0, - .min_speed = 0, - .max_speed = 0, - .min_angle = 0, - .max_angle = 0, - .begin_lifespan = 0, - .end_lifespan = 0, - .force_over_time = Vector2{0, 0}, - .boundary{ - .width = 0, - .height = 0, - .offset = Vector2{0, 0}, - .reset_on_exit = false, - }, - .sprite = test_sprite, - }); - - return 0; -} diff --git a/src/example/physics.cpp b/src/example/physics.cpp deleted file mode 100644 index ad663a0..0000000 --- a/src/example/physics.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include -#include -#include - -using namespace crepe; -using namespace std; - -int main(int argc, char * argv[]) { - ComponentManager mgr{}; - - GameObject game_object = mgr.new_object("Name", "Tag", Vector2{0, 0}, 0, 0); - game_object.add_component(Rigidbody::Data{ - .mass = 1, - .gravity_scale = 1, - .body_type = Rigidbody::BodyType::DYNAMIC, - .constraints = {0, 0, 0}, - .use_gravity = true, - .bounce = false, - }); - return 0; -} diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp deleted file mode 100644 index ecd3f6a..0000000 --- a/src/example/rendering.cpp +++ /dev/null @@ -1,72 +0,0 @@ -#include "api/Camera.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace std; -using namespace crepe; - -int main() { - dbg_trace(); - - ComponentManager mgr{}; - RenderSystem sys{mgr}; - - GameObject obj = mgr.new_object("name", "tag", Vector2{0, 0}, 1, 1); - GameObject obj1 = mgr.new_object("name", "tag", Vector2{500, 0}, 1, 0.1); - GameObject obj2 = mgr.new_object("name", "tag", Vector2{800, 0}, 1, 0.1); - - // Normal adding components - { - Color color(0, 0, 0, 0); - Sprite & sprite - = obj.add_component(make_shared("../asset/texture/img.png"), - color, FlipSettings{false, false}); - sprite.sorting_in_layer = 2; - sprite.order_in_layer = 1; - obj.add_component(Color::get_red()); - } - { - Color color(0, 0, 0, 0); - Sprite & sprite = obj1.add_component( - make_shared("../asset/texture/img.png"), color, FlipSettings{true, true}); - sprite.sorting_in_layer = 2; - sprite.order_in_layer = 2; - } - - { - Color color(0, 0, 0, 0); - Sprite & sprite = obj2.add_component( - make_shared("../asset/texture/img.png"), color, FlipSettings{true, true}); - sprite.sorting_in_layer = 1; - sprite.order_in_layer = 2; - } - - /* - { - Color color(0, 0, 0, 0); - auto img = mgr.cache("../asset/texture/second.png"); - obj2.add_component(img, color, FlipSettings{true, true}); - } - */ - - sys.update(); - /* - - auto start = std::chrono::steady_clock::now(); - while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { - sys.update(); - } - */ -} diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index c1f935d..61dd2d9 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -6,5 +6,6 @@ target_sources(test_main PUBLIC 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..b57eba9 --- /dev/null +++ b/src/test/DBTest.cpp @@ -0,0 +1,29 @@ +#include +#include + +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); +} + -- cgit v1.2.3