1 /*
2 * Copyright © 2014 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <config.h>
25
26 #include <check.h>
27
28 #include <valgrind/valgrind.h>
29
30 #include "util-list.h"
31 #include "util-strings.h"
32 #include "util-time.h"
33 #include "util-prop-parsers.h"
34 #include "util-macros.h"
35 #include "util-bits.h"
36 #include "util-ratelimit.h"
37 #include "util-matrix.h"
38
39 #define TEST_VERSIONSORT
40 #include "libinput-versionsort.h"
41
42 #include "check-double-macros.h"
43
START_TEST(bitfield_helpers)44 START_TEST(bitfield_helpers)
45 {
46 /* This value has a bit set on all of the word boundaries we want to
47 * test: 0, 1, 7, 8, 31, 32, and 33
48 */
49 unsigned char read_bitfield[] = { 0x83, 0x1, 0x0, 0x80, 0x3 };
50 unsigned char write_bitfield[ARRAY_LENGTH(read_bitfield)] = {0};
51 size_t i;
52
53 /* Now check that the bitfield we wrote to came out to be the same as
54 * the bitfield we were writing from */
55 for (i = 0; i < ARRAY_LENGTH(read_bitfield) * 8; i++) {
56 switch (i) {
57 case 0:
58 case 1:
59 case 7:
60 case 8:
61 case 31:
62 case 32:
63 case 33:
64 ck_assert(bit_is_set(read_bitfield, i));
65 set_bit(write_bitfield, i);
66 break;
67 default:
68 ck_assert(!bit_is_set(read_bitfield, i));
69 clear_bit(write_bitfield, i);
70 break;
71 }
72 }
73
74 ck_assert_int_eq(memcmp(read_bitfield,
75 write_bitfield,
76 sizeof(read_bitfield)),
77 0);
78 }
79 END_TEST
80
START_TEST(matrix_helpers)81 START_TEST(matrix_helpers)
82 {
83 struct matrix m1, m2, m3;
84 float f[6] = { 1, 2, 3, 4, 5, 6 };
85 int x, y;
86 int row, col;
87
88 matrix_init_identity(&m1);
89
90 for (row = 0; row < 3; row++) {
91 for (col = 0; col < 3; col++) {
92 ck_assert_int_eq(m1.val[row][col],
93 (row == col) ? 1 : 0);
94 }
95 }
96 ck_assert(matrix_is_identity(&m1));
97
98 matrix_from_farray6(&m2, f);
99 ck_assert_int_eq(m2.val[0][0], 1);
100 ck_assert_int_eq(m2.val[0][1], 2);
101 ck_assert_int_eq(m2.val[0][2], 3);
102 ck_assert_int_eq(m2.val[1][0], 4);
103 ck_assert_int_eq(m2.val[1][1], 5);
104 ck_assert_int_eq(m2.val[1][2], 6);
105 ck_assert_int_eq(m2.val[2][0], 0);
106 ck_assert_int_eq(m2.val[2][1], 0);
107 ck_assert_int_eq(m2.val[2][2], 1);
108
109 x = 100;
110 y = 5;
111 matrix_mult_vec(&m1, &x, &y);
112 ck_assert_int_eq(x, 100);
113 ck_assert_int_eq(y, 5);
114
115 matrix_mult(&m3, &m1, &m1);
116 ck_assert(matrix_is_identity(&m3));
117
118 matrix_init_scale(&m2, 2, 4);
119 ck_assert_int_eq(m2.val[0][0], 2);
120 ck_assert_int_eq(m2.val[0][1], 0);
121 ck_assert_int_eq(m2.val[0][2], 0);
122 ck_assert_int_eq(m2.val[1][0], 0);
123 ck_assert_int_eq(m2.val[1][1], 4);
124 ck_assert_int_eq(m2.val[1][2], 0);
125 ck_assert_int_eq(m2.val[2][0], 0);
126 ck_assert_int_eq(m2.val[2][1], 0);
127 ck_assert_int_eq(m2.val[2][2], 1);
128
129 matrix_mult_vec(&m2, &x, &y);
130 ck_assert_int_eq(x, 200);
131 ck_assert_int_eq(y, 20);
132
133 matrix_init_translate(&m2, 10, 100);
134 ck_assert_int_eq(m2.val[0][0], 1);
135 ck_assert_int_eq(m2.val[0][1], 0);
136 ck_assert_int_eq(m2.val[0][2], 10);
137 ck_assert_int_eq(m2.val[1][0], 0);
138 ck_assert_int_eq(m2.val[1][1], 1);
139 ck_assert_int_eq(m2.val[1][2], 100);
140 ck_assert_int_eq(m2.val[2][0], 0);
141 ck_assert_int_eq(m2.val[2][1], 0);
142 ck_assert_int_eq(m2.val[2][2], 1);
143
144 matrix_mult_vec(&m2, &x, &y);
145 ck_assert_int_eq(x, 210);
146 ck_assert_int_eq(y, 120);
147
148 matrix_to_farray6(&m2, f);
149 ck_assert_int_eq(f[0], 1);
150 ck_assert_int_eq(f[1], 0);
151 ck_assert_int_eq(f[2], 10);
152 ck_assert_int_eq(f[3], 0);
153 ck_assert_int_eq(f[4], 1);
154 ck_assert_int_eq(f[5], 100);
155 }
156 END_TEST
157
START_TEST(ratelimit_helpers)158 START_TEST(ratelimit_helpers)
159 {
160 struct ratelimit rl;
161 unsigned int i, j;
162
163 /* 10 attempts every 1000ms */
164 ratelimit_init(&rl, ms2us(1000), 10);
165
166 for (j = 0; j < 3; ++j) {
167 /* a burst of 9 attempts must succeed */
168 for (i = 0; i < 9; ++i) {
169 ck_assert_int_eq(ratelimit_test(&rl),
170 RATELIMIT_PASS);
171 }
172
173 /* the 10th attempt reaches the threshold */
174 ck_assert_int_eq(ratelimit_test(&rl), RATELIMIT_THRESHOLD);
175
176 /* ..then further attempts must fail.. */
177 ck_assert_int_eq(ratelimit_test(&rl), RATELIMIT_EXCEEDED);
178
179 /* ..regardless of how often we try. */
180 for (i = 0; i < 100; ++i) {
181 ck_assert_int_eq(ratelimit_test(&rl),
182 RATELIMIT_EXCEEDED);
183 }
184
185 /* ..even after waiting 20ms */
186 msleep(100);
187 for (i = 0; i < 100; ++i) {
188 ck_assert_int_eq(ratelimit_test(&rl),
189 RATELIMIT_EXCEEDED);
190 }
191
192 /* but after 1000ms the counter is reset */
193 msleep(950); /* +50ms to account for time drifts */
194 }
195 }
196 END_TEST
197
198 struct parser_test {
199 char *tag;
200 int expected_value;
201 };
202
START_TEST(dpi_parser)203 START_TEST(dpi_parser)
204 {
205 struct parser_test tests[] = {
206 { "450 *1800 3200", 1800 },
207 { "*450 1800 3200", 450 },
208 { "450 1800 *3200", 3200 },
209 { "450 1800 3200", 3200 },
210 { "450 1800 failboat", 0 },
211 { "450 1800 *failboat", 0 },
212 { "0 450 1800 *3200", 0 },
213 { "450@37 1800@12 *3200@6", 3200 },
214 { "450@125 1800@125 *3200@125 ", 3200 },
215 { "450@125 *1800@125 3200@125", 1800 },
216 { "*this @string fails", 0 },
217 { "12@34 *45@", 0 },
218 { "12@a *45@", 0 },
219 { "12@a *45@25", 0 },
220 { " * 12, 450, 800", 0 },
221 { " *12, 450, 800", 12 },
222 { "*12, *450, 800", 12 },
223 { "*-23412, 450, 800", 0 },
224 { "112@125, 450@125, 800@125, 900@-125", 0 },
225 { "", 0 },
226 { " ", 0 },
227 { "* ", 0 },
228 { NULL, 0 }
229 };
230 int i, dpi;
231
232 for (i = 0; tests[i].tag != NULL; i++) {
233 dpi = parse_mouse_dpi_property(tests[i].tag);
234 ck_assert_int_eq(dpi, tests[i].expected_value);
235 }
236
237 dpi = parse_mouse_dpi_property(NULL);
238 ck_assert_int_eq(dpi, 0);
239 }
240 END_TEST
241
START_TEST(wheel_click_parser)242 START_TEST(wheel_click_parser)
243 {
244 struct parser_test tests[] = {
245 { "1", 1 },
246 { "10", 10 },
247 { "-12", -12 },
248 { "360", 360 },
249
250 { "0", 0 },
251 { "-0", 0 },
252 { "a", 0 },
253 { "10a", 0 },
254 { "10-", 0 },
255 { "sadfasfd", 0 },
256 { "361", 0 },
257 { NULL, 0 }
258 };
259
260 int i, angle;
261
262 for (i = 0; tests[i].tag != NULL; i++) {
263 angle = parse_mouse_wheel_click_angle_property(tests[i].tag);
264 ck_assert_int_eq(angle, tests[i].expected_value);
265 }
266 }
267 END_TEST
268
START_TEST(wheel_click_count_parser)269 START_TEST(wheel_click_count_parser)
270 {
271 struct parser_test tests[] = {
272 { "1", 1 },
273 { "10", 10 },
274 { "-12", -12 },
275 { "360", 360 },
276
277 { "0", 0 },
278 { "-0", 0 },
279 { "a", 0 },
280 { "10a", 0 },
281 { "10-", 0 },
282 { "sadfasfd", 0 },
283 { "361", 0 },
284 { NULL, 0 }
285 };
286
287 int i, angle;
288
289 for (i = 0; tests[i].tag != NULL; i++) {
290 angle = parse_mouse_wheel_click_count_property(tests[i].tag);
291 ck_assert_int_eq(angle, tests[i].expected_value);
292 }
293
294 angle = parse_mouse_wheel_click_count_property(NULL);
295 ck_assert_int_eq(angle, 0);
296 }
297 END_TEST
298
START_TEST(dimension_prop_parser)299 START_TEST(dimension_prop_parser)
300 {
301 struct parser_test_dimension {
302 char *tag;
303 bool success;
304 int x, y;
305 } tests[] = {
306 { "10x10", true, 10, 10 },
307 { "1x20", true, 1, 20 },
308 { "1x8000", true, 1, 8000 },
309 { "238492x428210", true, 238492, 428210 },
310 { "0x0", false, 0, 0 },
311 { "-10x10", false, 0, 0 },
312 { "-1", false, 0, 0 },
313 { "1x-99", false, 0, 0 },
314 { "0", false, 0, 0 },
315 { "100", false, 0, 0 },
316 { "", false, 0, 0 },
317 { "abd", false, 0, 0 },
318 { "xabd", false, 0, 0 },
319 { "0xaf", false, 0, 0 },
320 { "0x0x", false, 0, 0 },
321 { "x10", false, 0, 0 },
322 { NULL, false, 0, 0 }
323 };
324 int i;
325 size_t x, y;
326 bool success;
327
328 for (i = 0; tests[i].tag != NULL; i++) {
329 x = y = 0xad;
330 success = parse_dimension_property(tests[i].tag, &x, &y);
331 ck_assert(success == tests[i].success);
332 if (success) {
333 ck_assert_int_eq(x, tests[i].x);
334 ck_assert_int_eq(y, tests[i].y);
335 } else {
336 ck_assert_int_eq(x, 0xad);
337 ck_assert_int_eq(y, 0xad);
338 }
339 }
340
341 success = parse_dimension_property(NULL, &x, &y);
342 ck_assert(success == false);
343 }
344 END_TEST
345
START_TEST(reliability_prop_parser)346 START_TEST(reliability_prop_parser)
347 {
348 struct parser_test_reliability {
349 char *tag;
350 bool success;
351 enum switch_reliability reliability;
352 } tests[] = {
353 { "reliable", true, RELIABILITY_RELIABLE },
354 { "unreliable", false, 0 },
355 { "", false, 0 },
356 { "0", false, 0 },
357 { "1", false, 0 },
358 { NULL, false, 0, }
359 };
360 enum switch_reliability r;
361 bool success;
362 int i;
363
364 for (i = 0; tests[i].tag != NULL; i++) {
365 r = 0xaf;
366 success = parse_switch_reliability_property(tests[i].tag, &r);
367 ck_assert(success == tests[i].success);
368 if (success)
369 ck_assert_int_eq(r, tests[i].reliability);
370 else
371 ck_assert_int_eq(r, 0xaf);
372 }
373
374 success = parse_switch_reliability_property(NULL, &r);
375 ck_assert(success == true);
376 ck_assert_int_eq(r, RELIABILITY_UNKNOWN);
377
378 success = parse_switch_reliability_property("foo", NULL);
379 ck_assert(success == false);
380 }
381 END_TEST
382
START_TEST(calibration_prop_parser)383 START_TEST(calibration_prop_parser)
384 {
385 #define DEFAULT_VALUES { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 }
386 const float untouched[6] = DEFAULT_VALUES;
387 struct parser_test_calibration {
388 char *prop;
389 bool success;
390 float values[6];
391 } tests[] = {
392 { "", false, DEFAULT_VALUES },
393 { "banana", false, DEFAULT_VALUES },
394 { "1 2 3 a 5 6", false, DEFAULT_VALUES },
395 { "2", false, DEFAULT_VALUES },
396 { "2 3 4 5 6", false, DEFAULT_VALUES },
397 { "1 2 3 4 5 6", true, DEFAULT_VALUES },
398 { "6.00012 3.244 4.238 5.2421 6.0134 8.860", true,
399 { 6.00012, 3.244, 4.238, 5.2421, 6.0134, 8.860 }},
400 { "0xff 2 3 4 5 6", false, DEFAULT_VALUES },
401 { NULL, false, DEFAULT_VALUES }
402 };
403 bool success;
404 float calibration[6];
405 int rc;
406 int i;
407
408 for (i = 0; tests[i].prop != NULL; i++) {
409 memcpy(calibration, untouched, sizeof(calibration));
410
411 success = parse_calibration_property(tests[i].prop,
412 calibration);
413 ck_assert_int_eq(success, tests[i].success);
414 if (success)
415 rc = memcmp(tests[i].values,
416 calibration,
417 sizeof(calibration));
418 else
419 rc = memcmp(untouched,
420 calibration,
421 sizeof(calibration));
422 ck_assert_int_eq(rc, 0);
423 }
424
425 memcpy(calibration, untouched, sizeof(calibration));
426
427 success = parse_calibration_property(NULL, calibration);
428 ck_assert(success == false);
429 rc = memcmp(untouched, calibration, sizeof(calibration));
430 ck_assert_int_eq(rc, 0);
431 }
432 END_TEST
433
START_TEST(range_prop_parser)434 START_TEST(range_prop_parser)
435 {
436 struct parser_test_range {
437 char *tag;
438 bool success;
439 int hi, lo;
440 } tests[] = {
441 { "10:8", true, 10, 8 },
442 { "100:-1", true, 100, -1 },
443 { "-203813:-502023", true, -203813, -502023 },
444 { "238492:28210", true, 238492, 28210 },
445 { "none", true, 0, 0 },
446 { "0:0", false, 0, 0 },
447 { "", false, 0, 0 },
448 { "abcd", false, 0, 0 },
449 { "10:30:10", false, 0, 0 },
450 { NULL, false, 0, 0 }
451 };
452 int i;
453 int hi, lo;
454 bool success;
455
456 for (i = 0; tests[i].tag != NULL; i++) {
457 hi = lo = 0xad;
458 success = parse_range_property(tests[i].tag, &hi, &lo);
459 ck_assert(success == tests[i].success);
460 if (success) {
461 ck_assert_int_eq(hi, tests[i].hi);
462 ck_assert_int_eq(lo, tests[i].lo);
463 } else {
464 ck_assert_int_eq(hi, 0xad);
465 ck_assert_int_eq(lo, 0xad);
466 }
467 }
468
469 success = parse_range_property(NULL, NULL, NULL);
470 ck_assert(success == false);
471 }
472 END_TEST
473
START_TEST(boolean_prop_parser)474 START_TEST(boolean_prop_parser)
475 {
476 struct parser_test_range {
477 char *tag;
478 bool success;
479 bool b;
480 } tests[] = {
481 { "0", true, false },
482 { "1", true, true },
483 { "-1", false, false },
484 { "2", false, false },
485 { "abcd", false, false },
486 { NULL, false, false }
487 };
488 int i;
489 bool success, b;
490
491 for (i = 0; tests[i].tag != NULL; i++) {
492 b = false;
493 success = parse_boolean_property(tests[i].tag, &b);
494 ck_assert(success == tests[i].success);
495 if (success)
496 ck_assert_int_eq(b, tests[i].b);
497 else
498 ck_assert_int_eq(b, false);
499 }
500
501 success = parse_boolean_property(NULL, NULL);
502 ck_assert(success == false);
503 }
504 END_TEST
505
START_TEST(evcode_prop_parser)506 START_TEST(evcode_prop_parser)
507 {
508 struct parser_test_tuple {
509 const char *prop;
510 bool success;
511 size_t ntuples;
512 int tuples[20];
513 } tests[] = {
514 { "EV_KEY", true, 1, {EV_KEY, 0xffff} },
515 { "EV_ABS;", true, 1, {EV_ABS, 0xffff} },
516 { "ABS_X;", true, 1, {EV_ABS, ABS_X} },
517 { "SW_TABLET_MODE;", true, 1, {EV_SW, SW_TABLET_MODE} },
518 { "EV_SW", true, 1, {EV_SW, 0xffff} },
519 { "ABS_Y", true, 1, {EV_ABS, ABS_Y} },
520 { "EV_ABS:0x00", true, 1, {EV_ABS, ABS_X} },
521 { "EV_ABS:01", true, 1, {EV_ABS, ABS_Y} },
522 { "ABS_TILT_X;ABS_TILT_Y;", true, 2,
523 { EV_ABS, ABS_TILT_X,
524 EV_ABS, ABS_TILT_Y} },
525 { "BTN_TOOL_DOUBLETAP;EV_KEY;KEY_A", true, 3,
526 { EV_KEY, BTN_TOOL_DOUBLETAP,
527 EV_KEY, 0xffff,
528 EV_KEY, KEY_A } },
529 { "REL_Y;ABS_Z;BTN_STYLUS", true, 3,
530 { EV_REL, REL_Y,
531 EV_ABS, ABS_Z,
532 EV_KEY, BTN_STYLUS } },
533 { "REL_Y;EV_KEY:0x123;BTN_STYLUS", true, 3,
534 { EV_REL, REL_Y,
535 EV_KEY, 0x123,
536 EV_KEY, BTN_STYLUS } },
537 { .prop = "", .success = false },
538 { .prop = "EV_FOO", .success = false },
539 { .prop = "EV_KEY;EV_FOO", .success = false },
540 { .prop = "BTN_STYLUS;EV_FOO", .success = false },
541 { .prop = "BTN_UNKNOWN", .success = false },
542 { .prop = "BTN_UNKNOWN;EV_KEY", .success = false },
543 { .prop = "PR_UNKNOWN", .success = false },
544 { .prop = "BTN_STYLUS;PR_UNKNOWN;ABS_X", .success = false },
545 { .prop = "EV_REL:0xffff", .success = false },
546 { .prop = "EV_REL:0x123.", .success = false },
547 { .prop = "EV_REL:ffff", .success = false },
548 { .prop = "EV_REL:blah", .success = false },
549 { .prop = "KEY_A:0x11", .success = false },
550 { .prop = "EV_KEY:0x11 ", .success = false },
551 { .prop = "EV_KEY:0x11not", .success = false },
552 { .prop = "none", .success = false },
553 { .prop = NULL },
554 };
555 struct parser_test_tuple *t;
556
557 for (int i = 0; tests[i].prop; i++) {
558 bool success;
559 struct input_event events[32];
560 size_t nevents = ARRAY_LENGTH(events);
561
562 t = &tests[i];
563 success = parse_evcode_property(t->prop, events, &nevents);
564 ck_assert(success == t->success);
565 if (!success)
566 continue;
567
568 ck_assert_int_eq(nevents, t->ntuples);
569 for (size_t j = 0; j < nevents; j++) {
570 int type, code;
571
572 type = events[j].type;
573 code = events[j].code;
574 ck_assert_int_eq(t->tuples[j * 2], type);
575 ck_assert_int_eq(t->tuples[j * 2 + 1], code);
576 }
577 }
578 }
579 END_TEST
580
START_TEST(input_prop_parser)581 START_TEST(input_prop_parser)
582 {
583 struct parser_test_val {
584 const char *prop;
585 bool success;
586 size_t nvals;
587 uint32_t values[20];
588 } tests[] = {
589 { "INPUT_PROP_BUTTONPAD", true, 1, {INPUT_PROP_BUTTONPAD}},
590 { "INPUT_PROP_BUTTONPAD;INPUT_PROP_POINTER", true, 2,
591 { INPUT_PROP_BUTTONPAD,
592 INPUT_PROP_POINTER }},
593 { "INPUT_PROP_BUTTONPAD;0x00;0x03", true, 3,
594 { INPUT_PROP_BUTTONPAD,
595 INPUT_PROP_POINTER,
596 INPUT_PROP_SEMI_MT }},
597 { .prop = "", .success = false },
598 { .prop = "0xff", .success = false },
599 { .prop = "INPUT_PROP", .success = false },
600 { .prop = "INPUT_PROP_FOO", .success = false },
601 { .prop = "INPUT_PROP_FOO;INPUT_PROP_FOO", .success = false },
602 { .prop = "INPUT_PROP_POINTER;INPUT_PROP_FOO", .success = false },
603 { .prop = "none", .success = false },
604 { .prop = NULL },
605 };
606 struct parser_test_val *t;
607
608 for (int i = 0; tests[i].prop; i++) {
609 bool success;
610 uint32_t props[32];
611 size_t nprops = ARRAY_LENGTH(props);
612
613 t = &tests[i];
614 success = parse_input_prop_property(t->prop, props, &nprops);
615 ck_assert(success == t->success);
616 if (!success)
617 continue;
618
619 ck_assert_int_eq(nprops, t->nvals);
620 for (size_t j = 0; j < t->nvals; j++) {
621 ck_assert_int_eq(t->values[j], props[j]);
622 }
623 }
624 }
625 END_TEST
626
START_TEST(evdev_abs_parser)627 START_TEST(evdev_abs_parser)
628 {
629 struct test {
630 uint32_t which;
631 const char *prop;
632 int min, max, res, fuzz, flat;
633
634 } tests[] = {
635 { .which = (ABS_MASK_MIN|ABS_MASK_MAX),
636 .prop = "1:2",
637 .min = 1, .max = 2 },
638 { .which = (ABS_MASK_MIN|ABS_MASK_MAX),
639 .prop = "1:2:",
640 .min = 1, .max = 2 },
641 { .which = (ABS_MASK_MIN|ABS_MASK_MAX|ABS_MASK_RES),
642 .prop = "10:20:30",
643 .min = 10, .max = 20, .res = 30 },
644 { .which = (ABS_MASK_RES),
645 .prop = "::100",
646 .res = 100 },
647 { .which = (ABS_MASK_MIN),
648 .prop = "10:",
649 .min = 10 },
650 { .which = (ABS_MASK_MAX|ABS_MASK_RES),
651 .prop = ":10:1001",
652 .max = 10, .res = 1001 },
653 { .which = (ABS_MASK_MIN|ABS_MASK_MAX|ABS_MASK_RES|ABS_MASK_FUZZ),
654 .prop = "1:2:3:4",
655 .min = 1, .max = 2, .res = 3, .fuzz = 4},
656 { .which = (ABS_MASK_MIN|ABS_MASK_MAX|ABS_MASK_RES|ABS_MASK_FUZZ|ABS_MASK_FLAT),
657 .prop = "1:2:3:4:5",
658 .min = 1, .max = 2, .res = 3, .fuzz = 4, .flat = 5},
659 { .which = (ABS_MASK_MIN|ABS_MASK_RES|ABS_MASK_FUZZ|ABS_MASK_FLAT),
660 .prop = "1::3:4:50",
661 .min = 1, .res = 3, .fuzz = 4, .flat = 50},
662 { .which = ABS_MASK_FUZZ|ABS_MASK_FLAT,
663 .prop = ":::5:60",
664 .fuzz = 5, .flat = 60},
665 { .which = ABS_MASK_FUZZ,
666 .prop = ":::5:",
667 .fuzz = 5 },
668 { .which = ABS_MASK_RES, .prop = "::12::",
669 .res = 12 },
670 /* Malformed property but parsing this one makes us more
671 * future proof */
672 { .which = (ABS_MASK_RES|ABS_MASK_FUZZ|ABS_MASK_FLAT),
673 .prop = "::12:1:2:3:4:5:6",
674 .res = 12, .fuzz = 1, .flat = 2 },
675 { .which = 0, .prop = ":::::" },
676 { .which = 0, .prop = ":" },
677 { .which = 0, .prop = "" },
678 { .which = 0, .prop = ":asb::::" },
679 { .which = 0, .prop = "foo" },
680 };
681 struct test *t;
682
683 ARRAY_FOR_EACH(tests, t) {
684 struct input_absinfo abs;
685 uint32_t mask;
686
687 mask = parse_evdev_abs_prop(t->prop, &abs);
688 ck_assert_int_eq(mask, t->which);
689
690 if (t->which & ABS_MASK_MIN)
691 ck_assert_int_eq(abs.minimum, t->min);
692 if (t->which & ABS_MASK_MAX)
693 ck_assert_int_eq(abs.maximum, t->max);
694 if (t->which & ABS_MASK_RES)
695 ck_assert_int_eq(abs.resolution, t->res);
696 if (t->which & ABS_MASK_FUZZ)
697 ck_assert_int_eq(abs.fuzz, t->fuzz);
698 if (t->which & ABS_MASK_FLAT)
699 ck_assert_int_eq(abs.flat, t->flat);
700 }
701 }
702 END_TEST
703
START_TEST(time_conversion)704 START_TEST(time_conversion)
705 {
706 ck_assert_int_eq(us(10), 10);
707 ck_assert_int_eq(ns2us(10000), 10);
708 ck_assert_int_eq(ms2us(10), 10000);
709 ck_assert_int_eq(s2us(1), 1000000);
710 ck_assert_int_eq(h2us(2), s2us(2 * 60 * 60));
711 ck_assert_int_eq(us2ms(10000), 10);
712 }
713 END_TEST
714
START_TEST(human_time)715 START_TEST(human_time)
716 {
717 struct ht_tests {
718 uint64_t interval;
719 unsigned int value;
720 const char *unit;
721 } tests[] = {
722 { 0, 0, "us" },
723 { 123, 123, "us" },
724 { ms2us(5), 5, "ms" },
725 { ms2us(100), 100, "ms" },
726 { s2us(5), 5, "s" },
727 { s2us(100), 100, "s" },
728 { s2us(120), 2, "min" },
729 { 5 * s2us(60), 5, "min" },
730 { 120 * s2us(60), 2, "h" },
731 { 5 * 60 * s2us(60), 5, "h" },
732 { 48 * 60 * s2us(60), 2, "d" },
733 { 1000 * 24 * 60 * s2us(60), 1000, "d" },
734 { 0, 0, NULL },
735 };
736 for (int i = 0; tests[i].unit != NULL; i++) {
737 struct human_time ht;
738
739 ht = to_human_time(tests[i].interval);
740 ck_assert_int_eq(ht.value, tests[i].value);
741 ck_assert_str_eq(ht.unit, tests[i].unit);
742 }
743 }
744 END_TEST
745
746 struct atoi_test {
747 char *str;
748 bool success;
749 int val;
750 };
751
START_TEST(safe_atoi_test)752 START_TEST(safe_atoi_test)
753 {
754 struct atoi_test tests[] = {
755 { "10", true, 10 },
756 { "20", true, 20 },
757 { "-1", true, -1 },
758 { "2147483647", true, 2147483647 },
759 { "-2147483648", true, -2147483648 },
760 { "4294967295", false, 0 },
761 { "0x0", false, 0 },
762 { "-10x10", false, 0 },
763 { "1x-99", false, 0 },
764 { "", false, 0 },
765 { "abd", false, 0 },
766 { "xabd", false, 0 },
767 { "0xaf", false, 0 },
768 { "0x0x", false, 0 },
769 { "x10", false, 0 },
770 { NULL, false, 0 }
771 };
772 int v;
773 bool success;
774
775 for (int i = 0; tests[i].str != NULL; i++) {
776 v = 0xad;
777 success = safe_atoi(tests[i].str, &v);
778 ck_assert(success == tests[i].success);
779 if (success)
780 ck_assert_int_eq(v, tests[i].val);
781 else
782 ck_assert_int_eq(v, 0xad);
783 }
784 }
785 END_TEST
786
START_TEST(safe_atoi_base_16_test)787 START_TEST(safe_atoi_base_16_test)
788 {
789 struct atoi_test tests[] = {
790 { "10", true, 0x10 },
791 { "20", true, 0x20 },
792 { "-1", true, -1 },
793 { "0x10", true, 0x10 },
794 { "0xff", true, 0xff },
795 { "abc", true, 0xabc },
796 { "-10", true, -0x10 },
797 { "0x0", true, 0 },
798 { "0", true, 0 },
799 { "0x-99", false, 0 },
800 { "0xak", false, 0 },
801 { "0x", false, 0 },
802 { "x10", false, 0 },
803 { NULL, false, 0 }
804 };
805
806 int v;
807 bool success;
808
809 for (int i = 0; tests[i].str != NULL; i++) {
810 v = 0xad;
811 success = safe_atoi_base(tests[i].str, &v, 16);
812 ck_assert(success == tests[i].success);
813 if (success)
814 ck_assert_int_eq(v, tests[i].val);
815 else
816 ck_assert_int_eq(v, 0xad);
817 }
818 }
819 END_TEST
820
START_TEST(safe_atoi_base_8_test)821 START_TEST(safe_atoi_base_8_test)
822 {
823 struct atoi_test tests[] = {
824 { "7", true, 07 },
825 { "10", true, 010 },
826 { "20", true, 020 },
827 { "-1", true, -1 },
828 { "010", true, 010 },
829 { "0ff", false, 0 },
830 { "abc", false, 0},
831 { "0xabc", false, 0},
832 { "-10", true, -010 },
833 { "0", true, 0 },
834 { "00", true, 0 },
835 { "0x0", false, 0 },
836 { "0x-99", false, 0 },
837 { "0xak", false, 0 },
838 { "0x", false, 0 },
839 { "x10", false, 0 },
840 { NULL, false, 0 }
841 };
842
843 int v;
844 bool success;
845
846 for (int i = 0; tests[i].str != NULL; i++) {
847 v = 0xad;
848 success = safe_atoi_base(tests[i].str, &v, 8);
849 ck_assert(success == tests[i].success);
850 if (success)
851 ck_assert_int_eq(v, tests[i].val);
852 else
853 ck_assert_int_eq(v, 0xad);
854 }
855 }
856 END_TEST
857
858 struct atou_test {
859 char *str;
860 bool success;
861 unsigned int val;
862 };
863
START_TEST(safe_atou_test)864 START_TEST(safe_atou_test)
865 {
866 struct atou_test tests[] = {
867 { "10", true, 10 },
868 { "20", true, 20 },
869 { "-1", false, 0 },
870 { "2147483647", true, 2147483647 },
871 { "-2147483648", false, 0},
872 { "0x0", false, 0 },
873 { "-10x10", false, 0 },
874 { "1x-99", false, 0 },
875 { "", false, 0 },
876 { "abd", false, 0 },
877 { "xabd", false, 0 },
878 { "0xaf", false, 0 },
879 { "0x0x", false, 0 },
880 { "x10", false, 0 },
881 { NULL, false, 0 }
882 };
883 unsigned int v;
884 bool success;
885
886 for (int i = 0; tests[i].str != NULL; i++) {
887 v = 0xad;
888 success = safe_atou(tests[i].str, &v);
889 ck_assert(success == tests[i].success);
890 if (success)
891 ck_assert_int_eq(v, tests[i].val);
892 else
893 ck_assert_int_eq(v, 0xad);
894 }
895 }
896 END_TEST
897
START_TEST(safe_atou_base_16_test)898 START_TEST(safe_atou_base_16_test)
899 {
900 struct atou_test tests[] = {
901 { "10", true, 0x10 },
902 { "20", true, 0x20 },
903 { "-1", false, 0 },
904 { "0x10", true, 0x10 },
905 { "0xff", true, 0xff },
906 { "abc", true, 0xabc },
907 { "-10", false, 0 },
908 { "0x0", true, 0 },
909 { "0", true, 0 },
910 { "0x-99", false, 0 },
911 { "0xak", false, 0 },
912 { "0x", false, 0 },
913 { "x10", false, 0 },
914 { NULL, false, 0 }
915 };
916
917 unsigned int v;
918 bool success;
919
920 for (int i = 0; tests[i].str != NULL; i++) {
921 v = 0xad;
922 success = safe_atou_base(tests[i].str, &v, 16);
923 ck_assert(success == tests[i].success);
924 if (success)
925 ck_assert_int_eq(v, tests[i].val);
926 else
927 ck_assert_int_eq(v, 0xad);
928 }
929 }
930 END_TEST
931
START_TEST(safe_atou_base_8_test)932 START_TEST(safe_atou_base_8_test)
933 {
934 struct atou_test tests[] = {
935 { "7", true, 07 },
936 { "10", true, 010 },
937 { "20", true, 020 },
938 { "-1", false, 0 },
939 { "010", true, 010 },
940 { "0ff", false, 0 },
941 { "abc", false, 0},
942 { "0xabc", false, 0},
943 { "-10", false, 0 },
944 { "0", true, 0 },
945 { "00", true, 0 },
946 { "0x0", false, 0 },
947 { "0x-99", false, 0 },
948 { "0xak", false, 0 },
949 { "0x", false, 0 },
950 { "x10", false, 0 },
951 { NULL, false, 0 }
952 };
953
954 unsigned int v;
955 bool success;
956
957 for (int i = 0; tests[i].str != NULL; i++) {
958 v = 0xad;
959 success = safe_atou_base(tests[i].str, &v, 8);
960 ck_assert(success == tests[i].success);
961 if (success)
962 ck_assert_int_eq(v, tests[i].val);
963 else
964 ck_assert_int_eq(v, 0xad);
965 }
966 }
967 END_TEST
968
START_TEST(safe_atod_test)969 START_TEST(safe_atod_test)
970 {
971 struct atod_test {
972 char *str;
973 bool success;
974 double val;
975 } tests[] = {
976 { "10", true, 10 },
977 { "20", true, 20 },
978 { "-1", true, -1 },
979 { "2147483647", true, 2147483647 },
980 { "-2147483648", true, -2147483648 },
981 { "4294967295", true, 4294967295 },
982 { "0x0", false, 0 },
983 { "0x10", false, 0 },
984 { "0xaf", false, 0 },
985 { "x80", false, 0 },
986 { "0.0", true, 0.0 },
987 { "0.1", true, 0.1 },
988 { "1.2", true, 1.2 },
989 { "-324.9", true, -324.9 },
990 { "9324.9", true, 9324.9 },
991 { "NAN", false, 0 },
992 { "INFINITY", false, 0 },
993 { "-10x10", false, 0 },
994 { "1x-99", false, 0 },
995 { "", false, 0 },
996 { "abd", false, 0 },
997 { "xabd", false, 0 },
998 { "0x0x", false, 0 },
999 { NULL, false, 0 }
1000 };
1001 double v;
1002 bool success;
1003
1004 for (int i = 0; tests[i].str != NULL; i++) {
1005 v = 0xad;
1006 success = safe_atod(tests[i].str, &v);
1007 ck_assert(success == tests[i].success);
1008 if (success)
1009 ck_assert_int_eq(v, tests[i].val);
1010 else
1011 ck_assert_int_eq(v, 0xad);
1012 }
1013 }
1014 END_TEST
1015
START_TEST(strsplit_test)1016 START_TEST(strsplit_test)
1017 {
1018 struct strsplit_test {
1019 const char *string;
1020 const char *delim;
1021 const char *results[10];
1022 } tests[] = {
1023 { "one two three", " ", { "one", "two", "three", NULL } },
1024 { "one", " ", { "one", NULL } },
1025 { "one two ", " ", { "one", "two", NULL } },
1026 { "one two", " ", { "one", "two", NULL } },
1027 { " one two", " ", { "one", "two", NULL } },
1028 { "one", "\t \r", { "one", NULL } },
1029 { "one two three", " t", { "one", "wo", "hree", NULL } },
1030 { " one two three", "te", { " on", " ", "wo ", "hr", NULL } },
1031 { "one", "ne", { "o", NULL } },
1032 { "onene", "ne", { "o", NULL } },
1033 { NULL, NULL, { NULL }}
1034 };
1035 struct strsplit_test *t = tests;
1036
1037 while (t->string) {
1038 char **strv;
1039 int idx = 0;
1040 strv = strv_from_string(t->string, t->delim);
1041 while (t->results[idx]) {
1042 ck_assert_str_eq(t->results[idx], strv[idx]);
1043 idx++;
1044 }
1045 ck_assert_ptr_eq(strv[idx], NULL);
1046 strv_free(strv);
1047 t++;
1048 }
1049
1050 /* Special cases */
1051 ck_assert_ptr_eq(strv_from_string("", " "), NULL);
1052 ck_assert_ptr_eq(strv_from_string(" ", " "), NULL);
1053 ck_assert_ptr_eq(strv_from_string(" ", " "), NULL);
1054 ck_assert_ptr_eq(strv_from_string("oneoneone", "one"), NULL);
1055 }
1056 END_TEST
1057
START_TEST(strargv_test)1058 START_TEST(strargv_test)
1059 {
1060 struct argv_test {
1061 int argc;
1062 char *argv[10];
1063 int expected;
1064 } tests[] = {
1065 { 0, {NULL}, 0 },
1066 { 1, {"hello", "World"}, 1 },
1067 { 2, {"hello", "World"}, 2 },
1068 { 2, {"", " "}, 2 },
1069 { 2, {"", NULL}, 0 },
1070 { 2, {NULL, NULL}, 0 },
1071 { 1, {NULL, NULL}, 0 },
1072 { 3, {"hello", NULL, "World"}, 0 },
1073 };
1074 struct argv_test *t;
1075
1076 ARRAY_FOR_EACH(tests, t) {
1077 char **strv = strv_from_argv(t->argc, t->argv);
1078
1079 if (t->expected == 0) {
1080 ck_assert(strv == NULL);
1081 } else {
1082 int count = 0;
1083 char **s = strv;
1084 while (*s) {
1085 ck_assert_str_eq(*s, t->argv[count]);
1086 count++;
1087 s++;
1088 }
1089 ck_assert_int_eq(t->expected, count);
1090 strv_free(strv);
1091 }
1092 }
1093 }
1094 END_TEST
1095
START_TEST(kvsplit_double_test)1096 START_TEST(kvsplit_double_test)
1097 {
1098 struct kvsplit_dbl_test {
1099 const char *string;
1100 const char *psep;
1101 const char *kvsep;
1102 ssize_t nresults;
1103 struct {
1104 double a;
1105 double b;
1106 } results[32];
1107 } tests[] = {
1108 { "1:2;3:4;5:6", ";", ":", 3, { {1, 2}, {3, 4}, {5, 6}}},
1109 { "1.0x2.3 -3.2x4.5 8.090909x-6.00", " ", "x", 3, { {1.0, 2.3}, {-3.2, 4.5}, {8.090909, -6}}},
1110
1111 { "1:2", "x", ":", 1, {{1, 2}}},
1112 { "1:2", ":", "x", -1, {}},
1113 { "1:2", NULL, "x", -1, {}},
1114 { "1:2", "", "x", -1, {}},
1115 { "1:2", "x", NULL, -1, {}},
1116 { "1:2", "x", "", -1, {}},
1117 { "a:b", "x", ":", -1, {}},
1118 { "", " ", "x", -1, {}},
1119 { "1.2.3.4.5", ".", "", -1, {}},
1120 { NULL }
1121 };
1122 struct kvsplit_dbl_test *t = tests;
1123
1124 while (t->string) {
1125 struct key_value_double *result = NULL;
1126 ssize_t npairs;
1127
1128 npairs = kv_double_from_string(t->string,
1129 t->psep,
1130 t->kvsep,
1131 &result);
1132 ck_assert_int_eq(npairs, t->nresults);
1133
1134 for (ssize_t i = 0; i < npairs; i++) {
1135 ck_assert_double_eq(t->results[i].a, result[i].key);
1136 ck_assert_double_eq(t->results[i].b, result[i].value);
1137 }
1138
1139
1140 free(result);
1141 t++;
1142 }
1143 }
1144 END_TEST
1145
START_TEST(strjoin_test)1146 START_TEST(strjoin_test)
1147 {
1148 struct strjoin_test {
1149 char *strv[10];
1150 const char *joiner;
1151 const char *result;
1152 } tests[] = {
1153 { { "one", "two", "three", NULL }, " ", "one two three" },
1154 { { "one", NULL }, "x", "one" },
1155 { { "one", "two", NULL }, "x", "onextwo" },
1156 { { "one", "two", NULL }, ",", "one,two" },
1157 { { "one", "two", NULL }, ", ", "one, two" },
1158 { { "one", "two", NULL }, "one", "oneonetwo" },
1159 { { "one", "two", NULL }, NULL, NULL },
1160 { { "", "", "", NULL }, " ", " " },
1161 { { "a", "b", "c", NULL }, "", "abc" },
1162 { { "", "b", "c", NULL }, "x", "xbxc" },
1163 { { "", "", "", NULL }, "", "" },
1164 { { NULL }, NULL, NULL }
1165 };
1166 struct strjoin_test *t = tests;
1167 struct strjoin_test nulltest = { {NULL}, "x", NULL };
1168
1169 while (t->strv[0]) {
1170 char *str;
1171 str = strv_join(t->strv, t->joiner);
1172 if (t->result == NULL)
1173 ck_assert(str == NULL);
1174 else
1175 ck_assert_str_eq(str, t->result);
1176 free(str);
1177 t++;
1178 }
1179
1180 ck_assert(strv_join(nulltest.strv, "x") == NULL);
1181 }
1182 END_TEST
1183
START_TEST(strstrip_test)1184 START_TEST(strstrip_test)
1185 {
1186 struct strstrip_test {
1187 const char *string;
1188 const char *expected;
1189 const char *what;
1190 } tests[] = {
1191 { "foo", "foo", "1234" },
1192 { "\"bar\"", "bar", "\"" },
1193 { "'bar'", "bar", "'" },
1194 { "\"bar\"", "\"bar\"", "'" },
1195 { "'bar'", "'bar'", "\"" },
1196 { "\"bar\"", "bar", "\"" },
1197 { "\"\"", "", "\"" },
1198 { "\"foo\"bar\"", "foo\"bar", "\"" },
1199 { "\"'foo\"bar\"", "foo\"bar", "\"'" },
1200 { "abcfooabcbarbca", "fooabcbar", "abc" },
1201 { "xxxxfoo", "foo", "x" },
1202 { "fooyyyy", "foo", "y" },
1203 { "xxxxfooyyyy", "foo", "xy" },
1204 { "x xfooy y", " xfooy ", "xy" },
1205 { " foo\n", "foo", " \n" },
1206 { "", "", "abc" },
1207 { "", "", "" },
1208 { NULL , NULL, NULL }
1209 };
1210 struct strstrip_test *t = tests;
1211
1212 while (t->string) {
1213 char *str;
1214 str = strstrip(t->string, t->what);
1215 ck_assert_str_eq(str, t->expected);
1216 free(str);
1217 t++;
1218 }
1219 }
1220 END_TEST
1221
START_TEST(strendswith_test)1222 START_TEST(strendswith_test)
1223 {
1224 struct strendswith_test {
1225 const char *string;
1226 const char *suffix;
1227 bool expected;
1228 } tests[] = {
1229 { "foobar", "bar", true },
1230 { "foobar", "foo", false },
1231 { "foobar", "foobar", true },
1232 { "foo", "foobar", false },
1233 { "foobar", "", false },
1234 { "", "", false },
1235 { "", "foo", false },
1236 { NULL, NULL, false },
1237 };
1238
1239 for (struct strendswith_test *t = tests; t->string; t++) {
1240 ck_assert_int_eq(strendswith(t->string, t->suffix),
1241 t->expected);
1242 }
1243 }
1244 END_TEST
1245
START_TEST(strstartswith_test)1246 START_TEST(strstartswith_test)
1247 {
1248 struct strstartswith_test {
1249 const char *string;
1250 const char *suffix;
1251 bool expected;
1252 } tests[] = {
1253 { "foobar", "foo", true },
1254 { "foobar", "bar", false },
1255 { "foobar", "foobar", true },
1256 { "foo", "foobar", false },
1257 { "foo", "", false },
1258 { "", "", false },
1259 { "foo", "", false },
1260 { NULL, NULL, false },
1261 };
1262
1263 for (struct strstartswith_test *t = tests; t->string; t++) {
1264 ck_assert_int_eq(strstartswith(t->string, t->suffix),
1265 t->expected);
1266 }
1267 }
1268 END_TEST
1269
START_TEST(strsanitize_test)1270 START_TEST(strsanitize_test)
1271 {
1272 struct strsanitize_test {
1273 const char *string;
1274 const char *expected;
1275 } tests[] = {
1276 { "foobar", "foobar" },
1277 { "", "" },
1278 { "%", "%%" },
1279 { "%%%%", "%%%%%%%%" },
1280 { "x %s", "x %%s" },
1281 { "x %", "x %%" },
1282 { "%sx", "%%sx" },
1283 { "%s%s", "%%s%%s" },
1284 { NULL, NULL },
1285 };
1286
1287 for (struct strsanitize_test *t = tests; t->string; t++) {
1288 char *sanitized = str_sanitize(t->string);
1289 ck_assert_str_eq(sanitized, t->expected);
1290 free(sanitized);
1291 }
1292 }
1293 END_TEST
1294
START_TEST(list_test_insert)1295 START_TEST(list_test_insert)
1296 {
1297 struct list_test {
1298 int val;
1299 struct list node;
1300 } tests[] = {
1301 { .val = 1 },
1302 { .val = 2 },
1303 { .val = 3 },
1304 { .val = 4 },
1305 };
1306 struct list_test *t;
1307 struct list head;
1308 int val;
1309
1310 list_init(&head);
1311
1312 ARRAY_FOR_EACH(tests, t) {
1313 list_insert(&head, &t->node);
1314 }
1315
1316 val = 4;
1317 list_for_each(t, &head, node) {
1318 ck_assert_int_eq(t->val, val);
1319 val--;
1320 }
1321
1322 ck_assert_int_eq(val, 0);
1323 }
1324 END_TEST
1325
START_TEST(list_test_append)1326 START_TEST(list_test_append)
1327 {
1328 struct list_test {
1329 int val;
1330 struct list node;
1331 } tests[] = {
1332 { .val = 1 },
1333 { .val = 2 },
1334 { .val = 3 },
1335 { .val = 4 },
1336 };
1337 struct list_test *t;
1338 struct list head;
1339 int val;
1340
1341 list_init(&head);
1342
1343 ARRAY_FOR_EACH(tests, t) {
1344 list_append(&head, &t->node);
1345 }
1346
1347 val = 1;
1348 list_for_each(t, &head, node) {
1349 ck_assert_int_eq(t->val, val);
1350 val++;
1351 }
1352 ck_assert_int_eq(val, 5);
1353 }
1354 END_TEST
1355
START_TEST(list_test_foreach)1356 START_TEST(list_test_foreach)
1357 {
1358 struct list_test {
1359 int val;
1360 struct list node;
1361 } tests[] = {
1362 { .val = 1 },
1363 { .val = 2 },
1364 { .val = 3 },
1365 { .val = 4 },
1366 };
1367 struct list_test *t;
1368 struct list head;
1369
1370 list_init(&head);
1371
1372 ARRAY_FOR_EACH(tests, t) {
1373 list_append(&head, &t->node);
1374 }
1375
1376 /* Make sure both loop macros are a single line statement */
1377 if (false)
1378 list_for_each(t, &head, node) {
1379 ck_abort_msg("We should not get here");
1380 }
1381
1382 if (false)
1383 list_for_each_safe(t, &head, node) {
1384 ck_abort_msg("We should not get here");
1385 }
1386 }
1387 END_TEST
1388
START_TEST(strverscmp_test)1389 START_TEST(strverscmp_test)
1390 {
1391 ck_assert_int_eq(libinput_strverscmp("", ""), 0);
1392 ck_assert_int_gt(libinput_strverscmp("0.0.1", ""), 0);
1393 ck_assert_int_lt(libinput_strverscmp("", "0.0.1"), 0);
1394 ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.0.1"), 0);
1395 ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.0.2"), -1);
1396 ck_assert_int_eq(libinput_strverscmp("0.0.2", "0.0.1"), 1);
1397 ck_assert_int_eq(libinput_strverscmp("0.0.1", "0.1.0"), -1);
1398 ck_assert_int_eq(libinput_strverscmp("0.1.0", "0.0.1"), 1);
1399 }
1400 END_TEST
1401
START_TEST(streq_test)1402 START_TEST(streq_test)
1403 {
1404 ck_assert(streq("", "") == true);
1405 ck_assert(streq(NULL, NULL) == true);
1406 ck_assert(streq("0.0.1", "") == false);
1407 ck_assert(streq("foo", NULL) == false);
1408 ck_assert(streq(NULL, "foo") == false);
1409 ck_assert(streq("0.0.1", "0.0.1") == true);
1410 }
1411 END_TEST
1412
START_TEST(strneq_test)1413 START_TEST(strneq_test)
1414 {
1415 ck_assert(strneq("", "", 1) == true);
1416 ck_assert(strneq(NULL, NULL, 1) == true);
1417 ck_assert(strneq("0.0.1", "", 6) == false);
1418 ck_assert(strneq("foo", NULL, 5) == false);
1419 ck_assert(strneq(NULL, "foo", 5) == false);
1420 ck_assert(strneq("0.0.1", "0.0.1", 6) == true);
1421 }
1422 END_TEST
1423
START_TEST(basename_test)1424 START_TEST(basename_test)
1425 {
1426 struct test {
1427 const char *path;
1428 const char *expected;
1429 } tests[] = {
1430 { "a", "a" },
1431 { "foo.c", "foo.c" },
1432 { "foo", "foo" },
1433 { "/path/to/foo.h", "foo.h" },
1434 { "../bar.foo", "bar.foo" },
1435 { "./bar.foo.baz", "bar.foo.baz" },
1436 { "./", NULL },
1437 { "/", NULL },
1438 { "/bar/", NULL },
1439 { "/bar", "bar" },
1440 { "", NULL },
1441 };
1442 struct test *t;
1443
1444 ARRAY_FOR_EACH(tests, t) {
1445 const char *result = safe_basename(t->path);
1446 if (t->expected == NULL)
1447 ck_assert(result == NULL);
1448 else
1449 ck_assert_str_eq(result, t->expected);
1450 }
1451 }
1452 END_TEST
START_TEST(trunkname_test)1453 START_TEST(trunkname_test)
1454 {
1455 struct test {
1456 const char *path;
1457 const char *expected;
1458 } tests[] = {
1459 { "foo.c", "foo" },
1460 { "/path/to/foo.h", "foo" },
1461 { "/path/to/foo", "foo" },
1462 { "../bar.foo", "bar" },
1463 { "./bar.foo.baz", "bar.foo" },
1464 { "./", "" },
1465 { "/", "" },
1466 { "/bar/", "" },
1467 { "/bar", "bar" },
1468 { "", "" },
1469 };
1470 struct test *t;
1471
1472 ARRAY_FOR_EACH(tests, t) {
1473 char *result = trunkname(t->path);
1474 ck_assert_str_eq(result, t->expected);
1475 free(result);
1476 }
1477 }
1478 END_TEST
1479
1480 static Suite *
litest_utils_suite(void)1481 litest_utils_suite(void)
1482 {
1483 TCase *tc;
1484 Suite *s;
1485
1486 s = suite_create("litest:utils");
1487 tc = tcase_create("utils");
1488
1489 tcase_add_test(tc, bitfield_helpers);
1490 tcase_add_test(tc, matrix_helpers);
1491 tcase_add_test(tc, ratelimit_helpers);
1492 tcase_add_test(tc, dpi_parser);
1493 tcase_add_test(tc, wheel_click_parser);
1494 tcase_add_test(tc, wheel_click_count_parser);
1495 tcase_add_test(tc, dimension_prop_parser);
1496 tcase_add_test(tc, reliability_prop_parser);
1497 tcase_add_test(tc, calibration_prop_parser);
1498 tcase_add_test(tc, range_prop_parser);
1499 tcase_add_test(tc, boolean_prop_parser);
1500 tcase_add_test(tc, evcode_prop_parser);
1501 tcase_add_test(tc, input_prop_parser);
1502 tcase_add_test(tc, evdev_abs_parser);
1503 tcase_add_test(tc, safe_atoi_test);
1504 tcase_add_test(tc, safe_atoi_base_16_test);
1505 tcase_add_test(tc, safe_atoi_base_8_test);
1506 tcase_add_test(tc, safe_atou_test);
1507 tcase_add_test(tc, safe_atou_base_16_test);
1508 tcase_add_test(tc, safe_atou_base_8_test);
1509 tcase_add_test(tc, safe_atod_test);
1510 tcase_add_test(tc, strsplit_test);
1511 tcase_add_test(tc, strargv_test);
1512 tcase_add_test(tc, kvsplit_double_test);
1513 tcase_add_test(tc, strjoin_test);
1514 tcase_add_test(tc, strstrip_test);
1515 tcase_add_test(tc, strendswith_test);
1516 tcase_add_test(tc, strstartswith_test);
1517 tcase_add_test(tc, strsanitize_test);
1518 tcase_add_test(tc, time_conversion);
1519 tcase_add_test(tc, human_time);
1520
1521 tcase_add_test(tc, list_test_insert);
1522 tcase_add_test(tc, list_test_append);
1523 tcase_add_test(tc, list_test_foreach);
1524 tcase_add_test(tc, strverscmp_test);
1525 tcase_add_test(tc, streq_test);
1526 tcase_add_test(tc, strneq_test);
1527 tcase_add_test(tc, trunkname_test);
1528 tcase_add_test(tc, basename_test);
1529
1530 suite_add_tcase(s, tc);
1531
1532 return s;
1533 }
1534
main(int argc,char ** argv)1535 int main(int argc, char **argv)
1536 {
1537 int nfailed;
1538 Suite *s;
1539 SRunner *sr;
1540
1541 s = litest_utils_suite();
1542 sr = srunner_create(s);
1543
1544 srunner_run_all(sr, CK_ENV);
1545 nfailed = srunner_ntests_failed(sr);
1546 srunner_free(sr);
1547
1548 return (nfailed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
1549 }
1550