source: mainline/uspace/lib/ui/test/menubar.c@ 252d03c

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 252d03c was 95a9cbc, checked in by jxsvoboda <5887334+jxsvoboda@…>, 5 years ago

UI menu unit tests

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * Copyright (c) 2021 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/menu.h>
36#include <ui/menubar.h>
37#include <ui/resource.h>
38#include <ui/ui.h>
39#include "../private/dummygc.h"
40#include "../private/menubar.h"
41
42PCUT_INIT;
43
44PCUT_TEST_SUITE(menubar);
45
46/** Create and destroy menu bar */
47PCUT_TEST(create_destroy)
48{
49 ui_menu_bar_t *mbar = NULL;
50 errno_t rc;
51
52 rc = ui_menu_bar_create(NULL, &mbar);
53 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
54 PCUT_ASSERT_NOT_NULL(mbar);
55
56 ui_menu_bar_destroy(mbar);
57}
58
59/** ui_menu_bar_destroy() can take NULL argument (no-op) */
60PCUT_TEST(destroy_null)
61{
62 ui_menu_bar_destroy(NULL);
63}
64
65/** ui_menu_bar_ctl() returns control that has a working virtual destructor */
66PCUT_TEST(ctl)
67{
68 ui_menu_bar_t *mbar = NULL;
69 ui_control_t *control;
70 errno_t rc;
71
72 rc = ui_menu_bar_create(NULL, &mbar);
73 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
74 PCUT_ASSERT_NOT_NULL(mbar);
75
76 control = ui_menu_bar_ctl(mbar);
77 PCUT_ASSERT_NOT_NULL(control);
78
79 ui_control_destroy(control);
80}
81
82/** Set menu bar rectangle sets internal field */
83PCUT_TEST(set_rect)
84{
85 errno_t rc;
86 dummy_gc_t *dgc;
87 gfx_context_t *gc;
88 ui_resource_t *resource = NULL;
89 ui_menu_bar_t *mbar = NULL;
90 gfx_rect_t rect;
91
92 rc = dummygc_create(&dgc);
93 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
94
95 gc = dummygc_get_ctx(dgc);
96
97 rc = ui_resource_create(gc, false, &resource);
98 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
99 PCUT_ASSERT_NOT_NULL(resource);
100
101 rc = ui_menu_bar_create(resource, &mbar);
102 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
103 PCUT_ASSERT_NOT_NULL(mbar);
104
105 rect.p0.x = 1;
106 rect.p0.y = 2;
107 rect.p1.x = 3;
108 rect.p1.y = 4;
109
110 ui_menu_bar_set_rect(mbar, &rect);
111 PCUT_ASSERT_INT_EQUALS(rect.p0.x, mbar->rect.p0.x);
112 PCUT_ASSERT_INT_EQUALS(rect.p0.y, mbar->rect.p0.y);
113 PCUT_ASSERT_INT_EQUALS(rect.p1.x, mbar->rect.p1.x);
114 PCUT_ASSERT_INT_EQUALS(rect.p1.y, mbar->rect.p1.y);
115
116 ui_menu_bar_destroy(mbar);
117 ui_resource_destroy(resource);
118 dummygc_destroy(dgc);
119}
120
121/** Paint menu bar */
122PCUT_TEST(paint)
123{
124 dummy_gc_t *dgc;
125 gfx_context_t *gc;
126 ui_resource_t *resource = NULL;
127 ui_menu_bar_t *mbar = NULL;
128 errno_t rc;
129
130 rc = dummygc_create(&dgc);
131 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
132
133 gc = dummygc_get_ctx(dgc);
134
135 rc = ui_resource_create(gc, false, &resource);
136 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
137 PCUT_ASSERT_NOT_NULL(resource);
138
139 rc = ui_menu_bar_create(resource, &mbar);
140 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
141 PCUT_ASSERT_NOT_NULL(mbar);
142
143 rc = ui_menu_bar_paint(mbar);
144 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
145
146 ui_menu_bar_destroy(mbar);
147 ui_resource_destroy(resource);
148 dummygc_destroy(dgc);
149}
150
151/** Press event on menu bar entry selects menu */
152PCUT_TEST(pos_event_select)
153{
154 dummy_gc_t *dgc;
155 gfx_context_t *gc;
156 ui_resource_t *resource = NULL;
157 ui_menu_bar_t *mbar = NULL;
158 ui_menu_t *menu = NULL;
159 ui_evclaim_t claimed;
160 pos_event_t event;
161 gfx_rect_t rect;
162 errno_t rc;
163
164 rc = dummygc_create(&dgc);
165 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
166
167 gc = dummygc_get_ctx(dgc);
168
169 rc = ui_resource_create(gc, false, &resource);
170 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
171 PCUT_ASSERT_NOT_NULL(resource);
172
173 rc = ui_menu_bar_create(resource, &mbar);
174 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
175 PCUT_ASSERT_NOT_NULL(mbar);
176
177 rect.p0.x = 0;
178 rect.p0.y = 0;
179 rect.p1.x = 50;
180 rect.p1.y = 25;
181 ui_menu_bar_set_rect(mbar, &rect);
182
183 rc = ui_menu_create(mbar, "Test", &menu);
184 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
185 PCUT_ASSERT_NOT_NULL(menu);
186
187 event.type = POS_PRESS;
188 event.hpos = 4;
189 event.vpos = 4;
190 claimed = ui_menu_bar_pos_event(mbar, &event);
191 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
192 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
193
194 /* Clicking the menu bar entry should select menu */
195 PCUT_ASSERT_EQUALS(menu, mbar->selected);
196
197 ui_menu_bar_destroy(mbar);
198 ui_resource_destroy(resource);
199 dummygc_destroy(dgc);
200}
201
202/** Position event is forwarded to menu */
203PCUT_TEST(pos_event_menu)
204{
205 dummy_gc_t *dgc;
206 gfx_context_t *gc;
207 ui_resource_t *resource = NULL;
208 ui_menu_bar_t *mbar = NULL;
209 ui_menu_t *menu = NULL;
210 ui_evclaim_t claimed;
211 pos_event_t event;
212 gfx_coord2_t pos;
213 gfx_rect_t rect;
214 errno_t rc;
215
216 rc = dummygc_create(&dgc);
217 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
218
219 gc = dummygc_get_ctx(dgc);
220
221 rc = ui_resource_create(gc, false, &resource);
222 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
223 PCUT_ASSERT_NOT_NULL(resource);
224
225 rc = ui_menu_bar_create(resource, &mbar);
226 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
227 PCUT_ASSERT_NOT_NULL(mbar);
228
229 rect.p0.x = 0;
230 rect.p0.y = 0;
231 rect.p1.x = 50;
232 rect.p1.y = 25;
233 ui_menu_bar_set_rect(mbar, &rect);
234
235 rc = ui_menu_create(mbar, "Test", &menu);
236 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
237 PCUT_ASSERT_NOT_NULL(menu);
238
239 pos.x = 0;
240 pos.y = 0;
241 ui_menu_bar_select(mbar, &pos, menu);
242 PCUT_ASSERT_EQUALS(menu, mbar->selected);
243
244 event.type = POS_PRESS;
245 event.hpos = 4;
246 event.vpos = 30;
247 claimed = ui_menu_bar_pos_event(mbar, &event);
248 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
249 PCUT_ASSERT_EQUALS(ui_claimed, claimed);
250
251 ui_menu_bar_destroy(mbar);
252 ui_resource_destroy(resource);
253 dummygc_destroy(dgc);
254}
255
256/* Unfocusing window closes open menu */
257PCUT_TEST(unfocus)
258{
259 dummy_gc_t *dgc;
260 gfx_context_t *gc;
261 ui_resource_t *resource = NULL;
262 ui_menu_bar_t *mbar = NULL;
263 ui_menu_t *menu = NULL;
264 gfx_coord2_t pos;
265 errno_t rc;
266
267 rc = dummygc_create(&dgc);
268 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
269
270 gc = dummygc_get_ctx(dgc);
271
272 rc = ui_resource_create(gc, false, &resource);
273 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
274 PCUT_ASSERT_NOT_NULL(resource);
275
276 rc = ui_menu_bar_create(resource, &mbar);
277 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
278 PCUT_ASSERT_NOT_NULL(mbar);
279
280 rc = ui_menu_create(mbar, "Test", &menu);
281 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
282 PCUT_ASSERT_NOT_NULL(menu);
283
284 /*
285 * Position does not matter here. Probably should get rid of this
286 * argument, storing the position in the menu itself.
287 */
288 pos.x = 0;
289 pos.y = 0;
290 ui_menu_bar_select(mbar, &pos, menu);
291 PCUT_ASSERT_EQUALS(menu, mbar->selected);
292
293 /* This should unselect the menu */
294 ui_menu_bar_unfocus(mbar);
295 PCUT_ASSERT_NULL(mbar->selected);
296
297 ui_menu_bar_destroy(mbar);
298 ui_resource_destroy(resource);
299 dummygc_destroy(dgc);
300}
301
302/** Calling ui_menu_bar_select() with the same menu twice deselects it */
303PCUT_TEST(select_same)
304{
305 dummy_gc_t *dgc;
306 gfx_context_t *gc;
307 ui_resource_t *resource = NULL;
308 ui_menu_bar_t *mbar = NULL;
309 ui_menu_t *menu = NULL;
310 gfx_coord2_t pos;
311 errno_t rc;
312
313 rc = dummygc_create(&dgc);
314 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
315
316 gc = dummygc_get_ctx(dgc);
317
318 rc = ui_resource_create(gc, false, &resource);
319 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
320 PCUT_ASSERT_NOT_NULL(resource);
321
322 rc = ui_menu_bar_create(resource, &mbar);
323 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
324 PCUT_ASSERT_NOT_NULL(mbar);
325
326 rc = ui_menu_create(mbar, "Test", &menu);
327 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
328 PCUT_ASSERT_NOT_NULL(menu);
329
330 pos.x = 0;
331 pos.y = 0;
332 ui_menu_bar_select(mbar, &pos, menu);
333 PCUT_ASSERT_EQUALS(menu, mbar->selected);
334
335 /* Selecting again should unselect the menu */
336 ui_menu_bar_select(mbar, &pos, menu);
337 PCUT_ASSERT_NULL(mbar->selected);
338
339 ui_menu_bar_destroy(mbar);
340 ui_resource_destroy(resource);
341 dummygc_destroy(dgc);
342}
343
344/** Calling ui_menu_bar_select() with another menu selects it */
345PCUT_TEST(select_different)
346{
347 dummy_gc_t *dgc;
348 gfx_context_t *gc;
349 ui_resource_t *resource = NULL;
350 ui_menu_bar_t *mbar = NULL;
351 ui_menu_t *menu1 = NULL;
352 ui_menu_t *menu2 = NULL;
353 gfx_coord2_t pos;
354 errno_t rc;
355
356 rc = dummygc_create(&dgc);
357 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
358
359 gc = dummygc_get_ctx(dgc);
360
361 rc = ui_resource_create(gc, false, &resource);
362 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
363 PCUT_ASSERT_NOT_NULL(resource);
364
365 rc = ui_menu_bar_create(resource, &mbar);
366 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
367 PCUT_ASSERT_NOT_NULL(mbar);
368
369 rc = ui_menu_create(mbar, "Test 1", &menu1);
370 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
371 PCUT_ASSERT_NOT_NULL(menu1);
372
373 rc = ui_menu_create(mbar, "Test 2", &menu2);
374 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
375 PCUT_ASSERT_NOT_NULL(menu2);
376
377 pos.x = 0;
378 pos.y = 0;
379 ui_menu_bar_select(mbar, &pos, menu1);
380 PCUT_ASSERT_EQUALS(menu1, mbar->selected);
381
382 /* Selecting different menu should select it */
383 ui_menu_bar_select(mbar, &pos, menu2);
384 PCUT_ASSERT_EQUALS(menu2, mbar->selected);
385
386 ui_menu_bar_destroy(mbar);
387 ui_resource_destroy(resource);
388 dummygc_destroy(dgc);
389}
390
391PCUT_EXPORT(menubar);
Note: See TracBrowser for help on using the repository browser.