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/common/effect_test_helpers.cc | 110 ++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/tests/common/effect_test_helpers.cc (limited to 'src/tests/common/effect_test_helpers.cc') diff --git a/src/tests/common/effect_test_helpers.cc b/src/tests/common/effect_test_helpers.cc new file mode 100644 index 0000000..9250366 --- /dev/null +++ b/src/tests/common/effect_test_helpers.cc @@ -0,0 +1,110 @@ +// This file is part of the 64k demo project. +// It implements reusable test helpers for GPU effect testing. +// Provides pixel validation and lifecycle testing utilities. + +#include "effect_test_helpers.h" +#include "gpu/effect.h" +#include + +// ============================================================================ +// Pixel Validation Helpers +// ============================================================================ + +bool validate_pixels( + const std::vector& pixels, int width, int height, + std::function predicate) { + const size_t pixel_count = width * height; + for (size_t i = 0; i < pixel_count; ++i) { + const size_t offset = i * 4; // BGRA8 = 4 bytes/pixel + const uint8_t b = pixels[offset + 0]; + const uint8_t g = pixels[offset + 1]; + const uint8_t r = pixels[offset + 2]; + const uint8_t a = pixels[offset + 3]; + + if (predicate(r, g, b, a)) { + return true; // At least one pixel matches + } + } + return false; // No pixels matched +} + +bool has_rendered_content(const std::vector& pixels, int width, + int height) { + return validate_pixels(pixels, width, height, + [](uint8_t r, uint8_t g, uint8_t b, uint8_t a) { + return r > 0 || g > 0 || b > 0; + }); +} + +bool all_pixels_match_color(const std::vector& pixels, int width, + int height, uint8_t target_r, uint8_t target_g, + uint8_t target_b, uint8_t tolerance) { + const size_t pixel_count = width * height; + for (size_t i = 0; i < pixel_count; ++i) { + const size_t offset = i * 4; + const uint8_t b = pixels[offset + 0]; + const uint8_t g = pixels[offset + 1]; + const uint8_t r = pixels[offset + 2]; + + const int diff_r = static_cast(r) - static_cast(target_r); + const int diff_g = static_cast(g) - static_cast(target_g); + const int diff_b = static_cast(b) - static_cast(target_b); + + if (diff_r * diff_r + diff_g * diff_g + diff_b * diff_b > + tolerance * tolerance) { + return false; // At least one pixel doesn't match + } + } + return true; // All pixels match +} + +uint64_t hash_pixels(const std::vector& pixels) { + // Simple FNV-1a hash + uint64_t hash = 14695981039346656037ULL; + for (const uint8_t byte : pixels) { + hash ^= byte; + hash *= 1099511628211ULL; + } + return hash; +} + +// ============================================================================ +// Effect Lifecycle Helpers +// ============================================================================ + +bool test_effect_lifecycle(Effect* effect, MainSequence* main_seq) { + assert(effect && "Effect pointer is null"); + assert(main_seq && "MainSequence pointer is null"); + + // Check initial state + if (effect->is_initialized) { + return false; // Should not be initialized yet + } + + // Initialize effect + effect->init(main_seq); + + // Check initialized state + if (!effect->is_initialized) { + return false; // Should be initialized now + } + + return true; // Lifecycle test passed +} + +bool test_effect_render_smoke(Effect* effect) { + assert(effect && "Effect pointer is null"); + + // Smoke test: Just call render with dummy parameters + // If this doesn't crash, consider it a success + // Note: This requires the effect to be initialized first + if (!effect->is_initialized) { + return false; // Cannot render uninitialized effect + } + + // We cannot actually render without a full render pass setup + // This is a placeholder for more sophisticated render testing + // Real render tests should use OffscreenRenderTarget + + return true; // Smoke test passed (no crash) +} -- cgit v1.2.3