// Tests for platform windowing and input abstraction. // Covers basic lifecycle, time queries, and string view helpers. #include "platform/platform.h" #include #include #include #if !defined(_WIN32) #include #else #include 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; }