ref: 1b78c4e98a365b5c80ac4ee93d98504805860808
dir: /parg/test/test_parg.c/
/* * test_parg - parg unit test * * Written in 2015-2016 by Joergen Ibsen * * To the extent possible under law, the author(s) have dedicated all * copyright and related and neighboring rights to this software to the * public domain worldwide. This software is distributed without any * warranty. <http://creativecommons.org/publicdomain/zero/1.0/> */ #include "parg.h" #include <assert.h> #include <stdio.h> #include <stdlib.h> #include "greatest.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) static const char *os_def = ":no::r:"; static const struct parg_option po_def[] = { { "noarg", PARG_NOARG, NULL, 'n' }, { "optarg", PARG_OPTARG, NULL, 'o' }, { "reqarg", PARG_REQARG, NULL, 'r' }, { "foo", PARG_NOARG, NULL, 'f' }, { "foobar", PARG_NOARG, NULL, 'b' }, { 0, 0, 0, 0 } }; /* * parg_getopt tests */ TEST parg_getopt_app_only(void) { struct parg_state ps; char *argv[] = { "app" }; parg_init(&ps); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(1, ps.optind); PASS(); } TEST parg_getopt_dash(void) { struct parg_state ps; char *argv[] = { "app", "-" }; parg_init(&ps); ASSERT_EQ(1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(argv[1], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_double_dash(void) { struct parg_state ps; char *argv[] = { "app", "--" }; parg_init(&ps); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_nonopt(void) { struct parg_state ps; char *argv[] = { "app", "foo" }; parg_init(&ps); ASSERT_EQ(1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(argv[1], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_no_match(void) { struct parg_state ps; char *argv[] = { "app", "-u" }; parg_init(&ps); ASSERT_EQ('?', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ('u', ps.optopt); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_noarg(void) { struct parg_state ps; char *argv[] = { "app", "-n" }; parg_init(&ps); ASSERT_EQ('n', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_optarg_missing(void) { struct parg_state ps; char *argv[] = { "app", "-o" }; parg_init(&ps); ASSERT_EQ('o', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_optarg_inline(void) { struct parg_state ps; char *argv[] = { "app", "-oarg" }; parg_init(&ps); ASSERT_EQ('o', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(&argv[1][2], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_reqarg_missing(void) { struct parg_state ps; char *argv[] = { "app", "-r" }; parg_init(&ps); ASSERT_EQ(':', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ('r', ps.optopt); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_reqarg_inline(void) { struct parg_state ps; char *argv[] = { "app", "-rarg" }; parg_init(&ps); ASSERT_EQ('r', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(&argv[1][2], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_reqarg_nextarg(void) { struct parg_state ps; char *argv[] = { "app", "-r", "arg" }; parg_init(&ps); ASSERT_EQ('r', parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(argv[2], ps.optarg); ASSERT_EQ(3, ps.optind); ASSERT_EQ(-1, parg_getopt(&ps, ARRAY_SIZE(argv), argv, os_def)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(3, ps.optind); PASS(); } /* * parg_getopt_long tests */ TEST parg_getopt_long_app_only(void) { struct parg_state ps; char *argv[] = { "app" }; int li = -1; parg_init(&ps); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(1, ps.optind); PASS(); } TEST parg_getopt_long_dash(void) { struct parg_state ps; char *argv[] = { "app", "-" }; int li = -1; parg_init(&ps); ASSERT_EQ(1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(argv[1], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_double_dash(void) { struct parg_state ps; char *argv[] = { "app", "--" }; int li = -1; parg_init(&ps); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_nonopt(void) { struct parg_state ps; char *argv[] = { "app", "foo" }; int li = -1; parg_init(&ps); ASSERT_EQ(1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(argv[1], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_no_match(void) { struct parg_state ps; char *argv[] = { "app", "--unknown" }; int li = -1; parg_init(&ps); ASSERT_EQ('?', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_flag(void) { struct parg_state ps; char *argv[] = { "app", "--flag" }; int li = -1; int flag = 0; struct parg_option po_flag[] = { { "flag", PARG_NOARG, 0, 1 }, { 0, 0, 0, 0 } }; po_flag[0].flag = &flag; parg_init(&ps); ASSERT_EQ(0, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_flag, &li)); ASSERT_EQ(0, li); ASSERT_EQ(1, flag); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_flag, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_noarg(void) { struct parg_state ps; char *argv[] = { "app", "--noarg" }; int li = -1; parg_init(&ps); ASSERT_EQ('n', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(0, li); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_noarg_inline(void) { struct parg_state ps; char *argv[] = { "app", "--noarg=arg" }; int li = -1; parg_init(&ps); ASSERT_EQ(':', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(0, li); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ('n', ps.optopt); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_optarg_missing(void) { struct parg_state ps; char *argv[] = { "app", "--optarg" }; int li = -1; parg_init(&ps); ASSERT_EQ('o', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(1, li); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_optarg_inline(void) { struct parg_state ps; char *argv[] = { "app", "--optarg=arg" }; int li = -1; parg_init(&ps); ASSERT_EQ('o', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(1, li); ASSERT_EQ(&argv[1][9], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_reqarg_missing(void) { struct parg_state ps; char *argv[] = { "app", "--reqarg" }; int li = -1; parg_init(&ps); ASSERT_EQ(':', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(2, li); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ('r', ps.optopt); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_reqarg_inline(void) { struct parg_state ps; char *argv[] = { "app", "--reqarg=arg" }; int li = -1; parg_init(&ps); ASSERT_EQ('r', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(2, li); ASSERT_EQ(&argv[1][9], ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_reqarg_nextarg(void) { struct parg_state ps; char *argv[] = { "app", "--reqarg", "arg" }; int li = -1; parg_init(&ps); ASSERT_EQ('r', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(2, li); ASSERT_EQ(argv[2], ps.optarg); ASSERT_EQ(3, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(3, ps.optind); PASS(); } TEST parg_getopt_long_prefix_ambiguous(void) { struct parg_state ps; char *argv[] = { "app", "--fo" }; int li = -1; parg_init(&ps); ASSERT_EQ('?', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_prefix_exact(void) { struct parg_state ps; char *argv[] = { "app", "--foo" }; int li = -1; parg_init(&ps); ASSERT_EQ('f', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(3, li); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } TEST parg_getopt_long_prefix_unambiguous(void) { struct parg_state ps; char *argv[] = { "app", "--foob" }; int li = -1; parg_init(&ps); ASSERT_EQ('b', parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(4, li); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); ASSERT_EQ(-1, parg_getopt_long(&ps, ARRAY_SIZE(argv), argv, ":", po_def, &li)); ASSERT_EQ(NULL, ps.optarg); ASSERT_EQ(2, ps.optind); PASS(); } /* * parg_reorder tests */ TEST parg_reorder_short(void) { char *argv[] = { "app", "first", "-r", "--", "foo", "-u", "bar", "-o", "--", "-n", "last" }; char *argv_expected[] = { "app", "-r", "--", "-u", "-o", "--", "first", "foo", "bar", "-n", "last" }; size_t i; ASSERT_EQ(6, parg_reorder(ARRAY_SIZE(argv), argv, os_def, NULL)); for (i = 0; i < ARRAY_SIZE(argv); ++i) { ASSERT_STR_EQ(argv_expected[i], argv[i]); } PASS(); } TEST parg_reorder_long(void) { char *argv[] = { "app", "first", "--reqarg", "--", "foo", "--unknown", "bar", "--optarg", "--", "--noarg", "last" }; char *argv_expected[] = { "app", "--reqarg", "--", "--unknown", "--optarg", "--", "first", "foo", "bar", "--noarg", "last" }; size_t i; ASSERT_EQ(6, parg_reorder(ARRAY_SIZE(argv), argv, "", po_def)); for (i = 0; i < ARRAY_SIZE(argv); ++i) { ASSERT_STR_EQ(argv_expected[i], argv[i]); } PASS(); } TEST parg_reorder_app_only(void) { char *argv[] = { "app" }; ASSERT_EQ(1, parg_reorder(ARRAY_SIZE(argv), argv, os_def, NULL)); PASS(); } TEST parg_reorder_double_dash_last(void) { char *argv[] = { "app", "foo", "-n", "--" }; char *argv_expected[] = { "app", "-n", "--", "foo" }; size_t i; ASSERT_EQ(3, parg_reorder(ARRAY_SIZE(argv), argv, os_def, NULL)); for (i = 0; i < ARRAY_SIZE(argv); ++i) { ASSERT_STR_EQ(argv_expected[i], argv[i]); } PASS(); } TEST parg_reorder_missing_arg_last(void) { char *argv[] = { "app", "foo", "-r" }; char *argv_expected[] = { "app", "-r", "foo" }; size_t i; ASSERT_EQ(2, parg_reorder(ARRAY_SIZE(argv), argv, os_def, NULL)); for (i = 0; i < ARRAY_SIZE(argv); ++i) { ASSERT_STR_EQ(argv_expected[i], argv[i]); } PASS(); } SUITE(parg_getopt_tests) { RUN_TEST(parg_getopt_app_only); RUN_TEST(parg_getopt_dash); RUN_TEST(parg_getopt_double_dash); RUN_TEST(parg_getopt_nonopt); RUN_TEST(parg_getopt_no_match); RUN_TEST(parg_getopt_noarg); RUN_TEST(parg_getopt_optarg_missing); RUN_TEST(parg_getopt_optarg_inline); RUN_TEST(parg_getopt_reqarg_missing); RUN_TEST(parg_getopt_reqarg_inline); RUN_TEST(parg_getopt_reqarg_nextarg); } SUITE(parg_getopt_long_tests) { RUN_TEST(parg_getopt_long_app_only); RUN_TEST(parg_getopt_long_dash); RUN_TEST(parg_getopt_long_double_dash); RUN_TEST(parg_getopt_long_nonopt); RUN_TEST(parg_getopt_long_no_match); RUN_TEST(parg_getopt_long_flag); RUN_TEST(parg_getopt_long_noarg); RUN_TEST(parg_getopt_long_noarg_inline); RUN_TEST(parg_getopt_long_optarg_missing); RUN_TEST(parg_getopt_long_optarg_inline); RUN_TEST(parg_getopt_long_reqarg_missing); RUN_TEST(parg_getopt_long_reqarg_inline); RUN_TEST(parg_getopt_long_reqarg_nextarg); RUN_TEST(parg_getopt_long_prefix_ambiguous); RUN_TEST(parg_getopt_long_prefix_exact); RUN_TEST(parg_getopt_long_prefix_unambiguous); } SUITE(parg_reorder_tests) { RUN_TEST(parg_reorder_short); RUN_TEST(parg_reorder_long); RUN_TEST(parg_reorder_app_only); RUN_TEST(parg_reorder_double_dash_last); RUN_TEST(parg_reorder_missing_arg_last); } GREATEST_MAIN_DEFS(); int main(int argc, char *argv[]) { GREATEST_MAIN_BEGIN(); RUN_SUITE(parg_getopt_tests); RUN_SUITE(parg_getopt_long_tests); RUN_SUITE(parg_reorder_tests); GREATEST_MAIN_END(); }