aboutsummaryrefslogtreecommitdiffstats
path: root/doc/example.c
blob: c048465806ab76ec95517f8ce29f3a1e111a72b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* SIMPLE_TEST_PRINT_FUN may be redefined like so. default is `printf` */
#define stderr_redirect(...) fprintf(stderr, __VA_ARGS__)
#define SIMPLE_TEST_PRINT_FUN stderr_redirect

/* colour output is on by default, but can be disabled */
/* #define SIMPLE_TEST_USE_COLOUR false */

#include "../simple-test.h"

/* global variables, functions, and includes must come before BEGIN_TEST */
char *global_s;

/* a teardown function must be of type `void function(void)` and can be called
 * by TESTs which include them using the TEARDOWN macro. the call occurs either
 * after an ASSERT fails or after the TEST is finished.
 *
 * the macro may be called multiple times, but only the most recently set
 * teardown function will be called.
 *
 * here i'm using it to free memory that's alloced inside tests below */
void teardown_fun(void)
{
	free(global_s);
}

/* must appear before an (optional) REGISTER_TEARDOWN and all TESTs */
BEGIN_TEST

/* run a test. provided description must be a string literal */
TEST("basic assertion")
{
	/* ASSERT fails if passed some sort of non-true value (0, false, NULL) */
	ASSERT(1);
}

TEST("basic not assertion")
{
	bool b = false;

	ASSERT_NOT(b);
}

TEST("boolean comparison")
{
	bool a = false, b = true;

	/* fail if parameters are not equal */
	ASSERT_EQ(a, b);
}

TEST("type mismatch")
{
	char a = 'a';
	int i = 97;
	char *b = NULL;

	/* for convenience's sake, when presented with mismatched types, assertions
	 * try to resolve them in a way that's most likely to match the
	 * programmer's intentions. here 'i' is interpreted as a char */
	ASSERT_EQ(a, i);

	/* if there isn't a straightforward comparison to make, though (as is the
	 * case here, with a 'char' and 'char *'), a type mismatch error occurs */
	ASSERT_EQ(a, b);
}

TEST("ECHO example")
{
	int i;

	/* ECHO can be used to neatly report information during a run */
	if (true)
		ECHO("loop until i not less than 1");

	for (i = 0; i < 2; i++) {
		/* it takes printf format strings and variable args as well */
		ECHO("i == %d", i);
		ASSERT_LT(i, 1);
	}
}

TEST("string comparison")
{
	char *s = "test";
	global_s = strdup("test");

	/* this tells this test to call the previously defined teardown function on
	 * exiting (successfully or otherwise) */
	TEARDOWN(teardown_fun);

	/* strings are compared by content, so this assertion succeeds */
	ASSERT_EQ(s, global_s);
}

TEST("pointer comparison")
{
	char *s = "test";
	global_s = strdup("test");
	TEARDOWN(teardown_fun);

	/* you can cast parameters in order to use a different type of comparison.
	 * here i'm casting the 'char *' to 'void *' so assertion performs a
	 * pointer comparison, which fails */
	ASSERT_EQ((void*)s, (void*)global_s);
}

/* must come after all TESTs */
END_TEST