Revision | 634024b01237b14848582a7d65279cc5724137bb (tree) |
---|---|
Time | 2014-09-13 22:16:52 |
Author | Hans Toshihide Törnqvist @ asterina <hans.tornqvist@gmai...> |
Commiter | Hans Toshihide Törnqvist @ asterina |
ctest -> htest, and ISC licensed.
@@ -0,0 +1,2 @@ | ||
1 | +syntax: regexp | |
2 | +/build_ |
@@ -0,0 +1,78 @@ | ||
1 | +# Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
2 | +# | |
3 | +# Permission to use, copy, modify, and distribute this software for any | |
4 | +# purpose with or without fee is hereby granted, provided that the above | |
5 | +# copyright notice and this permission notice appear in all copies. | |
6 | +# | |
7 | +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
8 | +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
9 | +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
10 | +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
11 | +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
12 | +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
13 | +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
14 | + | |
15 | +AR=ar | |
16 | +CC=gcc | |
17 | +CPPFLAGS=-Iinclude -D_GNU_SOURCE | |
18 | +CFLAGS=-ansi -ggdb -pedantic-errors -Wall -Werror -Wmissing-prototypes -Wshadow -Wstrict-prototypes -Wswitch-enum | |
19 | + | |
20 | +SUFFIX:=$(shell uname -s)_$(shell uname -m) | |
21 | +BUILD_DIR:=build_$(SUFFIX) | |
22 | + | |
23 | +AR_A=$(AR) rcs $@ $^ | |
24 | +CC_EXE=$(CC) -o $@ $^ $(LDFLAGS) | |
25 | +CC_O=$(CC) -c -o $@ $< -MMD $(CPPFLAGS) $(CFLAGS) | |
26 | +MV_D=file=$(patsubst %.c,%.d,$(<F)); if test -f $$file; then\ | |
27 | + echo -n $(@D)/ | cat - $$file > $(@:.o=.d);\ | |
28 | + rm -f $$file;\ | |
29 | +fi | |
30 | +MKDIR=test -d $(@D) || mkdir -p $(@D) | |
31 | + | |
32 | +ifeq ($(V),1) | |
33 | +AR_A_V=$(AR_A) | |
34 | +CC_EXE_V=$(CC_EXE) | |
35 | +CC_O_V=$(CC_O) | |
36 | +MV_D_V=$(MV_D) | |
37 | +MKDIR_V=$(MKDIR) | |
38 | +else | |
39 | +AR_A_V=@echo "AR $@" && $(AR_A) | |
40 | +CC_EXE_V=@echo "LD $@" && $(CC_EXE) | |
41 | +CC_O_V=@echo "CC $@" && $(CC_O) | |
42 | +MV_D_V=@$(MV_D) | |
43 | +MKDIR_V=@$(MKDIR) | |
44 | +endif | |
45 | + | |
46 | +HTEST_GEN:=$(BUILD_DIR)/tests/test_all.c | |
47 | +HTEST_SRC:=$(wildcard tests/*.c) | |
48 | + | |
49 | +LIB_SRC:=$(wildcard src/*.c) | |
50 | +LIB_OBJ:=$(patsubst %.c,$(BUILD_DIR)/%.o,$(LIB_SRC)) | |
51 | +TEST_OBJ:=$(patsubst %.c,$(BUILD_DIR)/%.o,$(HTEST_SRC)) $(HTEST_GEN:.c=.o) | |
52 | +ALL_DEP:=$(patsubst %.o,%.d,$(LIB_OBJ) $(TEST_OBJ)) | |
53 | + | |
54 | +all: $(BUILD_DIR)/tests/test | |
55 | + ./$< | |
56 | + | |
57 | +include htest.mk | |
58 | + | |
59 | +$(BUILD_DIR)/libhtest.a: $(LIB_OBJ) | |
60 | + $(AR_A_V) | |
61 | + | |
62 | +$(BUILD_DIR)/tests/test: $(BUILD_DIR)/libhtest.a $(TEST_OBJ) | |
63 | + $(CC_EXE_V) | |
64 | + | |
65 | +$(BUILD_DIR)/%.o: %.c Makefile htest.mk | |
66 | + $(MKDIR_V) | |
67 | + $(CC_O_V) | |
68 | + $(MV_D_V) | |
69 | + | |
70 | +%.o: %.c Makefile htest.mk | |
71 | + $(MKDIR_V) | |
72 | + $(CC_O_V) | |
73 | + $(MV_D_V) | |
74 | + | |
75 | +clean: clean_htest | |
76 | + rm -rf $(BUILD_DIR) | |
77 | + | |
78 | +-include $(ALL_DEP) |
@@ -0,0 +1,89 @@ | ||
1 | +htest - C unit testing framework | |
2 | +-------------------------------- | |
3 | + | |
4 | +A small unit testing framework for ansi C, which compiles with very strict | |
5 | +flags in gcc. | |
6 | + | |
7 | +My personal preferences for a testing framework follow my usual philosophy of | |
8 | +life: | |
9 | + "The easier it is to fully understand every bit of a subject, the better. | |
10 | + If the subject turns out to be easy to handle, bonus!" | |
11 | +This framework provides auto-registration of tests, verbose output on failed | |
12 | +expressions, and support for testing signals. Anything else is kept to a | |
13 | +minimum. | |
14 | + | |
15 | +Below follows the typical layout of a test: | |
16 | +--- | |
17 | + | |
18 | +#include <htest/htest.h> | |
19 | + | |
20 | +HTEST(SomeSuitableTestName) | |
21 | +{ | |
22 | + HTRY_...(expr); | |
23 | +} | |
24 | + | |
25 | +HTEST_SUITE(SomeAppropriateSuiteName) | |
26 | +{ | |
27 | + /* Fixture setup. */ | |
28 | + HTEST_ADD(SomeSuitableTestName); | |
29 | + /* Fixture tear down. */ | |
30 | +} | |
31 | + | |
32 | +--- | |
33 | + | |
34 | +A test consists of a small set of expressions and conditions encapsulated by | |
35 | +at least one HTRY_...() macro, a suite consists of a small set of tests that | |
36 | +belong together. That's all. | |
37 | + | |
38 | +The default behavior is to run every test in every suite in a separate process | |
39 | +by forking, in order to let all tests run. To make debugging easier, forking | |
40 | +can be suppressed with: | |
41 | + ./test -f | |
42 | + | |
43 | +Another default behaviour is to provide bw output, so if you prefer colors: | |
44 | + ./test -c | |
45 | + | |
46 | + | |
47 | +Good things to know | |
48 | +------------------- | |
49 | + | |
50 | +There's no need to write a main() or list all suites to be included for | |
51 | +testing. The htest.mk makefile snippet will analyze the test source code after | |
52 | +preprocessing and detect all suites, and libhtest.a will run all tests. | |
53 | + | |
54 | +The tests are static functions and are therefore safe from name collisions | |
55 | +between different files. A properly configured compiler should also complain | |
56 | +about unused tests. | |
57 | + | |
58 | +The suites run one test on each invocation, so fixtures can be implemented at | |
59 | +the entry and exit of a suite. | |
60 | + | |
61 | + | |
62 | +Test trials | |
63 | +----------- | |
64 | + | |
65 | +HTRY(type, format, a, op, b) | |
66 | + Binary comparison. | |
67 | + type - type of "a" and "b". | |
68 | + format - printf format of "a" and "b". | |
69 | + a - first operand. | |
70 | + op - operator. | |
71 | + b - second operand. | |
72 | + e.g. HTRY(int, d, 0, !=, 1); | |
73 | + | |
74 | +HTRY_I(a, op, b) | |
75 | + Wrapper for HTRY(int, d, a, op, b). | |
76 | + | |
77 | +HTRY_STR(a, op, b) | |
78 | + String comparison. | |
79 | + a - first operand. | |
80 | + op - operator. | |
81 | + b - second operand. | |
82 | + | |
83 | +HTEST_VOID(expr) | |
84 | + expr - expression that should run without signals. Note that this performs a | |
85 | + fork and the result from this test is lost for subsequent tests. | |
86 | + | |
87 | +HTEST_SIGNAL(expr) | |
88 | + expr - expression that should signal one of the six ANSI signals. Also | |
89 | + performs a fork. |
@@ -0,0 +1,50 @@ | ||
1 | +# Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
2 | +# | |
3 | +# Permission to use, copy, modify, and distribute this software for any | |
4 | +# purpose with or without fee is hereby granted, provided that the above | |
5 | +# copyright notice and this permission notice appear in all copies. | |
6 | +# | |
7 | +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
8 | +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
9 | +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
10 | +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
11 | +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
12 | +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
13 | +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
14 | + | |
15 | +# Input: | |
16 | +# $(BUILD_DIR) = where to put generated stuff. | |
17 | +# $(MKDIR) = creates directory $(@D) if it does not exist. | |
18 | +# $(HTEST_GEN) = source file in which to generate the suite list. | |
19 | +# $(HTEST_SRC) = test source files. | |
20 | +# Output: | |
21 | +# $(HTEST_SUITE) = test suite cache files. | |
22 | + | |
23 | +HTEST_CC_E=$(CC) -E $< $(CPPFLAGS) | \ | |
24 | + sed -n 's/.* htest_suite_header_\([^(]*\)_(.*/\1/p' > $@ | |
25 | +ifeq (1,$(V)) | |
26 | +HTEST_CC_E_V=$(HTEST_CC_E) | |
27 | +HTEST_QUIET= | |
28 | +HTEST_MKDIR_V=$(MKDIR) | |
29 | +else | |
30 | +HTEST_CC_E_V=@echo "SUITE $@" && $(HTEST_CC_E) | |
31 | +HTEST_QUIET=@echo "TESTS $@" && | |
32 | +HTEST_MKDIR_V=@$(MKDIR) | |
33 | +endif | |
34 | + | |
35 | +HTEST_SUITE:=$(addprefix $(BUILD_DIR)/,$(HTEST_SRC:.c=.suite)) | |
36 | + | |
37 | +$(HTEST_GEN): $(HTEST_SUITE) | |
38 | + $(HTEST_QUIET)echo "#include <htest/htest.h>" > $@ &&\ | |
39 | + cat $^ | sed 's/^\(.*\)$$/HTEST_SUITE_PROTO(\1);/' >> $@ &&\ | |
40 | + echo "HTEST_SUITE_LIST_BEGIN" >> $@ &&\ | |
41 | + cat $^ | sed 's/^\(.*\)$$/ HTEST_SUITE_LIST_ADD(\1)/' >> $@ &&\ | |
42 | + echo "HTEST_SUITE_LIST_END" >> $@ | |
43 | + | |
44 | +$(BUILD_DIR)/%.suite: %.c | |
45 | + $(HTEST_MKDIR_V) | |
46 | + $(HTEST_CC_E_V) | |
47 | + | |
48 | +.PHONY: clean_htest | |
49 | +clean_htest: | |
50 | + rm -f $(HTEST_GEN) $(HTEST_SUITE) |
@@ -0,0 +1,161 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#ifndef HTEST_HTEST_H | |
18 | +#define HTEST_HTEST_H | |
19 | + | |
20 | +#include <sys/types.h> | |
21 | +#include <sys/wait.h> | |
22 | +#include <stdio.h> | |
23 | +#include <stdlib.h> | |
24 | +#include <string.h> | |
25 | +#include <unistd.h> | |
26 | + | |
27 | +struct HTestSuite { | |
28 | + void (*header)(char const *, char const *); | |
29 | + void (*suite)(char const *, char const *, char const *, int, int | |
30 | + *const, int *const); | |
31 | +}; | |
32 | + | |
33 | +/* Test. */ | |
34 | + | |
35 | +#define HTEST(name) \ | |
36 | +static void \ | |
37 | +htest_test_header_##name##_(char const *a_color, char const *a_reset)\ | |
38 | +{\ | |
39 | + printf(" %sTest("__FILE__":%d:"#name")%s\n", a_color, __LINE__,\ | |
40 | + a_reset);\ | |
41 | +}\ | |
42 | +static void \ | |
43 | +htest_test_##name##_(char const *a_color, char const *a_reset, int *const \ | |
44 | + a_result) | |
45 | + | |
46 | +/* Suite. */ | |
47 | + | |
48 | +#define HTEST_SUITE_PROTO(name) \ | |
49 | +void htest_suite_header_##name##_(char const *, char const *);\ | |
50 | +void htest_suite_##name##_(char const *, char const *, char const *, int, \ | |
51 | + int *const, int *const) | |
52 | +#define HTEST_SUITE(name) \ | |
53 | +HTEST_SUITE_PROTO(name);\ | |
54 | +void \ | |
55 | +htest_suite_header_##name##_(char const *a_color, char const *a_reset) \ | |
56 | +{\ | |
57 | + printf("%sSuite("__FILE__":%d:"#name")%s\n", a_color, __LINE__,\ | |
58 | + a_reset);\ | |
59 | +}\ | |
60 | +void \ | |
61 | +htest_suite_##name##_(char const *a_color_header, char const *a_color_fail, \ | |
62 | + char const *a_reset, int a_test_index, int *const a_test_enumerator, int \ | |
63 | + *const a_result) | |
64 | +#define HTEST_ADD(name) \ | |
65 | +do {\ | |
66 | + ++*a_test_enumerator;\ | |
67 | + if (*a_test_enumerator == a_test_index) {\ | |
68 | + htest_test_header_##name##_(a_color_header, a_reset);\ | |
69 | + htest_test_##name##_(a_color_fail, a_reset, a_result);\ | |
70 | + }\ | |
71 | +} while (0) | |
72 | + | |
73 | +/* Generated suite list. */ | |
74 | + | |
75 | +#define HTEST_SUITE_LIST_BEGIN \ | |
76 | +struct HTestSuite htest_suite_list_[] = { | |
77 | +#define HTEST_SUITE_LIST_ADD(name) \ | |
78 | + {htest_suite_header_##name##_, htest_suite_##name##_}, | |
79 | +#define HTEST_SUITE_LIST_END \ | |
80 | + {NULL, NULL}\ | |
81 | +}; | |
82 | + | |
83 | +/* Tests. */ | |
84 | + | |
85 | +#define HTRY_FAIL_ *a_result = 1 | |
86 | +#define HTRY_FAIL_FMT_ " %sFail:%s%s:%d: " | |
87 | +#define HTRY_FAIL_ARG_ a_color, a_reset, __FILE__, __LINE__ | |
88 | + | |
89 | +#define HTRY(Type, fmt, a, op, b) \ | |
90 | +do {\ | |
91 | + Type aa = a;\ | |
92 | + Type bb = b;\ | |
93 | + if (!(aa op bb)) {\ | |
94 | + fprintf(stderr, HTRY_FAIL_FMT_"'"#a"'=%"#fmt" "#op" '"#b\ | |
95 | + "'=%"#fmt"\n", HTRY_FAIL_ARG_, aa, bb);\ | |
96 | + HTRY_FAIL_;\ | |
97 | + }\ | |
98 | +} while (0) | |
99 | +#define HTRY_I(a, op, b) HTRY(int, d, a, op, b) | |
100 | + | |
101 | +#define HTRY_STR(a, op, b) \ | |
102 | +do {\ | |
103 | + char const *aa = a;\ | |
104 | + char const *bb = b;\ | |
105 | + if (!(strcmp(aa, bb) op 0)) {\ | |
106 | + fprintf(stderr, HTRY_FAIL_FMT_"'"#a"'=\"%s\" "#op" '"#b\ | |
107 | + "'=\"%s\".\n", HTRY_FAIL_ARG_, aa, bb);\ | |
108 | + HTRY_FAIL_;\ | |
109 | + }\ | |
110 | +} while (0) | |
111 | + | |
112 | +#define HTRY_FORK_(expr, dtor) \ | |
113 | +pid_t pid;\ | |
114 | +int status;\ | |
115 | +pid = fork();\ | |
116 | +if (0 > pid) {\ | |
117 | + perror(NULL);\ | |
118 | + abort();\ | |
119 | +}\ | |
120 | +if (0 == pid) {\ | |
121 | + htest_dtor_ = dtor;\ | |
122 | + signal(SIGABRT, htest_sighandler_);\ | |
123 | + signal(SIGFPE, htest_sighandler_);\ | |
124 | + signal(SIGILL, htest_sighandler_);\ | |
125 | + signal(SIGINT, htest_sighandler_);\ | |
126 | + signal(SIGSEGV, htest_sighandler_);\ | |
127 | + signal(SIGTERM, htest_sighandler_);\ | |
128 | + expr;\ | |
129 | + htest_dtor_();\ | |
130 | + _exit(0);\ | |
131 | +}\ | |
132 | +waitpid(pid, &status, 0) | |
133 | + | |
134 | +#define HTRY_VOID_DTOR(expr, dtor) \ | |
135 | +do {\ | |
136 | + HTRY_FORK_(expr, dtor);\ | |
137 | + if (0 != status) {\ | |
138 | + fprintf(stderr, HTRY_FAIL_FMT_"Caught signal.\n",\ | |
139 | + HTRY_FAIL_ARG_);\ | |
140 | + HTRY_FAIL_;\ | |
141 | + }\ | |
142 | +} while (0) | |
143 | +#define HTRY_VOID(expr) HTRY_VOID_DTOR(expr, htest_dtor_nop_) | |
144 | + | |
145 | +#define HTRY_SIGNAL_DTOR(expr, dtor) \ | |
146 | +do {\ | |
147 | + HTRY_FORK_(expr, dtor);\ | |
148 | + if (0 == status) {\ | |
149 | + fprintf(stderr, HTRY_FAIL_FMT_"Missed signal.\n",\ | |
150 | + HTRY_FAIL_ARG_);\ | |
151 | + HTRY_FAIL_;\ | |
152 | + }\ | |
153 | +} while (0) | |
154 | +#define HTRY_SIGNAL(expr) HTRY_SIGNAL_DTOR(expr, htest_dtor_nop_) | |
155 | + | |
156 | +void htest_dtor_nop_(void); | |
157 | +void htest_sighandler_(int); | |
158 | + | |
159 | +extern void (*htest_dtor_)(void); | |
160 | + | |
161 | +#endif |
@@ -0,0 +1,163 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#include <sys/types.h> | |
18 | +#include <sys/wait.h> | |
19 | +#include <stdlib.h> | |
20 | +#include <unistd.h> | |
21 | +#include <htest/htest.h> | |
22 | +#include <string.h> | |
23 | + | |
24 | +#define BLUE "\033[1;34m" | |
25 | +#define GREEN "\033[1;32m" | |
26 | +#define RED "\033[1;31m" | |
27 | +#define RESET "\033[0m" | |
28 | + | |
29 | +static void handler(int); | |
30 | + | |
31 | +extern struct HTestSuite htest_suite_list_[]; | |
32 | +void (*htest_dtor_)(void); | |
33 | + | |
34 | +void | |
35 | +htest_dtor_nop_(void) | |
36 | +{ | |
37 | +} | |
38 | + | |
39 | +void | |
40 | +htest_sighandler_(int a_signum) | |
41 | +{ | |
42 | + (void)a_signum; | |
43 | + htest_dtor_(); | |
44 | + _exit(EXIT_FAILURE); | |
45 | +} | |
46 | + | |
47 | +void | |
48 | +handler(int a_signum) | |
49 | +{ | |
50 | + fprintf(stderr, " Fail: Caught signal = %s, next suite...\n", | |
51 | + strsignal(a_signum)); | |
52 | + _exit(EXIT_FAILURE); | |
53 | +} | |
54 | + | |
55 | +int | |
56 | +main(int argc, char **argv) | |
57 | +{ | |
58 | + struct HTestSuite *suite; | |
59 | + char const *suite_color; | |
60 | + char const *test_color; | |
61 | + char const *fail_color; | |
62 | + char const *reset_color; | |
63 | + int test_num, test_pass_num; | |
64 | + int do_colors, do_fork; | |
65 | + int opt; | |
66 | + | |
67 | + do_colors = 1; | |
68 | + do_fork = 0; | |
69 | + while (-1 != (opt = getopt(argc, argv, "cf"))) { | |
70 | + switch (opt) { | |
71 | + case 'c': | |
72 | + do_colors = 0; | |
73 | + break; | |
74 | + case 'f': | |
75 | + do_fork = 1; | |
76 | + break; | |
77 | + default: | |
78 | + fprintf(stderr, "Usage: %s [-c] [-f]\n", | |
79 | + argv[0]); | |
80 | + exit(EXIT_FAILURE); | |
81 | + } | |
82 | + } | |
83 | + | |
84 | + if (0 == do_colors) { | |
85 | + suite_color = GREEN; | |
86 | + test_color = BLUE; | |
87 | + fail_color = RED; | |
88 | + reset_color = RESET; | |
89 | + } else { | |
90 | + suite_color = ""; | |
91 | + test_color = ""; | |
92 | + fail_color = ""; | |
93 | + reset_color = ""; | |
94 | + } | |
95 | + | |
96 | + test_num = 0; | |
97 | + test_pass_num = 0; | |
98 | + for (suite = htest_suite_list_; NULL != suite->header; ++suite) { | |
99 | + int test_enumerator; | |
100 | + int test_index; | |
101 | + | |
102 | + suite->header(suite_color, reset_color); | |
103 | + | |
104 | + test_enumerator = 0; | |
105 | + suite->suite("", "", "", 0, &test_enumerator, NULL); | |
106 | + if (0 == test_enumerator) { | |
107 | + continue; | |
108 | + } | |
109 | + test_num += test_enumerator; | |
110 | + | |
111 | + for (test_index = 1; test_enumerator >= test_index; | |
112 | + ++test_index) { | |
113 | + if (0 == do_fork) { | |
114 | + pid_t pid; | |
115 | + | |
116 | + pid = fork(); | |
117 | + if (0 > pid) { | |
118 | + perror(NULL); | |
119 | + abort(); | |
120 | + } | |
121 | + if (0 == pid) { | |
122 | + int result; | |
123 | + | |
124 | + signal(SIGABRT, handler); | |
125 | + signal(SIGFPE, handler); | |
126 | + signal(SIGILL, handler); | |
127 | + signal(SIGINT, handler); | |
128 | + signal(SIGSEGV, handler); | |
129 | + signal(SIGTERM, handler); | |
130 | + test_enumerator = 0; | |
131 | + result = EXIT_SUCCESS; | |
132 | + suite->suite(test_color, fail_color, | |
133 | + reset_color, test_index, | |
134 | + &test_enumerator, &result); | |
135 | + _exit(0 == result ? EXIT_SUCCESS : | |
136 | + EXIT_FAILURE); | |
137 | + } else { | |
138 | + int status; | |
139 | + | |
140 | + waitpid(pid, &status, 0); | |
141 | + if (0 == status) { | |
142 | + ++test_pass_num; | |
143 | + } | |
144 | + } | |
145 | + } else { | |
146 | + int result; | |
147 | + | |
148 | + test_enumerator = 0; | |
149 | + result = 0; | |
150 | + suite->suite(test_color, fail_color, | |
151 | + reset_color, test_index, &test_enumerator, | |
152 | + &result); | |
153 | + if (0 == result) { | |
154 | + ++test_pass_num; | |
155 | + } | |
156 | + } | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + printf("Passed %d/%d (%.1f%%) tests.\n", test_pass_num, test_num, | |
161 | + 100.0f * test_pass_num / test_num); | |
162 | + return 0; | |
163 | +} |
@@ -0,0 +1,31 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#include <htest/htest.h> | |
18 | + | |
19 | +static int const c_zero = 0; | |
20 | +static int const c_one = 1; | |
21 | + | |
22 | +HTEST(ThisShouldFail) | |
23 | +{ | |
24 | + HTRY_I(c_zero + 1, ==, c_zero); | |
25 | + HTRY_I(c_zero, !=, c_one - 1); | |
26 | +} | |
27 | + | |
28 | +HTEST_SUITE(Fail) | |
29 | +{ | |
30 | + HTEST_ADD(ThisShouldFail); | |
31 | +} |
@@ -0,0 +1,42 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#include <htest/htest.h> | |
18 | + | |
19 | +static int *g_mojo; | |
20 | + | |
21 | +HTEST(SimpleFixture1) | |
22 | +{ | |
23 | + HTRY_I(*g_mojo, ==, 0x12345678); | |
24 | + ++(*g_mojo); | |
25 | + HTRY_I(*g_mojo, ==, 0x12345679); | |
26 | +} | |
27 | + | |
28 | +HTEST(SimpleFixture2) | |
29 | +{ | |
30 | + HTRY_I(*g_mojo, ==, 0x12345678); | |
31 | +} | |
32 | + | |
33 | +HTEST_SUITE(SimpleFixture) | |
34 | +{ | |
35 | + g_mojo = malloc(sizeof *g_mojo); | |
36 | + *g_mojo = 0x12345678; | |
37 | + | |
38 | + HTEST_ADD(SimpleFixture1); | |
39 | + HTEST_ADD(SimpleFixture2); | |
40 | + | |
41 | + free(g_mojo); | |
42 | +} |
@@ -0,0 +1,32 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#include <htest/htest.h> | |
18 | + | |
19 | +static int const c_zero = 0; | |
20 | +static int const c_one = 1; | |
21 | + | |
22 | +HTEST(ThisShouldPass) | |
23 | +{ | |
24 | + HTRY_I(c_zero, ==, c_zero); | |
25 | + HTRY_I(c_zero, !=, c_one); | |
26 | + HTRY_I(c_zero + 1, ==, c_one); | |
27 | +} | |
28 | + | |
29 | +HTEST_SUITE(Pass) | |
30 | +{ | |
31 | + HTEST_ADD(ThisShouldPass); | |
32 | +} |
@@ -0,0 +1,45 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#include <htest/htest.h> | |
18 | + | |
19 | +HTEST(ThisShouldNotSegfaultAndPass) | |
20 | +{ | |
21 | + HTRY_VOID((void)0); | |
22 | +} | |
23 | + | |
24 | +HTEST(ThisShouldNotSegfaultAndFail) | |
25 | +{ | |
26 | + HTRY_SIGNAL((void)0); | |
27 | +} | |
28 | + | |
29 | +HTEST(ThisShouldSegfaultAndPass) | |
30 | +{ | |
31 | + HTRY_SIGNAL(*(int *)NULL = 0); | |
32 | +} | |
33 | + | |
34 | +HTEST(ThisShouldSegfaultAndFail) | |
35 | +{ | |
36 | + HTRY_VOID(*(int *)NULL = 0); | |
37 | +} | |
38 | + | |
39 | +HTEST_SUITE(MySignal) | |
40 | +{ | |
41 | + HTEST_ADD(ThisShouldNotSegfaultAndPass); | |
42 | + HTEST_ADD(ThisShouldNotSegfaultAndFail); | |
43 | + HTEST_ADD(ThisShouldSegfaultAndPass); | |
44 | + HTEST_ADD(ThisShouldSegfaultAndFail); | |
45 | +} |
@@ -0,0 +1,31 @@ | ||
1 | +/* | |
2 | + * Copyright (c) 2014 Hans Toshihide Törnqvist <hans.tornqvist@gmail.com> | |
3 | + * | |
4 | + * Permission to use, copy, modify, and distribute this software for any | |
5 | + * purpose with or without fee is hereby granted, provided that the above | |
6 | + * copyright notice and this permission notice appear in all copies. | |
7 | + * | |
8 | + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | + */ | |
16 | + | |
17 | +#include <htest/htest.h> | |
18 | + | |
19 | +HTEST(SimpleStrings) | |
20 | +{ | |
21 | + char const c_hello[] = "Hello"; | |
22 | + | |
23 | + HTRY_STR("Hello", ==, c_hello); | |
24 | + HTRY_STR("abc", <, "def"); | |
25 | + HTRY_STR("def", >, "abc"); | |
26 | +} | |
27 | + | |
28 | +HTEST_SUITE(String) | |
29 | +{ | |
30 | + HTEST_ADD(SimpleStrings); | |
31 | +} |