From 124899f27b6c1ec02bfa16a57a4e43ea2b7ebac0 Mon Sep 17 00:00:00 2001 From: skal Date: Tue, 3 Feb 2026 10:59:08 +0100 Subject: test(shader): Add ShaderComposer and WGSL asset validation tests (Task #26) Implemented comprehensive unit tests for ShaderComposer and a validation test for production WGSL shader assets. This ensures the shader asset pipeline is robust and that all shaders contain required entry points and snippets. Also improved InitShaderComposer to be more robust during testing. --- src/tests/test_shader_assets.cc | 66 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/tests/test_shader_assets.cc (limited to 'src/tests/test_shader_assets.cc') diff --git a/src/tests/test_shader_assets.cc b/src/tests/test_shader_assets.cc new file mode 100644 index 0000000..42d1c4c --- /dev/null +++ b/src/tests/test_shader_assets.cc @@ -0,0 +1,66 @@ +// This file is part of the 64k demo project. +// It validates that WGSL shader assets are present and look like valid WGSL. + +#include "generated/assets.h" +#include +#include +#include +#include +#include + +bool validate_shader(AssetId id, const char* name, const std::vector& expected_keywords) { + printf("Validating shader: %s...\n", name); + size_t size = 0; + const char* data = (const char*)GetAsset(id, &size); + + if (data == nullptr || size == 0) { + printf("FAILED: Shader %s is missing or empty!\n", name); + return false; + } + + std::string code(data, size); + for (const char* keyword : expected_keywords) { + if (code.find(keyword) == std::string::npos) { + printf("FAILED: Shader %s missing expected keyword '%s'!\n", name, keyword); + // printf("Code snippet:\n%.100s...\n", data); + return false; + } + } + + printf("PASSED: %s (%zu bytes)\n", name, size); + return true; +} + +int main() { + printf("--- RUNNING SHADER ASSET VALIDATION ---\n"); + + bool all_passed = true; + + // Snippets + all_passed &= validate_shader(AssetId::ASSET_SHADER_COMMON_UNIFORMS, "COMMON_UNIFORMS", {"struct", "GlobalUniforms"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_SDF_PRIMITIVES, "SDF_PRIMITIVES", {"fn", "sd"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_LIGHTING, "LIGHTING", {"fn", "calc"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_RAY_BOX, "RAY_BOX", {"fn", "intersect"}); + + // Full Shaders (Entry points) + all_passed &= validate_shader(AssetId::ASSET_SHADER_RENDERER_3D, "RENDERER_3D", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_MAIN, "MAIN", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_PARTICLE_COMPUTE, "PARTICLE_COMPUTE", {"@compute", "main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_PARTICLE_RENDER, "PARTICLE_RENDER", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_PASSTHROUGH, "PASSTHROUGH", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_ELLIPSE, "ELLIPSE", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_PARTICLE_SPRAY_COMPUTE, "PARTICLE_SPRAY_COMPUTE", {"@compute", "main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_SOLARIZE, "SOLARIZE", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_DISTORT, "DISTORT", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_CHROMA_ABERRATION, "CHROMA_ABERRATION", {"@vertex", "vs_main", "@fragment", "fs_main"}); + all_passed &= validate_shader(AssetId::ASSET_SHADER_VISUAL_DEBUG, "VISUAL_DEBUG", {"@vertex", "vs_main", "@fragment", "fs_main"}); + + if (!all_passed) { + printf("--- SHADER ASSET VALIDATION FAILED ---\n"); + return 1; + } + + printf("--- ALL SHADER ASSETS VALIDATED ---\n"); + return 0; +} -- cgit v1.2.3