commit be897a7b9bdff1a8faae3850d96d39a03ef75bb0 from: Sven M. Hallberg date: Tue Jul 29 14:01:03 2025 UTC add manpage for test.h Replaces the top-of-file comment in test.h. commit - 5bc4ca7fa3c49d5b57406f3872f169737984cc87 commit + be897a7b9bdff1a8faae3850d96d39a03ef75bb0 blob - 4387b4bc96d75f771e7e6cc1220532f315c101e7 blob + ed698719d8f3a01b6f046d3b6e78dd389d8b1db2 --- exercise.1 +++ exercise.1 @@ -1,4 +1,4 @@ -.Dd May 25, 2025 +.Dd July 23, 2025 .Dt EXERCISE 1 .Os . @@ -285,7 +285,8 @@ Note the use of (shell) single quotes to embed the nec double quotes. . .Sh SEE ALSO -.Xr sh 1 +.Xr sh 1 , +.Xr test.h 3 . .Sh AUTHORS .An Sven M. Hallberg Aq Mt pesco@khjk.org blob - dc4a939317c2e7a83d535985ded67c49838312b6 blob + b1f35683ba3b436400f30fe3c12a5280615f9b80 --- lang/c/test.h +++ lang/c/test.h @@ -1,120 +1,7 @@ -/* test.h - terribly simple tests in plain C +/* + * test.h - terribly simple tests in plain C * pesco 2020, 2024, 2025 * ISC license - * - * SYNOPSIS - * #include "test.h" - * - * static int status; - * - * TEST(function, ...); - * RUNT(function, ...); - * - * assert(expression); - * expect(expression); - * - * fail(fmt, ...); - * rem(fmt, ...); - * - * - * DESCRIPTION - * The TEST() macro calls the given function as a unit test. Any - * additional arguments will be passed to function, allowing parameterized - * families of tests. - * - * TEST() is meant to be called from main() and inspects argc/argv. The - * command line should consist (only) of string prefixes that select the - * corresponding tests. An empty command line selects all tests. Any - * selected tests are passed to RUNT(). The RUNT() macro executes a test - * unconditionally and prints the test result to standard output. It does - * not depend on argc and argv being in scope. - * - * Test functions may be defined with any return type; their return value - * is ignored. To signal failure of a test, the fail() macro should be - * called with an appropriate error message, using printf(3)-style - * arguments. Diagnostics relating to the failure may be printed to stderr. - * - * The expect() macro tests a boolean condition. It calls fail() if the - * given expression evaluates to false. The user should define custom - * variants of expect() as suitable. - * - * The rem() macro can be used to produce miscellaneous messages; it is - * ignored unless V is set. Messages should consist of a single line, - * without a trailing newline, and will be printed to stdout prefixed by - * a TAB character to maintain a simple TSV format. No other output should - * be made to stdout. - * - * By default, the fail() macro does not immediately abort the running - * test. Checks that are a strict precondition for the continuation of - * the test should use assert(3); test.h includes assert.h for - * convenience. After a failed test returns, RUNT() normally calls - * exit(3), forgoing any remaining tests. See the K and X environment - * variables for changing the default behavior. - * - * The global variable status is set to 1 upon test failure and should be - * used to return the correct value from main (when K is set). - * - * ENVIRONMENT - * The following variables serve as flags. They enable the stated behavior - * whenever set, regardless of value. - * - * D Dry run. Print tests without executing them. - * - * V Verbose. Print any tests that are skipped and enable - * informational output from rem(). - * - * K Keep going after a failed test instead of exiting. - * - * X Exit with a call to abort(3) as soon as fail() is called. - * - * EXAMPLES - * The following shows a test program: - * - * #include "test.h" - * - * void foo(void) - * { - * expect(1 == 1); - * } - * - * void bar(unsigned int mask) - * { - * expect(0x01 & mask != 0); - * expect(0x10 & mask != 0); - * } - * - * int main(int argc, char **argv) - * { - * TEST(foo); - * TEST(bar, 0x0f); - * TEST(bar, 0xff); - * - * return status; - * } - * - * To run only the 'bar' family of tests: - * - * $ ./test bar - * bar(0xff) OK - * test.c:11: condition failed: (0x10 & mask) != 0 - * bar(0x0f) FAIL - * - * Running 'foo' and 'bar(0xff)': - * - * $ ./test foo bar\(0xf - * foo() OK - * bar(0xff) OK - * - * A list or count of tests matching a given selection can be produced by - * issuing a dry run: - * - * $ D=1 ./test - * foo() - * bar(0xff) - * bar(0x0f) - * - * $ D=1 ./test bar | wc -l - * 2 */ #ifndef TEST_H blob - /dev/null blob + d3d345769acbfc6d5784598262b8b669269bbd7f (mode 644) --- /dev/null +++ test.h.3 @@ -0,0 +1,203 @@ +.Dd July 23, 2025 +.Dt TEST.H 3 +.Os +. +.Sh NAME +.Nm test.h +.Nd terribly simple tests in plain C +. +.Sh SYNOPSIS +.In test.h +.Vt static int status; +.Fn TEST function ... +.Fn RUNT function ... +.Fn expect expression +.Fn fail fmt ... +.Fn rem fmt ... +. +.Sh DESCRIPTION +The +.Fn TEST +macro calls the given function as a test. +Any additional arguments are be passed through to +.Ar function , +allowing parameterized families of tests. +.Pp +.Fn TEST +is meant to be called from +.Fn main +and inspects +.Va argc +and +.Va argv . +The command line should consist (only) of string prefixes +that select the corresponding tests. +An empty command line selects all tests. +Each selected test is passed to the +.Fn RUNT +macro. +.Pp +.Fn RUNT +unconditionally executes the given test +and prints its result to standard output. +It does not depend on +.Va argc +and +.Va argv +being in scope. +.Pp +Test functions may be defined with any return type; +their return value is ignored. +To signal failure of a test, the +.Fn fail +macro should be called with an appropriate error message, using +.Xr printf 3 Ns +-style arguments. +Diagnostics relating to the failure may be printed to +.Va stderr . +.Pp +The +.Fn expect +macro tests a boolean condition. +It calls +.Fn fail +if the given expression evaluates to false. +The user should define custom variants of +.Fn expect +as suitable. +.Pp +The +.Fn rem +macro can be used to produce miscellaneous messages; +it is ignored unless +.Ev V +is set. +Messages should consist of a single line, +without a trailing newline, +and will be printed to +.\"Va stdout +standard output +prefixed by a TAB character to maintain a simple TSV format. +No other output should be made to +.Va stdout . +.Pp +By default, calling +.Fn fail +does not immediately abort the running test. +Checks that are a strict precondition for the continuation of +the test should use +.Xr assert 3 +\(em +.Pa test.h +includes +.In assert.h for convenience. +After a failed test returns, +.Fn RUNT +normally calls +.Xr exit 3 , +forgoing any remaining tests. +See the +.Ev K +and +.Ev X +environment variables for changing the default behavior. +.Pp +The global variable +.Va status +is set to 1 upon test failure and should be +used to return the correct value from main (when +.Ev K +is set). +. +.Sh ENVIRONMENT +The following variables serve as flags. +They enable the stated behavior whenever set, regardless of value. +.Bl -tag -width 3n +.It Ev D +Dry run. +Print tests without executing them. +.It Ev V +Verbose. +Print any tests that are skipped and enable informational output from +.Fn rem . +.It Ev K +Keep going after a failed test instead of exiting. +.It Ev X +Exit with a call to +.Xr abort 3 +as soon as +.Fn fail +is called. +.El +. +.Sh EXAMPLES +The following shows a test program consisting of two test functions, +one parameterized over an +.Vt unsigned int , +for a total of three test cases. +.Bd -literal -offset Ds +#include "test.h" + +void +foo(void) +{ + expect(1 == 1); +} + +void +bar(unsigned int mask) +{ + expect(0x01 & mask != 0); + expect(0x10 & mask != 0); +} + +int +main(int argc, char *argv[]) +{ + TEST(foo); + TEST(bar, 0x0f); + TEST(bar, 0xff); + + return status; +} +.Ed +.Pp +To run only the +.Sq bar +family of tests: +.Bd -literal -offset Ds +$ ./test bar +bar(0xff) OK +test.c:11: condition failed: (0x10 & mask) != 0 +bar(0x0f) FAIL +.Ed +.Pp +Running +.Sq foo +and +.Sq bar(0xff) : +.Bd -literal -offset Ds +$ ./test foo bar\\(0xf +foo() OK +bar(0xff) OK +.Ed +.Pp +A list or count of tests matching a given selection can be produced by +issuing a dry run: +.Bd -literal -offset Ds +$ D=1 ./test +foo() +bar(0xff) +bar(0x0f) + +$ D=1 ./test bar | wc -l +2 +.Ed +. +.Sh SEE ALSO +.Xr abort 3 , +.Xr assert 3 , +.Xr printf 3 +. +.Sh AUTHORS +.An Sven M. Hallberg Aq Mt pesco@khjk.org