aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md158
1 files changed, 135 insertions, 23 deletions
diff --git a/README.md b/README.md
index 407c234..c452c95 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
simple-test
-==============
+===========
simple unit testing for C implemented as a single header file
@@ -8,33 +8,145 @@ brief summary
Your tests should be written as a single .c file separate from
the body of text containing your functionality to be tested.
Write the tests, include simple-test.h, point your compiler at
-the necessary files, and you're done! see this
-[documentation (pdf)](https://github.com/shmibs/simple-test/blob/master/README.pdf?raw=true)
-for more details (because github markdown is annoying and doesn't
-let me colour things).
+the necessary files / libs, and you're done!
+
+an example
+----------
+
+consider the following simple program:
+
+```c
+/* keep this include at the very top of the file */
+#include "simple-test.h"
+
+/* any global variables, functions, other inclusions, etc.
+ * should be declared here */
+#include "header_with_stuff_to_be_tested.h"
+
+int add_here(int a, int b)
+{
+ /* ASSERT / ECHO statements within functions
+ * like this are perfectly valid. this is
+ * useful for writing initialisation functions
+ * called at the beginning of multiple TESTs */
+ ECHO("this is the local add");
+
+ /* ensure a and b are non-0 using generic ASSERT */
+ ASSERT(a);
+ ASSERT(b);
+
+ return a + b;
+}
+
+/* must come before all TESTs */
+BEGIN_TEST
+
+/* the string is a description of the test being run */
+TEST("check add()'s return value")
+{
+ /* mixing different precisions is allowed */
+ long var1 = 2;
+ int8_t var2 = 2;
+
+ /* add is a function included from our hypothetical
+ * header_with_stuff_to_be_tested.h */
+ ASSERT_INT_EQ(var1+var2, add(var1, var2));
+
+ /* generic versions of ASSERTions are also valid,
+ * but only for number types (int / uint / float ) */
+ ASSERT_EQ(var1+var2, add_here(var1, var2));
+}
+
+TEST("compare two arrays of strings")
+{
+ int i;
+ char array1[][10] = {
+ "str1",
+ "str2",
+ "str3",
+ };
+ char array2[][10] = {
+ "str1",
+ "str2",
+ /* matching will fail here */
+ "different",
+ };
+
+ for(i = 0; i < sizeof(array1) / sizeof(char[10]); i++) {
+ /* ECHO can be used to print (with pretty
+ * formatting) the current state within the
+ * test */
+ ECHO("checking strs at i == %i", i);
+
+ ASSERT_STR_EQ(array1[i], array2[i]);
+ }
+}
+
+/* must come after all TESTs */
+END_TEST
+```
+
+running this test, the output might look something like this:
+
+![run 1](doc/run-01.png)
+
+if var1 in the first test were changed to 0, like so:
+
+```c
+ /* mixing different precisions is allowed */
+ long var1 = 0;
+ int8_t var2 = 2;
+```
+
+ASSERT(a); in add_here() would fail like this:
+
+![run 2](doc/run-02.png)
+
+if array2 were modified instead so the third strings would match,
+a successful output would look like this:
+
+![run 3](doc/run-03.png)
+
defined macros
--------------
-NAME|DESCRIPTION
----:|:----------
-**BEGIN_TEST**|must appear before all tests and after all global variable declarations
-**END_TEST**|must appear at the end of your test program
-**CLEANUP(statements)**|this defines a list of statements to run when the test exits, either successfully or on a failure. it isn't necessary for a test to run, but, if it does appear, it must be after the declaration of all variables to which it makes reference.
-**RETURN()**|place at the end of a test which uses CLEANUP to ensure it is called before the test exits. i couldn't find any way around this without using more than just one header file, so i hope it isn't too annoying.
-**STATE(description)**|show a prettily-formatted description of the program's state during a test. takes printf-style arguments.
-**EXPECT_ZERO(summary, arg)**|fail if `arg` does not resolve to 0
-**EXPECT_ONE(summary, arg)**|fail if `arg` does not resolve to 1
-**EXPECT_GREATER_THAN_ZERO(summary, arg)**|fail if `arg` does not resolve to a value greater than 0. this will be replaced with more generic integer comparisons soon.
-**EXPECT_INT(summary, arg1, arg2)**|fail if `arg2` does not match the expected integer value `arg1`
-**EXPECT_EQUAL_INT(summary, arg1, arg2)**|fail if `arg1` and `arg2` are not equal
-**EXPECT_UNEQUAL_INT(summary, arg1, arg2)**|fail if `arg1` and `arg2` are equal
-**EXPECT_STR(summary, arg1, arg2)**|fail if string `arg2` does not match the expected string value `arg1`
-**EXPECT_EQUAL_STR(summary, arg1, arg2)**|fail if `arg1` and `arg2` are not equivalent strings
-**EXPECT_UNEQUAL_STR(summary, arg1, arg2)**|fail if `arg1` and `arg2` are equivalent strings
+| **NAME** | **DESCRIPTION** |
+|---------:|:----------------|
+| **BEGIN_TEST** | must be included once, after includes and global declarations and before the first TEST statement |
+| **END_TEST** | must be included once, after the final TEST statement |
+| **TEST(<description>)**{} | declare a test, described by `description`, which consists of statements between the {} |
+| **ECHO(<...>)** | print a formatted description of the state within the current test |
+| **ASSERT<_type_name><_condition>(<args>)** | assert, on either one or two `args` of type `_type_name`, that `_condition` is true |
+
+valid `_type_name`s and `_conditions` for ASSERT statements are:
+| **_type_name** | **DESCRIPTION** |
+|---------------:|:----------------|
+| | if the _type_name is omitted, generic assertions which automatically determine type are used. valid only for number types, i.e. int, unsigned, double. |
+| **_BOOL** | operate on args of type `bool` |
+| **_INT** | operate on signed integer types |
+| **_UINT** | operate on unsigned integer types |
+| **_HEX** | operate on unsigned integer types. output with %X formatting |
+| **_FLOAT** | operate on floating point types |
+| **_PTR** | operate on generic pointer types. casts to void* |
+| **_CHAR** | operate on args of type `char` |
+| **_STR** | operate on strings pointed to by args of type `char*`. |
+| **_WCHAR** | operate on wide character types |
+| **_WSTR** | operate on wide strings pointed to by args of type `wchar_t*` |
-**WARNING: this will work fine in gcc, but it uses the non-standard
-macro \__COUNTER__ and nested functions.**
+| **_condition** | **DESCRIPTION** |
+|---------------:|:----------------|
+| | if the _condition is omitted, fail if the single arg is a "not" value, i.e. NULL, 0, '\0' etc. |
+| **_EQ** | fail if the two args are not equal |
+| **_NEQ** | fail if the two args are equal |
+| **_G** | fail if the first arg is not greater than the second |
+| **_GEQ** | fail if the first arg is not greater than or equal to the second |
+| **_L** | fail if the first arg is not less than the second |
+| **_LEQ** | fail if the first arg is not less than or equal to the second |
+note
+----
+this makes heavy use of _Generic, so C11 support is required
+tested successfully both with gcc and clang