light/modules/input/private/system.test.cpp

200 lines
5.2 KiB
C++
Raw Normal View History

2025-09-18 19:16:54 +03:30
#include <ecs/entity.hpp>
#include <input/components.hpp>
#include <input/system.hpp>
#include <memory/reference.hpp>
#include <memory/scope.hpp>
2025-09-20 15:39:45 +03:30
#include <ranges>
2025-09-18 19:16:54 +03:30
#include <test/test.hpp>
// NOLINTBEGIN
using namespace lt;
using input::InputComponent;
using input::System;
using std::ignore;
using test::Case;
using test::expect_eq;
using test::expect_false;
using test::expect_ne;
using test::expect_not_nullptr;
using test::expect_throw;
using test::Suite;
// NOLINTEND
[[nodiscard]] auto tick_info() -> app::TickInfo
{
return {
.delta_time = std::chrono::milliseconds { 16 },
.budget = std::chrono::milliseconds { 10 },
.start_time = std::chrono::steady_clock::now(),
};
}
2025-09-18 19:16:54 +03:30
class Fixture
{
public:
[[nodiscard]] auto registry() -> memory::Ref<ecs::Registry>
2025-09-18 19:16:54 +03:30
{
return m_registry;
}
auto add_input_component() -> ecs::EntityId
2025-09-18 19:16:54 +03:30
{
2025-09-20 15:39:45 +03:30
auto entity = m_registry->create_entity();
m_registry->add<InputComponent>(entity, {});
2025-09-18 19:16:54 +03:30
return entity;
}
auto add_surface_component() -> ecs::EntityId
2025-09-18 19:16:54 +03:30
{
2025-09-20 15:39:45 +03:30
auto entity = m_registry->create_entity();
m_registry->add<surface::SurfaceComponent>(
entity,
surface::SurfaceComponent::CreateInfo {}
);
2025-09-18 19:16:54 +03:30
return entity;
}
private:
memory::Ref<ecs::Registry> m_registry = memory::create_ref<ecs::Registry>();
2025-09-18 19:16:54 +03:30
};
2025-09-30 06:44:09 +03:30
Suite raii = "raii"_suite = "raii"_suite = [] {
2025-09-18 19:16:54 +03:30
Case { "happy path won't throw" } = [&] {
System { Fixture {}.registry() };
};
Case { "many won't freeze/throw" } = [&] {
auto fixture = Fixture {};
for (auto idx : std::views::iota(0, 10'000))
{
ignore = System { fixture.registry() };
}
};
Case { "unhappy path throws" } = [] {
expect_throw([] { ignore = System { {} }; });
};
};
2025-09-30 06:44:09 +03:30
Suite system_events = "system_events"_suite = [] {
2025-09-18 19:16:54 +03:30
Case { "on_register won't throw" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
auto system = System { registry };
2025-09-18 19:16:54 +03:30
system.on_register();
2025-09-20 15:39:45 +03:30
expect_eq(registry->view<InputComponent>().get_size(), 0);
2025-09-18 19:16:54 +03:30
};
Case { "on_unregister won't throw" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
auto system = System { registry };
2025-09-18 19:16:54 +03:30
system.on_register();
system.on_unregister();
2025-09-20 15:39:45 +03:30
expect_eq(registry->view<InputComponent>().get_size(), 0);
2025-09-18 19:16:54 +03:30
};
};
2025-09-30 06:44:09 +03:30
Suite registry_events = "registry_events"_suite = [] {
2025-09-18 19:16:54 +03:30
Case { "on_construct<InputComnent>" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
auto system = System { registry };
2025-09-18 19:16:54 +03:30
const auto &entity = fixture.add_input_component();
2025-09-20 15:39:45 +03:30
expect_eq(registry->view<InputComponent>().get_size(), 1);
2025-09-18 19:16:54 +03:30
};
Case { "on_destrroy<InputComponent>" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
auto system = memory::create_scope<System>(registry);
2025-09-18 19:16:54 +03:30
auto entity_a = fixture.add_input_component();
auto entity_b = fixture.add_input_component();
2025-09-20 15:39:45 +03:30
expect_eq(registry->view<InputComponent>().get_size(), 2);
2025-09-18 19:16:54 +03:30
2025-09-20 15:39:45 +03:30
registry->remove<InputComponent>(entity_a);
expect_eq(registry->view<InputComponent>().get_size(), 1);
2025-09-18 19:16:54 +03:30
system.reset();
2025-09-20 15:39:45 +03:30
expect_eq(registry->view<InputComponent>().get_size(), 1);
2025-09-18 19:16:54 +03:30
2025-09-20 15:39:45 +03:30
registry->remove<InputComponent>(entity_b);
expect_eq(registry->view<InputComponent>().get_size(), 0);
2025-09-18 19:16:54 +03:30
};
};
2025-09-30 06:44:09 +03:30
Suite tick = "tick"_suite = [] {
2025-09-18 19:16:54 +03:30
Case { "Empty tick won't throw" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
2025-09-18 19:16:54 +03:30
auto system = System { fixture.registry() };
system.tick(tick_info());
2025-09-18 19:16:54 +03:30
};
Case { "Tick triggers input action" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
2025-09-18 19:16:54 +03:30
auto system = System { fixture.registry() };
2025-09-20 15:39:45 +03:30
auto surface_entity = fixture.add_surface_component();
auto &surface = registry->get<surface::SurfaceComponent>(surface_entity);
auto input_entity = fixture.add_input_component();
auto &input = registry->get<InputComponent>(input_entity);
2025-09-18 19:16:54 +03:30
auto action_key = input.add_action(
{
.name { "test" },
.trigger = { .mapped_keycode = 69 },
}
);
expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive);
system.tick(tick_info());
2025-09-18 19:16:54 +03:30
expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive);
surface.push_event(surface::KeyPressedEvent(69));
system.tick(tick_info());
2025-09-18 19:16:54 +03:30
expect_eq(input.get_action(action_key).state, input::InputAction::State::triggered);
system.tick(tick_info());
2025-09-18 19:46:52 +03:30
expect_eq(input.get_action(action_key).state, input::InputAction::State::active);
2025-09-18 19:16:54 +03:30
system.tick(tick_info());
system.tick(tick_info());
system.tick(tick_info());
2025-09-18 19:46:52 +03:30
expect_eq(input.get_action(action_key).state, input::InputAction::State::active);
2025-09-18 19:16:54 +03:30
2025-09-18 19:46:52 +03:30
surface.push_event(surface::KeyReleasedEvent(69));
system.tick(tick_info());
2025-09-18 19:46:52 +03:30
expect_eq(input.get_action(action_key).state, input::InputAction::State::inactive);
2025-09-18 19:16:54 +03:30
};
Case { "Tick triggers" } = [] {
auto fixture = Fixture {};
2025-09-20 15:39:45 +03:30
auto registry = fixture.registry();
2025-09-18 19:16:54 +03:30
auto system = System { fixture.registry() };
2025-09-20 15:39:45 +03:30
auto surface_entity = fixture.add_surface_component();
auto &surface = registry->get<surface::SurfaceComponent>(surface_entity);
auto input_entity = fixture.add_input_component();
auto &input = registry->get<InputComponent>(input_entity);
2025-09-18 19:16:54 +03:30
auto action_key = input.add_action(
{
.name { "test" },
.trigger = { .mapped_keycode = 69 },
}
);
2025-09-18 19:43:42 +03:30
};
2025-09-18 19:16:54 +03:30
};