Add `extern "C"` to header
[argpar.git] / tests / test_argpar.c
CommitLineData
903a5b8a 1/*
fc07e526
SM
2 * Copyright (c) 2019-2021 Philippe Proulx <pproulx@efficios.com>
3 * Copyright (c) 2020-2021 Simon Marchi <simon.marchi@efficios.com>
903a5b8a
SM
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; under version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
7ac57709 19#include <assert.h>
903a5b8a 20#include <stdlib.h>
d1f7bbdb 21#include <stdio.h>
903a5b8a 22#include <string.h>
11003cd5 23#include <stdbool.h>
903a5b8a
SM
24#include <glib.h>
25
26#include "tap/tap.h"
903a5b8a
SM
27#include "argpar/argpar.h"
28
29/*
11003cd5
PP
30 * Formats `item` and appends the resulting string to `res_str` to
31 * incrementally build an expected command line string.
32 *
33 * This function:
34 *
35 * * Prefers the `--long-opt=arg` style over the `-s arg` style.
36 *
37 * * Uses the `arg<A,B>` form for non-option arguments, where `A` is the
38 * original argument index and `B` is the non-option argument index.
903a5b8a
SM
39 */
40static
11003cd5
PP
41void append_to_res_str(GString * const res_str,
42 const struct argpar_item * const item)
fc07e526
SM
43{
44 if (res_str->len > 0) {
45 g_string_append_c(res_str, ' ');
46 }
47
d4539a90 48 switch (argpar_item_type(item)) {
fc07e526
SM
49 case ARGPAR_ITEM_TYPE_OPT:
50 {
d4539a90
PP
51 const struct argpar_opt_descr * const descr =
52 argpar_item_opt_descr(item);
53 const char * const arg = argpar_item_opt_arg(item);
fc07e526 54
d4539a90 55 if (descr->long_name) {
fc07e526 56 g_string_append_printf(res_str, "--%s",
d4539a90 57 descr->long_name);
fc07e526 58
d4539a90
PP
59 if (arg) {
60 g_string_append_printf(res_str, "=%s", arg);
fc07e526 61 }
d4539a90 62 } else if (descr->short_name) {
fc07e526 63 g_string_append_printf(res_str, "-%c",
d4539a90 64 descr->short_name);
fc07e526 65
d4539a90
PP
66 if (arg) {
67 g_string_append_printf(res_str, " %s", arg);
fc07e526
SM
68 }
69 }
70
71 break;
72 }
73 case ARGPAR_ITEM_TYPE_NON_OPT:
74 {
d4539a90
PP
75 const char * const arg = argpar_item_non_opt_arg(item);
76 const unsigned int orig_index =
77 argpar_item_non_opt_orig_index(item);
78 const unsigned int non_opt_index =
79 argpar_item_non_opt_non_opt_index(item);
fc07e526 80
d4539a90
PP
81 g_string_append_printf(res_str, "%s<%u,%u>", arg, orig_index,
82 non_opt_index);
fc07e526
SM
83 break;
84 }
85 default:
86 abort();
87 }
88}
89
11003cd5 90/*
4d6198b5 91 * Parses `cmdline` with the argpar API using the option descriptors
11003cd5
PP
92 * `descrs`, and ensures that the resulting effective command line is
93 * `expected_cmd_line` and that the number of ingested original
94 * arguments is `expected_ingested_orig_args`.
95 *
96 * This function splits `cmdline` on spaces to create an original
97 * argument array.
98 *
99 * This function builds the resulting command line from parsing items
100 * by space-separating each formatted item (see append_to_res_str()).
101 */
fc07e526 102static
4d6198b5 103void test_succeed(const char * const cmdline,
11003cd5
PP
104 const char * const expected_cmd_line,
105 const struct argpar_opt_descr * const descrs,
106 const unsigned int expected_ingested_orig_args)
fc07e526
SM
107{
108 struct argpar_iter *iter = NULL;
109 const struct argpar_item *item = NULL;
8b95d883 110 const struct argpar_error *error = NULL;
11003cd5
PP
111 GString * const res_str = g_string_new(NULL);
112 gchar ** const argv = g_strsplit(cmdline, " ", 0);
fc07e526
SM
113 unsigned int i, actual_ingested_orig_args;
114
115 assert(argv);
116 assert(res_str);
fc07e526
SM
117 iter = argpar_iter_create(g_strv_length(argv),
118 (const char * const *) argv, descrs);
119 assert(iter);
120
121 for (i = 0; ; i++) {
2af370d0 122 enum argpar_iter_next_status status;
fc07e526
SM
123
124 ARGPAR_ITEM_DESTROY_AND_RESET(item);
2af370d0 125 status = argpar_iter_next(iter, &item, &error);
fc07e526 126
2af370d0 127 ok(status == ARGPAR_ITER_NEXT_STATUS_OK ||
8b95d883 128 status == ARGPAR_ITER_NEXT_STATUS_END,
2af370d0 129 "argpar_iter_next() returns the expected status "
11003cd5
PP
130 "(%d) for command line `%s` (call %u)",
131 status, cmdline, i + 1);
8b95d883
PP
132 ok(!error,
133 "argpar_iter_next() doesn't set an error for "
134 "command line `%s` (call %u)",
135 cmdline, i + 1);
fc07e526 136
8b95d883 137 if (status == ARGPAR_ITER_NEXT_STATUS_END) {
11003cd5 138 ok(!item,
2af370d0
PP
139 "argpar_iter_next() doesn't set an item "
140 "for status `ARGPAR_ITER_NEXT_STATUS_END` "
11003cd5
PP
141 "and command line `%s` (call %u)",
142 cmdline, i + 1);
903a5b8a
SM
143 break;
144 }
fc07e526
SM
145
146 append_to_res_str(res_str, item);
903a5b8a
SM
147 }
148
f3ab5ca1 149 actual_ingested_orig_args = argpar_iter_ingested_orig_args(iter);
fc07e526 150 ok(actual_ingested_orig_args == expected_ingested_orig_args,
f3ab5ca1 151 "argpar_iter_ingested_orig_args() returns the expected "
11003cd5
PP
152 "number of ingested original arguments for command line `%s`",
153 cmdline);
154
fc07e526
SM
155 if (actual_ingested_orig_args != expected_ingested_orig_args) {
156 diag("Expected: %u Got: %u", expected_ingested_orig_args,
157 actual_ingested_orig_args);
903a5b8a
SM
158 }
159
160 ok(strcmp(expected_cmd_line, res_str->str) == 0,
2af370d0 161 "argpar_iter_next() returns the expected parsing items "
903a5b8a 162 "for command line `%s`", cmdline);
11003cd5 163
903a5b8a
SM
164 if (strcmp(expected_cmd_line, res_str->str) != 0) {
165 diag("Expected: `%s`", expected_cmd_line);
166 diag("Got: `%s`", res_str->str);
167 }
168
fc07e526
SM
169 argpar_item_destroy(item);
170 argpar_iter_destroy(iter);
8b95d883 171 assert(!error);
903a5b8a
SM
172 g_string_free(res_str, TRUE);
173 g_strfreev(argv);
fc07e526
SM
174}
175
903a5b8a
SM
176static
177void succeed_tests(void)
178{
179 /* No arguments */
180 {
1c9a6bde
SM
181 const struct argpar_opt_descr descrs[] = {
182 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
183 };
184
185 test_succeed(
186 "",
187 "",
188 descrs, 0);
189 }
190
191 /* Single long option */
192 {
1c9a6bde 193 const struct argpar_opt_descr descrs[] = {
903a5b8a 194 { 0, '\0', "salut", false },
1c9a6bde 195 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
196 };
197
198 test_succeed(
199 "--salut",
200 "--salut",
201 descrs, 1);
202 }
203
204 /* Single short option */
205 {
1c9a6bde 206 const struct argpar_opt_descr descrs[] = {
903a5b8a 207 { 0, 'f', NULL, false },
1c9a6bde 208 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
209 };
210
211 test_succeed(
212 "-f",
213 "-f",
214 descrs, 1);
215 }
216
217 /* Short and long option (aliases) */
218 {
1c9a6bde 219 const struct argpar_opt_descr descrs[] = {
903a5b8a 220 { 0, 'f', "flaw", false },
1c9a6bde 221 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
222 };
223
224 test_succeed(
225 "-f --flaw",
226 "--flaw --flaw",
227 descrs, 2);
228 }
229
230 /* Long option with argument (space form) */
231 {
1c9a6bde 232 const struct argpar_opt_descr descrs[] = {
903a5b8a 233 { 0, '\0', "tooth", true },
1c9a6bde 234 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
235 };
236
237 test_succeed(
238 "--tooth 67",
239 "--tooth=67",
240 descrs, 2);
241 }
242
243 /* Long option with argument (equal form) */
244 {
1c9a6bde 245 const struct argpar_opt_descr descrs[] = {
903a5b8a 246 { 0, '\0', "polish", true },
1c9a6bde 247 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
248 };
249
250 test_succeed(
251 "--polish=brick",
252 "--polish=brick",
253 descrs, 1);
254 }
255
256 /* Short option with argument (space form) */
257 {
1c9a6bde 258 const struct argpar_opt_descr descrs[] = {
903a5b8a 259 { 0, 'c', NULL, true },
1c9a6bde 260 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
261 };
262
263 test_succeed(
264 "-c chilly",
265 "-c chilly",
266 descrs, 2);
267 }
268
269 /* Short option with argument (glued form) */
270 {
1c9a6bde 271 const struct argpar_opt_descr descrs[] = {
903a5b8a 272 { 0, 'c', NULL, true },
1c9a6bde 273 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
274 };
275
276 test_succeed(
277 "-cchilly",
278 "-c chilly",
279 descrs, 1);
280 }
281
282 /* Short and long option (aliases) with argument (all forms) */
283 {
1c9a6bde 284 const struct argpar_opt_descr descrs[] = {
903a5b8a 285 { 0, 'd', "dry", true },
1c9a6bde 286 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
287 };
288
289 test_succeed(
290 "--dry=rate -dthing --dry street --dry=shape",
291 "--dry=rate --dry=thing --dry=street --dry=shape",
292 descrs, 5);
293 }
294
295 /* Many short options, last one with argument (glued form) */
296 {
1c9a6bde 297 const struct argpar_opt_descr descrs[] = {
903a5b8a
SM
298 { 0, 'd', NULL, false },
299 { 0, 'e', NULL, false },
300 { 0, 'f', NULL, true },
1c9a6bde 301 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
302 };
303
304 test_succeed(
305 "-defmeow",
306 "-d -e -f meow",
307 descrs, 1);
308 }
309
310 /* Many options */
311 {
1c9a6bde 312 const struct argpar_opt_descr descrs[] = {
903a5b8a
SM
313 { 0, 'd', NULL, false },
314 { 0, 'e', "east", true },
315 { 0, '\0', "mind", false },
1c9a6bde 316 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
317 };
318
319 test_succeed(
320 "-d --mind -destart --mind --east cough -d --east=itch",
321 "-d --mind -d --east=start --mind --east=cough -d --east=itch",
322 descrs, 8);
323 }
324
325 /* Single non-option argument */
326 {
1c9a6bde
SM
327 const struct argpar_opt_descr descrs[] = {
328 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
329 };
330
331 test_succeed(
332 "kilojoule",
333 "kilojoule<0,0>",
334 descrs, 1);
335 }
336
337 /* Two non-option arguments */
338 {
1c9a6bde
SM
339 const struct argpar_opt_descr descrs[] = {
340 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
341 };
342
343 test_succeed(
344 "kilojoule mitaine",
345 "kilojoule<0,0> mitaine<1,1>",
346 descrs, 2);
347 }
348
349 /* Single non-option argument mixed with options */
350 {
1c9a6bde 351 const struct argpar_opt_descr descrs[] = {
903a5b8a
SM
352 { 0, 'd', NULL, false },
353 { 0, '\0', "squeeze", true },
1c9a6bde 354 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
355 };
356
357 test_succeed(
358 "-d sprout yes --squeeze little bag -d",
359 "-d sprout<1,0> yes<2,1> --squeeze=little bag<5,2> -d",
360 descrs, 7);
361 }
362
903a5b8a
SM
363 /* Valid `---opt` */
364 {
1c9a6bde 365 const struct argpar_opt_descr descrs[] = {
903a5b8a 366 { 0, '\0', "-fuel", true },
1c9a6bde 367 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
368 };
369
370 test_succeed(
371 "---fuel=three",
372 "---fuel=three",
373 descrs, 1);
374 }
375
376 /* Long option containing `=` in argument (equal form) */
377 {
1c9a6bde 378 const struct argpar_opt_descr descrs[] = {
903a5b8a 379 { 0, '\0', "zebra", true },
1c9a6bde 380 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
381 };
382
383 test_succeed(
384 "--zebra=three=yes",
385 "--zebra=three=yes",
386 descrs, 1);
387 }
388
389 /* Short option's argument starting with `-` (glued form) */
390 {
1c9a6bde 391 const struct argpar_opt_descr descrs[] = {
903a5b8a 392 { 0, 'z', NULL, true },
1c9a6bde 393 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
394 };
395
396 test_succeed(
397 "-z-will",
398 "-z -will",
399 descrs, 1);
400 }
401
402 /* Short option's argument starting with `-` (space form) */
403 {
1c9a6bde 404 const struct argpar_opt_descr descrs[] = {
903a5b8a 405 { 0, 'z', NULL, true },
1c9a6bde 406 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
407 };
408
409 test_succeed(
410 "-z -will",
411 "-z -will",
412 descrs, 2);
413 }
414
415 /* Long option's argument starting with `-` (space form) */
416 {
1c9a6bde 417 const struct argpar_opt_descr descrs[] = {
903a5b8a 418 { 0, '\0', "janine", true },
1c9a6bde 419 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
420 };
421
422 test_succeed(
423 "--janine -sutto",
424 "--janine=-sutto",
425 descrs, 2);
426 }
427
428 /* Long option's argument starting with `-` (equal form) */
429 {
1c9a6bde 430 const struct argpar_opt_descr descrs[] = {
903a5b8a 431 { 0, '\0', "janine", true },
1c9a6bde 432 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
433 };
434
435 test_succeed(
436 "--janine=-sutto",
437 "--janine=-sutto",
438 descrs, 1);
439 }
440
441 /* Long option's empty argument (equal form) */
442 {
1c9a6bde 443 const struct argpar_opt_descr descrs[] = {
903a5b8a
SM
444 { 0, 'f', NULL, false },
445 { 0, '\0', "yeah", true },
1c9a6bde 446 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
447 };
448
449 test_succeed(
450 "-f --yeah= -f",
451 "-f --yeah= -f",
452 descrs, 3);
453 }
dd757a65
PP
454
455 /* `-` non-option argument */
456 {
457 const struct argpar_opt_descr descrs[] = {
458 { 0, 'f', NULL, false },
459 ARGPAR_OPT_DESCR_SENTINEL
460 };
461
462 test_succeed(
463 "-f - -f",
464 "-f -<1,0> -f",
465 descrs, 3);
466 }
467
468 /* `--` non-option argument */
469 {
470 const struct argpar_opt_descr descrs[] = {
471 { 0, 'f', NULL, false },
472 ARGPAR_OPT_DESCR_SENTINEL
473 };
474
475 test_succeed(
476 "-f -- -f",
477 "-f --<1,0> -f",
478 descrs, 3);
479 }
d1f7bbdb
PP
480
481 /* Very long name of long option */
482 {
483 const char opt_name[] =
484 "kale-chips-waistcoat-yr-bicycle-rights-gochujang-"
485 "woke-tumeric-flexitarian-biodiesel-chillwave-cliche-"
486 "ethical-cardigan-listicle-pok-pok-sustainable-live-"
487 "edge-jianbing-gochujang-butcher-disrupt-tattooed-"
488 "tumeric-prism-photo-booth-vape-kogi-jean-shorts-"
489 "blog-williamsburg-fingerstache-palo-santo-artisan-"
490 "affogato-occupy-skateboard-adaptogen-neutra-celiac-"
491 "put-a-bird-on-it-kombucha-everyday-carry-hot-chicken-"
492 "craft-beer-subway-tile-tote-bag-disrupt-selvage-"
493 "raclette-art-party-readymade-paleo-heirloom-trust-"
494 "fund-small-batch-kinfolk-woke-cardigan-prism-"
495 "chambray-la-croix-hashtag-unicorn-edison-bulb-tbh-"
496 "cornhole-cliche-tattooed-green-juice-adaptogen-"
497 "kitsch-lo-fi-vexillologist-migas-gentrify-"
498 "viral-raw-denim";
499 const struct argpar_opt_descr descrs[] = {
500 { 0, '\0', opt_name, true },
501 ARGPAR_OPT_DESCR_SENTINEL
502 };
503 char cmdline[1024];
504
505 sprintf(cmdline, "--%s=23", opt_name);
506 test_succeed(cmdline, cmdline, descrs, 1);
507 }
903a5b8a
SM
508}
509
11003cd5 510/*
4d6198b5 511 * Parses `cmdline` with the argpar API using the option descriptors
2af370d0 512 * `descrs`, and ensures that argpar_iter_next() fails with status
8b95d883
PP
513 * `expected_status` and that it sets an error having:
514 *
515 * * The original argument index `expected_orig_index`.
516 *
517 * * If applicable:
518 *
519 * * The unknown option name `expected_unknown_opt_name`.
520 *
521 * * The option descriptor at index `expected_opt_descr_index` of
522 * `descrs`.
523 *
524 * * The option type `expected_is_short`.
11003cd5
PP
525 *
526 * This function splits `cmdline` on spaces to create an original
527 * argument array.
528 */
fc07e526 529static
8b95d883 530void test_fail(const char * const cmdline,
10aefab2 531 const enum argpar_error_type expected_error_type,
8b95d883
PP
532 const unsigned int expected_orig_index,
533 const char * const expected_unknown_opt_name,
534 const unsigned int expected_opt_descr_index,
535 const bool expected_is_short,
11003cd5 536 const struct argpar_opt_descr * const descrs)
fc07e526
SM
537{
538 struct argpar_iter *iter = NULL;
539 const struct argpar_item *item = NULL;
11003cd5 540 gchar ** const argv = g_strsplit(cmdline, " ", 0);
fc07e526 541 unsigned int i;
8b95d883 542 const struct argpar_error *error = NULL;
fc07e526
SM
543
544 iter = argpar_iter_create(g_strv_length(argv),
545 (const char * const *) argv, descrs);
546 assert(iter);
547
548 for (i = 0; ; i++) {
2af370d0 549 enum argpar_iter_next_status status;
fc07e526
SM
550
551 ARGPAR_ITEM_DESTROY_AND_RESET(item);
2af370d0
PP
552 status = argpar_iter_next(iter, &item, &error);
553 ok(status == ARGPAR_ITER_NEXT_STATUS_OK ||
10aefab2
SM
554 (status == ARGPAR_ITER_NEXT_STATUS_ERROR &&
555 argpar_error_type(error) == expected_error_type),
2af370d0 556 "argpar_iter_next() returns the expected status "
10aefab2
SM
557 "and error type (%d) for command line `%s` (call %u)",
558 expected_error_type, cmdline, i + 1);
fc07e526 559
2af370d0 560 if (status != ARGPAR_ITER_NEXT_STATUS_OK) {
11003cd5 561 ok(!item,
2af370d0 562 "argpar_iter_next() doesn't set an item "
11003cd5 563 "for other status than "
2af370d0 564 "`ARGPAR_ITER_NEXT_STATUS_OK` "
11003cd5
PP
565 "and command line `%s` (call %u)",
566 cmdline, i + 1);
567 ok(error,
2af370d0 568 "argpar_iter_next() sets an error for "
11003cd5 569 "other status than "
2af370d0 570 " `ARGPAR_ITER_NEXT_STATUS_OK` "
11003cd5
PP
571 "and command line `%s` (call %u)",
572 cmdline, i + 1);
8b95d883
PP
573 ok(argpar_error_orig_index(error) ==
574 expected_orig_index,
575 "argpar_iter_next() sets an error with "
576 "the expected original argument index "
577 "for command line `%s` (call %u)",
578 cmdline, i + 1);
579
10aefab2 580 if (argpar_error_type(error) == ARGPAR_ERROR_TYPE_UNKNOWN_OPT) {
8b95d883
PP
581 ok(strcmp(argpar_error_unknown_opt_name(error),
582 expected_unknown_opt_name) == 0,
583 "argpar_iter_next() sets an error with "
584 "the expected unknown option name "
585 "for command line `%s` (call %u)",
586 cmdline, i + 1);
587 } else {
588 bool is_short;
589
590 ok(argpar_error_opt_descr(error, &is_short) ==
591 &descrs[expected_opt_descr_index],
592 "argpar_iter_next() sets an error with "
593 "the expected option descriptor "
594 "for command line `%s` (call %u)",
595 cmdline, i + 1);
596 ok(is_short == expected_is_short,
597 "argpar_iter_next() sets an error with "
598 "the expected option type "
599 "for command line `%s` (call %u)",
600 cmdline, i + 1);
601 }
fc07e526
SM
602 break;
603 }
604
11003cd5 605 ok(item,
2af370d0
PP
606 "argpar_iter_next() sets an item for status "
607 "`ARGPAR_ITER_NEXT_STATUS_OK` "
11003cd5
PP
608 "and command line `%s` (call %u)",
609 cmdline, i + 1);
610 ok(!error,
2af370d0
PP
611 "argpar_iter_next() doesn't set an error for status "
612 "`ARGPAR_ITER_NEXT_STATUS_OK` "
11003cd5
PP
613 "and command line `%s` (call %u)",
614 cmdline, i + 1);
fc07e526
SM
615 }
616
8b95d883 617 /*
fc07e526 618 ok(strcmp(expected_error, error) == 0,
2af370d0 619 "argpar_iter_next() sets the expected error string "
fc07e526 620 "for command line `%s`", cmdline);
11003cd5 621
fc07e526
SM
622 if (strcmp(expected_error, error) != 0) {
623 diag("Expected: `%s`", expected_error);
624 diag("Got: `%s`", error);
625 }
8b95d883 626 */
fc07e526
SM
627
628 argpar_item_destroy(item);
629 argpar_iter_destroy(iter);
8b95d883 630 argpar_error_destroy(error);
fc07e526
SM
631 g_strfreev(argv);
632}
633
903a5b8a
SM
634static
635void fail_tests(void)
636{
8b95d883
PP
637
638 /* Unknown short option (space form) */
639 {
640 const struct argpar_opt_descr descrs[] = {
641 { 0, 'd', NULL, true },
642 ARGPAR_OPT_DESCR_SENTINEL
643 };
644
645 test_fail(
646 "-d salut -e -d meow",
10aefab2 647 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
8b95d883
PP
648 2, "-e", 0, false,
649 descrs);
650 }
651
652 /* Unknown short option (glued form) */
653 {
654 const struct argpar_opt_descr descrs[] = {
655 { 0, 'd', 0, true },
656 ARGPAR_OPT_DESCR_SENTINEL
657 };
658
659 test_fail(
660 "-dsalut -e -d meow",
10aefab2 661 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
8b95d883
PP
662 1, "-e", 0, false,
663 descrs);
664 }
665
666 /* Unknown long option (space form) */
667 {
668 const struct argpar_opt_descr descrs[] = {
669 { 0, '\0', "sink", true },
670 ARGPAR_OPT_DESCR_SENTINEL
671 };
672
673 test_fail(
674 "--sink party --food --sink impulse",
10aefab2 675 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
8b95d883
PP
676 2, "--food", 0, false,
677 descrs);
678 }
679
680 /* Unknown long option (equal form) */
681 {
682 const struct argpar_opt_descr descrs[] = {
683 { 0, '\0', "sink", true },
684 ARGPAR_OPT_DESCR_SENTINEL
685 };
686
687 test_fail(
688 "--sink=party --food --sink=impulse",
10aefab2 689 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
8b95d883
PP
690 1, "--food", 0, false,
691 descrs);
692 }
693
694 /* Unknown option before non-option argument */
903a5b8a 695 {
1c9a6bde 696 const struct argpar_opt_descr descrs[] = {
903a5b8a 697 { 0, '\0', "thumb", true },
1c9a6bde 698 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
699 };
700
701 test_fail(
8b95d883 702 "--thumb=party --food=18 bateau --thumb waves",
10aefab2 703 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
8b95d883 704 1, "--food", 0, false,
903a5b8a
SM
705 descrs);
706 }
707
8b95d883 708 /* Unknown option after non-option argument */
903a5b8a 709 {
1c9a6bde 710 const struct argpar_opt_descr descrs[] = {
903a5b8a 711 { 0, '\0', "thumb", true },
1c9a6bde 712 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
713 };
714
715 test_fail(
8b95d883 716 "--thumb=party wound --food --thumb waves",
10aefab2 717 ARGPAR_ERROR_TYPE_UNKNOWN_OPT,
8b95d883 718 2, "--food", 0, false,
903a5b8a
SM
719 descrs);
720 }
721
722 /* Missing long option argument */
723 {
1c9a6bde 724 const struct argpar_opt_descr descrs[] = {
903a5b8a 725 { 0, '\0', "thumb", true },
1c9a6bde 726 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
727 };
728
729 test_fail(
8b95d883 730 "allo --thumb",
10aefab2 731 ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
8b95d883 732 1, NULL, 0, false,
903a5b8a
SM
733 descrs);
734 }
735
736 /* Missing short option argument */
737 {
1c9a6bde 738 const struct argpar_opt_descr descrs[] = {
903a5b8a 739 { 0, 'k', NULL, true },
1c9a6bde 740 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
741 };
742
743 test_fail(
8b95d883 744 "zoom heille -k",
10aefab2 745 ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
8b95d883 746 2, NULL, 0, true,
903a5b8a
SM
747 descrs);
748 }
749
750 /* Missing short option argument (multiple glued) */
751 {
1c9a6bde 752 const struct argpar_opt_descr descrs[] = {
903a5b8a
SM
753 { 0, 'a', NULL, false },
754 { 0, 'b', NULL, false },
755 { 0, 'c', NULL, true },
1c9a6bde 756 ARGPAR_OPT_DESCR_SENTINEL
903a5b8a
SM
757 };
758
759 test_fail(
760 "-abc",
10aefab2 761 ARGPAR_ERROR_TYPE_MISSING_OPT_ARG,
8b95d883 762 0, NULL, 2, true,
903a5b8a
SM
763 descrs);
764 }
765
dd757a65 766 /* Unexpected long option argument */
430fe886
SM
767 {
768 const struct argpar_opt_descr descrs[] = {
769 { 0, 'c', "chevre", false },
770 ARGPAR_OPT_DESCR_SENTINEL
771 };
772
773 test_fail(
8b95d883 774 "ambulance --chevre=fromage tar -cjv",
10aefab2 775 ARGPAR_ERROR_TYPE_UNEXPECTED_OPT_ARG,
8b95d883 776 1, NULL, 0, false,
430fe886
SM
777 descrs);
778 }
903a5b8a
SM
779}
780
781int main(void)
782{
8b95d883 783 plan_tests(309);
903a5b8a
SM
784 succeed_tests();
785 fail_tests();
786 return exit_status();
787}
This page took 0.094525 seconds and 4 git commands to generate.