libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2020-11-18 09:32:50
Commit7a809d7cf4099b9cfe16fa2387d01800e476d28d
Parent2a257628d68bc4cba5f0d686f409984fc5134d63

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