1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 
4 #include "unity/unity.h"
5 
setUp(void)6 void setUp(void)
7 {
8     /* Function run before every test */
9 }
10 
tearDown(void)11 void tearDown(void)
12 {
13     /* Function run after every test */
14     lv_obj_clean(lv_screen_active());
15 }
16 
17 
test_xml_widget_direct_create(void)18 void test_xml_widget_direct_create(void)
19 {
20     lv_obj_set_style_pad_all(lv_screen_active(), 16, 0);
21 
22     lv_obj_t * slider;
23 
24     /*Simple create*/
25     slider = lv_xml_create(lv_screen_active(), "lv_slider", NULL);
26 
27     /*Adjust the returned widget*/
28     slider = lv_xml_create(lv_screen_active(), "lv_slider", NULL);
29     lv_obj_set_pos(slider, 10, 100);
30     lv_slider_set_value(slider, 40, LV_ANIM_OFF);
31 
32     /*Use attributes*/
33     const char * attrs[] = {
34         "range_min", "-100",
35         "range_max", "100",
36         "mode", "symmetrical",
37         "value", "50",
38         NULL, NULL,
39     };
40 
41     slider = lv_xml_create(lv_screen_active(), "lv_slider", attrs);
42     lv_obj_set_pos(slider, 10, 200);
43 
44     TEST_ASSERT_EQUAL_SCREENSHOT("xml/widget_create_1.png");
45 }
46 
test_xml_widget_create_from_component(void)47 void test_xml_widget_create_from_component(void)
48 {
49     lv_obj_set_style_pad_all(lv_screen_active(), 16, 0);
50 
51     const char * red_slider_xml =
52         "<component>"
53         "<view extends=\"lv_slider\" value=\"20\" width=\"100%\" style_bg_color=\"0xff0000\">"
54         "</view>"
55         "</component>";
56 
57     lv_xml_component_register_from_data("red_slider", red_slider_xml);
58 
59     lv_obj_t * slider;
60 
61     /*Simple create*/
62     slider = lv_xml_create(lv_screen_active(), "red_slider", NULL);
63 
64     /*Adjust the returned widget*/
65     slider = lv_xml_create(lv_screen_active(), "red_slider", NULL);
66     lv_obj_set_pos(slider, 10, 100);
67     lv_slider_set_value(slider, 40, LV_ANIM_OFF);
68 
69     /*Use attributes*/
70     const char * attrs[] = {
71         "range_min", "-100",
72         "range_max", "100",
73         "mode", "symmetrical",
74         "value", "50",
75         NULL, NULL,
76     };
77 
78     slider = lv_xml_create(lv_screen_active(), "red_slider", attrs);
79     lv_obj_set_pos(slider, 10, 200);
80 
81 
82     TEST_ASSERT_EQUAL_SCREENSHOT("xml/component_create_1.png");
83 }
84 
test_xml_nesting(void)85 void test_xml_nesting(void)
86 {
87     const char * red_button_xml =
88         "<component>"
89         "<view extends=\"lv_button\" radius=\"0\" style_bg_color=\"0xff0000\">"
90         "</view>"
91         "</component>";
92 
93     const char * card_xml =
94         "<component>"
95         "<view width=\"200\" height=\"content\">"
96         "<lv_label text=\"Some text here\" align=\"top_mid\"/>"
97         "<red_button y=\"20\">"
98         "<lv_label text=\"Button 1\" align=\"center\"/>"
99         "</red_button>"
100         "</view>"
101         "</component>";
102 
103     lv_xml_component_register_from_data("red_button", red_button_xml);
104     lv_xml_component_register_from_data("card", card_xml);
105 
106     lv_obj_t * card;
107     card = lv_xml_create(lv_screen_active(), "card", NULL);
108     card = lv_xml_create(lv_screen_active(), "card", NULL);
109     lv_obj_set_y(card, 80);
110 
111     /*Use attributes*/
112     const char * attrs[] = {
113         "y", "160",
114         NULL, NULL,
115     };
116     card = lv_xml_create(lv_screen_active(), "card", attrs);
117 
118     TEST_ASSERT_EQUAL_SCREENSHOT("xml/nested_1.png");
119 }
120 
121 /*Pass style and simple properties 3 level deep*/
test_xml_component_params(void)122 void test_xml_component_params(void)
123 {
124     const char * h3_xml =
125         "<component>"
126         "<api>"
127         "<prop name=\"style\" type=\"style\"/>"
128         "</api>"
129         "<view extends=\"lv_label\" styles=\"$style\">"
130         "</view>"
131         "</component>";
132 
133     const char * red_button_xml =
134         "<component>"
135         "<api>"
136         "<prop type=\"string\" name=\"btn_text\"/>"
137         "<prop type=\"style\" name=\"label_style\"/>"
138         "</api>"
139         "<view extends=\"lv_button\" style_radius=\"0\" style_bg_color=\"0xff0000\">"
140         "<h3 text=\"$btn_text\" style=\"$label_style\"/>"
141         "</view>"
142         "</component>";
143 
144     const char * card_xml =
145         "<component>"
146         "<api>"
147         "<prop type=\"string\" name=\"action\" default=\"Default\"/>"
148         "</api>"
149         "<styles>"
150         "<style name=\"style1\" text_color=\"0xffff00\"/>"
151         "</styles>"
152         "<view width=\"200\" height=\"content\">"
153         "<h3 text=\"Title\" align=\"top_mid\" style_text_color=\"0xff0000\"/>"
154         "<red_button btn_text=\"$action\" label_style=\"style1\" y=\"20\"/>"
155         "</view>"
156         "</component>";
157 
158     lv_xml_component_register_from_data("h3", h3_xml);
159     lv_xml_component_register_from_data("red_button", red_button_xml);
160     lv_xml_component_register_from_data("card", card_xml);
161 
162     lv_xml_create(lv_screen_active(), "card", NULL);
163 
164     /*Use attributes*/
165     const char * attrs[] = {
166         "y", "100",
167         "action", "Ext. text",
168         NULL, NULL,
169     };
170     lv_xml_create(lv_screen_active(), "card", attrs);
171 
172     TEST_ASSERT_EQUAL_SCREENSHOT("xml/params_1.png");
173 }
174 
test_xml_component_consts(void)175 void test_xml_component_consts(void)
176 {
177     const char * h3_xml =
178         "<component>"
179         "<consts>"
180         "<string name=\"action\" value=\"Log in\"/>"
181         "<color name=\"dark_color\" value=\"0x804000\"/>"
182         "<color name=\"accent_color\" value=\"0xff8000\"/>"
183         "<int name=\"size\" value=\"200\"/>"
184         "</consts>"
185         "<styles>"
186         "<style name=\"style1\" bg_color=\"#dark_color\" bg_opa=\"255\"/>"
187         "</styles>"
188         "<view extends=\"lv_label\" width=\"#size\" style_text_color=\"#accent_color\" text=\"#action\" styles=\"style1\">"
189         "</view>"
190         "</component>";
191 
192     lv_xml_component_register_from_data("h3", h3_xml);
193 
194     lv_xml_create(lv_screen_active(), "h3", NULL);
195 
196     TEST_ASSERT_EQUAL_SCREENSHOT("xml/consts_1.png");
197 }
198 
test_xml_component_styles(void)199 void test_xml_component_styles(void)
200 {
201     const char * my_btn_xml =
202         "<component>"
203         "<styles>"
204         "<style name=\"rel_style\" bg_color=\"0xff0000\"/>"
205         "<style name=\"pr_style\" bg_color=\"0x800000\"/>"
206         "</styles>"
207         "<view extends=\"lv_button\" style_text_color=\"0x0000ff\" style_text_color:checked=\"0xa0a0ff\" styles=\"rel_style pr_style:checked\">"
208         "<lv_label/>"
209         "</view>"
210         "</component>";
211 
212     lv_xml_component_register_from_data("my_btn", my_btn_xml);
213 
214     lv_xml_create(lv_screen_active(), "my_btn", NULL);
215     lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
216     lv_obj_set_pos(btn, 0, 100);
217     lv_obj_add_state(btn, LV_STATE_CHECKED);
218 
219     lv_test_wait(300); /*Wait for the state transition animation*/
220     TEST_ASSERT_EQUAL_SCREENSHOT("xml/styles_1.png");
221 }
222 
test_xml_error_resilience_syntax_ok(void)223 void test_xml_error_resilience_syntax_ok(void)
224 {
225     const char * my_btn_xml =
226         "<component>"
227         "<consts>"
228         "<int name=\"abc\" value=\"0xff0000\"/>"
229         "<not_a_type name=\"xyz\" value=\"0xff0000\"/>"
230         "<int not_a_prop=\"abc\" value=\"0xff0000\"/>"
231         "<int name=\"abc\" not_a_value=\"0xff0000\"/>"
232         "</consts>"
233         "<styles>"
234         "<style name=\"rel_style\" bg_color=\"0xff0000\" not_a_prop=\"0xff0000\"/>"
235         "<inv_style name=\"rel_style\" bg_color=\"0x800000\"/>"
236         "<style bg_color=\"0x800000\"/>"
237         "</styles>"
238 
239         "<view extends=\"not_a_widget\" style_text_color=\"0x0000ff\" style_text_color:checked=\"0x8080ff\" styles=\"rel_style pr_style:checked\">"
240         "<unknown/>"
241         "<lv_label not_an_attr=\"40\"/>"
242         "</view>"
243         "</component>";
244 
245     lv_xml_component_register_from_data("my_btn", my_btn_xml);
246 
247     lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
248     if(btn) lv_obj_set_pos(btn, 0, 100);
249 }
250 
test_xml_image_and_font(void)251 void test_xml_image_and_font(void)
252 {
253     const char * btn_xml =
254         "<component>"
255         "<consts>"
256         "<font name=\"font1\" value=\"lv_montserrat_18\"/>"
257         "<image name=\"image1\" value=\"test_img1\"/>"
258         "</consts>"
259         "<styles>"
260         "<style name=\"style_rel\" text_font=\"#font1\" text_color=\"0xffffff\" bg_image_src=\"#image1\" bg_image_tiled=\"true\" radius=\"0\"/>"
261         "<style name=\"style_chk\" text_font=\"lv_montserrat_16\" text_color=\"0xffff00\" bg_image_src=\"test_img2\"/>"
262         "</styles>"
263         "<view extends=\"lv_obj\" width=\"100\" height=\"70\" styles=\"style_rel style_chk:checked\" >"
264         "<lv_label text=\"hello\" align=\"center\" style_bg_color=\"0x888888\" style_bg_opa=\"200\"/>"
265         "</view>"
266         "</component>";
267 
268     /*Monstserrat fonts are registered by LVGL */
269     LV_IMAGE_DECLARE(img_render_lvgl_logo_l8);
270     LV_IMAGE_DECLARE(img_render_lvgl_logo_rgb565);
271     lv_xml_register_image("test_img1", &img_render_lvgl_logo_l8);
272     lv_xml_register_image("test_img2", &img_render_lvgl_logo_rgb565);
273 
274     lv_xml_component_register_from_data("btn", btn_xml);
275 
276     lv_obj_t * btn;
277     btn = lv_xml_create(lv_screen_active(), "btn", NULL);
278 
279     btn = lv_xml_create(lv_screen_active(), "btn", NULL);
280     lv_obj_set_pos(btn, 0, 100);
281     lv_obj_add_state(btn, LV_STATE_CHECKED);
282 
283     TEST_ASSERT_EQUAL_SCREENSHOT("xml/image_and_font_1.png");
284 }
285 
test_xml_error_resilience_not_closed_tag(void)286 void test_xml_error_resilience_not_closed_tag(void)
287 {
288     const char * my_btn_xml =
289         "<component>"
290         "<view extends=\"lv_button\">"
291         "<lv_label/>"
292         "</component>";
293 
294     lv_xml_component_register_from_data("my_btn", my_btn_xml);
295 
296     lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
297     if(btn) lv_obj_set_pos(btn, 0, 100);
298 }
299 
test_xml_error_resilience_string(void)300 void test_xml_error_resilience_string(void)
301 {
302     const char * my_btn_xml =
303         "<component>"
304         "<view extends=\"lv_button>"
305         "<lv_label/>"
306         "</component>";
307 
308     lv_xml_component_register_from_data("my_btn", my_btn_xml);
309 
310     lv_obj_t * btn = lv_xml_create(lv_screen_active(), "my_btn", NULL);
311     if(btn) lv_obj_set_pos(btn, 0, 100);
312 }
313 
test_xml_complex(void)314 void test_xml_complex(void)
315 {
316     lv_xml_component_register_from_file("A:src/test_assets/xml/my_h3.xml");
317     lv_xml_component_register_from_file("A:src/test_assets/xml/my_card.xml");
318     lv_xml_component_register_from_file("A:src/test_assets/xml/my_button.xml");
319     lv_xml_component_register_from_file("A:src/test_assets/xml/view.xml");
320 
321     lv_obj_t * obj = lv_xml_create(lv_screen_active(), "view", NULL);
322     lv_obj_set_pos(obj, 10, 10);
323 
324     const char * my_button_attrs[] = {
325         "x", "10",
326         "y", "-10",
327         "align", "bottom_left",
328         "btn_text", "New button",
329         NULL, NULL,
330     };
331 
332     lv_xml_create(lv_screen_active(), "my_button", my_button_attrs);
333 
334     const char * slider_attrs[] = {
335         "x", "200",
336         "y", "-15",
337         "align", "bottom_left",
338         "value", "30",
339         NULL, NULL,
340     };
341 
342     lv_obj_t * slider = lv_xml_create(lv_screen_active(), "lv_slider", slider_attrs);
343     lv_obj_set_width(slider, 100);
344 
345     TEST_ASSERT_EQUAL_SCREENSHOT("xml/complex_1.png");
346 }
347 
348 #endif
349