diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-09 20:27:04 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-09 20:27:04 +0100 |
| commit | eff8d43479e7704df65fae2a80eefa787213f502 (patch) | |
| tree | 76f2fb8fe8d3db2c15179449df2cf12f7f54e0bf /src/tests/common/effect_test_helpers.cc | |
| parent | 12378b1b7e9091ba59895b4360b2fa959180a56a (diff) | |
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 <subsystem> filters work correctly
- make run_<subsystem>_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.
Diffstat (limited to 'src/tests/common/effect_test_helpers.cc')
| -rw-r--r-- | src/tests/common/effect_test_helpers.cc | 110 |
1 files changed, 110 insertions, 0 deletions
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 <cassert> + +// ============================================================================ +// Pixel Validation Helpers +// ============================================================================ + +bool validate_pixels( + const std::vector<uint8_t>& pixels, int width, int height, + std::function<bool(uint8_t r, uint8_t g, uint8_t b, uint8_t a)> 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<uint8_t>& 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<uint8_t>& 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<int>(r) - static_cast<int>(target_r); + const int diff_g = static_cast<int>(g) - static_cast<int>(target_g); + const int diff_b = static_cast<int>(b) - static_cast<int>(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<uint8_t>& 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) +} |
