Author | Jamozed <[email protected]> |
Date | 2020-11-18 09:32:50 |
Commit | 7a809d7cf4099b9cfe16fa2387d01800e476d28d |
Parent | 2a257628d68bc4cba5f0d686f409984fc5134d63 |
optget: Add optget unit test
Diffstat
M | CMakeLists.txt | | | 3 | ++- |
M | src/test_error.c | | | 2 | +- |
A | src/test_optget.c | | | 182 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/unit.h | | | 19 | +++++++++++++++++++ |
4 files changed, 204 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a4dd491..409ecd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,4 +14,5 @@ ADD_LIBRARY(lib STATIC ${LIBSRC}) LINK_LIBRARIES(lib) -ADD_EXECUTABLE(test_error ${PROJECT_SOURCE_DIR}/src/test_error.c) +ADD_EXECUTABLE(test_error ${PROJECT_SOURCE_DIR}/src/test_error.c) +ADD_EXECUTABLE(test_optget ${PROJECT_SOURCE_DIR}/src/test_optget.c) diff --git a/src/test_error.c b/src/test_error.c index af704ef..38f5070 100644 --- a/src/test_error.c +++ b/src/test_error.c @@ -1,5 +1,5 @@ // test_error.c -// Error test file for OMKOV lib +// Error unit test for OMKOV lib // Copyright (C) 2020, Jakob Wakeling // All rights reserved. diff --git a/src/test_optget.c b/src/test_optget.c new file mode 100644 index 0000000..9fbb1eb --- /dev/null +++ b/src/test_optget.c @@ -0,0 +1,182 @@ +// test_optget.c +// optget unit test for OMKOV lib +// Copyright (C) 2020, Jakob Wakeling +// All rights reserved. + +#include "lib/optget.h" +#include "unit.h" + +#include <stdbool.h> +#include <stdio.h> +#include <string.h> + +#define SEQ(s1, s2) (strcmp(s1, s2) == 0) + +int main(void) { + struct opt opt; + + { + char *av[] = { "G00", "-a", "-bfoo", "-c", "bar", "--", "baz", NULL }; + + opt = OPTGET_INIT; opt.str = ":ab:c:"; + ASSERT("G00T00 option", + optget(&opt, av, 1) == 'a'); + ASSERT("G00T01 option with shared argument", + optget(&opt, av, 1) == 'b'); + ASSERT("G00T02 optarg shared argument", + opt.arg == av[2] + 2); + ASSERT("G00T03 option with seperate argument", + optget(&opt, av, 1) == 'c'); + ASSERT("G00T04 optarg seperate argument", + opt.arg == av[4]); + ASSERT("G00T05 options end", + optget(&opt, av, 1) == -1); + ASSERT("G00T06 operand", + SEQ(av[opt.ind], "baz")); + } + + { + char *av[] = { "G01", "-abcfoo", "bar", NULL }; + + opt = OPTGET_INIT; opt.str = ":abc:"; + ASSERT("G01T00 option", + optget(&opt, av, 1) == 'a'); + ASSERT("G01T01 option", + optget(&opt, av, 1) == 'b'); + ASSERT("G01T02 option with shared argument", + optget(&opt, av, 1) == 'c'); + ASSERT("G01T03 optarg shared argument", + opt.arg == av[1] + 4); + ASSERT("G01T04 options end", + optget(&opt, av, 1) == -1); + ASSERT("G01T05 optind at end", + opt.ind == 2); + ASSERT("G01T06 optarg after end", + opt.arg == av[1] + 4); + ASSERT("G01T07 options still end", + optget(&opt, av, 1) == -1); + ASSERT("G01T08 optind still at end", + opt.ind == 2); + ASSERT("G01T09 operand", + SEQ(av[opt.ind], "bar")); + } + + { + char *av[] = { "G02", "-aa", "-b", NULL }; + + opt = OPTGET_INIT; opt.str = ":b:"; + ASSERT("G02T00 invalid option", + optget(&opt, av, 1) == '?'); + ASSERT("G02T01 optopt", + opt.opt == 'a'); + ASSERT("G02T00 invalid option again", + optget(&opt, av, 1) == '?'); + ASSERT("G02T01 optopt", + opt.opt == 'a'); + ASSERT("G02T02 missing option argument", + optget(&opt, av, 1) == ':'); + ASSERT("G02T03 optopt", + opt.opt == 'b'); + } + + { + char *av[] = { "G03", "foo", "-a", "bar", "-b", "baz", NULL }; + int argc = (sizeof (av) / sizeof (*av) - 1); + + opt = OPTGET_INIT; opt.str = ":ab:"; + ASSERT("G03T00 option", + optget(&opt, av, 1) == 'a'); + ASSERT("G03T01 option with seperate argument", + optget(&opt, av, 1) == 'b'); + ASSERT("G03T02 optarg seperate argument", + SEQ(opt.arg, "baz")); + ASSERT("G03T03 options end", + optget(&opt, av, 1) == -1); + ASSERT("G03T04 optind at end", + opt.ind == 4); + ASSERT("G03T05 options still end", + optget(&opt, av, 1) == -1); + ASSERT("G03T06 optind still at end", + opt.ind == 4); + ASSERT("G03T07 permuted operand", + SEQ(av[opt.ind], "foo")); ++opt.ind; + ASSERT("G03T08 permuted operand", + SEQ(av[opt.ind], "bar")); ++opt.ind; + ASSERT("G03T09 permuted operands end", + opt.ind >= argc); + } + + { + char *av[] = { "G04", "--foo", "--bar=arg", "--bar", "argument", + "--baz", NULL }; + + struct lop lops[] = { + { "foo", ARG_NUL, 256 }, + { "bar", ARG_REQ, 257 }, + { "baz", ARG_OPT, 258 }, + { NULL, 0, 0 } + }; + + opt = OPTGET_INIT; opt.str = ":"; opt.lops = lops; + ASSERT("G04T00 long option", + optget(&opt, av, 1) == 256); + ASSERT("G04T01 long option with shared argument", + optget(&opt, av, 1) == 257); + ASSERT("G04T02 optarg shared argument", + SEQ(opt.arg, "arg")); + ASSERT("G04T03 long option with seperate argument", + optget(&opt, av, 1) == 257); + ASSERT("G04T04 optarg seperate argument", + SEQ(opt.arg, "argument")); + ASSERT("G04T05 long option without argument", + optget(&opt, av, 1) == 258); + ASSERT("G04T06 optarg seperate argument", + opt.arg == NULL); + } + + { + char *av[] = { "G05", "foo", "--bar", "--", "baz", NULL }; + int argc = (sizeof (av) / sizeof (*av) - 1); + + struct lop lops[] = { + { "bar", ARG_NUL, 256 }, + { NULL, 0, 0 } + }; + + opt = OPTGET_INIT; opt.str = ":"; opt.lops = lops; + ASSERT("G05T00 long option", + optget(&opt, av, 1) == 256); + ASSERT("G05T01 options end", + optget(&opt, av, 1) == -1); + ASSERT("G05T02 permuted operand", + SEQ(av[opt.ind], "foo")); ++opt.ind; + ASSERT("G05T03 permuted operand", + SEQ(av[opt.ind], "baz")); ++opt.ind; + ASSERT("G05T04 permuted operands end", + opt.ind >= argc); + ASSERT("G05T05 options still end", + optget(&opt, av, 1) == -1); + ASSERT("G05T06 permutes operands still end", + opt.ind >= argc); + + } + + { + char *av[] = { "G06", "--foo", "bar", "-a", NULL }; + + opt = OPTGET_INIT; opt.str = ":a"; + ASSERT("G06T00 invalid option with NULL lopts", + optget(&opt, av, 0) == '?'); + ASSERT("G06T01 options end without permute", + optget(&opt, av, 0) == -1); + ASSERT("G06T02 unpermuted operand", + SEQ(av[opt.ind], "bar")); + ASSERT("G06T03 still no permute", + optget(&opt, av, 0) == -1); + ASSERT("G06T04 still unpermuted operand", + SEQ(av[opt.ind], "bar")); + } + + printf("%d of %d tests passed\n", testspassed, testsrun); + return testsfailed; +} diff --git a/src/unit.h b/src/unit.h new file mode 100644 index 0000000..b42e184 --- /dev/null +++ b/src/unit.h @@ -0,0 +1,19 @@ +// unit.h +// Unit testing library +// Copyright (C) 2019, Jakob Wakeling +// All righs reserved. + +#ifndef OMKOV_UNIT_H_YNUUN45Z +#define OMKOV_UNIT_H_YNUUN45Z + +#define PASS(message) printf("\033[1;32mPASS\033[0m %s\n", message) +#define FAIL(message) printf("\033[1;31mFAIL\033[0m %s\n", message) + +#define ASSERT(message, condition) do { \ + if(condition) { PASS(message); ++testspassed; } \ + else { FAIL(message); ++testsfailed; } ++testsrun; \ +} while (0) + +static int testsrun, testspassed, testsfailed; + +#endif // OMKOV_UNIT_H_YNUUN45Z