source: mainline/uspace/lib/ui/test/slider.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: 10.1 KB
Line 
1/*
2 * Copyright (c) 2022 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/slider.h>
36#include <ui/resource.h>
37#include "../private/slider.h"
38#include "../private/testgc.h"
39
40PCUT_INIT;
41
42PCUT_TEST_SUITE(slider);
43
44static void test_slider_moved(ui_slider_t *, void *, gfx_coord_t);
45
46static ui_slider_cb_t test_slider_cb = {
47 .moved = test_slider_moved
48};
49
50static ui_slider_cb_t dummy_slider_cb = {
51};
52
53typedef struct {
54 bool moved;
55 gfx_coord_t pos;
56} test_cb_resp_t;
57
58/** Create and destroy slider */
59PCUT_TEST(create_destroy)
60{
61 ui_slider_t *slider = NULL;
62 errno_t rc;
63
64 rc = ui_slider_create(NULL, &slider);
65 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
66 PCUT_ASSERT_NOT_NULL(slider);
67
68 ui_slider_destroy(slider);
69}
70
71/** ui_slider_destroy() can take NULL argument (no-op) */
72PCUT_TEST(destroy_null)
73{
74 ui_slider_destroy(NULL);
75}
76
77/** ui_slider_ctl() returns control that has a working virtual destructor */
78PCUT_TEST(ctl)
79{
80 ui_slider_t *slider;
81 ui_control_t *control;
82 errno_t rc;
83
84 rc = ui_slider_create(NULL, &slider);
85 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
86
87 control = ui_slider_ctl(slider);
88 PCUT_ASSERT_NOT_NULL(control);
89
90 ui_control_destroy(control);
91}
92
93/** Set slider rectangle sets internal field */
94PCUT_TEST(set_rect)
95{
96 ui_slider_t *slider;
97 gfx_rect_t rect;
98 errno_t rc;
99
100 rc = ui_slider_create(NULL, &slider);
101 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
102
103 rect.p0.x = 1;
104 rect.p0.y = 2;
105 rect.p1.x = 3;
106 rect.p1.y = 4;
107
108 ui_slider_set_rect(slider, &rect);
109 PCUT_ASSERT_INT_EQUALS(rect.p0.x, slider->rect.p0.x);
110 PCUT_ASSERT_INT_EQUALS(rect.p0.y, slider->rect.p0.y);
111 PCUT_ASSERT_INT_EQUALS(rect.p1.x, slider->rect.p1.x);
112 PCUT_ASSERT_INT_EQUALS(rect.p1.y, slider->rect.p1.y);
113
114 ui_slider_destroy(slider);
115}
116
117/** Paint slider in graphics mode */
118PCUT_TEST(paint_gfx)
119{
120 errno_t rc;
121 gfx_context_t *gc = NULL;
122 test_gc_t tgc;
123 ui_resource_t *resource = NULL;
124 ui_slider_t *slider;
125
126 memset(&tgc, 0, sizeof(tgc));
127 rc = gfx_context_new(&ops, &tgc, &gc);
128 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
129
130 rc = ui_resource_create(gc, false, &resource);
131 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
132 PCUT_ASSERT_NOT_NULL(resource);
133
134 rc = ui_slider_create(resource, &slider);
135 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
136
137 rc = ui_slider_paint_gfx(slider);
138 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
139
140 ui_slider_destroy(slider);
141 ui_resource_destroy(resource);
142
143 rc = gfx_context_delete(gc);
144 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
145}
146
147/** Paint slider in text mode */
148PCUT_TEST(paint_text)
149{
150 errno_t rc;
151 gfx_context_t *gc = NULL;
152 test_gc_t tgc;
153 ui_resource_t *resource = NULL;
154 ui_slider_t *slider;
155
156 memset(&tgc, 0, sizeof(tgc));
157 rc = gfx_context_new(&ops, &tgc, &gc);
158 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
159
160 rc = ui_resource_create(gc, false, &resource);
161 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
162 PCUT_ASSERT_NOT_NULL(resource);
163
164 rc = ui_slider_create(resource, &slider);
165 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
166
167 rc = ui_slider_paint_text(slider);
168 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
169
170 ui_slider_destroy(slider);
171 ui_resource_destroy(resource);
172
173 rc = gfx_context_delete(gc);
174 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
175}
176
177/** Test ui_slider_moved() */
178PCUT_TEST(moved)
179{
180 errno_t rc;
181 ui_slider_t *slider;
182 test_cb_resp_t resp;
183
184 rc = ui_slider_create(NULL, &slider);
185 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
186
187 /* Moved with no callbacks set */
188 ui_slider_moved(slider, 42);
189
190 /* Moved with callback not implementing moved */
191 ui_slider_set_cb(slider, &dummy_slider_cb, NULL);
192 ui_slider_moved(slider, 42);
193
194 /* Moved with real callback set */
195 resp.moved = false;
196 resp.pos = 0;
197 ui_slider_set_cb(slider, &test_slider_cb, &resp);
198 ui_slider_moved(slider, 42);
199 PCUT_ASSERT_TRUE(resp.moved);
200 PCUT_ASSERT_INT_EQUALS(42, resp.pos);
201
202 ui_slider_destroy(slider);
203}
204
205/** Press and release slider */
206PCUT_TEST(press_release)
207{
208 errno_t rc;
209 gfx_context_t *gc = NULL;
210 test_gc_t tgc;
211 ui_resource_t *resource = NULL;
212 gfx_coord2_t pos;
213 gfx_rect_t rect;
214 ui_slider_t *slider;
215 test_cb_resp_t resp;
216
217 memset(&tgc, 0, sizeof(tgc));
218 rc = gfx_context_new(&ops, &tgc, &gc);
219 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
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_slider_create(resource, &slider);
226 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
227
228 rect.p0.x = 10;
229 rect.p0.y = 20;
230 rect.p1.x = 110;
231 rect.p1.y = 120;
232 ui_slider_set_rect(slider, &rect);
233
234 resp.moved = false;
235 ui_slider_set_cb(slider, &test_slider_cb, &resp);
236
237 PCUT_ASSERT_FALSE(slider->held);
238
239 pos.x = 11;
240 pos.y = 22;
241
242 ui_slider_press(slider, &pos);
243 PCUT_ASSERT_TRUE(slider->held);
244 PCUT_ASSERT_FALSE(resp.moved);
245
246 pos.x = 21;
247 pos.y = 32;
248
249 ui_slider_release(slider, &pos);
250 PCUT_ASSERT_FALSE(slider->held);
251 PCUT_ASSERT_TRUE(resp.moved);
252 PCUT_ASSERT_INT_EQUALS(10, slider->pos);
253
254 ui_slider_destroy(slider);
255 ui_resource_destroy(resource);
256
257 rc = gfx_context_delete(gc);
258 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
259}
260
261/** Press, update and release slider */
262PCUT_TEST(press_uodate_release)
263{
264 errno_t rc;
265 gfx_context_t *gc = NULL;
266 test_gc_t tgc;
267 ui_resource_t *resource = NULL;
268 gfx_coord2_t pos;
269 gfx_rect_t rect;
270 ui_slider_t *slider;
271 test_cb_resp_t resp;
272
273 memset(&tgc, 0, sizeof(tgc));
274 rc = gfx_context_new(&ops, &tgc, &gc);
275 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
276
277 rc = ui_resource_create(gc, false, &resource);
278 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
279 PCUT_ASSERT_NOT_NULL(resource);
280
281 rc = ui_slider_create(resource, &slider);
282 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
283
284 rect.p0.x = 10;
285 rect.p0.y = 20;
286 rect.p1.x = 110;
287 rect.p1.y = 120;
288 ui_slider_set_rect(slider, &rect);
289
290 resp.moved = false;
291 ui_slider_set_cb(slider, &test_slider_cb, &resp);
292
293 PCUT_ASSERT_FALSE(slider->held);
294
295 pos.x = 11;
296 pos.y = 22;
297
298 ui_slider_press(slider, &pos);
299 PCUT_ASSERT_TRUE(slider->held);
300 PCUT_ASSERT_FALSE(resp.moved);
301
302 pos.x = 21;
303 pos.y = 32;
304
305 ui_slider_update(slider, &pos);
306 PCUT_ASSERT_TRUE(slider->held);
307 PCUT_ASSERT_TRUE(resp.moved);
308 PCUT_ASSERT_INT_EQUALS(10, slider->pos);
309
310 pos.x = 31;
311 pos.y = 42;
312
313 ui_slider_release(slider, &pos);
314 PCUT_ASSERT_FALSE(slider->held);
315 PCUT_ASSERT_TRUE(resp.moved);
316 PCUT_ASSERT_INT_EQUALS(20, slider->pos);
317
318 ui_slider_destroy(slider);
319 ui_resource_destroy(resource);
320
321 rc = gfx_context_delete(gc);
322 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
323}
324
325/** ui_pos_event() correctly translates POS_PRESS/POS_RELEASE */
326PCUT_TEST(pos_event_press_release)
327{
328 errno_t rc;
329 gfx_context_t *gc = NULL;
330 test_gc_t tgc;
331 ui_resource_t *resource = NULL;
332 ui_slider_t *slider;
333 ui_evclaim_t claim;
334 pos_event_t event;
335 gfx_rect_t rect;
336
337 memset(&tgc, 0, sizeof(tgc));
338 rc = gfx_context_new(&ops, &tgc, &gc);
339 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
340
341 rc = ui_resource_create(gc, false, &resource);
342 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
343 PCUT_ASSERT_NOT_NULL(resource);
344
345 rc = ui_slider_create(resource, &slider);
346 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
347
348 PCUT_ASSERT_FALSE(slider->held);
349
350 rect.p0.x = 10;
351 rect.p0.y = 20;
352 rect.p1.x = 30;
353 rect.p1.y = 40;
354 ui_slider_set_rect(slider, &rect);
355
356 /* Press outside is not claimed and does nothing */
357 event.type = POS_PRESS;
358 event.hpos = 1;
359 event.vpos = 2;
360 claim = ui_slider_pos_event(slider, &event);
361 PCUT_ASSERT_FALSE(slider->held);
362 PCUT_ASSERT_EQUALS(ui_unclaimed, claim);
363
364 /* Press inside is claimed and depresses slider */
365 event.type = POS_PRESS;
366 event.hpos = 11;
367 event.vpos = 22;
368 claim = ui_slider_pos_event(slider, &event);
369 PCUT_ASSERT_TRUE(slider->held);
370 PCUT_ASSERT_EQUALS(ui_claimed, claim);
371
372 /* Release outside (or anywhere) is claimed and relases slider */
373 event.type = POS_RELEASE;
374 event.hpos = 41;
375 event.vpos = 32;
376 claim = ui_slider_pos_event(slider, &event);
377 PCUT_ASSERT_FALSE(slider->held);
378 PCUT_ASSERT_EQUALS(ui_claimed, claim);
379
380 ui_slider_destroy(slider);
381 ui_resource_destroy(resource);
382
383 rc = gfx_context_delete(gc);
384 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
385}
386
387/** ui_slider_length() correctly determines slider length */
388PCUT_TEST(length)
389{
390 errno_t rc;
391 gfx_context_t *gc = NULL;
392 test_gc_t tgc;
393 ui_resource_t *resource = NULL;
394 ui_slider_t *slider;
395 gfx_coord_t length;
396 gfx_rect_t rect;
397
398 memset(&tgc, 0, sizeof(tgc));
399 rc = gfx_context_new(&ops, &tgc, &gc);
400 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
401
402 rc = ui_resource_create(gc, false, &resource);
403 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
404 PCUT_ASSERT_NOT_NULL(resource);
405
406 rc = ui_slider_create(resource, &slider);
407 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
408
409 PCUT_ASSERT_FALSE(slider->held);
410
411 rect.p0.x = 10;
412 rect.p0.y = 20;
413 rect.p1.x = 110;
414 rect.p1.y = 120;
415 ui_slider_set_rect(slider, &rect);
416
417 length = ui_slider_length(slider);
418 PCUT_ASSERT_INT_EQUALS(110 - 10 - 15, length);
419
420 ui_slider_destroy(slider);
421 ui_resource_destroy(resource);
422
423 rc = gfx_context_delete(gc);
424 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
425}
426
427static void test_slider_moved(ui_slider_t *slider, void *arg, gfx_coord_t pos)
428{
429 test_cb_resp_t *resp = (test_cb_resp_t *) arg;
430
431 resp->moved = true;
432 resp->pos = pos;
433}
434
435PCUT_EXPORT(slider);
Note: See TracBrowser for help on using the repository browser.