1 #if LV_BUILD_TEST
2 #include "../lvgl.h"
3 #include "../../lvgl_private.h"
4 
5 #include "unity/unity.h"
6 #include "lv_test_indev.h"
7 
8 static lv_obj_t * active_screen = NULL;
9 static lv_obj_t * spinbox_negative_min_range = NULL;
10 static lv_obj_t * spinbox_zero_min_range = NULL;
11 static lv_obj_t * spinbox_events = NULL;
12 static lv_group_t * g = NULL;
13 
14 static const int32_t SPINBOX_NEGATIVE_MIN_RANGE_VALUE = -11;
15 static const int32_t SPINBOX_ZERO_MIN_RANGE_VALUE = 0;
16 static const int32_t SPINBOX_NEGATIVE_MAX_RANGE_VALUE = 12;
17 static const uint8_t SPINBOX_DECIMAL_POSITION = 1U;
18 
setUp(void)19 void setUp(void)
20 {
21     active_screen = lv_screen_active();
22     spinbox_negative_min_range = lv_spinbox_create(active_screen);
23     spinbox_zero_min_range = lv_spinbox_create(active_screen);
24     spinbox_events = lv_spinbox_create(active_screen);
25 
26     lv_spinbox_set_range(spinbox_negative_min_range, SPINBOX_NEGATIVE_MIN_RANGE_VALUE, SPINBOX_NEGATIVE_MAX_RANGE_VALUE);
27     lv_spinbox_set_range(spinbox_zero_min_range, SPINBOX_ZERO_MIN_RANGE_VALUE, SPINBOX_NEGATIVE_MAX_RANGE_VALUE);
28 
29     g = lv_group_create();
30     lv_indev_set_group(lv_test_encoder_indev, g);
31 }
32 
tearDown(void)33 void tearDown(void)
34 {
35     lv_group_remove_obj(spinbox_events);
36 
37     lv_obj_delete(spinbox_negative_min_range);
38     lv_obj_delete(spinbox_zero_min_range);
39     lv_obj_delete(spinbox_events);
40 
41     lv_obj_clean(active_screen);
42 }
43 
44 /* See issue #3559 for more info */
test_spinbox_decrement_when_min_range_is_negative(void)45 void test_spinbox_decrement_when_min_range_is_negative(void)
46 {
47     /* Current spinbox value is 2 */
48     const int32_t expected_value = -11;
49     lv_spinbox_set_value(spinbox_negative_min_range, 2);
50 
51     /* Change cursor position of spinbox to 10 */
52     lv_spinbox_set_cursor_pos(spinbox_negative_min_range, SPINBOX_DECIMAL_POSITION);
53     lv_spinbox_decrement(spinbox_negative_min_range);
54     lv_spinbox_decrement(spinbox_negative_min_range);
55 
56     /* We expect value now being -11 */
57     int32_t actual_value = lv_spinbox_get_value(spinbox_negative_min_range);
58 
59     TEST_ASSERT_EQUAL_INT32(expected_value, actual_value);
60 }
61 
test_spinbox_decrement_when_min_range_is_zero(void)62 void test_spinbox_decrement_when_min_range_is_zero(void)
63 {
64     /* Current spinbox value is 2 */
65     const int32_t expected_value = 0;
66     lv_spinbox_set_value(spinbox_zero_min_range, 2);
67 
68     /* Change cursor position of spinbox to 10 */
69     lv_spinbox_set_cursor_pos(spinbox_zero_min_range, SPINBOX_DECIMAL_POSITION);
70     lv_spinbox_decrement(spinbox_zero_min_range);
71     lv_spinbox_decrement(spinbox_zero_min_range);
72 
73     /* We expect value now being 0 */
74     int32_t actual_value = lv_spinbox_get_value(spinbox_zero_min_range);
75 
76     TEST_ASSERT_EQUAL_INT32(expected_value, actual_value);
77 }
78 
test_spinbox_position_selection(void)79 void test_spinbox_position_selection(void)
80 {
81     /* Assert step is 1 when selecting the lowest possible position */
82     lv_spinbox_set_cursor_pos(spinbox_zero_min_range, 0);
83     TEST_ASSERT_EQUAL(1, lv_spinbox_get_step(spinbox_zero_min_range));
84 
85     /* The other branch in the if */
86     lv_spinbox_set_cursor_pos(spinbox_zero_min_range, 1);
87     TEST_ASSERT_EQUAL(10, lv_spinbox_get_step(spinbox_zero_min_range));
88 
89     /* When not possible to select the indicated position */
90     lv_obj_t * tmp;
91     tmp = lv_spinbox_create(active_screen);
92     lv_spinbox_set_range(tmp, 0, 10);
93     lv_spinbox_set_cursor_pos(tmp, 2);
94     TEST_ASSERT_EQUAL(1, lv_spinbox_get_step(tmp));
95     lv_obj_clean(tmp);
96 }
97 
test_spinbox_set_range(void)98 void test_spinbox_set_range(void)
99 {
100     int32_t range_max = 40;
101     int32_t range_min = 20;
102 
103     lv_obj_t * tmp;
104     tmp = lv_spinbox_create(active_screen);
105     lv_spinbox_set_range(tmp, 0, 100);
106     lv_spinbox_set_value(tmp, 50);
107 
108     /* Validate value gets updated when range_max is smaller */
109     lv_spinbox_set_range(tmp, 0, range_max);
110 
111     TEST_ASSERT_EQUAL(range_max, lv_spinbox_get_value(tmp));
112 
113     /* Validate value gets updated when range_min is bigger */
114     lv_spinbox_set_value(tmp, 5);
115     lv_spinbox_set_range(tmp, range_min, range_max);
116 
117     TEST_ASSERT_EQUAL(range_min, lv_spinbox_get_value(tmp));
118 
119     lv_obj_clean(tmp);
120 }
121 
test_spinbox_step_prev(void)122 void test_spinbox_step_prev(void)
123 {
124     lv_obj_t * tmp = lv_spinbox_create(active_screen);
125 
126     /* When next step is bigger than biggest range */
127     lv_spinbox_set_range(tmp, 0, 5);
128     lv_spinbox_step_prev(tmp);
129     TEST_ASSERT_EQUAL(1, lv_spinbox_get_step(tmp));
130 
131     lv_spinbox_step_next(tmp);
132     /* When next step is smaller than range_max */
133     lv_spinbox_set_range(tmp, 0, 20);
134     lv_spinbox_step_prev(tmp);
135     TEST_ASSERT_EQUAL(10, lv_spinbox_get_step(tmp));
136 
137     lv_spinbox_step_next(tmp);
138     /* When next step is smaller than abs(range_min) */
139     lv_spinbox_set_range(tmp, -25, 5);
140     lv_spinbox_step_prev(tmp);
141     TEST_ASSERT_EQUAL(10, lv_spinbox_get_step(tmp));
142 
143     lv_obj_clean(tmp);
144 }
145 
test_spinbox_rollover(void)146 void test_spinbox_rollover(void)
147 {
148     lv_obj_t * tmp = lv_spinbox_create(active_screen);
149 
150     lv_spinbox_set_rollover(tmp, true);
151     TEST_ASSERT_TRUE(lv_spinbox_get_rollover(tmp));
152 
153     lv_spinbox_set_rollover(tmp, false);
154     TEST_ASSERT_FALSE(lv_spinbox_get_rollover(tmp));
155 
156     lv_obj_clean(tmp);
157 }
158 
test_spinbox_event_key(void)159 void test_spinbox_event_key(void)
160 {
161     /* Spinbox should increment it's value by one after receiving the LV_KEY_UP event */
162     lv_spinbox_set_value(spinbox_events, 0);
163     uint32_t key = LV_KEY_UP;
164     lv_obj_send_event(spinbox_events, LV_EVENT_KEY, (void *) &key);
165 
166     TEST_ASSERT_EQUAL(1, lv_spinbox_get_value(spinbox_events));
167 
168     /* Spinbox should decrement it's value by one after receiving the LV_KEY_DOWN event */
169     key = LV_KEY_DOWN;
170     lv_obj_send_event(spinbox_events, LV_EVENT_KEY, (void *) &key);
171 
172     TEST_ASSERT_EQUAL(0, lv_spinbox_get_value(spinbox_events));
173 
174     /* Spinbox should multiply it's step vale by 10 after receiving the LV_KEY_LEFT event */
175     int32_t step = lv_spinbox_get_step(spinbox_events);
176     key = LV_KEY_LEFT;
177     lv_obj_send_event(spinbox_events, LV_EVENT_KEY, (void *) &key);
178 
179     TEST_ASSERT_EQUAL(step * 10, lv_spinbox_get_step(spinbox_events));
180 
181     /* Spinbox should divide it's step vale by 10 after receiving the LV_KEY_RIGHT event */
182     step = lv_spinbox_get_step(spinbox_events);
183     key = LV_KEY_RIGHT;
184     lv_obj_send_event(spinbox_events, LV_EVENT_KEY, (void *) &key);
185 
186     TEST_ASSERT_EQUAL(step / 10, lv_spinbox_get_step(spinbox_events));
187 }
188 
test_spinbox_event_key_encoder_indev_turn_right(void)189 void test_spinbox_event_key_encoder_indev_turn_right(void)
190 {
191     /* Setup group and encoder indev */
192     lv_group_add_obj(g, spinbox_events);
193 
194     /* Spinbox should increment it's value by one step after receiving the LV_KEY_UP event */
195     lv_spinbox_set_value(spinbox_events, 0);
196 
197     lv_test_encoder_click();
198     lv_test_encoder_turn(1);
199 
200     TEST_ASSERT_EQUAL(1, lv_spinbox_get_value(spinbox_events));
201 }
202 
test_spinbox_event_key_encoder_indev_turn_left(void)203 void test_spinbox_event_key_encoder_indev_turn_left(void)
204 {
205     int32_t value = 10;
206     /* Setup group and encoder indev */
207     lv_group_add_obj(g, spinbox_events);
208 
209     /* Spinbox should decrement it's value by one step after receiving the LV_KEY_UP event */
210     lv_spinbox_set_value(spinbox_events, value);
211     lv_spinbox_set_cursor_pos(spinbox_events, 0);
212 
213     lv_test_encoder_click();
214     lv_test_encoder_turn(-1);
215     TEST_ASSERT_EQUAL(value - 1, lv_spinbox_get_value(spinbox_events));
216 }
217 
test_spinbox_event_key_encoder_indev_editing_group(void)218 void test_spinbox_event_key_encoder_indev_editing_group(void)
219 {
220     int32_t value = 10;
221     /* Setup group and encoder indev */
222     lv_spinbox_set_range(spinbox_events, 0, 20);
223     lv_group_add_obj(g, spinbox_events);
224     lv_group_set_editing(g, true);
225 
226     lv_spinbox_set_value(spinbox_events, value);
227     lv_spinbox_set_cursor_pos(spinbox_events, 0);
228 
229     lv_test_encoder_click();
230     lv_test_encoder_turn(-1);
231     TEST_ASSERT_EQUAL(0, lv_spinbox_get_value(spinbox_events));
232     /* digit_count is 5, so we expect to be in the position of the MSB digit */
233     TEST_ASSERT_EQUAL(1000, lv_spinbox_get_step(spinbox_events));
234 
235     /* Test with digit_count == 1 */
236     lv_spinbox_set_digit_format(spinbox_events, 1, 2);
237     lv_spinbox_set_cursor_pos(spinbox_events, 0);
238 
239     lv_test_encoder_click();
240     lv_test_encoder_turn(-1);
241     TEST_ASSERT_EQUAL(0, lv_spinbox_get_value(spinbox_events));
242     /* digit_count is 1, so we expect to be in the same position */
243     TEST_ASSERT_EQUAL(1, lv_spinbox_get_step(spinbox_events));
244 }
245 
test_spinbox_event_key_encoder_indev_editing_group_left_step_direction(void)246 void test_spinbox_event_key_encoder_indev_editing_group_left_step_direction(void)
247 {
248     int32_t value = 10;
249     /* Setup group and encoder indev */
250     lv_spinbox_set_digit_step_direction(spinbox_events, LV_DIR_LEFT);
251     lv_spinbox_set_range(spinbox_events, 0, 20);
252     lv_group_add_obj(g, spinbox_events);
253     lv_group_set_editing(g, true);
254 
255     lv_spinbox_set_value(spinbox_events, value);
256     lv_spinbox_set_cursor_pos(spinbox_events, 0);
257 
258     lv_test_encoder_click();
259     lv_test_encoder_turn(-1);
260     TEST_ASSERT_EQUAL(0, lv_spinbox_get_value(spinbox_events));
261     /* digit_count is 5, we expect to be in the position next to the left */
262     TEST_ASSERT_EQUAL(10, lv_spinbox_get_step(spinbox_events));
263 
264     /* Test with digit_count == 1 */
265     lv_spinbox_set_digit_format(spinbox_events, 2, 2);
266     lv_spinbox_set_cursor_pos(spinbox_events, 1);
267 
268     lv_test_encoder_click();
269     lv_test_encoder_turn(-1);
270     TEST_ASSERT_EQUAL(0, lv_spinbox_get_value(spinbox_events));
271     /* digit_count is 1, so we expect to be in the same position */
272     TEST_ASSERT_EQUAL(1, lv_spinbox_get_step(spinbox_events));
273 }
274 
test_spinbox_event_release(void)275 void test_spinbox_event_release(void)
276 {
277     lv_spinbox_set_value(spinbox_events, 0);
278     lv_spinbox_set_digit_format(spinbox_events, 5, 2);
279 
280     /* Set cursor in least significant decimal digit */
281     lv_spinbox_set_cursor_pos(spinbox_events, 0);
282     lv_obj_send_event(spinbox_events, LV_EVENT_RELEASED, NULL);
283 
284     TEST_ASSERT_EQUAL(1, lv_spinbox_get_step(spinbox_events));
285 }
286 
test_spinbox_zero_crossing(void)287 void test_spinbox_zero_crossing(void)
288 {
289     int32_t value = -13;
290     /* Setup group and encoder indev */
291     lv_spinbox_set_digit_step_direction(spinbox_events, LV_DIR_LEFT);
292     lv_spinbox_set_range(spinbox_events, -20, 20);
293     lv_group_add_obj(g, spinbox_events);
294 
295     lv_spinbox_set_value(spinbox_events, value);
296     lv_spinbox_set_cursor_pos(spinbox_events, 1);
297 
298     lv_test_encoder_click();
299     lv_test_encoder_turn(1);
300     TEST_ASSERT_EQUAL(-3, lv_spinbox_get_value(spinbox_events));
301 
302     lv_test_encoder_turn(1);
303     TEST_ASSERT_EQUAL(3, lv_spinbox_get_value(spinbox_events));
304 
305     lv_test_encoder_turn(1);
306     TEST_ASSERT_EQUAL(13, lv_spinbox_get_value(spinbox_events));
307 }
308 
309 #endif
310