From abb9c1b1ec9b8e8661722eb18f537feccb8438ad Mon Sep 17 00:00:00 2001 From: light7734 Date: Tue, 20 Jan 2026 13:22:30 +0330 Subject: [PATCH] refactor: major qol changes --- modules/CMakeLists.txt | 3 + modules/assets/shader.test.cpp | 68 +++++++++++----------- modules/ecs/registry.test.cpp | 23 +++----- modules/ecs/sparse_set.cppm | 22 +++++++ modules/ecs/sparse_set.test.cpp | 54 ++++++++++++----- modules/input/system.test.cpp | 66 +++++++++------------ modules/input_codes/input_codes.cppm | 2 +- modules/logger/logger.test.cpp | 8 +-- modules/math/mat4.cppm | 23 +++++--- modules/math/vec2.cppm | 10 ++-- modules/math/vec2.test.cpp | 7 +++ modules/math/vec3.cppm | 10 ++-- modules/math/vec4.cppm | 10 ++-- modules/renderer/_tests/buffer.cpp | 4 +- modules/renderer/_tests/debugger.cpp | 4 +- modules/renderer/_tests/device.cpp | 4 +- modules/renderer/_tests/pass.cpp | 4 +- modules/renderer/_tests/renderer.cpp | 4 +- modules/renderer/_tests/surface.cpp | 4 +- modules/renderer/_tests/system.cpp | 4 +- modules/renderer/_tests/utils.cppm | 14 +---- modules/sandbox/CMakeLists.txt | 2 +- modules/sandbox/sandbox.cpp | 1 - modules/surface/system.cppm | 1 + modules/surface/system.test.cpp | 34 +++-------- modules/test/entrypoint.cpp | 15 ++--- modules/test/fuzz.cppm | 86 ---------------------------- modules/test/module.cppm | 23 ++++++++ modules/test/test.test.cpp | 16 +----- modules/time/timer.test.cpp | 25 +++----- 30 files changed, 231 insertions(+), 320 deletions(-) create mode 100644 modules/math/vec2.test.cpp delete mode 100644 modules/test/fuzz.cppm create mode 100644 modules/test/module.cppm diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index a282d41..541daae 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -14,6 +14,7 @@ add_module( NAME test INTERFACES + module.cppm test.cppm expects.cppm registry.cppm @@ -39,6 +40,8 @@ add_module( components.cppm DEPENDENCIES preliminary + TESTS + vec2.test.cpp ) add_module( diff --git a/modules/assets/shader.test.cpp b/modules/assets/shader.test.cpp index f9e1299..500bb3e 100644 --- a/modules/assets/shader.test.cpp +++ b/modules/assets/shader.test.cpp @@ -1,48 +1,42 @@ -import preliminary; +import test; import assets.metadata; import assets.shader; -import logger; -import logger; -import test.test; -import test.expects; using ::lt::assets::AssetMetadata; +using ::lt::assets::Blob; using ::lt::assets::BlobMetadata; using ::lt::assets::ShaderAsset; -using ::lt::test::Case; -using ::lt::test::expect_eq; -using ::lt::test::expect_throw; -using ::lt::test::expect_true; -using ::lt::test::Suite; -using ::lt::test::operator""_suite; const auto test_data_path = std::filesystem::path { "./data/test_assets" }; const auto tmp_path = std::filesystem::path { "/tmp/lt_assets_tests/" }; +[[nodiscard]] auto generate_blob(size_t size) -> Blob +{ + auto blob = Blob {}; + for (auto idx : std::views::iota(0u, size)) + { + blob.emplace_back(static_cast(idx)); + } + + return blob; +} + Suite raii = "shader_raii"_suite = [] { std::filesystem::current_path(test_data_path); std::filesystem::create_directories(tmp_path); - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { auto shader_asset = ShaderAsset { "triangle.frag.asset" }; }; - Case { "many won't freeze/throw" } = [] { - for (auto idx : std::views::iota(0u, 1'000u)) - { - ignore = idx; - auto shader_asset = ShaderAsset { "triangle.frag.asset" }; - } - }; - - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { // non-existent file expect_throw([] { ShaderAsset { "path" }; }); // incompatible type expect_throw([] { ShaderAsset { "dummytext" }; }); - // random stressing + // some random stressing expect_throw([] { for (auto idx : std::views::iota(0u, 1'000u)) { @@ -50,16 +44,22 @@ Suite raii = "shader_raii"_suite = [] { } }); }; + + Case { "many" } = [] { + for (auto idx : std::views::iota(0u, 1'000u)) + { + ignore = idx; + auto shader_asset = ShaderAsset { "triangle.frag.asset" }; + } + }; }; Suite packing = "shader_pack"_suite = [] { - Case { "" } = [] { + Case { "Unpacking packed data returns the same data" } = [] { const auto out_path = tmp_path / "shader_packing"; - auto dummy_blob = lt::assets::Blob {}; - for (auto idx : std::views::iota(0u, 255u)) - { - dummy_blob.emplace_back(static_cast(idx)); - } + constexpr auto blob_size = size_t { 255u }; + + auto blob = generate_blob(blob_size); const auto expected_size = // sizeof(AssetMetadata::type) // @@ -70,7 +70,7 @@ Suite packing = "shader_pack"_suite = [] { + sizeof(BlobMetadata::compression_type) // + sizeof(BlobMetadata::compressed_size) // + sizeof(BlobMetadata::uncompressed_size) // - + dummy_blob.size(); + + blob.size(); ShaderAsset::pack( out_path, @@ -81,7 +81,7 @@ Suite packing = "shader_pack"_suite = [] { ShaderAsset::Metadata { .type = ShaderAsset::Type::vertex, }, - std::move(dummy_blob) + std::move(blob) ); auto stream = std::ifstream { @@ -104,12 +104,12 @@ Suite packing = "shader_pack"_suite = [] { const auto &metadata = shader_asset.get_metadata(); expect_eq(metadata.type, ShaderAsset::Type::vertex); - auto blob = shader_asset.unpack(ShaderAsset::BlobTag::code); - expect_eq(blob.size(), 255u); + auto unpakced_blob = shader_asset.unpack(ShaderAsset::BlobTag::code); + expect_eq(unpakced_blob.size(), blob_size); - for (auto idx : std::views::iota(0u, 255u)) + for (auto idx : std::views::iota(0u, blob_size)) { - expect_eq(blob[idx], static_cast(idx)); + expect_eq(unpakced_blob[idx], static_cast(idx)); } }; }; diff --git a/modules/ecs/registry.test.cpp b/modules/ecs/registry.test.cpp index 9c59437..c7a4562 100644 --- a/modules/ecs/registry.test.cpp +++ b/modules/ecs/registry.test.cpp @@ -1,17 +1,8 @@ -import preliminary; +import test; import ecs.registry; -import test.test; -import test.expects; using ::lt::ecs::EntityId; using ::lt::ecs::Registry; -using ::lt::test::Case; -using ::lt::test::expect_eq; -using ::lt::test::expect_false; -using ::lt::test::expect_true; -using ::lt::test::expect_unreachable; -using ::lt::test::Suite; -using ::lt::test::operator""_suite; struct Component { @@ -61,11 +52,14 @@ struct std::formatter }; Suite raii = "raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { ignore = Registry {}; }; - Case { "many won't freeze/throw" } = [] { + Case { "unhappy paths" } = [] { + }; + + Case { "many" } = [] { for (auto idx : std::views::iota(0, 100'000)) { ignore = idx; @@ -73,9 +67,6 @@ Suite raii = "raii"_suite = [] { } }; - Case { "unhappy path throws" } = [] { - }; - Case { "post construct has correct state" } = [] { auto registry = Registry {}; expect_eq(registry.get_entity_count(), 0); @@ -227,7 +218,7 @@ Suite each = "each"_suite = [] { component_map_a[entity] = component; } - auto component_map_b = std::unordered_map {}; + auto component_map_b = std::unordered_map {}; for (auto idx : std::views::iota(0, 10'000)) { auto entity = EntityId {}; diff --git a/modules/ecs/sparse_set.cppm b/modules/ecs/sparse_set.cppm index b94cee8..b72febf 100644 --- a/modules/ecs/sparse_set.cppm +++ b/modules/ecs/sparse_set.cppm @@ -51,6 +51,8 @@ public: auto insert(Identifier_T identifier, Value_T value) -> Dense_T & { + ensure(identifier < max_capacity, "SparseSet::insert: identifier < max_capacity"); + if (m_sparse.size() < identifier + 1) { auto new_capacity = std::max(static_cast(identifier + 1), m_sparse.size() * 2); @@ -70,7 +72,27 @@ public: */ void remove(Identifier_T identifier) override { + ensure( + identifier < m_sparse.size(), + "Failed to ensure: identifier < m_sparse.size() [{} < {}]", + identifier, + m_sparse.size() + ); + auto &idx = m_sparse[identifier]; + ensure( + idx != null_identifier, + "Failed to ensure: idx != null_identifier [{} != {}]", + idx, + null_identifier + ); + ensure( + idx < m_dense.size(), + "Failed to ensure: idx < m_dense.size() [{} < {}]", + idx, + m_dense.size() + ); + auto &[entity, component] = m_dense[idx]; auto &[last_entity, last_component] = m_dense.back(); diff --git a/modules/ecs/sparse_set.test.cpp b/modules/ecs/sparse_set.test.cpp index 8338d75..b1f3186 100644 --- a/modules/ecs/sparse_set.test.cpp +++ b/modules/ecs/sparse_set.test.cpp @@ -1,31 +1,28 @@ -import preliminary; +import test; import ecs.sparse_set; -import test.test; -import test.expects; - -using ::lt::test::Case; -using ::lt::test::expect_eq; -using ::lt::test::expect_false; -using ::lt::test::expect_ne; -using ::lt::test::expect_throw; -using ::lt::test::expect_true; -using ::lt::test::Suite; -using ::lt::test::operator""_suite; using Value_T = i32; using Set = lt::ecs::SparseSet; + constexpr auto capacity = 100; Suite raii = "raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { ignore = Set {}; ignore = Set { Set::max_capacity }; }; - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { expect_throw([] { ignore = Set { Set::max_capacity + 1 }; }); }; + Case { "many" } = [] { + for (auto idx : std::views::iota(0, 1'000)) + { + ignore = Set { static_cast(idx) }; + } + }; + Case { "post construct has correct state" } = [&] { auto set = Set { capacity }; expect_eq(set.get_size(), 0); @@ -34,7 +31,29 @@ Suite raii = "raii"_suite = [] { }; Suite element_raii = "element_raii"_suite = [] { - Case { "many inserts/removes won't freeze/throw" } = [] { + Case { "happy paths" } = [] { + auto set = Set { capacity }; + set.insert(0, {}); + set.remove(0); + }; + + Case { "unhappy paths" } = [] { + expect_throw([] { + auto set = Set { capacity }; + set.insert(Set::max_capacity + 1, {}); + }); + + expect_throw([] { + auto set = Set { capacity }; + set.insert(0, {}); + set.insert(1, {}); + set.insert(2, {}); + + set.remove(3); + }); + }; + + Case { "many" } = [] { auto set = Set {}; for (auto idx : std::views::iota(0, 10'000)) { @@ -160,5 +179,10 @@ Suite clear = "clear"_suite = [] { set.clear(); expect_eq(set.get_size(), 0); + + for (auto idx : std::views::iota(0, 10'000)) + { + expect_throw([&] { ignore = set.at(idx); }); + } }; }; diff --git a/modules/input/system.test.cpp b/modules/input/system.test.cpp index 6e4d8eb..07df74b 100644 --- a/modules/input/system.test.cpp +++ b/modules/input/system.test.cpp @@ -1,9 +1,6 @@ -import std; +import test; import input.system; import input.codes; -import std; -import test.test; -import test.expects; import surface.events; import memory.scope; import memory.reference; @@ -12,22 +9,10 @@ import ecs.entity; import ecs.registry; import surface.system; +using ::lt::input::InputComponent; +using ::lt::input::System; -// NOLINTBEGIN -using namespace lt; -using input::InputComponent; -using input::System; -using test::Case; -using test::expect_eq; -using test::expect_false; -using test::expect_ne; -using test::expect_not_nullptr; -using test::operator""_suite; -using test::expect_throw; -using test::Suite; -// NOLINTEND - -[[nodiscard]] auto tick_info() -> app::TickInfo +[[nodiscard]] auto tick_info() -> lt::app::TickInfo { return { .delta_time = std::chrono::milliseconds { 16 }, @@ -39,12 +24,12 @@ using test::Suite; class Fixture { public: - [[nodiscard]] auto registry() -> memory::Ref + [[nodiscard]] auto registry() -> lt::memory::Ref { return m_registry; } - auto add_input_component() -> ecs::EntityId + auto add_input_component() -> lt::ecs::EntityId { auto entity = m_registry->create_entity(); m_registry->add(entity, {}); @@ -52,7 +37,7 @@ public: return entity; } - auto add_surface_component() -> ecs::EntityId + auto add_surface_component() -> lt::ecs::EntityId { auto entity = m_registry->create_entity(); m_surface_system.create_surface_component( @@ -64,17 +49,21 @@ public: } private: - memory::Ref m_registry = memory::create_ref(); + lt::memory::Ref m_registry = lt::memory::create_ref(); - surface::System m_surface_system = surface::System { m_registry }; + lt::surface::System m_surface_system = lt::surface::System { m_registry }; }; Suite raii = "raii"_suite = "raii"_suite = [] { - Case { "happy path won't throw" } = [&] { + Case { "happy paths" } = [&] { System { Fixture {}.registry() }; }; - Case { "many won't freeze/throw" } = [&] { + Case { "unhappy paths" } = [] { + expect_throw([] { ignore = System { {} }; }); + }; + + Case { "many" } = [&] { auto fixture = Fixture {}; for (auto idx : std::views::iota(0, 10'000)) { @@ -82,10 +71,6 @@ Suite raii = "raii"_suite = "raii"_suite = [] { ignore = System { fixture.registry() }; } }; - - Case { "unhappy path throws" } = [] { - expect_throw([] { ignore = System { {} }; }); - }; }; Suite system_events = "system_events"_suite = [] { @@ -122,7 +107,7 @@ Suite registry_events = "registry_events"_suite = [] { Case { "on_destrroy" } = [] { auto fixture = Fixture {}; auto registry = fixture.registry(); - auto system = memory::create_scope(registry); + auto system = lt::memory::create_scope(registry); auto entity_a = fixture.add_input_component(); auto entity_b = fixture.add_input_component(); @@ -154,7 +139,7 @@ Suite tick = "tick"_suite = [] { auto system = System { fixture.registry() }; auto surface_entity = fixture.add_surface_component(); - auto &surface = registry->get(surface_entity); + auto &surface = registry->get(surface_entity); auto input_entity = fixture.add_input_component(); auto &input = registry->get(input_entity); @@ -166,24 +151,25 @@ Suite tick = "tick"_suite = [] { } ); - expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive); + using enum ::lt::input::InputAction::State; + expect_eq(input.get_action(action_key).state, inactive); system.tick(tick_info()); - expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive); + expect_eq(input.get_action(action_key).state, inactive); - surface.push_event(surface::KeyPressedEvent(Key::a)); + surface.push_event(lt::surface::KeyPressedEvent(Key::a)); system.tick(tick_info()); - expect_eq(input.get_action(action_key).state, input::InputAction::State::triggered); + expect_eq(input.get_action(action_key).state, triggered); system.tick(tick_info()); - expect_eq(input.get_action(action_key).state, input::InputAction::State::active); + expect_eq(input.get_action(action_key).state, active); system.tick(tick_info()); system.tick(tick_info()); system.tick(tick_info()); - expect_eq(input.get_action(action_key).state, input::InputAction::State::active); + expect_eq(input.get_action(action_key).state, active); - surface.push_event(surface::KeyReleasedEvent(Key::a)); + surface.push_event(lt::surface::KeyReleasedEvent(Key::a)); system.tick(tick_info()); - expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive); + expect_eq(input.get_action(action_key).state, inactive); }; }; diff --git a/modules/input_codes/input_codes.cppm b/modules/input_codes/input_codes.cppm index 945e119..4dafa66 100644 --- a/modules/input_codes/input_codes.cppm +++ b/modules/input_codes/input_codes.cppm @@ -5,7 +5,7 @@ * * Hence, both `Surface` and `Input` needs to agree to the same input codes, while `Input` depends * on `Surface`. The simplest solution is to keep the codes in a 3rd module and make both depend on - * it. + * it. (I did not want to give `Surface` the responsibility of defining input codes...) */ export module input.codes; diff --git a/modules/logger/logger.test.cpp b/modules/logger/logger.test.cpp index 16273e0..1247e63 100644 --- a/modules/logger/logger.test.cpp +++ b/modules/logger/logger.test.cpp @@ -1,11 +1,7 @@ -import logger; -import test.test; - -using ::lt::test::Case; -using ::lt::test::Suite; +import test; Suite suite = [] { - Case { "no format" } = [] { + Case { "formatless" } = [] { lt::log::trace("trace"); lt::log::debug("debug"); lt::log::info("info"); diff --git a/modules/math/mat4.cppm b/modules/math/mat4.cppm index f2f5d9c..7d7ca79 100644 --- a/modules/math/mat4.cppm +++ b/modules/math/mat4.cppm @@ -5,9 +5,10 @@ import math.vec2; import math.vec3; import math.vec4; -namespace lt::math { +export namespace lt::math { -export template +template + requires(std::is_arithmetic_v) struct mat4_impl { using Column_T = vec4_impl; @@ -79,34 +80,38 @@ struct mat4_impl std::array values; }; -export template +/** @todo(Light): Implement */ +template [[nodiscard]] auto translate(const vec3_impl &value) -> mat4_impl { return mat4_impl {}; } -export template +/** @todo(Light): Implement */ +template [[nodiscard]] auto rotate(f32 value, const vec3_impl &xyz) -> mat4_impl { return mat4_impl {}; } -export template +/** @todo(Light): Implement */ +template [[nodiscard]] auto scale(const vec3_impl &value) -> mat4_impl { return mat4_impl {}; } -export template +/** @todo(Light): Implement */ +template [[nodiscard]] auto inverse(const mat4_impl &value) -> mat4_impl { return mat4_impl {}; } -export using mat4 = mat4_impl; +using mat4 = mat4_impl; -export using imat4 = mat4_impl; +using imat4 = mat4_impl; -export using umat4 = mat4_impl; +using umat4 = mat4_impl; } // namespace lt::math diff --git a/modules/math/vec2.cppm b/modules/math/vec2.cppm index 8bc57a1..bb59e33 100644 --- a/modules/math/vec2.cppm +++ b/modules/math/vec2.cppm @@ -2,9 +2,9 @@ export module math.vec2; import preliminary; -namespace lt::math { +export namespace lt::math { -export template +template requires(std::is_arithmetic_v) struct vec2_impl { @@ -88,11 +88,11 @@ struct vec2_impl }; -export using vec2 = vec2_impl; +using vec2 = vec2_impl; -export using ivec2 = vec2_impl; +using ivec2 = vec2_impl; -export using uvec2 = vec2_impl; +using uvec2 = vec2_impl; } // namespace lt::math diff --git a/modules/math/vec2.test.cpp b/modules/math/vec2.test.cpp new file mode 100644 index 0000000..08a4de0 --- /dev/null +++ b/modules/math/vec2.test.cpp @@ -0,0 +1,7 @@ +import test; +import math.vec2; + +Suite raii = "raii"_suite = [] { + Case { "happy path" } = [] { + }; +}; diff --git a/modules/math/vec3.cppm b/modules/math/vec3.cppm index 88c4fec..db13702 100644 --- a/modules/math/vec3.cppm +++ b/modules/math/vec3.cppm @@ -3,9 +3,9 @@ export module math.vec3; import preliminary; import math.vec2; -namespace lt::math { +export namespace lt::math { -export template +template requires(std::is_arithmetic_v) struct vec3_impl { @@ -102,11 +102,11 @@ struct vec3_impl T z; }; -export using vec3 = vec3_impl; +using vec3 = vec3_impl; -export using ivec3 = vec3_impl; +using ivec3 = vec3_impl; -export using uvec3 = vec3_impl; +using uvec3 = vec3_impl; } // namespace lt::math diff --git a/modules/math/vec4.cppm b/modules/math/vec4.cppm index 83e2d02..db5fdb6 100644 --- a/modules/math/vec4.cppm +++ b/modules/math/vec4.cppm @@ -4,9 +4,9 @@ import preliminary; import math.vec2; import math.vec3; -namespace lt::math { +export namespace lt::math { -export template +template requires(std::is_arithmetic_v) struct vec4_impl { @@ -121,11 +121,11 @@ struct vec4_impl T w; }; -export using vec4 = vec4_impl; +using vec4 = vec4_impl; -export using ivec4 = vec4_impl; +using ivec4 = vec4_impl; -export using uvec4 = vec4_impl; +using uvec4 = vec4_impl; } // namespace lt::math diff --git a/modules/renderer/_tests/buffer.cpp b/modules/renderer/_tests/buffer.cpp index f555174..2eec063 100644 --- a/modules/renderer/_tests/buffer.cpp +++ b/modules/renderer/_tests/buffer.cpp @@ -7,12 +7,12 @@ using ::std::this_thread::sleep_for; // TODO(Light): finish these (and many other) tests... Suite raii = "buffer_raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { auto fixture = FixtureDeviceSwapchain {}; }; sleep_for(std::chrono::milliseconds { 500u }); - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { auto fixture = FixtureDeviceSwapchain {}; }; sleep_for(std::chrono::milliseconds { 500u }); diff --git a/modules/renderer/_tests/debugger.cpp b/modules/renderer/_tests/debugger.cpp index 88c0985..60708e3 100644 --- a/modules/renderer/_tests/debugger.cpp +++ b/modules/renderer/_tests/debugger.cpp @@ -2,7 +2,7 @@ import renderer.frontend; import renderer.test_utils; Suite raii = "debugger_raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { ignore = lt::renderer::create_debugger( lt::renderer::Api::vulkan, lt::renderer::get_instance(lt::renderer::Api::vulkan), @@ -14,7 +14,7 @@ Suite raii = "debugger_raii"_suite = [] { ); }; - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { expect_throw([] { ignore = lt::renderer::create_debugger( lt::renderer::Api::vulkan, diff --git a/modules/renderer/_tests/device.cpp b/modules/renderer/_tests/device.cpp index ad75b19..d78148a 100644 --- a/modules/renderer/_tests/device.cpp +++ b/modules/renderer/_tests/device.cpp @@ -2,12 +2,12 @@ import renderer.frontend; import renderer.test_utils; Suite raii = "device_raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { auto fixture = Fixture_SurfaceGpu {}; ignore = lt::renderer::create_device(constants::api, fixture.gpu(), fixture.surface()); }; - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { auto fixture = Fixture_SurfaceGpu {}; expect_throw([&] { diff --git a/modules/renderer/_tests/pass.cpp b/modules/renderer/_tests/pass.cpp index be9ce00..7d09eca 100644 --- a/modules/renderer/_tests/pass.cpp +++ b/modules/renderer/_tests/pass.cpp @@ -2,7 +2,7 @@ import renderer.frontend; import renderer.test_utils; Suite raii = "pass_raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { auto fixture = FixtureDeviceSwapchain {}; ignore = lt::renderer::create_pass( constants::api, @@ -17,7 +17,7 @@ Suite raii = "pass_raii"_suite = [] { ); }; - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { auto fixture = FixtureDeviceSwapchain {}; expect_throw([&] { ignore = lt::renderer::create_pass( diff --git a/modules/renderer/_tests/renderer.cpp b/modules/renderer/_tests/renderer.cpp index 6edd944..d154f2b 100644 --- a/modules/renderer/_tests/renderer.cpp +++ b/modules/renderer/_tests/renderer.cpp @@ -2,7 +2,7 @@ import renderer.frontend; import renderer.test_utils; Suite raii = "renderer_raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { auto fixture = FixtureDeviceSwapchain {}; ignore = lt::renderer::create_renderer( constants::api, @@ -18,7 +18,7 @@ Suite raii = "renderer_raii"_suite = [] { ); }; - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { auto fixture = FixtureDeviceSwapchain {}; expect_throw([&] { diff --git a/modules/renderer/_tests/surface.cpp b/modules/renderer/_tests/surface.cpp index a567b55..463f790 100644 --- a/modules/renderer/_tests/surface.cpp +++ b/modules/renderer/_tests/surface.cpp @@ -2,7 +2,7 @@ import renderer.frontend; import renderer.test_utils; Suite raii = "surface"_suite = [] { - Case { "happy path won't throw" } = [&] { + Case { "happy paths" } = [&] { auto fixture = Fixture_SurfaceSystem {}; const auto surface = lt::renderer::create_surface( @@ -16,7 +16,7 @@ Suite raii = "surface"_suite = [] { expect_eq(y, constants::resolution.y); }; - Case { "unhappy path throws" } = [&] { + Case { "unhappy paths" } = [&] { auto registry = lt::memory::create_ref(); auto entity = lt::ecs::Entity { registry, registry->create_entity() }; auto system = lt::surface::System(registry); diff --git a/modules/renderer/_tests/system.cpp b/modules/renderer/_tests/system.cpp index bfa0787..d58c29b 100644 --- a/modules/renderer/_tests/system.cpp +++ b/modules/renderer/_tests/system.cpp @@ -18,7 +18,7 @@ struct RendererContext }; Suite raii = "system_raii"_suite = [] { - Case { "happy path has no errors" } = [] { + Case { "happy paths" } = [] { auto fixture = Fixture_RendererSystem {}; expect_false(fixture.has_any_messages_of(lt::renderer::IDebugger::MessageSeverity::error)); expect_false( @@ -26,7 +26,7 @@ Suite raii = "system_raii"_suite = [] { ); }; - Case { "unhappy path throws" } = [] { + Case { "unhappy paths" } = [] { auto fixture = Fixture_SurfaceSystem {}; auto empty_entity = lt::ecs::Entity { fixture.registry(), fixture.registry()->create_entity() }; diff --git a/modules/renderer/_tests/utils.cppm b/modules/renderer/_tests/utils.cppm index 9b2657e..1a35e21 100644 --- a/modules/renderer/_tests/utils.cppm +++ b/modules/renderer/_tests/utils.cppm @@ -1,12 +1,9 @@ export module renderer.test_utils; -export import preliminary; -export import logger; +export import test; export import surface.system; export import ecs.registry; export import renderer.factory; -export import test.test; -export import test.expects; export import memory.reference; export import renderer.frontend; export import renderer.system; @@ -15,15 +12,6 @@ export import math.vec3; export import math.vec4; export import math.mat4; -export using ::lt::test::Case; -export using ::lt::test::expect_eq; -export using ::lt::test::expect_false; -export using ::lt::test::expect_not_nullptr; -export using ::lt::test::expect_throw; -export using ::lt::test::operator""_suite; -export using ::lt::test::expect_true; -export using ::lt::test::Suite; - export namespace constants { constexpr auto api = lt::renderer::Api::vulkan; diff --git a/modules/sandbox/CMakeLists.txt b/modules/sandbox/CMakeLists.txt index e13542a..ed768e8 100644 --- a/modules/sandbox/CMakeLists.txt +++ b/modules/sandbox/CMakeLists.txt @@ -1,3 +1,3 @@ add_executable(sandbox sandbox.cpp) -target_link_libraries(sandbox PRIVATE preliminary logger bitwise env memory time test math assets app ecs surface renderer input mirror) +target_link_libraries(sandbox PRIVATE preliminary logger bitwise memory time test math assets app ecs surface renderer input mirror) diff --git a/modules/sandbox/sandbox.cpp b/modules/sandbox/sandbox.cpp index 3e7ea65..7bff5c5 100644 --- a/modules/sandbox/sandbox.cpp +++ b/modules/sandbox/sandbox.cpp @@ -1,5 +1,4 @@ import preliminary; -import test.test; import time; import test.expects; import surface.system; diff --git a/modules/surface/system.cppm b/modules/surface/system.cppm index 3f1d7bf..973ad5d 100644 --- a/modules/surface/system.cppm +++ b/modules/surface/system.cppm @@ -1099,6 +1099,7 @@ void System::modify_resolution(SurfaceComponent &surface, const ModifyResolution void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequest &request) { + log::debug("Setting window position to: {}, {}", request.position.x, request.position.y); SetWindowPos( surface.m_native_data.window, {}, diff --git a/modules/surface/system.test.cpp b/modules/surface/system.test.cpp index 6b37cf7..48e39fb 100644 --- a/modules/surface/system.test.cpp +++ b/modules/surface/system.test.cpp @@ -1,26 +1,16 @@ -import preliminary; -import test.test; +import test; import time; -import test.expects; import surface.system; import surface.events; import surface.requests; import ecs.registry; import memory.scope; import memory.reference; -import logger; import math.vec2; import app.system; using ::lt::surface::SurfaceComponent; using ::lt::surface::System; -using ::lt::test::Case; -using ::lt::test::expect_eq; -using ::lt::test::expect_ne; -using ::lt::test::expect_not_nullptr; -using ::lt::test::expect_throw; -using ::lt::test::Suite; -using ::lt::test::operator""_suite; [[nodiscard]] auto tick_info() -> lt::app::TickInfo { @@ -87,12 +77,16 @@ private: }; Suite raii = "raii"_suite = [] { - Case { "happy path won't throw" } = [] { + Case { "happy paths" } = [] { auto fixture = Fixture {}; auto system = System { fixture.registry() }; }; - Case { "many won't freeze/throw" } = [] { + Case { "unhappy paths" } = [] { + expect_throw([] { ignore = System { {} }; }); + }; + + Case { "many" } = [] { auto fixture = Fixture {}; for (auto idx : std::views::iota(0, 250)) { @@ -101,10 +95,6 @@ Suite raii = "raii"_suite = [] { } }; - Case { "unhappy path throws" } = [] { - expect_throw([] { ignore = System { {} }; }); - }; - Case { "post construct has correct state" } = [] { auto fixture = Fixture {}; auto system = System { fixture.registry() }; @@ -269,15 +259,5 @@ Suite tick_handles_requests = "tick_handles_requests"_suite = [] { expect_eq(surface.get_title(), title); expect_eq(surface.get_position(), position); expect_eq(surface.get_resolution(), resolution); - - lt::log::debug("EVENT COUNT: {}", surface.peek_events().size()); - for (const auto &event : surface.peek_events()) - { - const auto visitor = overloads { - [&](auto event) { lt::log::debug("event: {}", event.to_string()); }, - }; - - std::visit(visitor, event); - } }; }; diff --git a/modules/test/entrypoint.cpp b/modules/test/entrypoint.cpp index bb00114..0265d33 100644 --- a/modules/test/entrypoint.cpp +++ b/modules/test/entrypoint.cpp @@ -1,12 +1,7 @@ -import logger; -import test.test; +import test; import test.registry; -import preliminary; - -using namespace ::lt::test; - -void parse_option(std::string_view argument, Registry::Options &options) +void parse_option(std::string_view argument, lt::test::Registry::Options &options) { constexpr auto case_str = std::string_view { "--case=" }; constexpr auto suite_str = std::string_view { "--suite=" }; @@ -19,7 +14,7 @@ void parse_option(std::string_view argument, Registry::Options &options) if (argument.starts_with("--mode=") && argument.substr(7ul) == "stats") { - options.execution_policy = Registry::ExecutionPolicy::stats; + options.execution_policy = lt::test::Registry::ExecutionPolicy::stats; return; } @@ -56,7 +51,7 @@ try { auto raw_arguments = std::span(argv, argc); - auto options = Registry::Options {}; + auto options = lt::test::Registry::Options {}; for (auto idx = 0; auto &raw_argument : raw_arguments) { // First argument is the "cwd' @@ -83,7 +78,7 @@ try } } - return static_cast(Registry::run_all(options)); + return static_cast(lt::test::Registry::run_all(options)); } catch (const std::exception &exp) { diff --git a/modules/test/fuzz.cppm b/modules/test/fuzz.cppm deleted file mode 100644 index 2bad548..0000000 --- a/modules/test/fuzz.cppm +++ /dev/null @@ -1,86 +0,0 @@ - -#include -#include - -namespace lt::test { - -class FuzzDataProvider -{ -public: - FuzzDataProvider(const uint8_t *data, size_t size): m_data(data, size) - { - } - - template - requires( - std::is_trivially_constructible_v // - && std::is_trivially_copy_constructible_v // - && std::is_trivially_copy_assignable_v - ) - - auto consume() -> std::optional - { - if (m_data.size() < sizeof(T)) - { - return std::nullopt; - } - - T value; - std::memcpy(&value, m_data.data(), sizeof(T)); - - m_data = m_data.subspan(sizeof(T)); - return value; - } - - auto consume_string(size_t size) -> std::optional - { - if (m_data.size() < size) - { - return std::nullopt; - } - - // NOLINTNEXTLINE - auto value = std::string { (const char *)m_data.data(), size }; - m_data = m_data.subspan(size); - - return value; - } - - auto consume_remaining_as_string() -> std::string - { - if (m_data.empty()) - { - return std::string {}; - } - - return { m_data.begin(), m_data.end() }; - }; - -private: - std::span m_data; -}; - -} // namespace lt::test - -namespace lt::test { - -auto process_fuzz_input(const uint8_t *data, size_t size) -> int32_t -try -{ - return details::Registry::process_fuzz_input(data, size); -} -catch (const std::exception &exp) -{ - std::println("Fuzz input resulted in uncaught exception:"); - std::println("\twhat: {}", exp.what()); - std::println("\tinput size: {}", size); - - return EXIT_FAILURE; -} - -}; // namespace lt::test - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) -{ - return lt::test::process_fuzz_input(data, size); -} diff --git a/modules/test/module.cppm b/modules/test/module.cppm new file mode 100644 index 0000000..e140304 --- /dev/null +++ b/modules/test/module.cppm @@ -0,0 +1,23 @@ +export module test; + +export import preliminary; +export import test.test; +export import test.expects; +export import test.expects; +export import logger; + +export using ::lt::test::Suite; +export using ::lt::test::Case; + +export using ::lt::test::expect_eq; +export using ::lt::test::expect_ne; +export using ::lt::test::expect_le; + +export using ::lt::test::expect_true; +export using ::lt::test::expect_false; + +export using ::lt::test::expect_throw; +export using ::lt::test::expect_not_nullptr; +export using ::lt::test::expect_unreachable; + +export using ::lt::test::operator""_suite; diff --git a/modules/test/test.test.cpp b/modules/test/test.test.cpp index 11bb64f..a755761 100644 --- a/modules/test/test.test.cpp +++ b/modules/test/test.test.cpp @@ -1,20 +1,6 @@ -import preliminary; -import test.test; -import test.expects; - -using lt::test::Case; -using lt::test::Suite; -using lt::test::operator""_suite; +import test; Suite expects = "expects"_suite = []() { - using lt::test::expect_unreachable; - using lt::test::expect_true; - using lt::test::expect_false; - using lt::test::expect_eq; - using lt::test::expect_ne; - using lt::test::expect_le; - using lt::test::expect_throw; - Case { "" } = [] { }; diff --git a/modules/time/timer.test.cpp b/modules/time/timer.test.cpp index 162ec37..d7819b2 100644 --- a/modules/time/timer.test.cpp +++ b/modules/time/timer.test.cpp @@ -1,31 +1,22 @@ -import preliminary; +import test; import time; -import test.test; -import test.expects; -using ::lt::test::Case; -using ::lt::test::expect_le; -using ::lt::test::operator""_suite; -using ::lt::test::Suite; using ::lt::time::Timer; -// error margin is high since run-time may slow down extremely due to -// sanitization/debugging or execution through valgrind... -// -// <1us error margin is tested manually in release builds and it works fine. +/* @note: error margin is high since run-time may slow down extremely due to + * sanitization/debugging or execution through valgrind... + * <1us error margin is tested manually in release builds and it works fine. + **/ constexpr auto max_error_margin = std::chrono::milliseconds { 1 }; Suite raii = "raii"_suite = [] { using std::chrono::microseconds; - Case { "default" } = [] { + Case { "happy paths" } = [] { Timer {}; }; - Case { "unhappy path throws" } = [] { - }; - - Case { "plenty" } = [] { + Case { "many" } = [] { for (auto idx : std::views::iota(0, 100'001)) { ignore = idx; @@ -38,7 +29,7 @@ Suite reset_and_elapsed_time = "reset_and_elapsed_time"_suite = [] { using std::chrono::hours; using std::chrono::microseconds; - Case { "won't throw" } = [] { + Case { "happy path" } = [] { Timer {}.reset(); ignore = Timer {}.elapsed_time(); };