1 #include <stdarg.h>
2 #include <stddef.h>
3 #include <setjmp.h>
4 #include <cmocka.h>
5 #include <stdlib.h>
6
7 #include "tools/parser.h"
8
9 void
parse_null_returns_null(void ** state)10 parse_null_returns_null(void** state)
11 {
12 char* inp = NULL;
13 gboolean result = TRUE;
14 gchar** args = parse_args(inp, 1, 2, &result);
15
16 assert_false(result);
17 assert_null(args);
18 g_strfreev(args);
19 }
20
21 void
parse_empty_returns_null(void ** state)22 parse_empty_returns_null(void** state)
23 {
24 char* inp = "";
25 gboolean result = TRUE;
26 gchar** args = parse_args(inp, 1, 2, &result);
27
28 assert_false(result);
29 assert_null(args);
30 g_strfreev(args);
31 }
32
33 void
parse_space_returns_null(void ** state)34 parse_space_returns_null(void** state)
35 {
36 char* inp = " ";
37 gboolean result = TRUE;
38 gchar** args = parse_args(inp, 1, 2, &result);
39
40 assert_false(result);
41 assert_null(args);
42 g_strfreev(args);
43 }
44
45 void
parse_cmd_no_args_returns_null(void ** state)46 parse_cmd_no_args_returns_null(void** state)
47 {
48 char* inp = "/cmd";
49 gboolean result = TRUE;
50 gchar** args = parse_args(inp, 1, 2, &result);
51
52 assert_false(result);
53 assert_null(args);
54 g_strfreev(args);
55 }
56
57 void
parse_cmd_with_space_returns_null(void ** state)58 parse_cmd_with_space_returns_null(void** state)
59 {
60 char* inp = "/cmd ";
61 gboolean result = TRUE;
62 gchar** args = parse_args(inp, 1, 2, &result);
63
64 assert_false(result);
65 assert_null(args);
66 g_strfreev(args);
67 }
68
69 void
parse_cmd_with_too_few_returns_null(void ** state)70 parse_cmd_with_too_few_returns_null(void** state)
71 {
72 char* inp = "/cmd arg1";
73 gboolean result = TRUE;
74 gchar** args = parse_args(inp, 2, 3, &result);
75
76 assert_false(result);
77 assert_null(args);
78 g_strfreev(args);
79 }
80
81 void
parse_cmd_with_too_many_returns_null(void ** state)82 parse_cmd_with_too_many_returns_null(void** state)
83 {
84 char* inp = "/cmd arg1 arg2 arg3 arg4";
85 gboolean result = TRUE;
86 gchar** args = parse_args(inp, 1, 3, &result);
87
88 assert_false(result);
89 assert_null(args);
90 g_strfreev(args);
91 }
92
93 void
parse_cmd_one_arg(void ** state)94 parse_cmd_one_arg(void** state)
95 {
96 char* inp = "/cmd arg1";
97 gboolean result = FALSE;
98 gchar** args = parse_args(inp, 1, 2, &result);
99
100 assert_true(result);
101 assert_int_equal(1, g_strv_length(args));
102 assert_string_equal("arg1", args[0]);
103 g_strfreev(args);
104 }
105
106 void
parse_cmd_two_args(void ** state)107 parse_cmd_two_args(void** state)
108 {
109 char* inp = "/cmd arg1 arg2";
110 gboolean result = FALSE;
111 gchar** args = parse_args(inp, 1, 2, &result);
112
113 assert_true(result);
114 assert_int_equal(2, g_strv_length(args));
115 assert_string_equal("arg1", args[0]);
116 assert_string_equal("arg2", args[1]);
117 g_strfreev(args);
118 }
119
120 void
parse_cmd_three_args(void ** state)121 parse_cmd_three_args(void** state)
122 {
123 char* inp = "/cmd arg1 arg2 arg3";
124 gboolean result = FALSE;
125 gchar** args = parse_args(inp, 3, 3, &result);
126
127 assert_true(result);
128 assert_int_equal(3, g_strv_length(args));
129 assert_string_equal("arg1", args[0]);
130 assert_string_equal("arg2", args[1]);
131 assert_string_equal("arg3", args[2]);
132 g_strfreev(args);
133 }
134
135 void
parse_cmd_three_args_with_spaces(void ** state)136 parse_cmd_three_args_with_spaces(void** state)
137 {
138 char* inp = " /cmd arg1 arg2 arg3 ";
139 gboolean result = FALSE;
140 gchar** args = parse_args(inp, 3, 3, &result);
141
142 assert_true(result);
143 assert_int_equal(3, g_strv_length(args));
144 assert_string_equal("arg1", args[0]);
145 assert_string_equal("arg2", args[1]);
146 assert_string_equal("arg3", args[2]);
147 g_strfreev(args);
148 }
149
150 void
parse_cmd_with_freetext(void ** state)151 parse_cmd_with_freetext(void** state)
152 {
153 char* inp = "/cmd this is some free text";
154 gboolean result = FALSE;
155 gchar** args = parse_args_with_freetext(inp, 1, 1, &result);
156
157 assert_true(result);
158 assert_int_equal(1, g_strv_length(args));
159 assert_string_equal("this is some free text", args[0]);
160 g_strfreev(args);
161 }
162
163 void
parse_cmd_one_arg_with_freetext(void ** state)164 parse_cmd_one_arg_with_freetext(void** state)
165 {
166 char* inp = "/cmd arg1 this is some free text";
167 gboolean result = FALSE;
168 gchar** args = parse_args_with_freetext(inp, 1, 2, &result);
169
170 assert_true(result);
171 assert_int_equal(2, g_strv_length(args));
172 assert_string_equal("arg1", args[0]);
173 assert_string_equal("this is some free text", args[1]);
174 g_strfreev(args);
175 }
176
177 void
parse_cmd_two_args_with_freetext(void ** state)178 parse_cmd_two_args_with_freetext(void** state)
179 {
180 char* inp = "/cmd arg1 arg2 this is some free text";
181 gboolean result = FALSE;
182 gchar** args = parse_args_with_freetext(inp, 1, 3, &result);
183
184 assert_true(result);
185 assert_int_equal(3, g_strv_length(args));
186 assert_string_equal("arg1", args[0]);
187 assert_string_equal("arg2", args[1]);
188 assert_string_equal("this is some free text", args[2]);
189 g_strfreev(args);
190 }
191
192 void
parse_cmd_min_zero(void ** state)193 parse_cmd_min_zero(void** state)
194 {
195 char* inp = "/cmd";
196 gboolean result = FALSE;
197 gchar** args = parse_args(inp, 0, 2, &result);
198
199 assert_true(result);
200 assert_int_equal(0, g_strv_length(args));
201 assert_null(args[0]);
202 g_strfreev(args);
203 }
204
205 void
parse_cmd_min_zero_with_freetext(void ** state)206 parse_cmd_min_zero_with_freetext(void** state)
207 {
208 char* inp = "/cmd";
209 gboolean result = FALSE;
210 gchar** args = parse_args_with_freetext(inp, 0, 2, &result);
211
212 assert_true(result);
213 assert_int_equal(0, g_strv_length(args));
214 assert_null(args[0]);
215 g_strfreev(args);
216 }
217
218 void
parse_cmd_with_quoted(void ** state)219 parse_cmd_with_quoted(void** state)
220 {
221 char* inp = "/cmd \"arg1\" arg2";
222 gboolean result = FALSE;
223 gchar** args = parse_args(inp, 2, 2, &result);
224
225 assert_true(result);
226 assert_int_equal(2, g_strv_length(args));
227 assert_string_equal("arg1", args[0]);
228 assert_string_equal("arg2", args[1]);
229 g_strfreev(args);
230 }
231
232 void
parse_cmd_with_quoted_and_space(void ** state)233 parse_cmd_with_quoted_and_space(void** state)
234 {
235 char* inp = "/cmd \"the arg1\" arg2";
236 gboolean result = FALSE;
237 gchar** args = parse_args(inp, 2, 2, &result);
238
239 assert_true(result);
240 assert_int_equal(2, g_strv_length(args));
241 assert_string_equal("the arg1", args[0]);
242 assert_string_equal("arg2", args[1]);
243 g_strfreev(args);
244 }
245
246 void
parse_cmd_with_quoted_and_many_spaces(void ** state)247 parse_cmd_with_quoted_and_many_spaces(void** state)
248 {
249 char* inp = "/cmd \"the arg1 is here\" arg2";
250 gboolean result = FALSE;
251 gchar** args = parse_args(inp, 2, 2, &result);
252
253 assert_true(result);
254 assert_int_equal(2, g_strv_length(args));
255 assert_string_equal("the arg1 is here", args[0]);
256 assert_string_equal("arg2", args[1]);
257 g_strfreev(args);
258 }
259
260 void
parse_cmd_with_many_quoted_and_many_spaces(void ** state)261 parse_cmd_with_many_quoted_and_many_spaces(void** state)
262 {
263 char* inp = "/cmd \"the arg1 is here\" \"and arg2 is right here\"";
264 gboolean result = FALSE;
265 gchar** args = parse_args(inp, 2, 2, &result);
266
267 assert_true(result);
268 assert_int_equal(2, g_strv_length(args));
269 assert_string_equal("the arg1 is here", args[0]);
270 assert_string_equal("and arg2 is right here", args[1]);
271 g_strfreev(args);
272 }
273
274 void
parse_cmd_freetext_with_quoted(void ** state)275 parse_cmd_freetext_with_quoted(void** state)
276 {
277 char* inp = "/cmd \"arg1\" arg2 hello there whats up";
278 gboolean result = FALSE;
279 gchar** args = parse_args_with_freetext(inp, 3, 3, &result);
280
281 assert_true(result);
282 assert_int_equal(3, g_strv_length(args));
283 assert_string_equal("arg1", args[0]);
284 assert_string_equal("arg2", args[1]);
285 assert_string_equal("hello there whats up", args[2]);
286 g_strfreev(args);
287 }
288
289 void
parse_cmd_freetext_with_quoted_and_space(void ** state)290 parse_cmd_freetext_with_quoted_and_space(void** state)
291 {
292 char* inp = "/cmd \"the arg1\" arg2 another bit of freetext";
293 gboolean result = FALSE;
294 gchar** args = parse_args_with_freetext(inp, 3, 3, &result);
295
296 assert_true(result);
297 assert_int_equal(3, g_strv_length(args));
298 assert_string_equal("the arg1", args[0]);
299 assert_string_equal("arg2", args[1]);
300 assert_string_equal("another bit of freetext", args[2]);
301 g_strfreev(args);
302 }
303
304 void
parse_cmd_freetext_with_quoted_and_many_spaces(void ** state)305 parse_cmd_freetext_with_quoted_and_many_spaces(void** state)
306 {
307 char* inp = "/cmd \"the arg1 is here\" arg2 some more freetext";
308 gboolean result = FALSE;
309 gchar** args = parse_args_with_freetext(inp, 3, 3, &result);
310
311 assert_true(result);
312 assert_int_equal(3, g_strv_length(args));
313 assert_string_equal("the arg1 is here", args[0]);
314 assert_string_equal("arg2", args[1]);
315 assert_string_equal("some more freetext", args[2]);
316 g_strfreev(args);
317 }
318
319 void
parse_cmd_freetext_with_many_quoted_and_many_spaces(void ** state)320 parse_cmd_freetext_with_many_quoted_and_many_spaces(void** state)
321 {
322 char* inp = "/cmd \"the arg1 is here\" \"and arg2 is right here\" and heres the free text";
323 gboolean result = FALSE;
324 gchar** args = parse_args_with_freetext(inp, 3, 3, &result);
325
326 assert_true(result);
327 assert_int_equal(3, g_strv_length(args));
328 assert_string_equal("the arg1 is here", args[0]);
329 assert_string_equal("and arg2 is right here", args[1]);
330 assert_string_equal("and heres the free text", args[2]);
331 g_strfreev(args);
332 }
333
334 void
parse_cmd_with_quoted_freetext(void ** state)335 parse_cmd_with_quoted_freetext(void** state)
336 {
337 char* inp = "/cmd arg1 here is \"some\" quoted freetext";
338 gboolean result = FALSE;
339 gchar** args = parse_args_with_freetext(inp, 1, 2, &result);
340
341 assert_true(result);
342 assert_int_equal(2, g_strv_length(args));
343 assert_string_equal("arg1", args[0]);
344 assert_string_equal("here is \"some\" quoted freetext", args[1]);
345 g_strfreev(args);
346 }
347
348 void
parse_cmd_with_third_arg_quoted_0_min_3_max(void ** state)349 parse_cmd_with_third_arg_quoted_0_min_3_max(void** state)
350 {
351 char* inp = "/group add friends \"The User\"";
352 gboolean result = FALSE;
353 gchar** args = parse_args_with_freetext(inp, 0, 3, &result);
354
355 assert_true(result);
356 assert_int_equal(3, g_strv_length(args));
357 assert_string_equal("add", args[0]);
358 assert_string_equal("friends", args[1]);
359 assert_string_equal("The User", args[2]);
360
361 g_strfreev(args);
362 }
363
364 void
parse_cmd_with_second_arg_quoted_0_min_3_max(void ** state)365 parse_cmd_with_second_arg_quoted_0_min_3_max(void** state)
366 {
367 char* inp = "/group add \"The Group\" friend";
368 gboolean result = FALSE;
369 gchar** args = parse_args_with_freetext(inp, 0, 3, &result);
370
371 assert_true(result);
372 assert_int_equal(3, g_strv_length(args));
373 assert_string_equal("add", args[0]);
374 assert_string_equal("The Group", args[1]);
375 assert_string_equal("friend", args[2]);
376
377 g_strfreev(args);
378 }
379
380 void
parse_cmd_with_second_and_third_arg_quoted_0_min_3_max(void ** state)381 parse_cmd_with_second_and_third_arg_quoted_0_min_3_max(void** state)
382 {
383 char* inp = "/group add \"The Group\" \"The User\"";
384 gboolean result = FALSE;
385 gchar** args = parse_args_with_freetext(inp, 0, 3, &result);
386
387 assert_true(result);
388 assert_int_equal(3, g_strv_length(args));
389 assert_string_equal("add", args[0]);
390 assert_string_equal("The Group", args[1]);
391 assert_string_equal("The User", args[2]);
392
393 g_strfreev(args);
394 }
395
396 void
count_one_token(void ** state)397 count_one_token(void** state)
398 {
399 char* inp = "one";
400 int result = count_tokens(inp);
401
402 assert_int_equal(1, result);
403 }
404
405 void
count_one_token_quoted_no_whitespace(void ** state)406 count_one_token_quoted_no_whitespace(void** state)
407 {
408 char* inp = "\"one\"";
409 int result = count_tokens(inp);
410
411 assert_int_equal(1, result);
412 }
413
414 void
count_one_token_quoted_with_whitespace(void ** state)415 count_one_token_quoted_with_whitespace(void** state)
416 {
417 char* inp = "\"one two\"";
418 int result = count_tokens(inp);
419
420 assert_int_equal(1, result);
421 }
422
423 void
count_two_tokens(void ** state)424 count_two_tokens(void** state)
425 {
426 char* inp = "one two";
427 int result = count_tokens(inp);
428
429 assert_int_equal(2, result);
430 }
431
432 void
count_two_tokens_first_quoted(void ** state)433 count_two_tokens_first_quoted(void** state)
434 {
435 char* inp = "\"one and\" two";
436 int result = count_tokens(inp);
437
438 assert_int_equal(2, result);
439 }
440
441 void
count_two_tokens_second_quoted(void ** state)442 count_two_tokens_second_quoted(void** state)
443 {
444 char* inp = "one \"two and\"";
445 int result = count_tokens(inp);
446
447 assert_int_equal(2, result);
448 }
449
450 void
count_two_tokens_both_quoted(void ** state)451 count_two_tokens_both_quoted(void** state)
452 {
453 char* inp = "\"one and then\" \"two and\"";
454 int result = count_tokens(inp);
455
456 assert_int_equal(2, result);
457 }
458
459 void
get_first_of_one(void ** state)460 get_first_of_one(void** state)
461 {
462 char* inp = "one";
463 char* result = get_start(inp, 2);
464
465 assert_string_equal("one", result);
466 free(result);
467 }
468
469 void
get_first_of_two(void ** state)470 get_first_of_two(void** state)
471 {
472 char* inp = "one two";
473 char* result = get_start(inp, 2);
474
475 assert_string_equal("one ", result);
476 free(result);
477 }
478
479 void
get_first_two_of_three(void ** state)480 get_first_two_of_three(void** state)
481 {
482 char* inp = "one two three";
483 char* result = get_start(inp, 3);
484
485 assert_string_equal("one two ", result);
486 free(result);
487 }
488
489 void
get_first_two_of_three_first_quoted(void ** state)490 get_first_two_of_three_first_quoted(void** state)
491 {
492 char* inp = "\"one\" two three";
493 char* result = get_start(inp, 3);
494
495 assert_string_equal("\"one\" two ", result);
496 free(result);
497 }
498
499 void
get_first_two_of_three_second_quoted(void ** state)500 get_first_two_of_three_second_quoted(void** state)
501 {
502 char* inp = "one \"two\" three";
503 char* result = get_start(inp, 3);
504
505 assert_string_equal("one \"two\" ", result);
506 free(result);
507 }
508
509 void
get_first_two_of_three_first_and_second_quoted(void ** state)510 get_first_two_of_three_first_and_second_quoted(void** state)
511 {
512 char* inp = "\"one\" \"two\" three";
513 char* result = get_start(inp, 3);
514
515 assert_string_equal("\"one\" \"two\" ", result);
516 free(result);
517 }
518
519 void
parse_options_when_none_returns_empty_hasmap(void ** state)520 parse_options_when_none_returns_empty_hasmap(void** state)
521 {
522 gchar* args[] = { "cmd1", "cmd2", NULL };
523 gchar* keys[] = { "opt1", NULL };
524
525 gboolean res = FALSE;
526
527 GHashTable* options = parse_options(&args[2], keys, &res);
528
529 assert_true(options != NULL);
530 assert_int_equal(0, g_hash_table_size(options));
531 assert_true(res);
532
533 options_destroy(options);
534 }
535
536 void
parse_options_when_opt1_no_val_sets_error(void ** state)537 parse_options_when_opt1_no_val_sets_error(void** state)
538 {
539 gchar* args[] = { "cmd1", "cmd2", "opt1", NULL };
540 gchar* keys[] = { "opt1", NULL };
541
542 gboolean res = TRUE;
543
544 GHashTable* options = parse_options(&args[2], keys, &res);
545
546 assert_null(options);
547 assert_false(res);
548
549 options_destroy(options);
550 }
551
552 void
parse_options_when_one_returns_map(void ** state)553 parse_options_when_one_returns_map(void** state)
554 {
555 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", NULL };
556 gchar* keys[] = { "opt1", NULL };
557
558 gboolean res = FALSE;
559
560 GHashTable* options = parse_options(&args[2], keys, &res);
561
562 assert_int_equal(1, g_hash_table_size(options));
563 assert_true(g_hash_table_contains(options, "opt1"));
564 assert_string_equal("val1", g_hash_table_lookup(options, "opt1"));
565 assert_true(res);
566
567 options_destroy(options);
568 }
569
570 void
parse_options_when_opt2_no_val_sets_error(void ** state)571 parse_options_when_opt2_no_val_sets_error(void** state)
572 {
573 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", "opt2", NULL };
574 gchar* keys[] = { "opt1", "opt2", NULL };
575
576 gboolean res = TRUE;
577
578 GHashTable* options = parse_options(&args[2], keys, &res);
579
580 assert_null(options);
581 assert_false(res);
582
583 options_destroy(options);
584 }
585
586 void
parse_options_when_two_returns_map(void ** state)587 parse_options_when_two_returns_map(void** state)
588 {
589 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", "opt2", "val2", NULL };
590 gchar* keys[] = { "opt1", "opt2", NULL };
591
592 gboolean res = FALSE;
593
594 GHashTable* options = parse_options(&args[2], keys, &res);
595
596 assert_int_equal(2, g_hash_table_size(options));
597 assert_true(g_hash_table_contains(options, "opt1"));
598 assert_true(g_hash_table_contains(options, "opt2"));
599 assert_string_equal("val1", g_hash_table_lookup(options, "opt1"));
600 assert_string_equal("val2", g_hash_table_lookup(options, "opt2"));
601 assert_true(res);
602
603 options_destroy(options);
604 }
605
606 void
parse_options_when_opt3_no_val_sets_error(void ** state)607 parse_options_when_opt3_no_val_sets_error(void** state)
608 {
609 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", "opt2", "val2", "opt3", NULL };
610 gchar* keys[] = { "opt1", "opt2", "opt3", NULL };
611
612 gboolean res = TRUE;
613
614 GHashTable* options = parse_options(&args[2], keys, &res);
615
616 assert_null(options);
617 assert_false(res);
618
619 options_destroy(options);
620 }
621
622 void
parse_options_when_three_returns_map(void ** state)623 parse_options_when_three_returns_map(void** state)
624 {
625 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", "opt2", "val2", "opt3", "val3", NULL };
626 gchar* keys[] = { "opt1", "opt2", "opt3", NULL };
627
628 gboolean res = FALSE;
629
630 GHashTable* options = parse_options(&args[2], keys, &res);
631
632 assert_int_equal(3, g_hash_table_size(options));
633 assert_true(g_hash_table_contains(options, "opt1"));
634 assert_true(g_hash_table_contains(options, "opt2"));
635 assert_true(g_hash_table_contains(options, "opt3"));
636 assert_string_equal("val1", g_hash_table_lookup(options, "opt1"));
637 assert_string_equal("val2", g_hash_table_lookup(options, "opt2"));
638 assert_string_equal("val3", g_hash_table_lookup(options, "opt3"));
639 assert_true(res);
640
641 options_destroy(options);
642 }
643
644 void
parse_options_when_unknown_opt_sets_error(void ** state)645 parse_options_when_unknown_opt_sets_error(void** state)
646 {
647 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", "oops", "val2", "opt3", "val3", NULL };
648 gchar* keys[] = { "opt1", "opt2", "opt3", NULL };
649
650 gboolean res = TRUE;
651
652 GHashTable* options = parse_options(&args[2], keys, &res);
653
654 assert_null(options);
655 assert_false(res);
656
657 options_destroy(options);
658 }
659
660 void
parse_options_with_duplicated_option_sets_error(void ** state)661 parse_options_with_duplicated_option_sets_error(void** state)
662 {
663 gchar* args[] = { "cmd1", "cmd2", "opt1", "val1", "opt2", "val2", "opt1", "val3", NULL };
664 gchar* keys[] = { "opt1", "opt2", "opt3", NULL };
665
666 gboolean res = TRUE;
667
668 GHashTable* options = parse_options(&args[2], keys, &res);
669
670 assert_null(options);
671 assert_false(res);
672
673 options_destroy(options);
674 }
675