summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/test/testautomation_events.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testautomation_events.c')
-rw-r--r--src/contrib/SDL-3.2.20/test/testautomation_events.c341
1 files changed, 341 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testautomation_events.c b/src/contrib/SDL-3.2.20/test/testautomation_events.c
new file mode 100644
index 0000000..ed4e684
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/test/testautomation_events.c
@@ -0,0 +1,341 @@
1/**
2 * Events test suite
3 */
4#include <SDL3/SDL.h>
5#include <SDL3/SDL_test.h>
6#include "testautomation_suites.h"
7
8/* ================= Test Case Implementation ================== */
9
10/* Test case functions */
11
12/* Flag indicating if the userdata should be checked */
13static int g_userdataCheck = 0;
14
15/* Userdata value to check */
16static int g_userdataValue = 0;
17
18/* Flag indicating that the filter was called */
19static int g_eventFilterCalled = 0;
20
21/* Userdata values for event */
22static int g_userdataValue1 = 1;
23static int g_userdataValue2 = 2;
24
25#define MAX_ITERATIONS 100
26
27/* Event filter that sets some flags and optionally checks userdata */
28static bool SDLCALL events_sampleNullEventFilter(void *userdata, SDL_Event *event)
29{
30 g_eventFilterCalled = 1;
31
32 if (g_userdataCheck != 0) {
33 SDLTest_AssertCheck(userdata != NULL, "Check userdata pointer, expected: non-NULL, got: %s", (userdata != NULL) ? "non-NULL" : "NULL");
34 if (userdata != NULL) {
35 SDLTest_AssertCheck(*(int *)userdata == g_userdataValue, "Check userdata value, expected: %i, got: %i", g_userdataValue, *(int *)userdata);
36 }
37 }
38
39 return true;
40}
41
42/**
43 * Test pumping and peeking events.
44 *
45 * \sa SDL_PumpEvents
46 * \sa SDL_PollEvent
47 */
48static int SDLCALL events_pushPumpAndPollUserevent(void *arg)
49{
50 SDL_Event event_in;
51 SDL_Event event_out;
52 int result;
53 int i;
54 Sint32 ref_code = SDLTest_RandomSint32();
55 SDL_Window *event_window;
56
57 /* Flush all events */
58 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST);
59 SDLTest_AssertCheck(!SDL_HasEvents(SDL_EVENT_USER, SDL_EVENT_USER), "Check SDL_HasEvents returns false");
60
61 /* Create user event */
62 event_in.type = SDL_EVENT_USER;
63 event_in.user.windowID = 0;
64 event_in.common.timestamp = 0;
65 event_in.user.code = ref_code;
66 event_in.user.data1 = (void *)&g_userdataValue1;
67 event_in.user.data2 = (void *)&g_userdataValue2;
68
69 /* Push a user event onto the queue and force queue update */
70 SDL_PushEvent(&event_in);
71 SDLTest_AssertPass("Call to SDL_PushEvent()");
72 SDL_PumpEvents();
73 SDLTest_AssertPass("Call to SDL_PumpEvents()");
74
75 SDLTest_AssertCheck(SDL_HasEvents(SDL_EVENT_USER, SDL_EVENT_USER), "Check SDL_HasEvents returns true");
76
77 /* Poll until we get a user event. */
78 for (i = 0; i < MAX_ITERATIONS; i++) {
79 result = SDL_PollEvent(&event_out);
80 SDLTest_AssertPass("Call to SDL_PollEvent()");
81 SDLTest_AssertCheck(result == 1, "Check result from SDL_PollEvent, expected: 1, got: %d", result);
82 if (!result) {
83 break;
84 }
85 if (event_out.type == SDL_EVENT_USER) {
86 break;
87 }
88 }
89 SDLTest_AssertCheck(i < MAX_ITERATIONS, "Check the user event is seen in less then %d polls, got %d poll", MAX_ITERATIONS, i + 1);
90
91 SDLTest_AssertCheck(SDL_EVENT_USER == event_out.type, "Check event type is SDL_EVENT_USER, expected: 0x%x, got: 0x%" SDL_PRIx32, SDL_EVENT_USER, event_out.type);
92 SDLTest_AssertCheck(ref_code == event_out.user.code, "Check SDL_Event.user.code, expected: 0x%" SDL_PRIx32 ", got: 0x%" SDL_PRIx32 , ref_code, event_out.user.code);
93 SDLTest_AssertCheck(0 == event_out.user.windowID, "Check SDL_Event.user.windowID, expected: NULL , got: %" SDL_PRIu32, event_out.user.windowID);
94 SDLTest_AssertCheck((void *)&g_userdataValue1 == event_out.user.data1, "Check SDL_Event.user.data1, expected: %p, got: %p", &g_userdataValue1, event_out.user.data1);
95 SDLTest_AssertCheck((void *)&g_userdataValue2 == event_out.user.data2, "Check SDL_Event.user.data2, expected: %p, got: %p", &g_userdataValue2, event_out.user.data2);
96 event_window = SDL_GetWindowFromEvent(&event_out);
97 SDLTest_AssertCheck(NULL == SDL_GetWindowFromEvent(&event_out), "Check SDL_GetWindowFromEvent returns the window id from a user event, expected: NULL, got: %p", event_window);
98
99 /* Need to finish getting all events and sentinel, otherwise other tests that rely on event are in bad state */
100 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST);
101
102 return TEST_COMPLETED;
103}
104
105/**
106 * Adds and deletes an event watch function with NULL userdata
107 *
108 * \sa SDL_AddEventWatch
109 * \sa SDL_RemoveEventWatch
110 *
111 */
112static int SDLCALL events_addDelEventWatch(void *arg)
113{
114 SDL_Event event;
115
116 /* Create user event */
117 event.type = SDL_EVENT_USER;
118 event.common.timestamp = 0;
119 event.user.code = SDLTest_RandomSint32();
120 event.user.data1 = (void *)&g_userdataValue1;
121 event.user.data2 = (void *)&g_userdataValue2;
122
123 /* Disable userdata check */
124 g_userdataCheck = 0;
125
126 /* Reset event filter call tracker */
127 g_eventFilterCalled = 0;
128
129 /* Add watch */
130 SDL_AddEventWatch(events_sampleNullEventFilter, NULL);
131 SDLTest_AssertPass("Call to SDL_AddEventWatch()");
132
133 /* Push a user event onto the queue and force queue update */
134 SDL_PushEvent(&event);
135 SDLTest_AssertPass("Call to SDL_PushEvent()");
136 SDL_PumpEvents();
137 SDLTest_AssertPass("Call to SDL_PumpEvents()");
138 SDLTest_AssertCheck(g_eventFilterCalled == 1, "Check that event filter was called");
139
140 /* Delete watch */
141 SDL_RemoveEventWatch(events_sampleNullEventFilter, NULL);
142 SDLTest_AssertPass("Call to SDL_RemoveEventWatch()");
143
144 /* Push a user event onto the queue and force queue update */
145 g_eventFilterCalled = 0;
146 SDL_PushEvent(&event);
147 SDLTest_AssertPass("Call to SDL_PushEvent()");
148 SDL_PumpEvents();
149 SDLTest_AssertPass("Call to SDL_PumpEvents()");
150 SDLTest_AssertCheck(g_eventFilterCalled == 0, "Check that event filter was NOT called");
151
152 return TEST_COMPLETED;
153}
154
155/**
156 * Adds and deletes an event watch function with userdata
157 *
158 * \sa SDL_AddEventWatch
159 * \sa SDL_RemoveEventWatch
160 *
161 */
162static int SDLCALL events_addDelEventWatchWithUserdata(void *arg)
163{
164 SDL_Event event;
165
166 /* Create user event */
167 event.type = SDL_EVENT_USER;
168 event.common.timestamp = 0;
169 event.user.code = SDLTest_RandomSint32();
170 event.user.data1 = (void *)&g_userdataValue1;
171 event.user.data2 = (void *)&g_userdataValue2;
172
173 /* Enable userdata check and set a value to check */
174 g_userdataCheck = 1;
175 g_userdataValue = SDLTest_RandomIntegerInRange(-1024, 1024);
176
177 /* Reset event filter call tracker */
178 g_eventFilterCalled = 0;
179
180 /* Add watch */
181 SDL_AddEventWatch(events_sampleNullEventFilter, (void *)&g_userdataValue);
182 SDLTest_AssertPass("Call to SDL_AddEventWatch()");
183
184 /* Push a user event onto the queue and force queue update */
185 SDL_PushEvent(&event);
186 SDLTest_AssertPass("Call to SDL_PushEvent()");
187 SDL_PumpEvents();
188 SDLTest_AssertPass("Call to SDL_PumpEvents()");
189 SDLTest_AssertCheck(g_eventFilterCalled == 1, "Check that event filter was called");
190
191 /* Delete watch */
192 SDL_RemoveEventWatch(events_sampleNullEventFilter, (void *)&g_userdataValue);
193 SDLTest_AssertPass("Call to SDL_RemoveEventWatch()");
194
195 /* Push a user event onto the queue and force queue update */
196 g_eventFilterCalled = 0;
197 SDL_PushEvent(&event);
198 SDLTest_AssertPass("Call to SDL_PushEvent()");
199 SDL_PumpEvents();
200 SDLTest_AssertPass("Call to SDL_PumpEvents()");
201 SDLTest_AssertCheck(g_eventFilterCalled == 0, "Check that event filter was NOT called");
202
203 return TEST_COMPLETED;
204}
205
206/**
207 * Runs callbacks on the main thread.
208 *
209 * \sa SDL_IsMainThread
210 * \sa SDL_RunOnMainThread
211 *
212 */
213
214typedef struct IncrementCounterData_t
215{
216 Uint32 delay;
217 int counter;
218} IncrementCounterData_t;
219
220static void SDLCALL IncrementCounter(void *userdata)
221{
222 IncrementCounterData_t *data = (IncrementCounterData_t *)userdata;
223 ++data->counter;
224}
225
226#ifndef SDL_PLATFORM_EMSCRIPTEN /* Emscripten doesn't have threads */
227static int SDLCALL IncrementCounterThread(void *userdata)
228{
229 IncrementCounterData_t *data = (IncrementCounterData_t *)userdata;
230 SDL_Event event;
231
232 SDL_assert(!SDL_IsMainThread());
233
234 if (data->delay > 0) {
235 SDL_Delay(data->delay);
236 }
237
238 if (!SDL_RunOnMainThread(IncrementCounter, userdata, false)) {
239 SDLTest_LogError("Couldn't run IncrementCounter asynchronously on main thread: %s", SDL_GetError());
240 }
241 if (!SDL_RunOnMainThread(IncrementCounter, userdata, true)) {
242 SDLTest_LogError("Couldn't run IncrementCounter synchronously on main thread: %s", SDL_GetError());
243 }
244
245 /* Send an event to unblock the main thread, which is waiting in SDL_WaitEvent() */
246 event.type = SDL_EVENT_USER;
247 SDL_PushEvent(&event);
248
249 return 0;
250}
251#endif /* !SDL_PLATFORM_EMSCRIPTEN */
252
253static int SDLCALL events_mainThreadCallbacks(void *arg)
254{
255 IncrementCounterData_t data = { 0, 0 };
256
257 /* Make sure we're on the main thread */
258 SDLTest_AssertCheck(SDL_IsMainThread(), "Verify we're on the main thread");
259
260 SDL_RunOnMainThread(IncrementCounter, &data, true);
261 SDLTest_AssertCheck(data.counter == 1, "Incremented counter on main thread, expected 1, got %d", data.counter);
262
263#ifndef SDL_PLATFORM_EMSCRIPTEN /* Emscripten doesn't have threads */
264 {
265 SDL_Window *window;
266 SDL_Thread *thread;
267 SDL_Event event;
268
269 window = SDL_CreateWindow("test", 0, 0, SDL_WINDOW_HIDDEN);
270 SDLTest_AssertCheck(window != NULL, "Create window, expected non-NULL, got %p", window);
271
272 /* Flush any pending events */
273 SDL_PumpEvents();
274 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST);
275
276 /* Increment the counter on a thread, waiting for both calls to be queued */
277 thread = SDL_CreateThread(IncrementCounterThread, NULL, &data);
278 SDLTest_AssertCheck(thread != NULL, "Create counter thread");
279
280 /* Wait for both increment calls to be queued up */
281 SDL_Delay(100);
282
283 /* Run the main callbacks */
284 SDL_WaitEvent(&event);
285 SDLTest_AssertCheck(event.type == SDL_EVENT_USER, "Expected user event (0x%.4x), got 0x%.4x", SDL_EVENT_USER, (int)event.type);
286 SDL_WaitThread(thread, NULL);
287 SDLTest_AssertCheck(data.counter == 3, "Incremented counter on main thread, expected 3, got %d", data.counter);
288
289 /* Try again, but this time delay the calls until we've started waiting for events */
290 data.delay = 100;
291 thread = SDL_CreateThread(IncrementCounterThread, NULL, &data);
292 SDLTest_AssertCheck(thread != NULL, "Create counter thread");
293
294 /* Run the main callbacks */
295 SDL_WaitEvent(&event);
296 SDLTest_AssertCheck(event.type == SDL_EVENT_USER, "Expected user event (0x%.4x), got 0x%.4x", SDL_EVENT_USER, (int)event.type);
297 SDL_WaitThread(thread, NULL);
298 SDLTest_AssertCheck(data.counter == 5, "Incremented counter on main thread, expected 5, got %d", data.counter);
299
300 SDL_DestroyWindow(window);
301 }
302#endif /* !SDL_PLATFORM_EMSCRIPTEN */
303
304 return TEST_COMPLETED;
305}
306
307/* ================= Test References ================== */
308
309/* Events test cases */
310static const SDLTest_TestCaseReference eventsTest_pushPumpAndPollUserevent = {
311 events_pushPumpAndPollUserevent, "events_pushPumpAndPollUserevent", "Pushes, pumps and polls a user event", TEST_ENABLED
312};
313
314static const SDLTest_TestCaseReference eventsTest_addDelEventWatch = {
315 events_addDelEventWatch, "events_addDelEventWatch", "Adds and deletes an event watch function with NULL userdata", TEST_ENABLED
316};
317
318static const SDLTest_TestCaseReference eventsTest_addDelEventWatchWithUserdata = {
319 events_addDelEventWatchWithUserdata, "events_addDelEventWatchWithUserdata", "Adds and deletes an event watch function with userdata", TEST_ENABLED
320};
321
322static const SDLTest_TestCaseReference eventsTest_mainThreadCallbacks = {
323 events_mainThreadCallbacks, "events_mainThreadCallbacks", "Run callbacks on the main thread", TEST_ENABLED
324};
325
326/* Sequence of Events test cases */
327static const SDLTest_TestCaseReference *eventsTests[] = {
328 &eventsTest_pushPumpAndPollUserevent,
329 &eventsTest_addDelEventWatch,
330 &eventsTest_addDelEventWatchWithUserdata,
331 &eventsTest_mainThreadCallbacks,
332 NULL
333};
334
335/* Events test suite (global) */
336SDLTest_TestSuiteReference eventsTestSuite = {
337 "Events",
338 NULL,
339 eventsTests,
340 NULL
341};