diff options
| author | Alistair Popple <alistair@popple.id.au> | 2018-06-20 15:34:08 +1000 |
|---|---|---|
| committer | Alistair Popple <alistair@popple.id.au> | 2018-06-25 16:05:38 +1000 |
| commit | 7e98b3be26424f41876aea9af30085030e80fef3 (patch) | |
| tree | 5ceaf6f275eeff4e0a77b9c7b947da5168d3d88c | |
| parent | 6be301f376e6546a142104174df61fc3248da80f (diff) | |
| download | pdbg-7e98b3be26424f41876aea9af30085030e80fef3.tar.gz pdbg-7e98b3be26424f41876aea9af30085030e80fef3.zip | |
optcmd: Add tests
We don't really have infrastructure in place to easily add/build/run tests,
but that shouldn't stop them being written. This adds some basic tests of
the argument parsing logic.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
| -rw-r--r-- | Makefile.am | 5 | ||||
| -rw-r--r-- | src/tests/optcmd_test.c | 161 |
2 files changed, 165 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index b860e14..23f2080 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ AM_MAKEFLAGS = --no-print-directory GIT_SHA1 ?= `git --work-tree=$(top_srcdir) --git-dir=$(top_srcdir)/.git describe --always --long --dirty || echo unknown` -bin_PROGRAMS = pdbg +bin_PROGRAMS = pdbg optcmd_test ACLOCAL_AMFLAGS = -Im4 AM_CFLAGS = -I$(top_srcdir)/ccan/array_size -Wall -Werror -O2 @@ -26,6 +26,9 @@ DT_headers = $(DT:.dts=.dt.h) BUILT_SOURCES = $(DT) $(DT_headers) +optcmd_test_SOURCES = src/optcmd.c src/parsers.c src/tests/optcmd_test.c +optcmd_test_CFLAGS = -Wall -g + pdbg_SOURCES = \ src/main.c \ src/cfam.c \ diff --git a/src/tests/optcmd_test.c b/src/tests/optcmd_test.c new file mode 100644 index 0000000..bfa0667 --- /dev/null +++ b/src/tests/optcmd_test.c @@ -0,0 +1,161 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <string.h> +#include <assert.h> +#include <ccan/array_size/array_size.h> + +#include "../optcmd.h" +#include "../parsers.h" + +/* The OPTCMD_TEST_BREAK_BUILD* defines can be used to test that we catch type + * mistmatch errors between function/flag definitions and parsers */ +#ifdef OPTCMD_TEST_BREAK_BUILD1 +struct flags { + bool test_bool; + int test_num; +}; +#else +struct flags { + bool test_bool; + uint64_t test_num; +}; +#endif + +/* Format: (<flag>, <field>, <parser>, <default value>) */ +#define FLAG_TEST_BOOL ("--test-bool", test_bool, parse_flag_noarg, false) +#define FLAG_TEST_NUM ("--test-num", test_num, parse_number64, 10) + +/* Format: (<parser>, <default value>) + * + * <default value> may be NULL if argument must be supplied. + */ +#define ARG_NUM (parse_number64, NULL) +#define ARG_NUM_OPT (parse_number64, "2") + +static uint64_t num, opt, flag; +static bool bool_flag; + +static int test(void) +{ + bool_flag = true; + + return 0; +} +OPTCMD_DEFINE_CMD(test, test); + +#ifdef OPTCMD_TEST_BREAK_BUILD2 +static int test_args(int num_arg, int opt_arg) +{ + return 0; +} +#else +static int test_args(uint64_t num_arg, uint64_t opt_arg) +{ + num = num_arg; + opt = opt_arg; + + return 0; +} +#endif +OPTCMD_DEFINE_CMD_WITH_ARGS(test_args, test_args, (ARG_NUM, ARG_NUM_OPT)); + +static int test_flags(uint64_t num_arg, uint64_t opt_arg, struct flags flags) +{ + num = num_arg; + opt = opt_arg; + flag = flags.test_num; + bool_flag = flags.test_bool; + + return 0; +} +OPTCMD_DEFINE_CMD_WITH_FLAGS(test_flags, test_flags, (ARG_NUM, ARG_NUM_OPT), + flags, (FLAG_TEST_BOOL, FLAG_TEST_NUM)); + +int parse_argv(const char *argv[], int argc) +{ + int i, rc; + void **args, **flags; + struct optcmd_cmd *cmds[] = { &optcmd_test, &optcmd_test_args, &optcmd_test_flags }; + optcmd_cmd_t *cmd; + + for (i = 0; i < ARRAY_SIZE(cmds); i++) { + if (!strcmp(argv[0], cmds[i]->cmd)) { + /* Found our command */ + cmd = optcmd_parse(cmds[i], &argv[1], argc - 1, &args, &flags); + if (cmd) { + rc = cmd(args, flags); + return rc; + } + } + } + + return -1; +} + +int main(void) +{ + /* Tests */ + const char *test1_argv[] = { "test" }; + bool_flag = false; + assert(!parse_argv(test1_argv, ARRAY_SIZE(test1_argv))); + assert(bool_flag); + + const char *test2_argv[] = { "test_args", "1" }; + assert(!parse_argv(test2_argv, ARRAY_SIZE(test2_argv))); + assert(num == 1); + assert(opt == 2); + + const char *test3_argv[] = { "test_args", "2", "3" }; + assert(!parse_argv(test3_argv, ARRAY_SIZE(test3_argv))); + assert(num == 2); + assert(opt == 3); + + const char *test4_argv[] = { "test_flags", "4", "5" }; + assert(!parse_argv(test4_argv, ARRAY_SIZE(test4_argv))); + assert(num == 4); + assert(opt == 5); + assert(flag == 10); + + bool_flag = false; + + const char *test5_argv[] = { "test_flags", "5", "6" }; + assert(!parse_argv(test5_argv, ARRAY_SIZE(test5_argv))); + assert(num == 5); + assert(opt == 6); + assert(flag == 10); + assert(!bool_flag); + + const char *test6_argv[] = { "test_flags", "7", "8", "--test-num=9" }; + assert(!parse_argv(test6_argv, ARRAY_SIZE(test6_argv))); + assert(num == 7); + assert(opt == 8); + assert(flag == 9); + assert(!bool_flag); + + const char *test7_argv[] = { "test_flags", "8", "9", "--test-bool" }; + assert(!parse_argv(test7_argv, ARRAY_SIZE(test7_argv))); + assert(num == 8); + assert(opt == 9); + assert(flag == 10); + assert(bool_flag); + + bool_flag = false; + + const char *test8_argv[] = { "test_flags", "9", "10", "--test-bool", "--test-num=11" }; + assert(!parse_argv(test8_argv, ARRAY_SIZE(test8_argv))); + assert(num == 9); + assert(opt == 10); + assert(flag == 11); + assert(bool_flag); + + /* This should fail, too many arguments */ + const char *test9_argv[] = { "test_flags", "9", "10", "11", "--test-bool", "--test-num=11" }; + assert(parse_argv(test9_argv, ARRAY_SIZE(test9_argv))); + + /* So should this, unknown flag */ + const char *test10_argv[] = { "test_flags", "9", "10", "--test-blah", "--test-num=11" }; + assert(parse_argv(test10_argv, ARRAY_SIZE(test10_argv))); + + return 0; +} |

