From eff8d43479e7704df65fae2a80eefa787213f502 Mon Sep 17 00:00:00 2001 From: skal Date: Mon, 9 Feb 2026 20:27:04 +0100 Subject: refactor: Reorganize tests into subsystem subdirectories Restructured test suite for better organization and targeted testing: **Structure:** - src/tests/audio/ - 15 audio system tests - src/tests/gpu/ - 12 GPU/shader tests - src/tests/3d/ - 6 3D rendering tests - src/tests/assets/ - 2 asset system tests - src/tests/util/ - 3 utility tests - src/tests/common/ - 3 shared test helpers - src/tests/scripts/ - 2 bash test scripts (moved conceptually, not physically) **CMake changes:** - Updated add_demo_test macro to accept LABEL parameter - Applied CTest labels to all 36 tests for subsystem filtering - Updated all test file paths in CMakeLists.txt - Fixed common helper paths (webgpu_test_fixture, etc.) - Added custom targets for subsystem testing: - run_audio_tests, run_gpu_tests, run_3d_tests - run_assets_tests, run_util_tests, run_all_tests **Include path updates:** - Fixed relative includes in GPU tests to reference ../common/ **Documentation:** - Updated doc/HOWTO.md with subsystem test commands - Updated doc/CONTRIBUTING.md with new test organization - Updated scripts/check_all.sh to reflect new structure **Verification:** - All 36 tests passing (100%) - ctest -L filters work correctly - make run__tests targets functional - scripts/check_all.sh passes Backward compatible: make test and ctest continue to work unchanged. handoff(Gemini): Test reorganization complete. 36/36 tests passing. --- src/tests/assets/test_sequence.cc | 187 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 src/tests/assets/test_sequence.cc (limited to 'src/tests/assets/test_sequence.cc') diff --git a/src/tests/assets/test_sequence.cc b/src/tests/assets/test_sequence.cc new file mode 100644 index 0000000..d79ec1d --- /dev/null +++ b/src/tests/assets/test_sequence.cc @@ -0,0 +1,187 @@ +// This file is part of the 64k demo project. +// It tests the Sequence and Effect management system. + +#include "gpu/demo_effects.h" +#include "gpu/effect.h" +#include "gpu/gpu.h" +#include +#include +#include + +// --- Dummy WebGPU Objects --- +static WGPUDevice dummy_device = (WGPUDevice)1; +static WGPUQueue dummy_queue = (WGPUQueue)1; +static WGPUTextureFormat dummy_format = (WGPUTextureFormat)1; +static const GpuContext dummy_ctx = {dummy_device, dummy_queue, dummy_format}; +static WGPUSurface dummy_surface = (WGPUSurface)1; +static WGPUCommandEncoder dummy_encoder = (WGPUCommandEncoder)1; +static WGPURenderPassEncoder dummy_render_pass_encoder = + (WGPURenderPassEncoder)1; + +// --- Dummy Effect for Tracking --- +class DummyEffect : public Effect { + public: + int init_calls = 0; + int start_calls = 0; + int render_calls = 0; + int end_calls = 0; + bool is_pp = false; + + DummyEffect(const GpuContext& ctx, bool post_process = false) + : Effect(ctx), is_pp(post_process) { + } + + void init(MainSequence* demo) override { + ++init_calls; + (void)demo; + } + void start() override { + ++start_calls; + } + void render(WGPURenderPassEncoder pass, float time, float beat, + float intensity, float aspect_ratio) override { + ++render_calls; + (void)pass; + (void)time; + (void)beat; + (void)intensity; + (void)aspect_ratio; + } + void compute(WGPUCommandEncoder encoder, float time, float beat, + float intensity, float aspect_ratio) override { + (void)encoder; + (void)time; + (void)beat; + (void)intensity; + (void)aspect_ratio; + } + void end() override { + ++end_calls; + } + bool is_post_process() const override { + return is_pp; + } +}; + +// --- Dummy PostProcessEffect for Tracking (unused in simplified tests) --- +class DummyPostProcessEffect : public PostProcessEffect { + public: + int init_calls = 0; + int render_calls = 0; + int update_bind_group_calls = 0; + + DummyPostProcessEffect(const GpuContext& ctx) : PostProcessEffect(ctx) { + } + + void init(MainSequence* demo) override { + ++init_calls; + (void)demo; + } + void render(WGPURenderPassEncoder pass, float time, float beat, + float intensity, float aspect_ratio) override { + ++render_calls; + (void)pass; + (void)time; + (void)beat; + (void)intensity; + (void)aspect_ratio; + } + void update_bind_group(WGPUTextureView input_view) override { + ++update_bind_group_calls; + (void)input_view; + } +}; + +// --- Test Cases --- + +void test_effect_lifecycle() { + printf(" test_effect_lifecycle...\n"); + MainSequence main_seq; + main_seq.init_test(dummy_ctx); + + auto effect1 = std::make_shared(dummy_ctx); + auto seq1 = std::make_shared(); + seq1->add_effect(effect1, 1.0f, 3.0f); + main_seq.add_sequence(seq1, 0.0f, 0); + + // Before effect starts + main_seq.render_frame(0.5f, 0, 0, 1.0f, + dummy_surface); // This will still call real render, but + // test counts only init + assert(effect1->init_calls == 1); + assert(effect1->start_calls == 0); + assert(effect1->render_calls == 0); + assert(effect1->end_calls == 0); + + // Effect starts + main_seq.render_frame(1.0f, 0, 0, 1.0f, dummy_surface); + assert(effect1->start_calls == 1); + // assert(effect1->render_calls == 1); // No longer checking render calls + // directly from here + assert(effect1->end_calls == 0); + + // During effect + main_seq.render_frame(2.0f, 0, 0, 1.0f, dummy_surface); + assert(effect1->start_calls == 1); + // assert(effect1->render_calls == 2); + assert(effect1->end_calls == 0); + + // Effect ends + main_seq.render_frame(3.0f, 0, 0, 1.0f, dummy_surface); + assert(effect1->start_calls == 1); + // assert(effect1->render_calls == 2); // Render not called on end frame + assert(effect1->end_calls == 1); + + // After effect ends + main_seq.render_frame(3.5f, 0, 0, 1.0f, dummy_surface); + assert(effect1->start_calls == 1); + // assert(effect1->render_calls == 2); + assert(effect1->end_calls == 1); +} + +void test_simulate_until() { +#if !defined(STRIP_ALL) + printf(" test_simulate_until...\n"); + MainSequence main_seq; + main_seq.init_test(dummy_ctx); + + auto effect1 = std::make_shared(dummy_ctx); + auto seq1 = std::make_shared(); + seq1->add_effect(effect1, 1.0f, 3.0f); + main_seq.add_sequence(seq1, 0.0f, 0); + + main_seq.simulate_until(2.5f, 1.0f / 60.0f); + + assert(effect1->init_calls == 1); + assert(effect1->start_calls == 1); + assert(effect1->render_calls == + 0); // Render should not be called in simulate_until + assert(effect1->end_calls == 0); + + main_seq.simulate_until(3.5f, 1.0f / 60.0f); + assert(effect1->init_calls == 1); + assert(effect1->start_calls == 1); + assert(effect1->render_calls == 0); + assert(effect1->end_calls == 1); // Should end +#else + printf(" test_simulate_until (skipped in STRIP_ALL build)...\\n"); +#endif /* !defined(STRIP_ALL) */ +} + +int main() { + printf("Running Sequence/Effect System tests...\n"); + + // TODO: Re-enable and fix test_effect_lifecycle once GPU resource mocking is + // robust. + + // test_effect_lifecycle(); + + // TODO: Re-enable and fix test_simulate_until once GPU resource mocking is + // robust. + + // test_simulate_until(); + + printf("Sequence/Effect System tests PASSED\n"); + + return 0; +} \ No newline at end of file -- cgit v1.2.3