]>
Commit | Line | Data |
---|---|---|
fe93c14b SG |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright 2022 Google LLC | |
4 | * Written by Simon Glass <sjg@chromium.org> | |
5 | */ | |
6 | ||
d678a59d | 7 | #include <common.h> |
87c1a413 | 8 | #include <command.h> |
fe93c14b SG |
9 | #include <dm.h> |
10 | #include <expo.h> | |
11 | #include <menu.h> | |
12 | #include <video.h> | |
13 | #include <linux/input.h> | |
14 | #include <test/suites.h> | |
15 | #include <test/ut.h> | |
16 | #include "bootstd_common.h" | |
82cafee1 | 17 | #include <test/cedit-test.h> |
fe93c14b SG |
18 | #include "../../boot/scene_internal.h" |
19 | ||
20 | enum { | |
21 | /* scenes */ | |
22 | SCENE1 = 7, | |
23 | SCENE2, | |
24 | ||
25 | /* objects */ | |
26 | OBJ_LOGO, | |
27 | OBJ_TEXT, | |
28 | OBJ_TEXT2, | |
29 | OBJ_MENU, | |
30 | OBJ_MENU_TITLE, | |
31 | ||
32 | /* strings */ | |
def898c4 SG |
33 | STR_SCENE_TITLE, |
34 | ||
fe93c14b SG |
35 | STR_TEXT, |
36 | STR_TEXT2, | |
37 | STR_MENU_TITLE, | |
38 | STR_POINTER_TEXT, | |
39 | ||
40 | STR_ITEM1_LABEL, | |
41 | STR_ITEM1_DESC, | |
42 | STR_ITEM1_KEY, | |
43 | STR_ITEM1_PREVIEW, | |
44 | ||
45 | STR_ITEM2_LABEL, | |
46 | STR_ITEM2_DESC, | |
47 | STR_ITEM2_KEY, | |
48 | STR_ITEM2_PREVIEW, | |
49 | ||
50 | /* menu items */ | |
51 | ITEM1, | |
52 | ITEM1_LABEL, | |
53 | ITEM1_DESC, | |
54 | ITEM1_KEY, | |
55 | ITEM1_PREVIEW, | |
56 | ||
57 | ITEM2, | |
58 | ITEM2_LABEL, | |
59 | ITEM2_DESC, | |
60 | ITEM2_KEY, | |
61 | ITEM2_PREVIEW, | |
62 | ||
63 | /* pointer to current item */ | |
64 | POINTER_TEXT, | |
65 | }; | |
66 | ||
67 | #define BAD_POINTER ((void *)1) | |
68 | ||
69 | /* names for various things */ | |
70 | #define EXPO_NAME "my menus" | |
71 | #define SCENE_NAME1 "main" | |
72 | #define SCENE_NAME2 "second" | |
73 | #define SCENE_TITLE "Main Menu" | |
74 | #define LOGO_NAME "logo" | |
75 | ||
76 | /* Check base expo support */ | |
77 | static int expo_base(struct unit_test_state *uts) | |
78 | { | |
79 | struct udevice *dev; | |
80 | struct expo *exp; | |
81 | ulong start_mem; | |
82 | char name[100]; | |
83 | int i; | |
84 | ||
85 | ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev)); | |
86 | ||
87 | start_mem = ut_check_free(); | |
88 | ||
89 | exp = NULL; | |
90 | strcpy(name, EXPO_NAME); | |
91 | ut_assertok(expo_new(name, NULL, &exp)); | |
92 | *name = '\0'; | |
93 | ut_assertnonnull(exp); | |
94 | ut_asserteq(0, exp->scene_id); | |
95 | ut_asserteq(0, exp->next_id); | |
96 | ||
97 | /* Make sure the name was allocated */ | |
98 | ut_assertnonnull(exp->name); | |
99 | ut_asserteq_str(EXPO_NAME, exp->name); | |
100 | ||
101 | ut_assertok(expo_set_display(exp, dev)); | |
102 | expo_destroy(exp); | |
103 | ut_assertok(ut_check_delta(start_mem)); | |
104 | ||
105 | /* test handling out-of-memory conditions */ | |
106 | for (i = 0; i < 2; i++) { | |
107 | struct expo *exp2; | |
108 | ||
109 | malloc_enable_testing(i); | |
110 | exp2 = BAD_POINTER; | |
111 | ut_asserteq(-ENOMEM, expo_new(EXPO_NAME, NULL, &exp2)); | |
112 | ut_asserteq_ptr(BAD_POINTER, exp2); | |
113 | malloc_disable_testing(); | |
114 | } | |
115 | ||
116 | return 0; | |
117 | } | |
118 | BOOTSTD_TEST(expo_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT); | |
119 | ||
120 | /* Check creating a scene */ | |
121 | static int expo_scene(struct unit_test_state *uts) | |
122 | { | |
123 | struct scene *scn; | |
124 | struct expo *exp; | |
125 | ulong start_mem; | |
126 | char name[100]; | |
def898c4 | 127 | int id, title_id; |
fe93c14b SG |
128 | |
129 | start_mem = ut_check_free(); | |
130 | ||
131 | ut_assertok(expo_new(EXPO_NAME, NULL, &exp)); | |
132 | ||
133 | scn = NULL; | |
134 | ut_asserteq(0, exp->next_id); | |
135 | strcpy(name, SCENE_NAME1); | |
136 | id = scene_new(exp, name, SCENE1, &scn); | |
137 | *name = '\0'; | |
138 | ut_assertnonnull(scn); | |
139 | ut_asserteq(SCENE1, id); | |
140 | ut_asserteq(SCENE1 + 1, exp->next_id); | |
141 | ut_asserteq_ptr(exp, scn->expo); | |
142 | ||
143 | /* Make sure the name was allocated */ | |
144 | ut_assertnonnull(scn->name); | |
145 | ut_asserteq_str(SCENE_NAME1, scn->name); | |
146 | ||
147 | /* Set the title */ | |
def898c4 SG |
148 | title_id = expo_str(exp, "title", STR_SCENE_TITLE, SCENE_TITLE); |
149 | ut_assert(title_id >= 0); | |
fe93c14b | 150 | |
def898c4 | 151 | /* Use an allocated ID - this will be allocated after the title str */ |
fe93c14b SG |
152 | scn = NULL; |
153 | id = scene_new(exp, SCENE_NAME2, 0, &scn); | |
154 | ut_assertnonnull(scn); | |
def898c4 SG |
155 | ut_assertok(scene_title_set(scn, title_id)); |
156 | ut_asserteq(STR_SCENE_TITLE + 1, id); | |
157 | ut_asserteq(STR_SCENE_TITLE + 2, exp->next_id); | |
fe93c14b SG |
158 | ut_asserteq_ptr(exp, scn->expo); |
159 | ||
160 | ut_asserteq_str(SCENE_NAME2, scn->name); | |
def898c4 | 161 | ut_asserteq(title_id, scn->title_id); |
fe93c14b SG |
162 | |
163 | expo_destroy(exp); | |
164 | ||
165 | ut_assertok(ut_check_delta(start_mem)); | |
166 | ||
167 | return 0; | |
168 | } | |
169 | BOOTSTD_TEST(expo_scene, UT_TESTF_DM | UT_TESTF_SCAN_FDT); | |
170 | ||
171 | /* Check creating a scene with objects */ | |
172 | static int expo_object(struct unit_test_state *uts) | |
173 | { | |
174 | struct scene_obj_img *img; | |
175 | struct scene_obj_txt *txt; | |
176 | struct scene *scn; | |
177 | struct expo *exp; | |
178 | ulong start_mem; | |
179 | char name[100]; | |
180 | char *data; | |
181 | int id; | |
182 | ||
183 | start_mem = ut_check_free(); | |
184 | ||
185 | ut_assertok(expo_new(EXPO_NAME, NULL, &exp)); | |
186 | id = scene_new(exp, SCENE_NAME1, SCENE1, &scn); | |
187 | ut_assert(id > 0); | |
188 | ||
189 | ut_asserteq(0, scene_obj_count(scn)); | |
190 | ||
191 | data = NULL; | |
192 | strcpy(name, LOGO_NAME); | |
193 | id = scene_img(scn, name, OBJ_LOGO, data, &img); | |
194 | ut_assert(id > 0); | |
195 | *name = '\0'; | |
196 | ut_assertnonnull(img); | |
197 | ut_asserteq(OBJ_LOGO, id); | |
198 | ut_asserteq(OBJ_LOGO + 1, exp->next_id); | |
199 | ut_asserteq_ptr(scn, img->obj.scene); | |
200 | ut_asserteq(SCENEOBJT_IMAGE, img->obj.type); | |
201 | ||
202 | ut_asserteq_ptr(data, img->data); | |
203 | ||
204 | /* Make sure the name was allocated */ | |
205 | ut_assertnonnull(scn->name); | |
206 | ut_asserteq_str(SCENE_NAME1, scn->name); | |
207 | ||
208 | ut_asserteq(1, scene_obj_count(scn)); | |
209 | ||
210 | id = scene_txt_str(scn, "text", OBJ_TEXT, STR_TEXT, "my string", &txt); | |
211 | ut_assert(id > 0); | |
212 | ut_assertnonnull(txt); | |
213 | ut_asserteq(OBJ_TEXT, id); | |
214 | ut_asserteq(SCENEOBJT_TEXT, txt->obj.type); | |
215 | ut_asserteq(2, scene_obj_count(scn)); | |
216 | ||
217 | /* Check passing NULL as the final parameter */ | |
218 | id = scene_txt_str(scn, "text2", OBJ_TEXT2, STR_TEXT2, "another string", | |
219 | NULL); | |
220 | ut_assert(id > 0); | |
221 | ut_asserteq(3, scene_obj_count(scn)); | |
222 | ||
223 | expo_destroy(exp); | |
224 | ||
225 | ut_assertok(ut_check_delta(start_mem)); | |
226 | ||
227 | return 0; | |
228 | } | |
229 | BOOTSTD_TEST(expo_object, UT_TESTF_DM | UT_TESTF_SCAN_FDT); | |
230 | ||
2e593897 | 231 | /* Check setting object attributes and using themes */ |
fe93c14b SG |
232 | static int expo_object_attr(struct unit_test_state *uts) |
233 | { | |
234 | struct scene_obj_menu *menu; | |
235 | struct scene_obj_img *img; | |
236 | struct scene_obj_txt *txt; | |
237 | struct scene *scn; | |
238 | struct expo *exp; | |
239 | ulong start_mem; | |
240 | char name[100]; | |
2e593897 | 241 | ofnode node; |
fe93c14b SG |
242 | char *data; |
243 | int id; | |
244 | ||
245 | start_mem = ut_check_free(); | |
246 | ||
247 | ut_assertok(expo_new(EXPO_NAME, NULL, &exp)); | |
248 | id = scene_new(exp, SCENE_NAME1, SCENE1, &scn); | |
249 | ut_assert(id > 0); | |
250 | ||
251 | data = NULL; | |
252 | id = scene_img(scn, LOGO_NAME, OBJ_LOGO, data, &img); | |
253 | ut_assert(id > 0); | |
254 | ||
255 | ut_assertok(scene_obj_set_pos(scn, OBJ_LOGO, 123, 456)); | |
ae45d6cf SG |
256 | ut_asserteq(123, img->obj.dim.x); |
257 | ut_asserteq(456, img->obj.dim.y); | |
fe93c14b SG |
258 | |
259 | ut_asserteq(-ENOENT, scene_obj_set_pos(scn, OBJ_TEXT2, 0, 0)); | |
260 | ||
261 | id = scene_txt_str(scn, "text", OBJ_TEXT, STR_TEXT, "my string", &txt); | |
262 | ut_assert(id > 0); | |
263 | ||
264 | strcpy(name, "font2"); | |
265 | ut_assertok(scene_txt_set_font(scn, OBJ_TEXT, name, 42)); | |
266 | ut_asserteq_ptr(name, txt->font_name); | |
267 | ut_asserteq(42, txt->font_size); | |
268 | ||
269 | ut_asserteq(-ENOENT, scene_txt_set_font(scn, OBJ_TEXT2, name, 42)); | |
270 | ||
271 | id = scene_menu(scn, "main", OBJ_MENU, &menu); | |
272 | ut_assert(id > 0); | |
273 | ||
274 | ut_assertok(scene_menu_set_title(scn, OBJ_MENU, OBJ_TEXT)); | |
275 | ||
276 | ut_asserteq(-ENOENT, scene_menu_set_title(scn, OBJ_TEXT2, OBJ_TEXT)); | |
277 | ut_asserteq(-EINVAL, scene_menu_set_title(scn, OBJ_MENU, OBJ_TEXT2)); | |
278 | ||
2e593897 SG |
279 | node = ofnode_path("/bootstd/theme"); |
280 | ut_assert(ofnode_valid(node)); | |
281 | ut_assertok(expo_apply_theme(exp, node)); | |
282 | ut_asserteq(30, txt->font_size); | |
283 | ||
fe93c14b SG |
284 | expo_destroy(exp); |
285 | ||
286 | ut_assertok(ut_check_delta(start_mem)); | |
287 | ||
288 | return 0; | |
289 | } | |
290 | BOOTSTD_TEST(expo_object_attr, UT_TESTF_DM | UT_TESTF_SCAN_FDT); | |
291 | ||
f2eb6ad5 SG |
292 | /** |
293 | * struct test_iter_priv - private data for expo-iterator test | |
294 | * | |
295 | * @count: number of scene objects | |
296 | * @menu_count: number of menus | |
297 | * @fail_at: item ID at which to return an error | |
298 | */ | |
299 | struct test_iter_priv { | |
300 | int count; | |
301 | int menu_count; | |
302 | int fail_at; | |
303 | }; | |
304 | ||
305 | int h_test_iter(struct scene_obj *obj, void *vpriv) | |
306 | { | |
307 | struct test_iter_priv *priv = vpriv; | |
308 | ||
309 | if (priv->fail_at == obj->id) | |
310 | return -EINVAL; | |
311 | ||
312 | priv->count++; | |
313 | if (obj->type == SCENEOBJT_MENU) | |
314 | priv->menu_count++; | |
315 | ||
316 | return 0; | |
317 | } | |
318 | ||
fe93c14b SG |
319 | /* Check creating a scene with a menu */ |
320 | static int expo_object_menu(struct unit_test_state *uts) | |
321 | { | |
322 | struct scene_obj_menu *menu; | |
323 | struct scene_menitem *item; | |
324 | int id, label_id, desc_id, key_id, pointer_id, preview_id; | |
325 | struct scene_obj_txt *ptr, *name1, *desc1, *key1, *tit, *prev1; | |
f2eb6ad5 | 326 | struct test_iter_priv priv; |
fe93c14b SG |
327 | struct scene *scn; |
328 | struct expo *exp; | |
329 | ulong start_mem; | |
330 | ||
331 | start_mem = ut_check_free(); | |
332 | ||
333 | ut_assertok(expo_new(EXPO_NAME, NULL, &exp)); | |
334 | id = scene_new(exp, SCENE_NAME1, SCENE1, &scn); | |
335 | ut_assert(id > 0); | |
336 | ||
337 | id = scene_menu(scn, "main", OBJ_MENU, &menu); | |
338 | ut_assert(id > 0); | |
339 | ut_assertnonnull(menu); | |
340 | ut_asserteq(OBJ_MENU, id); | |
341 | ut_asserteq(SCENEOBJT_MENU, menu->obj.type); | |
342 | ut_asserteq(0, menu->title_id); | |
343 | ut_asserteq(0, menu->pointer_id); | |
344 | ||
345 | ut_assertok(scene_obj_set_pos(scn, OBJ_MENU, 50, 400)); | |
ae45d6cf SG |
346 | ut_asserteq(50, menu->obj.dim.x); |
347 | ut_asserteq(400, menu->obj.dim.y); | |
fe93c14b SG |
348 | |
349 | id = scene_txt_str(scn, "title", OBJ_MENU_TITLE, STR_MENU_TITLE, | |
350 | "Main Menu", &tit); | |
351 | ut_assert(id > 0); | |
352 | ut_assertok(scene_menu_set_title(scn, OBJ_MENU, OBJ_MENU_TITLE)); | |
353 | ut_asserteq(OBJ_MENU_TITLE, menu->title_id); | |
354 | ||
355 | pointer_id = scene_txt_str(scn, "cur_item", POINTER_TEXT, | |
356 | STR_POINTER_TEXT, ">", &ptr); | |
357 | ut_assert(pointer_id > 0); | |
358 | ||
359 | ut_assertok(scene_menu_set_pointer(scn, OBJ_MENU, POINTER_TEXT)); | |
360 | ut_asserteq(POINTER_TEXT, menu->pointer_id); | |
361 | ||
362 | label_id = scene_txt_str(scn, "label1", ITEM1_LABEL, STR_ITEM1_LABEL, | |
363 | "Play", &name1); | |
364 | ut_assert(label_id > 0); | |
365 | ||
366 | desc_id = scene_txt_str(scn, "desc1", ITEM1_DESC, STR_ITEM1_DESC, | |
367 | "Lord Melchett", &desc1); | |
368 | ut_assert(desc_id > 0); | |
369 | ||
370 | key_id = scene_txt_str(scn, "item1-key", ITEM1_KEY, STR_ITEM1_KEY, "1", | |
371 | &key1); | |
372 | ut_assert(key_id > 0); | |
373 | ||
374 | preview_id = scene_txt_str(scn, "item1-preview", ITEM1_PREVIEW, | |
375 | STR_ITEM1_PREVIEW, "(preview1)", &prev1); | |
376 | ut_assert(preview_id > 0); | |
377 | ||
378 | id = scene_menuitem(scn, OBJ_MENU, "linux", ITEM1, ITEM1_KEY, | |
379 | ITEM1_LABEL, ITEM1_DESC, ITEM1_PREVIEW, 0, &item); | |
380 | ut_asserteq(ITEM1, id); | |
381 | ut_asserteq(id, item->id); | |
382 | ut_asserteq(key_id, item->key_id); | |
383 | ut_asserteq(label_id, item->label_id); | |
384 | ut_asserteq(desc_id, item->desc_id); | |
385 | ut_asserteq(preview_id, item->preview_id); | |
386 | ||
14a86a51 SG |
387 | ut_assertok(scene_arrange(scn)); |
388 | ||
389 | /* arranging the scene should cause the first item to become current */ | |
fe93c14b SG |
390 | ut_asserteq(id, menu->cur_item_id); |
391 | ||
392 | /* the title should be at the top */ | |
ae45d6cf SG |
393 | ut_asserteq(menu->obj.dim.x, tit->obj.dim.x); |
394 | ut_asserteq(menu->obj.dim.y, tit->obj.dim.y); | |
fe93c14b SG |
395 | |
396 | /* the first item should be next */ | |
ae45d6cf SG |
397 | ut_asserteq(menu->obj.dim.x, name1->obj.dim.x); |
398 | ut_asserteq(menu->obj.dim.y + 32, name1->obj.dim.y); | |
fe93c14b | 399 | |
ae45d6cf SG |
400 | ut_asserteq(menu->obj.dim.x + 230, key1->obj.dim.x); |
401 | ut_asserteq(menu->obj.dim.y + 32, key1->obj.dim.y); | |
fe93c14b | 402 | |
ae45d6cf SG |
403 | ut_asserteq(menu->obj.dim.x + 200, ptr->obj.dim.x); |
404 | ut_asserteq(menu->obj.dim.y + 32, ptr->obj.dim.y); | |
fe93c14b | 405 | |
ae45d6cf SG |
406 | ut_asserteq(menu->obj.dim.x + 280, desc1->obj.dim.x); |
407 | ut_asserteq(menu->obj.dim.y + 32, desc1->obj.dim.y); | |
fe93c14b | 408 | |
ae45d6cf SG |
409 | ut_asserteq(-4, prev1->obj.dim.x); |
410 | ut_asserteq(menu->obj.dim.y + 32, prev1->obj.dim.y); | |
8872bc7f | 411 | ut_asserteq(true, prev1->obj.flags & SCENEOF_HIDE); |
fe93c14b | 412 | |
f2eb6ad5 SG |
413 | /* check iterating through scene items */ |
414 | memset(&priv, '\0', sizeof(priv)); | |
415 | ut_assertok(expo_iter_scene_objs(exp, h_test_iter, &priv)); | |
416 | ut_asserteq(7, priv.count); | |
417 | ut_asserteq(1, priv.menu_count); | |
418 | ||
419 | /* check the iterator failing part way through iteration */ | |
420 | memset(&priv, '\0', sizeof(priv)); | |
421 | priv.fail_at = key_id; | |
422 | ut_asserteq(-EINVAL, expo_iter_scene_objs(exp, h_test_iter, &priv)); | |
423 | ||
424 | /* 2 items (preview_id and the menuitem) are after key_id, 7 - 2 = 5 */ | |
425 | ut_asserteq(5, priv.count); | |
426 | ||
427 | /* menu is first, so is still processed */ | |
428 | ut_asserteq(1, priv.menu_count); | |
429 | ||
fe93c14b SG |
430 | expo_destroy(exp); |
431 | ||
432 | ut_assertok(ut_check_delta(start_mem)); | |
433 | ||
434 | return 0; | |
435 | } | |
436 | BOOTSTD_TEST(expo_object_menu, UT_TESTF_DM | UT_TESTF_SCAN_FDT); | |
437 | ||
438 | /* Check rendering a scene */ | |
439 | static int expo_render_image(struct unit_test_state *uts) | |
440 | { | |
441 | struct scene_obj_menu *menu; | |
442 | struct scene *scn, *scn2; | |
443 | struct expo_action act; | |
444 | struct scene_obj *obj; | |
445 | struct udevice *dev; | |
446 | struct expo *exp; | |
447 | int id; | |
448 | ||
449 | console_record_reset_enable(); | |
450 | ut_assertok(uclass_first_device_err(UCLASS_VIDEO, &dev)); | |
451 | ||
452 | ut_assertok(expo_new(EXPO_NAME, NULL, &exp)); | |
453 | id = scene_new(exp, SCENE_NAME1, SCENE1, &scn); | |
454 | ut_assert(id > 0); | |
455 | ut_assertok(expo_set_display(exp, dev)); | |
456 | ||
457 | id = scene_img(scn, "logo", OBJ_LOGO, video_get_u_boot_logo(), NULL); | |
458 | ut_assert(id > 0); | |
459 | ut_assertok(scene_obj_set_pos(scn, OBJ_LOGO, 50, 20)); | |
460 | ||
461 | id = scene_txt_str(scn, "text", OBJ_TEXT, STR_TEXT, "my string", NULL); | |
462 | ut_assert(id > 0); | |
463 | ut_assertok(scene_txt_set_font(scn, OBJ_TEXT, "cantoraone_regular", | |
464 | 40)); | |
465 | ut_assertok(scene_obj_set_pos(scn, OBJ_TEXT, 400, 100)); | |
466 | ||
467 | id = scene_txt_str(scn, "text", OBJ_TEXT2, STR_TEXT2, "another string", | |
468 | NULL); | |
469 | ut_assert(id > 0); | |
470 | ut_assertok(scene_txt_set_font(scn, OBJ_TEXT2, "nimbus_sans_l_regular", | |
471 | 60)); | |
472 | ut_assertok(scene_obj_set_pos(scn, OBJ_TEXT2, 200, 600)); | |
473 | ||
474 | id = scene_menu(scn, "main", OBJ_MENU, &menu); | |
475 | ut_assert(id > 0); | |
476 | ||
477 | id = scene_txt_str(scn, "title", OBJ_MENU_TITLE, STR_MENU_TITLE, | |
478 | "Main Menu", NULL); | |
479 | ut_assert(id > 0); | |
480 | ut_assertok(scene_menu_set_title(scn, OBJ_MENU, OBJ_MENU_TITLE)); | |
481 | ||
482 | id = scene_txt_str(scn, "cur_item", POINTER_TEXT, STR_POINTER_TEXT, ">", | |
483 | NULL); | |
484 | ut_assert(id > 0); | |
485 | ut_assertok(scene_menu_set_pointer(scn, OBJ_MENU, POINTER_TEXT)); | |
486 | ||
487 | id = scene_txt_str(scn, "label1", ITEM1_LABEL, STR_ITEM1_LABEL, "Play", | |
488 | NULL); | |
489 | ut_assert(id > 0); | |
490 | id = scene_txt_str(scn, "item1 txt", ITEM1_DESC, STR_ITEM1_DESC, | |
491 | "Lord Melchett", NULL); | |
492 | ut_assert(id > 0); | |
493 | id = scene_txt_str(scn, "item1-key", ITEM1_KEY, STR_ITEM1_KEY, "1", | |
494 | NULL); | |
495 | ut_assert(id > 0); | |
496 | id = scene_img(scn, "item1-preview", ITEM1_PREVIEW, | |
497 | video_get_u_boot_logo(), NULL); | |
498 | id = scene_menuitem(scn, OBJ_MENU, "item1", ITEM1, ITEM1_KEY, | |
499 | ITEM1_LABEL, ITEM1_DESC, ITEM1_PREVIEW, 0, NULL); | |
500 | ut_assert(id > 0); | |
501 | ||
502 | id = scene_txt_str(scn, "label2", ITEM2_LABEL, STR_ITEM2_LABEL, "Now", | |
503 | NULL); | |
504 | ut_assert(id > 0); | |
505 | id = scene_txt_str(scn, "item2 txt", ITEM2_DESC, STR_ITEM2_DESC, | |
506 | "Lord Percy", NULL); | |
507 | ut_assert(id > 0); | |
508 | id = scene_txt_str(scn, "item2-key", ITEM2_KEY, STR_ITEM2_KEY, "2", | |
509 | NULL); | |
510 | ut_assert(id > 0); | |
511 | id = scene_img(scn, "item2-preview", ITEM2_PREVIEW, | |
512 | video_get_u_boot_logo(), NULL); | |
513 | ut_assert(id > 0); | |
514 | ||
515 | id = scene_menuitem(scn, OBJ_MENU, "item2", ITEM2, ITEM2_KEY, | |
516 | ITEM2_LABEL, ITEM2_DESC, ITEM2_PREVIEW, 0, NULL); | |
517 | ut_assert(id > 0); | |
518 | ||
519 | ut_assertok(scene_obj_set_pos(scn, OBJ_MENU, 50, 400)); | |
520 | ||
521 | scn2 = expo_lookup_scene_id(exp, SCENE1); | |
522 | ut_asserteq_ptr(scn, scn2); | |
523 | scn2 = expo_lookup_scene_id(exp, SCENE2); | |
524 | ut_assertnull(scn2); | |
525 | ||
526 | /* render without a scene */ | |
527 | ut_asserteq(-ECHILD, expo_render(exp)); | |
528 | ||
699b0acb SG |
529 | ut_assertok(expo_calc_dims(exp)); |
530 | ut_assertok(scene_arrange(scn)); | |
531 | ||
532 | /* check dimensions of text */ | |
533 | obj = scene_obj_find(scn, OBJ_TEXT, SCENEOBJT_NONE); | |
534 | ut_assertnonnull(obj); | |
535 | ut_asserteq(400, obj->dim.x); | |
536 | ut_asserteq(100, obj->dim.y); | |
537 | ut_asserteq(126, obj->dim.w); | |
538 | ut_asserteq(40, obj->dim.h); | |
539 | ||
540 | /* check dimensions of image */ | |
541 | obj = scene_obj_find(scn, OBJ_LOGO, SCENEOBJT_NONE); | |
542 | ut_assertnonnull(obj); | |
543 | ut_asserteq(50, obj->dim.x); | |
544 | ut_asserteq(20, obj->dim.y); | |
545 | ut_asserteq(160, obj->dim.w); | |
546 | ut_asserteq(160, obj->dim.h); | |
547 | ||
548 | /* check dimensions of menu labels - both should be the same width */ | |
549 | obj = scene_obj_find(scn, ITEM1_LABEL, SCENEOBJT_NONE); | |
550 | ut_assertnonnull(obj); | |
551 | ut_asserteq(50, obj->dim.x); | |
552 | ut_asserteq(436, obj->dim.y); | |
553 | ut_asserteq(29, obj->dim.w); | |
554 | ut_asserteq(18, obj->dim.h); | |
555 | ||
556 | obj = scene_obj_find(scn, ITEM2_LABEL, SCENEOBJT_NONE); | |
557 | ut_assertnonnull(obj); | |
558 | ut_asserteq(50, obj->dim.x); | |
559 | ut_asserteq(454, obj->dim.y); | |
560 | ut_asserteq(29, obj->dim.w); | |
561 | ut_asserteq(18, obj->dim.h); | |
562 | ||
563 | /* check dimensions of menu */ | |
564 | obj = scene_obj_find(scn, OBJ_MENU, SCENEOBJT_NONE); | |
565 | ut_assertnonnull(obj); | |
566 | ut_asserteq(50, obj->dim.x); | |
567 | ut_asserteq(400, obj->dim.y); | |
568 | ut_asserteq(160, obj->dim.w); | |
569 | ut_asserteq(160, obj->dim.h); | |
570 | ||
fe93c14b SG |
571 | /* render it */ |
572 | expo_set_scene_id(exp, SCENE1); | |
573 | ut_assertok(expo_render(exp)); | |
574 | ||
575 | /* move down */ | |
576 | ut_assertok(expo_send_key(exp, BKEY_DOWN)); | |
577 | ||
578 | ut_assertok(expo_action_get(exp, &act)); | |
579 | ||
3f33b9c7 | 580 | ut_asserteq(EXPOACT_POINT_ITEM, act.type); |
fe93c14b SG |
581 | ut_asserteq(ITEM2, act.select.id); |
582 | ut_assertok(expo_render(exp)); | |
583 | ||
584 | /* make sure only the preview for the second item is shown */ | |
585 | obj = scene_obj_find(scn, ITEM1_PREVIEW, SCENEOBJT_NONE); | |
ce72c9ec | 586 | ut_asserteq(true, obj->flags & SCENEOF_HIDE); |
fe93c14b SG |
587 | |
588 | obj = scene_obj_find(scn, ITEM2_PREVIEW, SCENEOBJT_NONE); | |
ce72c9ec | 589 | ut_asserteq(false, obj->flags & SCENEOF_HIDE); |
fe93c14b SG |
590 | |
591 | /* select it */ | |
592 | ut_assertok(expo_send_key(exp, BKEY_SELECT)); | |
593 | ||
594 | ut_assertok(expo_action_get(exp, &act)); | |
595 | ut_asserteq(EXPOACT_SELECT, act.type); | |
596 | ut_asserteq(ITEM2, act.select.id); | |
597 | ||
598 | /* make sure the action doesn't come again */ | |
599 | ut_asserteq(-EAGAIN, expo_action_get(exp, &act)); | |
600 | ||
601 | /* make sure there was no console output */ | |
602 | ut_assert_console_end(); | |
603 | ||
604 | /* now try in text mode */ | |
5904d953 | 605 | expo_set_text_mode(exp, true); |
fe93c14b SG |
606 | ut_assertok(expo_render(exp)); |
607 | ||
608 | ut_assert_nextline("U-Boot : Boot Menu"); | |
609 | ut_assert_nextline("%s", ""); | |
610 | ut_assert_nextline("Main Menu"); | |
611 | ut_assert_nextline("%s", ""); | |
612 | ut_assert_nextline(" 1 Play Lord Melchett"); | |
613 | ut_assert_nextline(" > 2 Now Lord Percy"); | |
614 | ||
615 | /* Move back up to the first item */ | |
616 | ut_assertok(expo_send_key(exp, BKEY_UP)); | |
617 | ||
618 | ut_assertok(expo_action_get(exp, &act)); | |
619 | ||
3f33b9c7 | 620 | ut_asserteq(EXPOACT_POINT_ITEM, act.type); |
fe93c14b SG |
621 | ut_asserteq(ITEM1, act.select.id); |
622 | ||
623 | ut_assertok(expo_render(exp)); | |
624 | ut_assert_nextline("U-Boot : Boot Menu"); | |
625 | ut_assert_nextline("%s", ""); | |
626 | ut_assert_nextline("Main Menu"); | |
627 | ut_assert_nextline("%s", ""); | |
628 | ut_assert_nextline(" > 1 Play Lord Melchett"); | |
629 | ut_assert_nextline(" 2 Now Lord Percy"); | |
630 | ||
631 | ut_assert_console_end(); | |
632 | ||
633 | expo_destroy(exp); | |
634 | ||
635 | return 0; | |
636 | } | |
637 | BOOTSTD_TEST(expo_render_image, UT_TESTF_DM | UT_TESTF_SCAN_FDT); | |
82cafee1 SG |
638 | |
639 | /* Check building an expo from a devicetree description */ | |
640 | static int expo_test_build(struct unit_test_state *uts) | |
641 | { | |
642 | struct scene_obj_menu *menu; | |
643 | struct scene_menitem *item; | |
644 | struct scene_obj_txt *txt; | |
645 | struct scene_obj *obj; | |
646 | struct scene *scn; | |
647 | struct expo *exp; | |
648 | int count; | |
649 | ofnode node; | |
650 | ||
651 | node = ofnode_path("/cedit"); | |
652 | ut_assert(ofnode_valid(node)); | |
653 | ut_assertok(expo_build(node, &exp)); | |
654 | ||
655 | ut_asserteq_str("name", exp->name); | |
656 | ut_asserteq(0, exp->scene_id); | |
c2bd2d33 | 657 | ut_asserteq(ID_DYNAMIC_START + 24, exp->next_id); |
82cafee1 SG |
658 | ut_asserteq(false, exp->popup); |
659 | ||
660 | /* check the scene */ | |
661 | scn = expo_lookup_scene_id(exp, ID_SCENE1); | |
662 | ut_assertnonnull(scn); | |
663 | ut_asserteq_str("main", scn->name); | |
664 | ut_asserteq(ID_SCENE1, scn->id); | |
665 | ut_asserteq(ID_DYNAMIC_START + 1, scn->title_id); | |
666 | ut_asserteq(0, scn->highlight_id); | |
667 | ||
668 | /* check the title */ | |
669 | txt = scene_obj_find(scn, scn->title_id, SCENEOBJT_NONE); | |
670 | ut_assertnonnull(txt); | |
671 | obj = &txt->obj; | |
672 | ut_asserteq_ptr(scn, obj->scene); | |
673 | ut_asserteq_str("title", obj->name); | |
674 | ut_asserteq(scn->title_id, obj->id); | |
675 | ut_asserteq(SCENEOBJT_TEXT, obj->type); | |
676 | ut_asserteq(0, obj->flags); | |
677 | ut_asserteq_str("Test Configuration", expo_get_str(exp, txt->str_id)); | |
678 | ||
679 | /* check the menu */ | |
680 | menu = scene_obj_find(scn, ID_CPU_SPEED, SCENEOBJT_NONE); | |
681 | obj = &menu->obj; | |
682 | ut_asserteq_ptr(scn, obj->scene); | |
683 | ut_asserteq_str("cpu-speed", obj->name); | |
684 | ut_asserteq(ID_CPU_SPEED, obj->id); | |
685 | ut_asserteq(SCENEOBJT_MENU, obj->type); | |
686 | ut_asserteq(0, obj->flags); | |
687 | ||
688 | txt = scene_obj_find(scn, menu->title_id, SCENEOBJT_NONE); | |
689 | ut_asserteq_str("CPU speed", expo_get_str(exp, txt->str_id)); | |
690 | ||
691 | ut_asserteq(0, menu->cur_item_id); | |
692 | ut_asserteq(0, menu->pointer_id); | |
693 | ||
694 | /* check the items */ | |
695 | item = list_first_entry(&menu->item_head, struct scene_menitem, | |
696 | sibling); | |
697 | ut_asserteq_str("00", item->name); | |
698 | ut_asserteq(ID_CPU_SPEED_1, item->id); | |
699 | ut_asserteq(0, item->key_id); | |
700 | ut_asserteq(0, item->desc_id); | |
701 | ut_asserteq(0, item->preview_id); | |
702 | ut_asserteq(0, item->flags); | |
703 | ||
704 | txt = scene_obj_find(scn, item->label_id, SCENEOBJT_NONE); | |
705 | ut_asserteq_str("2 GHz", expo_get_str(exp, txt->str_id)); | |
706 | ||
707 | count = 0; | |
708 | list_for_each_entry(item, &menu->item_head, sibling) | |
709 | count++; | |
710 | ut_asserteq(3, count); | |
711 | ||
712 | expo_destroy(exp); | |
713 | ||
714 | return 0; | |
715 | } | |
716 | BOOTSTD_TEST(expo_test_build, UT_TESTF_DM); |