source: mainline/uspace/lib/ui/test/menu.c@ 1c6c3e1d

ticket/834-toolchain-update
Last change on this file since 1c6c3e1d was 46bd63c9, checked in by Jiri Svoboda <jiri@…>, 22 months ago

Split drop-down menu into two classes: drop-down and menu

Naming is clearly the hardest problem in computer science.

  • Property mode set to 100644
File size: 18.6 KB
Line 
1/*
2 * Copyright (c) 2023 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 <str.h>
35#include <ui/control.h>
36#include <ui/menu.h>
37#include <ui/menubar.h>
38#include <ui/menuentry.h>
39#include <ui/ui.h>
40#include <ui/window.h>
41#include "../private/menu.h"
42#include "../private/menubar.h"
43
44PCUT_INIT;
45
46PCUT_TEST_SUITE(menu);
47
48typedef struct {
49 bool left_called;
50 bool right_called;
51 bool close_req_called;
52 bool press_accel_called;
53 ui_menu_t *menu;
54 sysarg_t idev_id;
55 char32_t c;
56} test_resp_t;
57
58static void testmenu_left(ui_menu_t *, void *, sysarg_t);
59static void testmenu_right(ui_menu_t *, void *, sysarg_t);
60static void testmenu_close_req(ui_menu_t *, void *);
61static void testmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
62
63ui_menu_cb_t testmenu_cb = {
64 .left = testmenu_left,
65 .right = testmenu_right,
66 .close_req = testmenu_close_req,
67 .press_accel = testmenu_press_accel
68};
69
70ui_menu_cb_t dummy_cb = {
71};
72
73/** Create and destroy menu */
74PCUT_TEST(create_destroy)
75{
76 ui_menu_t *menu = NULL;
77 errno_t rc;
78
79 rc = ui_menu_create(NULL, &menu);
80 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
81 PCUT_ASSERT_NOT_NULL(menu);
82
83 ui_menu_destroy(menu);
84}
85
86/** ui_menu_destroy() can take NULL argument (no-op) */
87PCUT_TEST(destroy_null)
88{
89 ui_menu_destroy(NULL);
90}
91
92/** ui_menu_set_cb() sets the internal fields */
93PCUT_TEST(set_cb)
94{
95 ui_menu_t *menu = NULL;
96 ui_menu_cb_t cb;
97 int obj;
98 errno_t rc;
99
100 rc = ui_menu_create(NULL, &menu);
101 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
102 PCUT_ASSERT_NOT_NULL(menu);
103
104 ui_menu_set_cb(menu, &cb, (void *)&obj);
105 PCUT_ASSERT_EQUALS(&cb, menu->cb);
106 PCUT_ASSERT_EQUALS((void *)&obj, menu->arg);
107
108 ui_menu_destroy(menu);
109}
110
111/** Computing menu geometry */
112PCUT_TEST(get_geom)
113{
114 ui_t *ui = NULL;
115 ui_window_t *window = NULL;
116 ui_wnd_params_t params;
117 ui_menu_t *menu = NULL;
118 ui_menu_geom_t geom;
119 gfx_coord2_t pos;
120 errno_t rc;
121
122 rc = ui_create_disp(NULL, &ui);
123 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
124
125 ui_wnd_params_init(&params);
126 params.caption = "Hello";
127
128 rc = ui_window_create(ui, &params, &window);
129 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
130 PCUT_ASSERT_NOT_NULL(window);
131
132 rc = ui_menu_create(window, &menu);
133 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
134 PCUT_ASSERT_NOT_NULL(menu);
135
136 pos.x = 0;
137 pos.y = 0;
138 ui_menu_get_geom(menu, &pos, &geom);
139
140 PCUT_ASSERT_INT_EQUALS(0, geom.outer_rect.p0.x);
141 PCUT_ASSERT_INT_EQUALS(0, geom.outer_rect.p0.y);
142 PCUT_ASSERT_INT_EQUALS(16, geom.outer_rect.p1.x);
143 PCUT_ASSERT_INT_EQUALS(8, geom.outer_rect.p1.y);
144 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p0.x);
145 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p0.y);
146 PCUT_ASSERT_INT_EQUALS(12, geom.entries_rect.p1.x);
147 PCUT_ASSERT_INT_EQUALS(4, geom.entries_rect.p1.y);
148
149 ui_menu_destroy(menu);
150 ui_window_destroy(window);
151 ui_destroy(ui);
152}
153
154/** ui_menu_get_res() gets the menu's resource */
155PCUT_TEST(get_res)
156{
157 ui_t *ui = NULL;
158 ui_window_t *window = NULL;
159 ui_wnd_params_t params;
160 ui_menu_t *menu = NULL;
161 ui_resource_t *res;
162 gfx_rect_t prect;
163 errno_t rc;
164
165 rc = ui_create_disp(NULL, &ui);
166 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
167
168 ui_wnd_params_init(&params);
169 params.caption = "Hello";
170
171 rc = ui_window_create(ui, &params, &window);
172 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
173 PCUT_ASSERT_NOT_NULL(window);
174
175 rc = ui_menu_create(window, &menu);
176 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
177 PCUT_ASSERT_NOT_NULL(menu);
178
179 prect.p0.x = 0;
180 prect.p0.y = 0;
181 prect.p1.x = 0;
182 prect.p1.y = 0;
183
184 /* The menu must be open first */
185 rc = ui_menu_open(menu, &prect, 0);
186 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
187
188 res = ui_menu_get_res(menu);
189 PCUT_ASSERT_NOT_NULL(res);
190
191 ui_menu_destroy(menu);
192
193 ui_window_destroy(window);
194 ui_destroy(ui);
195}
196
197/** Open and close menu with ui_menu_open() / ui_menu_close() */
198PCUT_TEST(open_close)
199{
200 ui_t *ui = NULL;
201 ui_window_t *window = NULL;
202 ui_wnd_params_t params;
203 ui_menu_t *menu = NULL;
204 gfx_rect_t prect;
205 errno_t rc;
206
207 rc = ui_create_disp(NULL, &ui);
208 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
209
210 ui_wnd_params_init(&params);
211 params.caption = "Hello";
212
213 rc = ui_window_create(ui, &params, &window);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215 PCUT_ASSERT_NOT_NULL(window);
216
217 rc = ui_menu_create(window, &menu);
218 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
219 PCUT_ASSERT_NOT_NULL(menu);
220
221 prect.p0.x = 0;
222 prect.p0.y = 0;
223 prect.p1.x = 0;
224 prect.p1.y = 0;
225
226 /* Open and close */
227 rc = ui_menu_open(menu, &prect, 0);
228 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
229
230 ui_menu_close(menu);
231
232 ui_menu_destroy(menu);
233 ui_window_destroy(window);
234 ui_destroy(ui);
235}
236
237/** ui_menu_is_open() correctly returns menu state */
238PCUT_TEST(is_open)
239{
240 ui_t *ui = NULL;
241 ui_window_t *window = NULL;
242 ui_wnd_params_t params;
243 ui_menu_t *menu = NULL;
244 gfx_rect_t prect;
245 bool open;
246 errno_t rc;
247
248 rc = ui_create_disp(NULL, &ui);
249 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
250
251 ui_wnd_params_init(&params);
252 params.caption = "Hello";
253
254 rc = ui_window_create(ui, &params, &window);
255 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
256 PCUT_ASSERT_NOT_NULL(window);
257
258 rc = ui_menu_create(window, &menu);
259 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
260 PCUT_ASSERT_NOT_NULL(menu);
261
262 prect.p0.x = 0;
263 prect.p0.y = 0;
264 prect.p1.x = 0;
265 prect.p1.y = 0;
266
267 open = ui_menu_is_open(menu);
268 PCUT_ASSERT_FALSE(open);
269
270 rc = ui_menu_open(menu, &prect, 0);
271 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
272
273 open = ui_menu_is_open(menu);
274 PCUT_ASSERT_TRUE(open);
275
276 ui_menu_close(menu);
277
278 open = ui_menu_is_open(menu);
279 PCUT_ASSERT_FALSE(open);
280
281 ui_menu_destroy(menu);
282 ui_window_destroy(window);
283 ui_destroy(ui);
284}
285
286/** Paint background in graphics mode */
287PCUT_TEST(paint_bg_gfx)
288{
289 ui_t *ui = NULL;
290 ui_window_t *window = NULL;
291 ui_wnd_params_t params;
292 ui_menu_t *menu = NULL;
293 gfx_rect_t prect;
294 gfx_coord2_t pos;
295 errno_t rc;
296
297 rc = ui_create_disp(NULL, &ui);
298 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
299
300 ui_wnd_params_init(&params);
301 params.caption = "Hello";
302
303 rc = ui_window_create(ui, &params, &window);
304 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
305 PCUT_ASSERT_NOT_NULL(window);
306
307 rc = ui_menu_create(window, &menu);
308 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
309 PCUT_ASSERT_NOT_NULL(menu);
310
311 prect.p0.x = 0;
312 prect.p0.y = 0;
313 prect.p1.x = 0;
314 prect.p1.y = 0;
315
316 /* Menu needs to be open to be able to paint it */
317 rc = ui_menu_open(menu, &prect, 0);
318 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
319
320 pos.x = 0;
321 pos.y = 0;
322 rc = ui_menu_paint_bg_gfx(menu, &pos);
323 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
324
325 ui_window_destroy(window);
326 ui_destroy(ui);
327}
328
329/** Paint background in text mode */
330PCUT_TEST(paint_bg_text)
331{
332 ui_t *ui = NULL;
333 ui_window_t *window = NULL;
334 ui_wnd_params_t params;
335 ui_menu_t *menu = NULL;
336 gfx_rect_t prect;
337 gfx_coord2_t pos;
338 errno_t rc;
339
340 rc = ui_create_disp(NULL, &ui);
341 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
342
343 ui_wnd_params_init(&params);
344 params.caption = "Hello";
345
346 rc = ui_window_create(ui, &params, &window);
347 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
348 PCUT_ASSERT_NOT_NULL(window);
349
350 rc = ui_menu_create(window, &menu);
351 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
352 PCUT_ASSERT_NOT_NULL(menu);
353
354 prect.p0.x = 0;
355 prect.p0.y = 0;
356 prect.p1.x = 0;
357 prect.p1.y = 0;
358
359 /* Menu needs to be open to be able to paint it */
360 rc = ui_menu_open(menu, &prect, 0);
361 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
362
363 pos.x = 0;
364 pos.y = 0;
365 rc = ui_menu_paint_bg_text(menu, &pos);
366 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
367
368 ui_window_destroy(window);
369 ui_destroy(ui);
370}
371
372/** Paint menu */
373PCUT_TEST(paint)
374{
375 ui_t *ui = NULL;
376 ui_window_t *window = NULL;
377 ui_wnd_params_t params;
378 ui_menu_t *menu = NULL;
379 gfx_rect_t prect;
380 gfx_coord2_t pos;
381 errno_t rc;
382
383 rc = ui_create_disp(NULL, &ui);
384 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
385
386 ui_wnd_params_init(&params);
387 params.caption = "Hello";
388
389 rc = ui_window_create(ui, &params, &window);
390 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
391 PCUT_ASSERT_NOT_NULL(window);
392
393 rc = ui_menu_create(window, &menu);
394 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
395 PCUT_ASSERT_NOT_NULL(menu);
396
397 prect.p0.x = 0;
398 prect.p0.y = 0;
399 prect.p1.x = 0;
400 prect.p1.y = 0;
401
402 /* Menu needs to be open to be able to paint it */
403 rc = ui_menu_open(menu, &prect, 0);
404 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
405
406 pos.x = 0;
407 pos.y = 0;
408 rc = ui_menu_paint(menu, &pos);
409 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
410
411 ui_window_destroy(window);
412 ui_destroy(ui);
413}
414
415/** ui_menu_pos_event() inside menu is claimed */
416PCUT_TEST(pos_event_inside)
417{
418 ui_t *ui = NULL;
419 ui_window_t *window = NULL;
420 ui_wnd_params_t params;
421 ui_menu_t *menu = NULL;
422 ui_evclaim_t claimed;
423 gfx_coord2_t pos;
424 pos_event_t event;
425 errno_t rc;
426
427 rc = ui_create_disp(NULL, &ui);
428 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
429
430 ui_wnd_params_init(&params);
431 params.caption = "Hello";
432
433 rc = ui_window_create(ui, &params, &window);
434 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
435 PCUT_ASSERT_NOT_NULL(window);
436
437 rc = ui_menu_create(window, &menu);
438 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
439 PCUT_ASSERT_NOT_NULL(menu);
440
441 pos.x = 0;
442 pos.y = 0;
443 event.type = POS_PRESS;
444 event.hpos = 0;
445 event.vpos = 0;
446 claimed = ui_menu_pos_event(menu, &pos, &event);
447 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
448
449 ui_window_destroy(window);
450 ui_destroy(ui);
451}
452
453/** ui_menu_up() with empty menu does nothing */
454PCUT_TEST(up_empty)
455{
456 ui_t *ui = NULL;
457 ui_window_t *window = NULL;
458 ui_wnd_params_t params;
459 ui_menu_t *menu = NULL;
460 gfx_rect_t prect;
461 errno_t rc;
462
463 rc = ui_create_disp(NULL, &ui);
464 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
465
466 ui_wnd_params_init(&params);
467 params.caption = "Hello";
468
469 rc = ui_window_create(ui, &params, &window);
470 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
471 PCUT_ASSERT_NOT_NULL(window);
472
473 rc = ui_menu_create(window, &menu);
474 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
475 PCUT_ASSERT_NOT_NULL(menu);
476
477 prect.p0.x = 0;
478 prect.p0.y = 0;
479 prect.p1.x = 0;
480 prect.p1.y = 0;
481
482 /* Menu needs to be open to be able to move around it */
483 rc = ui_menu_open(menu, &prect, 0);
484 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
485
486 ui_menu_up(menu);
487
488 ui_window_destroy(window);
489 ui_destroy(ui);
490}
491
492/** ui_menu_up() moves one entry up, skips separators, wraps around */
493PCUT_TEST(up)
494{
495 ui_t *ui = NULL;
496 ui_window_t *window = NULL;
497 ui_wnd_params_t params;
498 ui_menu_t *menu = NULL;
499 ui_menu_entry_t *mentry1 = NULL;
500 ui_menu_entry_t *mentry2 = NULL;
501 ui_menu_entry_t *mentry3 = NULL;
502 gfx_rect_t prect;
503 errno_t rc;
504
505 rc = ui_create_disp(NULL, &ui);
506 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
507
508 ui_wnd_params_init(&params);
509 params.caption = "Hello";
510
511 rc = ui_window_create(ui, &params, &window);
512 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
513 PCUT_ASSERT_NOT_NULL(window);
514
515 rc = ui_menu_create(window, &menu);
516 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
517 PCUT_ASSERT_NOT_NULL(menu);
518
519 rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry1);
520 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
521 PCUT_ASSERT_NOT_NULL(mentry1);
522
523 rc = ui_menu_entry_sep_create(menu, &mentry2);
524 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
525 PCUT_ASSERT_NOT_NULL(mentry2);
526
527 rc = ui_menu_entry_create(menu, "Bar", "F2", &mentry3);
528 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
529 PCUT_ASSERT_NOT_NULL(mentry3);
530
531 prect.p0.x = 0;
532 prect.p0.y = 0;
533 prect.p1.x = 0;
534 prect.p1.y = 0;
535
536 /* Menu needs to be open to be able to move around it */
537 rc = ui_menu_open(menu, &prect, 0);
538 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
539
540 /* When menu is open, the first entry is selected */
541 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
542
543 ui_menu_up(menu);
544
545 /* Now we've wrapped around to the last entry */
546 PCUT_ASSERT_EQUALS(mentry3, menu->selected);
547
548 ui_menu_up(menu);
549
550 /* mentry2 is a separator and was skipped */
551 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
552
553 ui_window_destroy(window);
554 ui_destroy(ui);
555}
556
557/** ui_menu_down() with empty menu does nothing */
558PCUT_TEST(down_empty)
559{
560 ui_t *ui = NULL;
561 ui_window_t *window = NULL;
562 ui_wnd_params_t params;
563 ui_menu_t *menu = NULL;
564 gfx_rect_t prect;
565 errno_t rc;
566
567 rc = ui_create_disp(NULL, &ui);
568 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
569
570 ui_wnd_params_init(&params);
571 params.caption = "Hello";
572
573 rc = ui_window_create(ui, &params, &window);
574 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
575 PCUT_ASSERT_NOT_NULL(window);
576
577 rc = ui_menu_create(window, &menu);
578 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
579 PCUT_ASSERT_NOT_NULL(menu);
580
581 prect.p0.x = 0;
582 prect.p0.y = 0;
583 prect.p1.x = 0;
584 prect.p1.y = 0;
585
586 /* Menu needs to be open to be able to move around it */
587 rc = ui_menu_open(menu, &prect, 0);
588 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
589
590 ui_menu_down(menu);
591
592 ui_window_destroy(window);
593 ui_destroy(ui);
594}
595
596/** ui_menu_down() moves one entry down, skips separators, wraps around */
597PCUT_TEST(down)
598{
599 ui_t *ui = NULL;
600 ui_window_t *window = NULL;
601 ui_wnd_params_t params;
602 ui_menu_t *menu = NULL;
603 ui_menu_entry_t *mentry1 = NULL;
604 ui_menu_entry_t *mentry2 = NULL;
605 ui_menu_entry_t *mentry3 = NULL;
606 gfx_rect_t prect;
607 errno_t rc;
608
609 rc = ui_create_disp(NULL, &ui);
610 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
611
612 ui_wnd_params_init(&params);
613 params.caption = "Hello";
614
615 rc = ui_window_create(ui, &params, &window);
616 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
617 PCUT_ASSERT_NOT_NULL(window);
618
619 rc = ui_menu_create(window, &menu);
620 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
621 PCUT_ASSERT_NOT_NULL(menu);
622
623 rc = ui_menu_entry_create(menu, "Foo", "F1", &mentry1);
624 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
625 PCUT_ASSERT_NOT_NULL(mentry1);
626
627 rc = ui_menu_entry_sep_create(menu, &mentry2);
628 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
629 PCUT_ASSERT_NOT_NULL(mentry2);
630
631 rc = ui_menu_entry_create(menu, "Bar", "F2", &mentry3);
632 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
633 PCUT_ASSERT_NOT_NULL(mentry3);
634
635 prect.p0.x = 0;
636 prect.p0.y = 0;
637 prect.p1.x = 0;
638 prect.p1.y = 0;
639
640 /* Menu needs to be open to be able to move around it */
641 rc = ui_menu_open(menu, &prect, 0);
642 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
643
644 /* When menu is open, the first entry is selected */
645 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
646
647 ui_menu_down(menu);
648
649 /* mentry2 is a separator and was skipped */
650 PCUT_ASSERT_EQUALS(mentry3, menu->selected);
651
652 ui_menu_up(menu);
653
654 /* Now we've wrapped around to the first entry */
655 PCUT_ASSERT_EQUALS(mentry1, menu->selected);
656
657 ui_window_destroy(window);
658 ui_destroy(ui);
659}
660
661/** Sending an unhandled event does nothing. */
662PCUT_TEST(send_unhandled)
663{
664 ui_menu_t *menu = NULL;
665 errno_t rc;
666 sysarg_t idev_id;
667 char32_t c;
668
669 rc = ui_menu_create(NULL, &menu);
670 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
671 PCUT_ASSERT_NOT_NULL(menu);
672
673 /* Send events without setting callback */
674 c = 'A';
675 idev_id = 42;
676 ui_menu_left(menu, idev_id);
677 ui_menu_right(menu, idev_id);
678 ui_menu_close_req(menu);
679 ui_menu_press_accel(menu, c, idev_id);
680
681 /* Set dummy callback structure */
682 ui_menu_set_cb(menu, &dummy_cb, NULL);
683
684 /* Send unhandled events */
685 ui_menu_left(menu, idev_id);
686 ui_menu_right(menu, idev_id);
687 ui_menu_close_req(menu);
688 ui_menu_press_accel(menu, c, idev_id);
689
690 ui_menu_destroy(menu);
691}
692
693/** ui_menu_left() sends left event */
694PCUT_TEST(left)
695{
696 ui_menu_t *menu = NULL;
697 errno_t rc;
698 test_resp_t resp;
699 sysarg_t idev_id;
700
701 rc = ui_menu_create(NULL, &menu);
702 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
703 PCUT_ASSERT_NOT_NULL(menu);
704
705 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
706
707 memset(&resp, 0, sizeof(resp));
708 PCUT_ASSERT_FALSE(resp.left_called);
709
710 idev_id = 42;
711 ui_menu_left(menu, idev_id);
712
713 PCUT_ASSERT_TRUE(resp.left_called);
714 PCUT_ASSERT_EQUALS(menu, resp.menu);
715 PCUT_ASSERT_INT_EQUALS(idev_id, resp.idev_id);
716
717 ui_menu_destroy(menu);
718}
719
720/** ui_menu_right() sends right event */
721PCUT_TEST(right)
722{
723 ui_menu_t *menu = NULL;
724 errno_t rc;
725 test_resp_t resp;
726 sysarg_t idev_id;
727
728 rc = ui_menu_create(NULL, &menu);
729 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
730 PCUT_ASSERT_NOT_NULL(menu);
731
732 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
733
734 memset(&resp, 0, sizeof(resp));
735 PCUT_ASSERT_FALSE(resp.right_called);
736
737 idev_id = 42;
738 ui_menu_right(menu, idev_id);
739
740 PCUT_ASSERT_TRUE(resp.right_called);
741 PCUT_ASSERT_EQUALS(menu, resp.menu);
742 PCUT_ASSERT_INT_EQUALS(idev_id, resp.idev_id);
743
744 ui_menu_destroy(menu);
745}
746
747/** ui_menu_close_req() sends close_req event */
748PCUT_TEST(close_req)
749{
750 ui_menu_t *menu = NULL;
751 errno_t rc;
752 test_resp_t resp;
753
754 rc = ui_menu_create(NULL, &menu);
755 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
756 PCUT_ASSERT_NOT_NULL(menu);
757
758 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
759
760 memset(&resp, 0, sizeof(resp));
761 PCUT_ASSERT_FALSE(resp.close_req_called);
762
763 ui_menu_close_req(menu);
764
765 PCUT_ASSERT_TRUE(resp.close_req_called);
766 PCUT_ASSERT_EQUALS(menu, resp.menu);
767
768 ui_menu_destroy(menu);
769}
770
771/** ui_menu_press_accel() sends press_accel event */
772PCUT_TEST(press_accel)
773{
774 ui_menu_t *menu = NULL;
775 errno_t rc;
776 test_resp_t resp;
777 char32_t c;
778 sysarg_t idev_id;
779
780 rc = ui_menu_create(NULL, &menu);
781 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
782 PCUT_ASSERT_NOT_NULL(menu);
783
784 ui_menu_set_cb(menu, &testmenu_cb, (void *)&resp);
785
786 memset(&resp, 0, sizeof(resp));
787 PCUT_ASSERT_FALSE(resp.press_accel_called);
788
789 c = 'A';
790 idev_id = 42;
791 ui_menu_press_accel(menu, c, idev_id);
792
793 PCUT_ASSERT_TRUE(resp.press_accel_called);
794 PCUT_ASSERT_EQUALS(menu, resp.menu);
795 PCUT_ASSERT_EQUALS(c, resp.c);
796 PCUT_ASSERT_INT_EQUALS(idev_id, resp.idev_id);
797
798 ui_menu_destroy(menu);
799}
800
801/** Test menu left callback */
802static void testmenu_left(ui_menu_t *menu, void *arg, sysarg_t idev_id)
803{
804 test_resp_t *resp = (test_resp_t *)arg;
805
806 resp->left_called = true;
807 resp->menu = menu;
808 resp->idev_id = idev_id;
809}
810
811/** Test menu right callback */
812static void testmenu_right(ui_menu_t *menu, void *arg, sysarg_t idev_id)
813{
814 test_resp_t *resp = (test_resp_t *)arg;
815
816 resp->right_called = true;
817 resp->menu = menu;
818 resp->idev_id = idev_id;
819}
820
821/** Test menu close callback */
822static void testmenu_close_req(ui_menu_t *menu, void *arg)
823{
824 test_resp_t *resp = (test_resp_t *)arg;
825
826 resp->close_req_called = true;
827 resp->menu = menu;
828}
829
830/** Test menu press accel callback */
831static void testmenu_press_accel(ui_menu_t *menu, void *arg,
832 char32_t c, sysarg_t kbd_id)
833{
834 test_resp_t *resp = (test_resp_t *)arg;
835
836 resp->press_accel_called = true;
837 resp->menu = menu;
838 resp->c = c;
839 resp->idev_id = kbd_id;
840}
841
842PCUT_EXPORT(menu);
Note: See TracBrowser for help on using the repository browser.