1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
// Tests for platform windowing and input abstraction.
// Covers basic lifecycle, time queries, and string view helpers.
#include "platform/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;
}
|