diff options
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/test_platform.cc | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/tests/test_platform.cc b/src/tests/test_platform.cc new file mode 100644 index 0000000..80016ec --- /dev/null +++ b/src/tests/test_platform.cc @@ -0,0 +1,190 @@ +// Tests for platform windowing and input abstraction. +// Covers basic lifecycle, time queries, and string view helpers. + +#include "platform.h" +#include <cassert> +#include <cmath> +#include <cstdio> + +#if !defined(_WIN32) +#include <unistd.h> +#else +#include <windows.h> +static void usleep(int microseconds) { + Sleep(microseconds / 1000); +} +#endif /* !defined(_WIN32) */ + +// Test 1: Time query function (requires GLFW init) +// Note: platform_get_time() wraps glfwGetTime() which requires GLFW initialized +static void test_platform_get_time_with_context() { + printf("Testing platform_get_time() with GLFW context...\n"); + + // Create minimal platform state to init GLFW + PlatformState state = platform_init(false, 320, 240); + + const double t1 = platform_get_time(); + assert(t1 >= 0.0 && "Time should be non-negative"); + + usleep(10000); // Sleep 10ms + + const double t2 = platform_get_time(); + assert(t2 > t1 && "Time should advance"); + assert(t2 - t1 >= 0.008 && "Time delta should be at least 8ms"); + assert(t2 - t1 < 0.1 && "Time delta should be less than 100ms"); + + printf(" ✓ Time query works (t1=%.6f, t2=%.6f, delta=%.6f)\n", t1, t2, + t2 - t1); + + platform_shutdown(&state); +} + +// Test 2: String view helpers (Win32 vs native) +static void test_string_views() { + printf("Testing string view helpers...\n"); + + const char* test_str = "test_string"; + const char* null_str = nullptr; + +#if defined(DEMO_CROSS_COMPILE_WIN32) + // Win32: returns const char* + const char* sv = str_view(test_str); + assert(sv == test_str && "str_view should return same pointer"); + + const char* sv_null = str_view(null_str); + assert(sv_null == nullptr && "str_view(nullptr) should return nullptr"); + + const char* lv = label_view(test_str); + assert(lv == test_str && "label_view should return same pointer"); + + printf(" ✓ Win32 string views work\n"); +#else + // Native: returns WGPUStringView + WGPUStringView sv = str_view(test_str); + assert(sv.data == test_str && "str_view data should match"); + assert(sv.length == 11 && "str_view length should be correct"); + + WGPUStringView sv_null = str_view(null_str); + assert(sv_null.data == nullptr && "str_view(nullptr) data should be null"); + assert(sv_null.length == 0 && "str_view(nullptr) length should be 0"); + +#if !defined(STRIP_ALL) + WGPUStringView lv = label_view(test_str); + assert(lv.data == test_str && "label_view data should match"); + assert(lv.length == 11 && "label_view length should be correct"); + printf(" ✓ Native string views work (non-stripped)\n"); +#else + WGPUStringView lv = label_view(test_str); + assert(lv.data == nullptr && "label_view in STRIP_ALL should return null"); + assert(lv.length == 0 && "label_view in STRIP_ALL should have 0 length"); + printf(" ✓ Native string views work (stripped)\n"); +#endif /* !defined(STRIP_ALL) */ +#endif /* defined(DEMO_CROSS_COMPILE_WIN32) */ +} + +// Test 3: Basic platform lifecycle (headless window) +static void test_platform_lifecycle() { + printf("Testing platform lifecycle...\n"); + + // Initialize with small window (minimize resource usage) + PlatformState state = platform_init(false, 320, 240); + + assert(state.window != nullptr && "Window should be created"); + assert(state.width > 0 && "Width should be positive"); + assert(state.height > 0 && "Height should be positive"); + assert(state.aspect_ratio > 0.0f && "Aspect ratio should be positive"); + assert(fabs(state.aspect_ratio - (float)state.width / (float)state.height) < + 0.01f && + "Aspect ratio should match dimensions"); + assert(state.time >= 0.0 && "Time should be non-negative"); + assert(!state.is_fullscreen && "Should not be fullscreen initially"); + + printf(" ✓ Init: window=%p, size=%dx%d, aspect=%.2f, time=%.6f\n", + (void*)state.window, state.width, state.height, state.aspect_ratio, + state.time); + + // Poll should update time + const double t1 = state.time; + usleep(10000); // Sleep 10ms + platform_poll(&state); + assert(state.time > t1 && "Time should advance after poll"); + + printf(" ✓ Poll: time advanced %.6f → %.6f\n", t1, state.time); + + // Should not close initially + assert(!platform_should_close(&state) && "Should not close initially"); + + printf(" ✓ Should close: false (as expected)\n"); + + // Shutdown should not crash + platform_shutdown(&state); + + printf(" ✓ Shutdown completed\n"); +} + +// Test 4: Fullscreen toggle state tracking +static void test_fullscreen_toggle() { + printf("Testing fullscreen toggle...\n"); + + PlatformState state = platform_init(false, 640, 480); + + assert(!state.is_fullscreen && "Should start windowed"); + + // Toggle to fullscreen + platform_toggle_fullscreen(&state); + assert(state.is_fullscreen && "Should be fullscreen after toggle"); + + // Window geometry should be preserved + assert(state.windowed_w > 0 && "Windowed width should be saved"); + assert(state.windowed_h > 0 && "Windowed height should be saved"); + + printf(" ✓ Fullscreen enabled, saved geometry: %dx%d at (%d,%d)\n", + state.windowed_w, state.windowed_h, state.windowed_x, + state.windowed_y); + + // Toggle back to windowed + platform_toggle_fullscreen(&state); + assert(!state.is_fullscreen && "Should be windowed after second toggle"); + + printf(" ✓ Fullscreen disabled\n"); + + platform_shutdown(&state); +} + +// Test 5: PlatformState default initialization +static void test_platform_state_constructor() { + printf("Testing PlatformState default initialization...\n"); + + PlatformState state = {}; + + // PlatformState has default member initializers, so check expected defaults + assert(state.window == nullptr && "Window should be null"); + assert(state.width == 1280 && "Width should be 1280 (default)"); + assert(state.height == 720 && "Height should be 720 (default)"); + assert(state.aspect_ratio == 1.0f && "Aspect ratio should be 1.0 (default)"); + assert(state.time == 0.0 && "Time should be zero"); + assert(!state.is_fullscreen && "Fullscreen should be false"); + assert(state.windowed_x == 0 && "Windowed X should be zero"); + assert(state.windowed_y == 0 && "Windowed Y should be zero"); + assert(state.windowed_w == 0 && "Windowed W should be zero"); + assert(state.windowed_h == 0 && "Windowed H should be zero"); + + printf(" ✓ Default initialization works (1280x720, aspect=1.0)\n"); +} + +int main() { + printf("=== Platform Tests ===\n\n"); + + // Test functions that don't require GLFW context + test_string_views(); + test_platform_state_constructor(); + + // Test functions that require GLFW context (may fail in headless CI) + printf("\n"); + test_platform_get_time_with_context(); + test_platform_lifecycle(); + test_fullscreen_toggle(); + + printf("\n=== All Platform Tests Passed ===\n"); + return 0; +} |
