diff options
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/test_3d.cc | 31 | ||||
| -rw-r--r-- | src/tests/test_3d_physics.cc | 10 | ||||
| -rw-r--r-- | src/tests/test_assets.cc | 62 | ||||
| -rw-r--r-- | src/tests/test_audio_backend.cc | 12 | ||||
| -rw-r--r-- | src/tests/test_audio_engine.cc | 34 | ||||
| -rw-r--r-- | src/tests/test_audio_gen.cc | 144 | ||||
| -rw-r--r-- | src/tests/test_dct.cc | 57 | ||||
| -rw-r--r-- | src/tests/test_maths.cc | 35 | ||||
| -rw-r--r-- | src/tests/test_mock_backend.cc | 4 | ||||
| -rw-r--r-- | src/tests/test_physics.cc | 93 | ||||
| -rw-r--r-- | src/tests/test_procedural.cc | 30 | ||||
| -rw-r--r-- | src/tests/test_shader_composer.cc | 14 | ||||
| -rw-r--r-- | src/tests/test_synth.cc | 80 |
13 files changed, 321 insertions, 285 deletions
diff --git a/src/tests/test_3d.cc b/src/tests/test_3d.cc index 90869bf..e0fb2e0 100644 --- a/src/tests/test_3d.cc +++ b/src/tests/test_3d.cc @@ -23,14 +23,14 @@ void test_camera() { assert(near(view.m[14], -10.0f)); // Test Camera::set_look_at - cam.set_look_at({5, 0, 0}, {0, 0, 0}, {0, 1, 0}); // Look at origin from (5,0,0) + cam.set_look_at({5, 0, 0}, {0, 0, 0}, + {0, 1, 0}); // Look at origin from (5,0,0) mat4 view_shifted = cam.get_view_matrix(); - // The camera's forward vector (0,0,-1) should now point towards (-1,0,0) in world space. - // The translation part of the view matrix should be based on -dot(s, eye), -dot(u, eye), dot(f, eye) - // s = (0,0,-1), u = (0,1,0), f = (-1,0,0) - // m[12] = -dot({0,0,-1}, {5,0,0}) = 0 - // m[13] = -dot({0,1,0}, {5,0,0}) = 0 - // m[14] = dot({-1,0,0}, {5,0,0}) = -5 + // The camera's forward vector (0,0,-1) should now point towards (-1,0,0) in + // world space. The translation part of the view matrix should be based on + // -dot(s, eye), -dot(u, eye), dot(f, eye) s = (0,0,-1), u = (0,1,0), f = + // (-1,0,0) m[12] = -dot({0,0,-1}, {5,0,0}) = 0 m[13] = -dot({0,1,0}, {5,0,0}) + // = 0 m[14] = dot({-1,0,0}, {5,0,0}) = -5 assert(near(view_shifted.m[12], 0.0f)); assert(near(view_shifted.m[13], 0.0f)); assert(near(view_shifted.m[14], -5.0f)); @@ -76,22 +76,27 @@ void test_object_transform() { mat4 inv_model_t = model_t.inverse(); // Applying inv_model to a translated point should undo the translation. // Point (5,0,0) should go to (0,0,0) - vec4 translated_point(5,0,0,1); - vec4 original_space_t = inv_model_t * vec4(translated_point.x, translated_point.y, translated_point.z, 1.0); - assert(near(original_space_t.x, 0.0f) && near(original_space_t.y, 0.0f) && near(original_space_t.z, 0.0f)); + vec4 translated_point(5, 0, 0, 1); + vec4 original_space_t = + inv_model_t * + vec4(translated_point.x, translated_point.y, translated_point.z, 1.0); + assert(near(original_space_t.x, 0.0f) && near(original_space_t.y, 0.0f) && + near(original_space_t.z, 0.0f)); // Model matrix with rotation (90 deg Y) and translation (5,0,0) obj.position = vec3(5, 0, 0); obj.rotation = quat::from_axis({0, 1, 0}, 1.570796f); mat4 model_trs = obj.get_model_matrix(); mat4 inv_model_trs = model_trs.inverse(); - // Transform point (1,0,0) (local right) via TRS: Rotates to (0,0,-1), Translates to (5,0,-1) - vec4 p_trs(1,0,0,1); + // Transform point (1,0,0) (local right) via TRS: Rotates to (0,0,-1), + // Translates to (5,0,-1) + vec4 p_trs(1, 0, 0, 1); vec4 transformed_p = model_trs * p_trs; assert(near(transformed_p.x, 5.0f) && near(transformed_p.z, -1.0f)); // Apply inverse to transformed point to get back original point vec4 original_space_trs = inv_model_trs * transformed_p; - assert(near(original_space_trs.x, 1.0f) && near(original_space_trs.y, 0.0f) && near(original_space_trs.z, 0.0f)); + assert(near(original_space_trs.x, 1.0f) && near(original_space_trs.y, 0.0f) && + near(original_space_trs.z, 0.0f)); } void test_scene() { diff --git a/src/tests/test_3d_physics.cc b/src/tests/test_3d_physics.cc index 6d7f476..84be333 100644 --- a/src/tests/test_3d_physics.cc +++ b/src/tests/test_3d_physics.cc @@ -1,12 +1,12 @@ // This file is part of the 64k demo project. // Standalone "mini-demo" for testing the 3D physics engine. +#include "3d/bvh.h" #include "3d/camera.h" #include "3d/object.h" +#include "3d/physics.h" #include "3d/renderer.h" #include "3d/scene.h" -#include "3d/bvh.h" -#include "3d/physics.h" #include "gpu/effects/shaders.h" #include "gpu/texture_manager.h" #include "platform.h" @@ -171,7 +171,8 @@ void setup_scene() { obj.color = vec4((rand() % 100) / 100.0f, (rand() % 100) / 100.0f, (rand() % 100) / 100.0f, 1.0f); obj.is_static = false; - obj.velocity = vec3((rand() % 100 - 50) * 0.01f, 0, (rand() % 100 - 50) * 0.01f); + obj.velocity = + vec3((rand() % 100 - 50) * 0.01f, 0, (rand() % 100 - 50) * 0.01f); g_scene.add_object(obj); } } @@ -247,7 +248,8 @@ int main(int argc, char** argv) { static double last_time = 0; float dt = (float)(platform_state.time - last_time); - if (dt > 0.1f) dt = 0.1f; // Cap dt for stability + if (dt > 0.1f) + dt = 0.1f; // Cap dt for stability last_time = platform_state.time; g_physics.update(g_scene, dt); diff --git a/src/tests/test_assets.cc b/src/tests/test_assets.cc index 5ae266e..86b4ba4 100644 --- a/src/tests/test_assets.cc +++ b/src/tests/test_assets.cc @@ -55,7 +55,7 @@ int main() { GetAsset(AssetId::ASSET_PROC_NOISE_256, &proc_size); assert(proc_data_1 != nullptr); // Expect 256x256 RGBA8 + 8 byte header - assert(proc_size == 256 * 256 * 4 + 8); + assert(proc_size == 256 * 256 * 4 + 8); // Verify first few bytes of DATA (skip header) // Header is 8 bytes @@ -97,24 +97,30 @@ int main() { assert(tex.pixels != nullptr); assert(tex.width == 2); assert(tex.height == 2); - + // Verify pixels (Expected RGBA) // Pixel 0: Red (255, 0, 0, 255) - assert(tex.pixels[0] == 255 && tex.pixels[1] == 0 && tex.pixels[2] == 0 && tex.pixels[3] == 255); + assert(tex.pixels[0] == 255 && tex.pixels[1] == 0 && tex.pixels[2] == 0 && + tex.pixels[3] == 255); // Pixel 1: Green (0, 255, 0, 255) - assert(tex.pixels[4] == 0 && tex.pixels[5] == 255 && tex.pixels[6] == 0 && tex.pixels[7] == 255); + assert(tex.pixels[4] == 0 && tex.pixels[5] == 255 && tex.pixels[6] == 0 && + tex.pixels[7] == 255); // Pixel 2: Blue (0, 0, 255, 255) - assert(tex.pixels[8] == 0 && tex.pixels[9] == 0 && tex.pixels[10] == 255 && tex.pixels[11] == 255); + assert(tex.pixels[8] == 0 && tex.pixels[9] == 0 && tex.pixels[10] == 255 && + tex.pixels[11] == 255); // Pixel 3: White (255, 255, 255, 255) - assert(tex.pixels[12] == 255 && tex.pixels[13] == 255 && tex.pixels[14] == 255 && tex.pixels[15] == 255); - + assert(tex.pixels[12] == 255 && tex.pixels[13] == 255 && + tex.pixels[14] == 255 && tex.pixels[15] == 255); + printf("Texture Asset content verification: SUCCESS\n"); // Test Unknown Procedural Function printf("\nRunning Unknown Procedural Function test...\n"); size_t unknown_size = 0; - // This should print an error to stderr: "Error: Unknown procedural function..." - const uint8_t* unknown_data = GetAsset(AssetId::ASSET_PROC_UNKNOWN, &unknown_size); + // This should print an error to stderr: "Error: Unknown procedural + // function..." + const uint8_t* unknown_data = + GetAsset(AssetId::ASSET_PROC_UNKNOWN, &unknown_size); assert(unknown_data == nullptr); assert(unknown_size == 0); printf("Unknown Procedural Function test: SUCCESS\n"); @@ -122,17 +128,20 @@ int main() { // Test Failing Procedural Function printf("\nRunning Failing Procedural Function test...\n"); size_t fail_size = 0; - // This should print an error to stderr: "Error: Procedural generation failed..." + // This should print an error to stderr: "Error: Procedural generation + // failed..." const uint8_t* fail_data = GetAsset(AssetId::ASSET_PROC_FAIL, &fail_size); assert(fail_data == nullptr); assert(fail_size == 0); printf("Failing Procedural Function test: SUCCESS\n"); // Test Out-of-Bounds ID (beyond ASSET_LAST_ID) - // Casting to AssetId to suppress compiler warnings if checking strict enum types + // Casting to AssetId to suppress compiler warnings if checking strict enum + // types printf("\nRunning Out-of-Bounds ID test...\n"); size_t oob_size = 0; - const uint8_t* oob_data = GetAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), &oob_size); + const uint8_t* oob_data = + GetAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), &oob_size); assert(oob_data == nullptr); assert(oob_size == 0); printf("Out-of-Bounds ID test: SUCCESS\n"); @@ -141,25 +150,28 @@ int main() { printf("\nRunning DropAsset edge cases test...\n"); // Invalid ID DropAsset((AssetId)((int)AssetId::ASSET_LAST_ID + 1), nullptr); - + // Mismatched pointer (should do nothing) - // We use proc_data_2 which is valid, but pass a different ID (e.g. ASSET_TEST_ASSET_1 which is static) + // We use proc_data_2 which is valid, but pass a different ID (e.g. + // ASSET_TEST_ASSET_1 which is static) DropAsset(AssetId::ASSET_TEST_ASSET_1, proc_data_2); - // Verify proc_data_2 is still valid (by checking it's in cache). - // Note: GetAsset will just return the cached pointer. If DropAsset worked, it would have been cleared. - // But wait, DropAsset clears it from cache. - // The correct test for "mismatched pointer" is: pass the correct ID but WRONG pointer. - // This ensures we don't clear the cache if the user passes a stale/wrong pointer. - + // Verify proc_data_2 is still valid (by checking it's in cache). + // Note: GetAsset will just return the cached pointer. If DropAsset worked, it + // would have been cleared. But wait, DropAsset clears it from cache. The + // correct test for "mismatched pointer" is: pass the correct ID but WRONG + // pointer. This ensures we don't clear the cache if the user passes a + // stale/wrong pointer. + // Let's try to drop ASSET_PROC_NOISE_256 with a dummy pointer. uint8_t dummy_ptr; DropAsset(AssetId::ASSET_PROC_NOISE_256, &dummy_ptr); - // Check if asset is still in cache (should be, as we didn't drop the real one) - // We can't peek into g_asset_cache directly from here (it's static). - // But GetAsset should return the SAME pointer as proc_data_2 without re-generation. - // If it was dropped, GetAsset would re-generate and likely return a NEW pointer (new allocation). + // Check if asset is still in cache (should be, as we didn't drop the real + // one) We can't peek into g_asset_cache directly from here (it's static). But + // GetAsset should return the SAME pointer as proc_data_2 without + // re-generation. If it was dropped, GetAsset would re-generate and likely + // return a NEW pointer (new allocation). const uint8_t* proc_data_3 = GetAsset(AssetId::ASSET_PROC_NOISE_256, nullptr); - assert(proc_data_3 == proc_data_2); + assert(proc_data_3 == proc_data_2); printf("DropAsset edge cases test: SUCCESS\n"); printf("Procedural Asset test PASSED\n"); diff --git a/src/tests/test_audio_backend.cc b/src/tests/test_audio_backend.cc index 050956b..4bd5a53 100644 --- a/src/tests/test_audio_backend.cc +++ b/src/tests/test_audio_backend.cc @@ -26,11 +26,17 @@ class TestBackend : public AudioBackend { bool start_called = false; bool shutdown_called = false; - void init() override { init_called = true; } + void init() override { + init_called = true; + } - void start() override { start_called = true; } + void start() override { + start_called = true; + } - void shutdown() override { shutdown_called = true; } + void shutdown() override { + shutdown_called = true; + } void on_voice_triggered(float timestamp, int spectrogram_id, float volume, float pan) override { diff --git a/src/tests/test_audio_engine.cc b/src/tests/test_audio_engine.cc index eb6ccb1..3b29dcd 100644 --- a/src/tests/test_audio_engine.cc +++ b/src/tests/test_audio_engine.cc @@ -37,19 +37,19 @@ void test_audio_engine_music_loading() { engine.init(); // Load global music data - engine.load_music_data(&g_tracker_score, - g_tracker_samples, - g_tracker_sample_assets, - g_tracker_samples_count); + engine.load_music_data(&g_tracker_score, g_tracker_samples, + g_tracker_sample_assets, g_tracker_samples_count); - // Verify resource manager was initialized (samples registered but not loaded yet) + // Verify resource manager was initialized (samples registered but not loaded + // yet) SpectrogramResourceManager* res_mgr = engine.get_resource_manager(); assert(res_mgr != nullptr); // Initially, no samples should be loaded (lazy loading) assert(res_mgr->get_loaded_count() == 0); - printf(" ✓ Music data loaded: %u samples registered\n", g_tracker_samples_count); + printf(" ✓ Music data loaded: %u samples registered\n", + g_tracker_samples_count); engine.shutdown(); @@ -64,14 +64,12 @@ void test_audio_engine_manual_resource_loading() { engine.init(); // Load music data - engine.load_music_data(&g_tracker_score, - g_tracker_samples, - g_tracker_sample_assets, - g_tracker_samples_count); + engine.load_music_data(&g_tracker_score, g_tracker_samples, + g_tracker_sample_assets, g_tracker_samples_count); SpectrogramResourceManager* res_mgr = engine.get_resource_manager(); const int initial_loaded = res_mgr->get_loaded_count(); - assert(initial_loaded == 0); // No samples loaded yet + assert(initial_loaded == 0); // No samples loaded yet // Manually preload first few samples res_mgr->preload(0); @@ -80,7 +78,7 @@ void test_audio_engine_manual_resource_loading() { const int after_preload = res_mgr->get_loaded_count(); printf(" Samples loaded after manual preload: %d\n", after_preload); - assert(after_preload == 3); // Should have 3 samples loaded + assert(after_preload == 3); // Should have 3 samples loaded // Verify samples are accessible const Spectrogram* spec0 = res_mgr->get_spectrogram(0); @@ -103,10 +101,8 @@ void test_audio_engine_reset() { AudioEngine engine; engine.init(); - engine.load_music_data(&g_tracker_score, - g_tracker_samples, - g_tracker_sample_assets, - g_tracker_samples_count); + engine.load_music_data(&g_tracker_score, g_tracker_samples, + g_tracker_sample_assets, g_tracker_samples_count); SpectrogramResourceManager* res_mgr = engine.get_resource_manager(); @@ -143,10 +139,8 @@ void test_audio_engine_seeking() { AudioEngine engine; engine.init(); - engine.load_music_data(&g_tracker_score, - g_tracker_samples, - g_tracker_sample_assets, - g_tracker_samples_count); + engine.load_music_data(&g_tracker_score, g_tracker_samples, + g_tracker_sample_assets, g_tracker_samples_count); // Seek to t=5.0s engine.seek(5.0f); diff --git a/src/tests/test_audio_gen.cc b/src/tests/test_audio_gen.cc index 2877fc4..ebdcb25 100644 --- a/src/tests/test_audio_gen.cc +++ b/src/tests/test_audio_gen.cc @@ -1,97 +1,97 @@ // This file is part of the 64k demo project. // It tests the procedural audio generation functions. -#include "audio/gen.h" #include "audio/dct.h" -#include <vector> +#include "audio/gen.h" #include <cassert> -#include <iostream> #include <cmath> +#include <iostream> +#include <vector> void test_generate_note() { - NoteParams params; - params.base_freq = 440.0f; - params.duration_sec = 0.1f; // ~3 frames - params.amplitude = 0.5f; - params.attack_sec = 0.01f; - params.decay_sec = 0.0f; - params.vibrato_rate = 0.0f; - params.vibrato_depth = 0.0f; - params.num_harmonics = 1; - params.harmonic_decay = 1.0f; - params.pitch_randomness = 0.0f; - params.amp_randomness = 0.0f; + NoteParams params; + params.base_freq = 440.0f; + params.duration_sec = 0.1f; // ~3 frames + params.amplitude = 0.5f; + params.attack_sec = 0.01f; + params.decay_sec = 0.0f; + params.vibrato_rate = 0.0f; + params.vibrato_depth = 0.0f; + params.num_harmonics = 1; + params.harmonic_decay = 1.0f; + params.pitch_randomness = 0.0f; + params.amp_randomness = 0.0f; - int num_frames = 0; - std::vector<float> data = generate_note_spectrogram(params, &num_frames); + int num_frames = 0; + std::vector<float> data = generate_note_spectrogram(params, &num_frames); - assert(num_frames > 0); - assert(data.size() == (size_t)num_frames * DCT_SIZE); - - // Check if data is not all zero - bool non_zero = false; - for (float v : data) { - if (std::abs(v) > 1e-6f) { - non_zero = true; - break; - } + assert(num_frames > 0); + assert(data.size() == (size_t)num_frames * DCT_SIZE); + + // Check if data is not all zero + bool non_zero = false; + for (float v : data) { + if (std::abs(v) > 1e-6f) { + non_zero = true; + break; } - assert(non_zero); + } + assert(non_zero); } void test_paste() { - std::vector<float> dest; - int dest_frames = 0; - std::vector<float> src(DCT_SIZE * 2, 1.0f); // 2 frames of 1.0s - - paste_spectrogram(dest, &dest_frames, src, 2, 0); - assert(dest_frames == 2); - assert(dest.size() == 2 * DCT_SIZE); - assert(dest[0] == 1.0f); + std::vector<float> dest; + int dest_frames = 0; + std::vector<float> src(DCT_SIZE * 2, 1.0f); // 2 frames of 1.0s + + paste_spectrogram(dest, &dest_frames, src, 2, 0); + assert(dest_frames == 2); + assert(dest.size() == 2 * DCT_SIZE); + assert(dest[0] == 1.0f); - // Paste with offset - paste_spectrogram(dest, &dest_frames, src, 2, 1); - // Dest was 2 frames. We paste 2 frames at offset 1. - // Result should be 1 + 2 = 3 frames. - assert(dest_frames == 3); - assert(dest.size() == 3 * DCT_SIZE); - // Overlap at frame 1: 1.0 + 1.0 = 2.0 - assert(dest[DCT_SIZE] == 2.0f); - // Frame 2: 0.0 (original) + 1.0 (new) = 1.0 - assert(dest[2 * DCT_SIZE] == 1.0f); + // Paste with offset + paste_spectrogram(dest, &dest_frames, src, 2, 1); + // Dest was 2 frames. We paste 2 frames at offset 1. + // Result should be 1 + 2 = 3 frames. + assert(dest_frames == 3); + assert(dest.size() == 3 * DCT_SIZE); + // Overlap at frame 1: 1.0 + 1.0 = 2.0 + assert(dest[DCT_SIZE] == 2.0f); + // Frame 2: 0.0 (original) + 1.0 (new) = 1.0 + assert(dest[2 * DCT_SIZE] == 1.0f); } void test_filters() { - int num_frames = 1; - std::vector<float> data(DCT_SIZE, 1.0f); + int num_frames = 1; + std::vector<float> data(DCT_SIZE, 1.0f); - // Lowpass - apply_spectral_lowpass(data, num_frames, 0.5f); - // Bins >= 256 should be 0 - assert(data[0] == 1.0f); - assert(data[DCT_SIZE - 1] == 0.0f); - assert(data[256] == 0.0f); - assert(data[255] == 1.0f); // Boundary check + // Lowpass + apply_spectral_lowpass(data, num_frames, 0.5f); + // Bins >= 256 should be 0 + assert(data[0] == 1.0f); + assert(data[DCT_SIZE - 1] == 0.0f); + assert(data[256] == 0.0f); + assert(data[255] == 1.0f); // Boundary check - // Comb - data.assign(DCT_SIZE, 1.0f); - apply_spectral_comb(data, num_frames, 10.0f, 1.0f); - // Just check modification - assert(data[0] != 1.0f || data[1] != 1.0f); // It should change values + // Comb + data.assign(DCT_SIZE, 1.0f); + apply_spectral_comb(data, num_frames, 10.0f, 1.0f); + // Just check modification + assert(data[0] != 1.0f || data[1] != 1.0f); // It should change values - // Noise - data.assign(DCT_SIZE, 1.0f); - srand(42); - apply_spectral_noise(data, num_frames, 0.5f); - // Should be noisy - assert(data[0] != 1.0f); + // Noise + data.assign(DCT_SIZE, 1.0f); + srand(42); + apply_spectral_noise(data, num_frames, 0.5f); + // Should be noisy + assert(data[0] != 1.0f); } int main() { - std::cout << "Running Audio Gen tests..." << std::endl; - test_generate_note(); - test_paste(); - test_filters(); - std::cout << "Audio Gen tests PASSED" << std::endl; - return 0; + std::cout << "Running Audio Gen tests..." << std::endl; + test_generate_note(); + test_paste(); + test_filters(); + std::cout << "Audio Gen tests PASSED" << std::endl; + return 0; } diff --git a/src/tests/test_dct.cc b/src/tests/test_dct.cc index b40f392..89b7964 100644 --- a/src/tests/test_dct.cc +++ b/src/tests/test_dct.cc @@ -2,42 +2,43 @@ // It tests the DCT implementation for correctness and coverage. #include "audio/dct.h" -#include <vector> -#include <cmath> #include <cassert> -#include <iostream> +#include <cmath> #include <cstdlib> +#include <iostream> +#include <vector> void test_fdct_idct() { - float input[DCT_SIZE]; - float freq[DCT_SIZE]; - float output[DCT_SIZE]; + float input[DCT_SIZE]; + float freq[DCT_SIZE]; + float output[DCT_SIZE]; + + // Initialize with random data + srand(12345); // Fixed seed for reproducibility + for (int i = 0; i < DCT_SIZE; ++i) { + input[i] = (float)rand() / RAND_MAX * 2.0f - 1.0f; + } - // Initialize with random data - srand(12345); // Fixed seed for reproducibility - for (int i = 0; i < DCT_SIZE; ++i) { - input[i] = (float)rand() / RAND_MAX * 2.0f - 1.0f; - } + fdct_512(input, freq); + idct_512(freq, output); - fdct_512(input, freq); - idct_512(freq, output); + // Verify reconstruction + float max_error = 0.0f; + for (int i = 0; i < DCT_SIZE; ++i) { + float err = std::abs(input[i] - output[i]); + if (err > max_error) + max_error = err; + } + std::cout << "Max reconstruction error: " << max_error << std::endl; - // Verify reconstruction - float max_error = 0.0f; - for (int i = 0; i < DCT_SIZE; ++i) { - float err = std::abs(input[i] - output[i]); - if (err > max_error) max_error = err; - } - std::cout << "Max reconstruction error: " << max_error << std::endl; - - // Allow some error due to float precision and iterative sum - // 512 sums can accumulate error. - assert(max_error < 1e-4f); + // Allow some error due to float precision and iterative sum + // 512 sums can accumulate error. + assert(max_error < 1e-4f); } int main() { - std::cout << "Running DCT tests..." << std::endl; - test_fdct_idct(); - std::cout << "DCT tests PASSED" << std::endl; - return 0; + std::cout << "Running DCT tests..." << std::endl; + test_fdct_idct(); + std::cout << "DCT tests PASSED" << std::endl; + return 0; } diff --git a/src/tests/test_maths.cc b/src/tests/test_maths.cc index ffc56f2..0fed85c 100644 --- a/src/tests/test_maths.cc +++ b/src/tests/test_maths.cc @@ -49,7 +49,8 @@ template <typename T> void test_vector_ops(int n) { // Normalize zero vector T zero_vec = T(); // Default construct to zero T norm_zero = zero_vec.normalize(); - for(int i = 0; i < n; ++i) assert(near(norm_zero[i], 0.0f)); + for (int i = 0; i < n; ++i) + assert(near(norm_zero[i], 0.0f)); // Lerp T l = lerp(a, b, 0.3f); @@ -82,17 +83,18 @@ void test_quat() { assert(near(r.x, 0) && near(r.z, -1)); // Rotation edge cases: 0 deg, 180 deg, zero vector - quat zero_rot = quat::from_axis({1,0,0}, 0.0f); + quat zero_rot = quat::from_axis({1, 0, 0}, 0.0f); vec3 rotated_zero = zero_rot.rotate(v); assert(near(rotated_zero.x, 1.0f)); // Original vector - quat half_pi_rot = quat::from_axis({0,1,0}, 3.14159f); // 180 deg Y + quat half_pi_rot = quat::from_axis({0, 1, 0}, 3.14159f); // 180 deg Y vec3 rotated_half_pi = half_pi_rot.rotate(v); assert(near(rotated_half_pi.x, -1.0f)); // Rotated 180 deg around Y - vec3 zero_vec(0,0,0); + vec3 zero_vec(0, 0, 0); vec3 rotated_zero_vec = q.rotate(zero_vec); - assert(near(rotated_zero_vec.x, 0.0f) && near(rotated_zero_vec.y, 0.0f) && near(rotated_zero_vec.z, 0.0f)); + assert(near(rotated_zero_vec.x, 0.0f) && near(rotated_zero_vec.y, 0.0f) && + near(rotated_zero_vec.z, 0.0f)); // Look At // Looking from origin to +X, with +Y as up. @@ -109,13 +111,16 @@ void test_quat() { // Slerp edge cases quat slerp_mid_edge = slerp(q1, q2, 0.0f); - assert(near(slerp_mid_edge.w, q1.w) && near(slerp_mid_edge.x, q1.x) && near(slerp_mid_edge.y, q1.y) && near(slerp_mid_edge.z, q1.z)); + assert(near(slerp_mid_edge.w, q1.w) && near(slerp_mid_edge.x, q1.x) && + near(slerp_mid_edge.y, q1.y) && near(slerp_mid_edge.z, q1.z)); slerp_mid_edge = slerp(q1, q2, 1.0f); - assert(near(slerp_mid_edge.w, q2.w) && near(slerp_mid_edge.x, q2.x) && near(slerp_mid_edge.y, q2.y) && near(slerp_mid_edge.z, q2.z)); + assert(near(slerp_mid_edge.w, q2.w) && near(slerp_mid_edge.x, q2.x) && + near(slerp_mid_edge.y, q2.y) && near(slerp_mid_edge.z, q2.z)); // FromTo - quat from_to_test = quat::from_to({1,0,0}, {0,1,0}); // 90 deg rotation around Z - vec3 rotated = from_to_test.rotate({1,0,0}); + quat from_to_test = + quat::from_to({1, 0, 0}, {0, 1, 0}); // 90 deg rotation around Z + vec3 rotated = from_to_test.rotate({1, 0, 0}); assert(near(rotated.y, 1.0f)); } @@ -172,8 +177,10 @@ void test_ease() { assert(near(ease::out_expo(1.0f), 1.0f)); // Midpoint/Logic tests - assert(ease::out_cubic(0.5f) > 0.5f); // Out curves should exceed linear value early - assert(near(ease::in_out_quad(0.5f), 0.5f)); // Symmetric curves hit 0.5 at 0.5 + assert(ease::out_cubic(0.5f) > + 0.5f); // Out curves should exceed linear value early + assert( + near(ease::in_out_quad(0.5f), 0.5f)); // Symmetric curves hit 0.5 at 0.5 assert(ease::out_expo(0.5f) > 0.5f); // Exponential out should be above linear } @@ -187,7 +194,8 @@ void test_spring() { assert(p > 8.5f); // Should be close to 10 after 1 sec // Test convergence over longer period - p = 0; v = 0; + p = 0; + v = 0; for (int i = 0; i < 200; ++i) spring::solve(p, v, 10.0f, 0.5f, 0.016f); assert(near(p, 10.0f, 0.1f)); // Should be very close to target @@ -264,7 +272,8 @@ void test_matrix_inversion() { mat4 singular_scale; singular_scale.m[5] = 0.0f; // Scale Y by zero, making it singular mat4 singular_inv = singular_scale.inverse(); - // The inverse of a singular matrix should be the identity matrix as per the implementation + // The inverse of a singular matrix should be the identity matrix as per the + // implementation check_identity(singular_inv); } diff --git a/src/tests/test_mock_backend.cc b/src/tests/test_mock_backend.cc index 9173bb2..f696800 100644 --- a/src/tests/test_mock_backend.cc +++ b/src/tests/test_mock_backend.cc @@ -2,12 +2,12 @@ // It tests the MockAudioBackend implementation. // Verifies event recording, time tracking, and synth integration. -#include "audio/mock_audio_backend.h" #include "audio/audio.h" +#include "audio/mock_audio_backend.h" #include "audio/synth.h" #include <assert.h> -#include <stdio.h> #include <cmath> +#include <stdio.h> #if !defined(STRIP_ALL) diff --git a/src/tests/test_physics.cc b/src/tests/test_physics.cc index a59502c..df21e70 100644 --- a/src/tests/test_physics.cc +++ b/src/tests/test_physics.cc @@ -101,51 +101,50 @@ void test_bvh() { assert(results.size() == 0); // Query both - results.clear(); - bvh.query({{-12, -2, -2}, {12, 2, 2}}, results); - assert(results.size() == 2); - } - - void test_physics_falling() { - std::cout << "Testing Physics falling..." << std::endl; - Scene scene; - - // Plane at y = -1 - Object3D plane(ObjectType::PLANE); - plane.position = {0, -1, 0}; - plane.is_static = true; - scene.add_object(plane); - - // Sphere at y = 5 - Object3D sphere(ObjectType::SPHERE); - sphere.position = {0, 5, 0}; - sphere.velocity = {0, 0, 0}; - sphere.restitution = 0.0f; // No bounce for simple test - scene.add_object(sphere); - - PhysicsSystem physics; - float dt = 0.016f; - for (int i = 0; i < 100; ++i) { - physics.update(scene, dt); - } - - // Sphere should be above or at plane (y >= 0 because sphere radius is 1, - // plane is at -1) - assert(scene.objects[1].position.y >= -0.01f); - // Also should have slowed down - assert(scene.objects[1].velocity.y > -1.0f); - } - - int main() { - test_sdf_sphere(); - test_sdf_box(); - test_sdf_torus(); - test_sdf_plane(); - test_calc_normal(); - test_bvh(); - test_physics_falling(); - - std::cout << "--- ALL PHYSICS TESTS PASSED ---" << std::endl; - return 0; + results.clear(); + bvh.query({{-12, -2, -2}, {12, 2, 2}}, results); + assert(results.size() == 2); +} + +void test_physics_falling() { + std::cout << "Testing Physics falling..." << std::endl; + Scene scene; + + // Plane at y = -1 + Object3D plane(ObjectType::PLANE); + plane.position = {0, -1, 0}; + plane.is_static = true; + scene.add_object(plane); + + // Sphere at y = 5 + Object3D sphere(ObjectType::SPHERE); + sphere.position = {0, 5, 0}; + sphere.velocity = {0, 0, 0}; + sphere.restitution = 0.0f; // No bounce for simple test + scene.add_object(sphere); + + PhysicsSystem physics; + float dt = 0.016f; + for (int i = 0; i < 100; ++i) { + physics.update(scene, dt); } -
\ No newline at end of file + + // Sphere should be above or at plane (y >= 0 because sphere radius is 1, + // plane is at -1) + assert(scene.objects[1].position.y >= -0.01f); + // Also should have slowed down + assert(scene.objects[1].velocity.y > -1.0f); +} + +int main() { + test_sdf_sphere(); + test_sdf_box(); + test_sdf_torus(); + test_sdf_plane(); + test_calc_normal(); + test_bvh(); + test_physics_falling(); + + std::cout << "--- ALL PHYSICS TESTS PASSED ---" << std::endl; + return 0; +} diff --git a/src/tests/test_procedural.cc b/src/tests/test_procedural.cc index 0373402..e9f9a02 100644 --- a/src/tests/test_procedural.cc +++ b/src/tests/test_procedural.cc @@ -3,9 +3,9 @@ #include "procedural/generator.h" #include <cassert> +#include <cmath> #include <iostream> #include <vector> -#include <cmath> void test_noise() { std::cout << "Testing Noise Generator..." << std::endl; @@ -17,7 +17,7 @@ void test_noise() { bool res = procedural::gen_noise(buffer.data(), w, h, params, 2); assert(res); assert(buffer[3] == 255); - + // Check that not all pixels are black bool nonzero = false; for (size_t i = 0; i < buffer.size(); i += 4) { @@ -39,7 +39,7 @@ void test_perlin() { std::cout << "Testing Perlin Generator..." << std::endl; int w = 64, h = 64; std::vector<uint8_t> buffer(w * h * 4); - + // Test with explicit params // Params: Seed, Freq, Amp, Decay, Octaves float params[] = {12345, 4.0f, 1.0f, 0.5f, 4.0f}; @@ -63,8 +63,8 @@ void test_perlin() { assert(buffer[3] == 255); // Test memory allocation failure simulation (large dimensions) - // This is hard to robustly test without mocking, but we can try an excessively large allocation if desired. - // For now, we trust the logic path. + // This is hard to robustly test without mocking, but we can try an + // excessively large allocation if desired. For now, we trust the logic path. } void test_grid() { @@ -98,19 +98,19 @@ void test_periodic() { std::vector<uint8_t> buffer(w * h * 4); // Fill with horizontal gradient: left=0, right=255 - for(int y=0; y<h; ++y) { - for(int x=0; x<w; ++x) { - int idx = (y*w + x) * 4; - buffer[idx] = (uint8_t)(x * 255 / (w-1)); - buffer[idx+1] = 0; - buffer[idx+2] = 0; - buffer[idx+3] = 255; + for (int y = 0; y < h; ++y) { + for (int x = 0; x < w; ++x) { + int idx = (y * w + x) * 4; + buffer[idx] = (uint8_t)(x * 255 / (w - 1)); + buffer[idx + 1] = 0; + buffer[idx + 2] = 0; + buffer[idx + 3] = 255; } } // Pre-check: edges are different assert(buffer[0] == 0); - assert(buffer[(w-1)*4] == 255); + assert(buffer[(w - 1) * 4] == 255); float params[] = {0.1f}; // Blend ratio 10% bool res = procedural::make_periodic(buffer.data(), w, h, params, 1); @@ -119,10 +119,10 @@ void test_periodic() { // Post-check: Left edge (x=0) should now be blended with right edge. // Logic: blend right edge INTO left edge. At x=0, we copy from right side. // So buffer[0] should be close to 255 (value from right). - assert(buffer[0] > 200); + assert(buffer[0] > 200); // Check invalid ratio - float invalid_params[] = { -1.0f }; + float invalid_params[] = {-1.0f}; res = procedural::make_periodic(buffer.data(), w, h, invalid_params, 1); assert(res); // Should return true but do nothing } diff --git a/src/tests/test_shader_composer.cc b/src/tests/test_shader_composer.cc index 1dd8298..a98a259 100644 --- a/src/tests/test_shader_composer.cc +++ b/src/tests/test_shader_composer.cc @@ -81,7 +81,9 @@ void test_recursive_composition() { sc.RegisterSnippet("base", "fn base() {}"); sc.RegisterSnippet("mid", "#include \"base\"\nfn mid() { base(); }"); - sc.RegisterSnippet("top", "#include \"mid\"\n#include \"base\"\nfn top() { mid(); base(); }"); + sc.RegisterSnippet( + "top", + "#include \"mid\"\n#include \"base\"\nfn top() { mid(); base(); }"); std::string main_code = "#include \"top\"\nfn main() { top(); }"; std::string result = sc.Compose({}, main_code); @@ -106,11 +108,15 @@ void test_renderer_composition() { std::cout << "Testing Renderer Shader Composition..." << std::endl; auto& sc = ShaderComposer::Get(); - sc.RegisterSnippet("common_uniforms", "struct GlobalUniforms { view_proj: mat4x4<f32> };"); + sc.RegisterSnippet("common_uniforms", + "struct GlobalUniforms { view_proj: mat4x4<f32> };"); sc.RegisterSnippet("math/sdf_shapes", "fn sdSphere() {}"); - sc.RegisterSnippet("render/scene_query", "#include \"math/sdf_shapes\"\nfn map_scene() {}"); + sc.RegisterSnippet("render/scene_query", + "#include \"math/sdf_shapes\"\nfn map_scene() {}"); - std::string main_code = "#include \"common_uniforms\"\n#include \"render/scene_query\"\nfn main() {}"; + std::string main_code = + "#include \"common_uniforms\"\n#include \"render/scene_query\"\nfn " + "main() {}"; std::string result = sc.Compose({}, main_code); assert(result.find("struct GlobalUniforms") != std::string::npos); diff --git a/src/tests/test_synth.cc b/src/tests/test_synth.cc index c172da1..12cbc54 100644 --- a/src/tests/test_synth.cc +++ b/src/tests/test_synth.cc @@ -4,8 +4,8 @@ #include "audio/synth.h" #include <assert.h> -#include <stdio.h> #include <cmath> +#include <stdio.h> void test_registration() { synth_init(); @@ -15,7 +15,7 @@ void test_registration() { int id = synth_register_spectrogram(&spec); assert(id >= 0); assert(synth_get_active_voice_count() == 0); - + synth_unregister_spectrogram(id); // Re-register to check slot reuse int id2 = synth_register_spectrogram(&spec); @@ -36,66 +36,68 @@ void test_render() { synth_init(); float data[DCT_SIZE * 2] = {0}; // Put some signal in (DC component) - data[0] = 100.0f; + data[0] = 100.0f; Spectrogram spec = {data, data, 2}; int id = synth_register_spectrogram(&spec); - + synth_trigger_voice(id, 1.0f, 0.0f); - - float output[1024] = {0}; + + float output[1024] = {0}; synth_render(output, 256); - + // Verify output is not all zero (IDCT of DC component should be constant) bool non_zero = false; - for(int i=0; i<256; ++i) { - if(std::abs(output[i]) > 1e-6f) non_zero = true; + for (int i = 0; i < 256; ++i) { + if (std::abs(output[i]) > 1e-6f) + non_zero = true; } assert(non_zero); - + // Test render with no voices synth_init(); // Reset float output2[1024] = {0}; synth_render(output2, 256); - for(int i=0; i<256; ++i) assert(output2[i] == 0.0f); + for (int i = 0; i < 256; ++i) + assert(output2[i] == 0.0f); } void test_update() { - synth_init(); - float data[DCT_SIZE * 2] = {0}; - Spectrogram spec = {data, data, 2}; - int id = synth_register_spectrogram(&spec); - - float* back_buf = synth_begin_update(id); - assert(back_buf != nullptr); - // Write something - back_buf[0] = 50.0f; - synth_commit_update(id); - - // Test invalid ID - assert(synth_begin_update(-1) == nullptr); - synth_commit_update(-1); // Should not crash + synth_init(); + float data[DCT_SIZE * 2] = {0}; + Spectrogram spec = {data, data, 2}; + int id = synth_register_spectrogram(&spec); + + float* back_buf = synth_begin_update(id); + assert(back_buf != nullptr); + // Write something + back_buf[0] = 50.0f; + synth_commit_update(id); + + // Test invalid ID + assert(synth_begin_update(-1) == nullptr); + synth_commit_update(-1); // Should not crash } void test_exhaustion() { - synth_init(); - float data[DCT_SIZE * 2] = {0}; - Spectrogram spec = {data, data, 2}; - - for(int i=0; i<MAX_SPECTROGRAMS; ++i) { - int id = synth_register_spectrogram(&spec); - assert(id >= 0); - } - // Next one should fail + synth_init(); + float data[DCT_SIZE * 2] = {0}; + Spectrogram spec = {data, data, 2}; + + for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { int id = synth_register_spectrogram(&spec); - assert(id == -1); + assert(id >= 0); + } + // Next one should fail + int id = synth_register_spectrogram(&spec); + assert(id == -1); } void test_peak() { - // Already called render in test_render. - // Just call the getter. - float peak = synth_get_output_peak(); - assert(peak >= 0.0f); + // Already called render in test_render. + // Just call the getter. + float peak = synth_get_output_peak(); + assert(peak >= 0.0f); } int main() { |
