source: mainline/uspace/lib/ui/test/checkbox.c

Last change on this file was 1fa6292, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 5 months ago

Remove a ton of duplicated code in libui/libgfxfont tests

  • Property mode set to 100644
File size: 13.1 KB
Line 
1/*
2 * Copyright (c) 2024 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <gfx/context.h>
30#include <gfx/coord.h>
31#include <mem.h>
32#include <pcut/pcut.h>
33#include <stdbool.h>
34#include <ui/control.h>
35#include <ui/checkbox.h>
36#include <ui/resource.h>
37#include "../private/checkbox.h"
38#include "../private/testgc.h"
39
40PCUT_INIT;
41
42PCUT_TEST_SUITE(checkbox);
43
44static void test_checkbox_switched(ui_checkbox_t *, void *, bool);
45
46static ui_checkbox_cb_t test_checkbox_cb = {
47 .switched = test_checkbox_switched
48};
49
50static ui_checkbox_cb_t dummy_checkbox_cb = {
51};
52
53typedef struct {
54 bool switched;
55} test_cb_resp_t;
56
57/** Create and destroy check box */
58PCUT_TEST(create_destroy)
59{
60 ui_checkbox_t *checkbox = NULL;
61 errno_t rc;
62
63 rc = ui_checkbox_create(NULL, "Hello", &checkbox);
64 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
65 PCUT_ASSERT_NOT_NULL(checkbox);
66
67 ui_checkbox_destroy(checkbox);
68}
69
70/** ui_checkbox_destroy() can take NULL argument (no-op) */
71PCUT_TEST(destroy_null)
72{
73 ui_checkbox_destroy(NULL);
74}
75
76/** ui_checkbox_ctl() returns control that has a working virtual destructor */
77PCUT_TEST(ctl)
78{
79 ui_checkbox_t *checkbox;
80 ui_control_t *control;
81 errno_t rc;
82
83 rc = ui_checkbox_create(NULL, "Hello", &checkbox);
84 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
85
86 control = ui_checkbox_ctl(checkbox);
87 PCUT_ASSERT_NOT_NULL(control);
88
89 ui_control_destroy(control);
90}
91
92/** Set check box rectangle sets internal field */
93PCUT_TEST(set_rect)
94{
95 ui_checkbox_t *checkbox;
96 gfx_rect_t rect;
97 errno_t rc;
98
99 rc = ui_checkbox_create(NULL, "Hello", &checkbox);
100 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
101
102 rect.p0.x = 1;
103 rect.p0.y = 2;
104 rect.p1.x = 3;
105 rect.p1.y = 4;
106
107 ui_checkbox_set_rect(checkbox, &rect);
108 PCUT_ASSERT_INT_EQUALS(rect.p0.x, checkbox->rect.p0.x);
109 PCUT_ASSERT_INT_EQUALS(rect.p0.y, checkbox->rect.p0.y);
110 PCUT_ASSERT_INT_EQUALS(rect.p1.x, checkbox->rect.p1.x);
111 PCUT_ASSERT_INT_EQUALS(rect.p1.y, checkbox->rect.p1.y);
112
113 ui_checkbox_destroy(checkbox);
114}
115
116/** Get check box checked returns internal field */
117PCUT_TEST(get_checked)
118{
119 ui_checkbox_t *checkbox;
120 errno_t rc;
121
122 rc = ui_checkbox_create(NULL, "Hello", &checkbox);
123 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
124
125 checkbox->checked = false;
126 PCUT_ASSERT_FALSE(ui_checkbox_get_checked(checkbox));
127 checkbox->checked = true;
128 PCUT_ASSERT_TRUE(ui_checkbox_get_checked(checkbox));
129
130 ui_checkbox_destroy(checkbox);
131}
132
133/** Set check box checked sets internal field */
134PCUT_TEST(set_checked)
135{
136 ui_checkbox_t *checkbox;
137 errno_t rc;
138
139 rc = ui_checkbox_create(NULL, "Hello", &checkbox);
140 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
141
142 ui_checkbox_set_checked(checkbox, true);
143 PCUT_ASSERT_TRUE(checkbox->checked);
144 ui_checkbox_set_checked(checkbox, false);
145 PCUT_ASSERT_FALSE(checkbox->checked);
146
147 ui_checkbox_destroy(checkbox);
148}
149
150/** Paint check box in graphics mode */
151PCUT_TEST(paint_gfx)
152{
153 errno_t rc;
154 gfx_context_t *gc = NULL;
155 test_gc_t tgc;
156 ui_resource_t *resource = NULL;
157 ui_checkbox_t *checkbox;
158
159 memset(&tgc, 0, sizeof(tgc));
160 rc = gfx_context_new(&ops, &tgc, &gc);
161 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
162
163 rc = ui_resource_create(gc, false, &resource);
164 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
165 PCUT_ASSERT_NOT_NULL(resource);
166
167 rc = ui_checkbox_create(resource, "Hello", &checkbox);
168 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
169
170 rc = ui_checkbox_paint_gfx(checkbox);
171 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
172
173 ui_checkbox_destroy(checkbox);
174 ui_resource_destroy(resource);
175
176 rc = gfx_context_delete(gc);
177 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
178}
179
180/** Paint check box in text mode */
181PCUT_TEST(paint_text)
182{
183 errno_t rc;
184 gfx_context_t *gc = NULL;
185 test_gc_t tgc;
186 ui_resource_t *resource = NULL;
187 ui_checkbox_t *checkbox;
188
189 memset(&tgc, 0, sizeof(tgc));
190 rc = gfx_context_new(&ops, &tgc, &gc);
191 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
192
193 rc = ui_resource_create(gc, false, &resource);
194 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
195 PCUT_ASSERT_NOT_NULL(resource);
196
197 rc = ui_checkbox_create(resource, "Hello", &checkbox);
198 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
199
200 rc = ui_checkbox_paint_text(checkbox);
201 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
202
203 ui_checkbox_destroy(checkbox);
204 ui_resource_destroy(resource);
205
206 rc = gfx_context_delete(gc);
207 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
208}
209
210/** Test ui_checkbox_switched() */
211PCUT_TEST(switched)
212{
213 errno_t rc;
214 ui_checkbox_t *checkbox;
215 test_cb_resp_t resp;
216
217 rc = ui_checkbox_create(NULL, "Hello", &checkbox);
218 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
219
220 /* Switched with no callbacks set */
221 ui_checkbox_switched(checkbox);
222
223 /* Switched with callback not implementing switched */
224 ui_checkbox_set_cb(checkbox, &dummy_checkbox_cb, NULL);
225 ui_checkbox_switched(checkbox);
226
227 /* Switched with real callback set */
228 resp.switched = false;
229 ui_checkbox_set_cb(checkbox, &test_checkbox_cb, &resp);
230 ui_checkbox_switched(checkbox);
231 PCUT_ASSERT_TRUE(resp.switched);
232
233 ui_checkbox_destroy(checkbox);
234}
235
236/** Press and release check box */
237PCUT_TEST(press_release)
238{
239 errno_t rc;
240 gfx_context_t *gc = NULL;
241 test_gc_t tgc;
242 ui_resource_t *resource = NULL;
243 ui_checkbox_t *checkbox;
244 test_cb_resp_t resp;
245
246 memset(&tgc, 0, sizeof(tgc));
247 rc = gfx_context_new(&ops, &tgc, &gc);
248 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
249
250 rc = ui_resource_create(gc, false, &resource);
251 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
252 PCUT_ASSERT_NOT_NULL(resource);
253
254 rc = ui_checkbox_create(resource, "Hello", &checkbox);
255 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
256 PCUT_ASSERT_FALSE(checkbox->checked);
257
258 resp.switched = false;
259 ui_checkbox_set_cb(checkbox, &test_checkbox_cb, &resp);
260
261 PCUT_ASSERT_FALSE(checkbox->held);
262 PCUT_ASSERT_FALSE(checkbox->inside);
263
264 ui_checkbox_press(checkbox);
265 PCUT_ASSERT_TRUE(checkbox->held);
266 PCUT_ASSERT_TRUE(checkbox->inside);
267 PCUT_ASSERT_FALSE(resp.switched);
268 PCUT_ASSERT_FALSE(checkbox->checked);
269
270 ui_checkbox_release(checkbox);
271 PCUT_ASSERT_FALSE(checkbox->held);
272 PCUT_ASSERT_TRUE(checkbox->inside);
273 PCUT_ASSERT_TRUE(resp.switched);
274 PCUT_ASSERT_TRUE(checkbox->checked);
275
276 ui_checkbox_destroy(checkbox);
277 ui_resource_destroy(resource);
278
279 rc = gfx_context_delete(gc);
280 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
281}
282
283/** Press, leave and release check box */
284PCUT_TEST(press_leave_release)
285{
286 errno_t rc;
287 gfx_context_t *gc = NULL;
288 test_gc_t tgc;
289 ui_resource_t *resource = NULL;
290 ui_checkbox_t *checkbox;
291 test_cb_resp_t resp;
292
293 memset(&tgc, 0, sizeof(tgc));
294 rc = gfx_context_new(&ops, &tgc, &gc);
295 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
296
297 rc = ui_resource_create(gc, false, &resource);
298 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
299 PCUT_ASSERT_NOT_NULL(resource);
300
301 rc = ui_checkbox_create(resource, "Hello", &checkbox);
302 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
303
304 resp.switched = false;
305 ui_checkbox_set_cb(checkbox, &test_checkbox_cb, &resp);
306
307 PCUT_ASSERT_FALSE(checkbox->held);
308 PCUT_ASSERT_FALSE(checkbox->inside);
309
310 ui_checkbox_press(checkbox);
311 PCUT_ASSERT_TRUE(checkbox->held);
312 PCUT_ASSERT_TRUE(checkbox->inside);
313 PCUT_ASSERT_FALSE(resp.switched);
314 PCUT_ASSERT_FALSE(checkbox->checked);
315
316 ui_checkbox_leave(checkbox);
317 PCUT_ASSERT_TRUE(checkbox->held);
318 PCUT_ASSERT_FALSE(checkbox->inside);
319 PCUT_ASSERT_FALSE(resp.switched);
320 PCUT_ASSERT_FALSE(checkbox->checked);
321
322 ui_checkbox_release(checkbox);
323 PCUT_ASSERT_FALSE(checkbox->held);
324 PCUT_ASSERT_FALSE(checkbox->inside);
325 PCUT_ASSERT_FALSE(resp.switched);
326 PCUT_ASSERT_FALSE(checkbox->checked);
327
328 ui_checkbox_destroy(checkbox);
329 ui_resource_destroy(resource);
330
331 rc = gfx_context_delete(gc);
332 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
333}
334
335/** Press, leave, enter and release check box */
336PCUT_TEST(press_leave_enter_release)
337{
338 errno_t rc;
339 gfx_context_t *gc = NULL;
340 test_gc_t tgc;
341 ui_resource_t *resource = NULL;
342 ui_checkbox_t *checkbox;
343 test_cb_resp_t resp;
344
345 memset(&tgc, 0, sizeof(tgc));
346 rc = gfx_context_new(&ops, &tgc, &gc);
347 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
348
349 rc = ui_resource_create(gc, false, &resource);
350 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
351 PCUT_ASSERT_NOT_NULL(resource);
352
353 rc = ui_checkbox_create(resource, "Hello", &checkbox);
354 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
355 PCUT_ASSERT_FALSE(checkbox->checked);
356
357 resp.switched = false;
358 ui_checkbox_set_cb(checkbox, &test_checkbox_cb, &resp);
359
360 PCUT_ASSERT_FALSE(checkbox->held);
361 PCUT_ASSERT_FALSE(checkbox->inside);
362
363 ui_checkbox_press(checkbox);
364 PCUT_ASSERT_TRUE(checkbox->held);
365 PCUT_ASSERT_TRUE(checkbox->inside);
366 PCUT_ASSERT_FALSE(resp.switched);
367 PCUT_ASSERT_FALSE(checkbox->checked);
368
369 ui_checkbox_leave(checkbox);
370 PCUT_ASSERT_TRUE(checkbox->held);
371 PCUT_ASSERT_FALSE(checkbox->inside);
372 PCUT_ASSERT_FALSE(resp.switched);
373 PCUT_ASSERT_FALSE(checkbox->checked);
374
375 ui_checkbox_enter(checkbox);
376 PCUT_ASSERT_TRUE(checkbox->held);
377 PCUT_ASSERT_TRUE(checkbox->inside);
378 PCUT_ASSERT_FALSE(resp.switched);
379 PCUT_ASSERT_FALSE(checkbox->checked);
380
381 ui_checkbox_release(checkbox);
382 PCUT_ASSERT_FALSE(checkbox->held);
383 PCUT_ASSERT_TRUE(checkbox->inside);
384 PCUT_ASSERT_TRUE(resp.switched);
385 PCUT_ASSERT_TRUE(checkbox->checked);
386
387 ui_checkbox_destroy(checkbox);
388 ui_resource_destroy(resource);
389
390 rc = gfx_context_delete(gc);
391 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
392}
393
394/** ui_pos_event() correctly translates POS_PRESS/POS_RELEASE */
395PCUT_TEST(pos_event_press_release)
396{
397 errno_t rc;
398 gfx_context_t *gc = NULL;
399 test_gc_t tgc;
400 ui_resource_t *resource = NULL;
401 ui_checkbox_t *checkbox;
402 ui_evclaim_t claim;
403 pos_event_t event;
404 gfx_rect_t rect;
405
406 memset(&tgc, 0, sizeof(tgc));
407 rc = gfx_context_new(&ops, &tgc, &gc);
408 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
409
410 rc = ui_resource_create(gc, false, &resource);
411 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
412 PCUT_ASSERT_NOT_NULL(resource);
413
414 rc = ui_checkbox_create(resource, "Hello", &checkbox);
415 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
416
417 PCUT_ASSERT_FALSE(checkbox->held);
418
419 rect.p0.x = 10;
420 rect.p0.y = 20;
421 rect.p1.x = 30;
422 rect.p1.y = 40;
423 ui_checkbox_set_rect(checkbox, &rect);
424
425 /* Press outside is not claimed and does nothing */
426 event.type = POS_PRESS;
427 event.hpos = 9;
428 event.vpos = 20;
429 claim = ui_checkbox_pos_event(checkbox, &event);
430 PCUT_ASSERT_FALSE(checkbox->held);
431 PCUT_ASSERT_EQUALS(ui_unclaimed, claim);
432
433 /* Press inside is claimed and depresses check box */
434 event.type = POS_PRESS;
435 event.hpos = 10;
436 event.vpos = 20;
437 claim = ui_checkbox_pos_event(checkbox, &event);
438 PCUT_ASSERT_TRUE(checkbox->held);
439 PCUT_ASSERT_EQUALS(ui_claimed, claim);
440
441 /* Release outside (or anywhere) is claimed and relases check box */
442 event.type = POS_RELEASE;
443 event.hpos = 9;
444 event.vpos = 20;
445 claim = ui_checkbox_pos_event(checkbox, &event);
446 PCUT_ASSERT_FALSE(checkbox->held);
447 PCUT_ASSERT_EQUALS(ui_claimed, claim);
448
449 ui_checkbox_destroy(checkbox);
450 ui_resource_destroy(resource);
451
452 rc = gfx_context_delete(gc);
453 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
454}
455
456/** ui_pos_event() correctly translates POS_UPDATE to enter/leave */
457PCUT_TEST(pos_event_enter_leave)
458{
459 errno_t rc;
460 gfx_context_t *gc = NULL;
461 test_gc_t tgc;
462 ui_resource_t *resource = NULL;
463 ui_checkbox_t *checkbox;
464 pos_event_t event;
465 gfx_rect_t rect;
466
467 memset(&tgc, 0, sizeof(tgc));
468 rc = gfx_context_new(&ops, &tgc, &gc);
469 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
470
471 rc = ui_resource_create(gc, false, &resource);
472 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
473 PCUT_ASSERT_NOT_NULL(resource);
474
475 rc = ui_checkbox_create(resource, "Hello", &checkbox);
476 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
477
478 PCUT_ASSERT_FALSE(checkbox->inside);
479
480 rect.p0.x = 10;
481 rect.p0.y = 20;
482 rect.p1.x = 30;
483 rect.p1.y = 40;
484 ui_checkbox_set_rect(checkbox, &rect);
485
486 /* Moving outside does nothing */
487 event.type = POS_UPDATE;
488 event.hpos = 9;
489 event.vpos = 20;
490 ui_checkbox_pos_event(checkbox, &event);
491 PCUT_ASSERT_FALSE(checkbox->inside);
492
493 /* Moving inside sets inside flag */
494 event.type = POS_UPDATE;
495 event.hpos = 10;
496 event.vpos = 20;
497 ui_checkbox_pos_event(checkbox, &event);
498 PCUT_ASSERT_TRUE(checkbox->inside);
499
500 /* Moving outside clears inside flag */
501 event.type = POS_UPDATE;
502 event.hpos = 9;
503 event.vpos = 20;
504 ui_checkbox_pos_event(checkbox, &event);
505 PCUT_ASSERT_FALSE(checkbox->inside);
506
507 ui_checkbox_destroy(checkbox);
508 ui_resource_destroy(resource);
509
510 rc = gfx_context_delete(gc);
511 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
512}
513
514static void test_checkbox_switched(ui_checkbox_t *checkbox, void *arg,
515 bool checked)
516{
517 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
518
519 resp->switched = true;
520}
521
522PCUT_EXPORT(checkbox);
Note: See TracBrowser for help on using the repository browser.