1 /* Copyright (c) 2010 James Grenning and Contributed to Unity Project
2 * ==========================================
3 * Unity Project - A Test Framework for C
4 * Copyright (c) 2007 Mike Karlesky, Mark VanderVoord, Greg Williams
5 * [Released under MIT License. Please refer to license.txt for details]
6 * ========================================== */
7
8 #include "unity_fixture.h"
9 #include "unity_internals.h"
10 #include <string.h>
11
12 struct UNITY_FIXTURE_T UnityFixture;
13
14 /* If you decide to use the function pointer approach.
15 * Build with -D UNITY_OUTPUT_CHAR=outputChar and include <stdio.h>
16 * int (*outputChar)(int) = putchar; */
17
setUp(void)18 void setUp(void) { /*does nothing*/ }
tearDown(void)19 void tearDown(void) { /*does nothing*/ }
20
announceTestRun(unsigned int runNumber)21 static void announceTestRun(unsigned int runNumber)
22 {
23 UnityPrint("Unity test run ");
24 UnityPrintNumberUnsigned(runNumber+1);
25 UnityPrint(" of ");
26 UnityPrintNumberUnsigned(UnityFixture.RepeatCount);
27 UNITY_PRINT_EOL();
28 }
29
UnityMain(int argc,const char * argv[],void (* runAllTests)(void))30 int UnityMain(int argc, const char* argv[], void (*runAllTests)(void))
31 {
32 int result = UnityGetCommandLineOptions(argc, argv);
33 unsigned int r;
34 if (result != 0)
35 return result;
36
37 for (r = 0; r < UnityFixture.RepeatCount; r++)
38 {
39 UnityBegin(argv[0]);
40 announceTestRun(r);
41 runAllTests();
42 if (!UnityFixture.Verbose) UNITY_PRINT_EOL();
43 UnityEnd();
44 }
45
46 return (int)Unity.TestFailures;
47 }
48
selected(const char * filter,const char * name)49 static int selected(const char* filter, const char* name)
50 {
51 if (filter == 0)
52 return 1;
53 return strstr(name, filter) ? 1 : 0;
54 }
55
testSelected(const char * test)56 static int testSelected(const char* test)
57 {
58 return selected(UnityFixture.NameFilter, test);
59 }
60
groupSelected(const char * group)61 static int groupSelected(const char* group)
62 {
63 return selected(UnityFixture.GroupFilter, group);
64 }
65
UnityTestRunner(unityfunction * setup,unityfunction * testBody,unityfunction * teardown,const char * printableName,const char * group,const char * name,const char * file,unsigned int line)66 void UnityTestRunner(unityfunction* setup,
67 unityfunction* testBody,
68 unityfunction* teardown,
69 const char* printableName,
70 const char* group,
71 const char* name,
72 const char* file,
73 unsigned int line)
74 {
75 if (testSelected(name) && groupSelected(group))
76 {
77 Unity.TestFile = file;
78 Unity.CurrentTestName = printableName;
79 Unity.CurrentTestLineNumber = line;
80 if (UnityFixture.Verbose)
81 {
82 UnityPrint(printableName);
83 #ifndef UNITY_REPEAT_TEST_NAME
84 Unity.CurrentTestName = NULL;
85 #endif
86 }
87 else if (UnityFixture.Silent)
88 {
89 /* Do Nothing */
90 }
91 else
92 {
93 UNITY_OUTPUT_CHAR('.');
94 }
95
96 Unity.NumberOfTests++;
97 UnityPointer_Init();
98
99 UNITY_EXEC_TIME_START();
100
101 if (TEST_PROTECT())
102 {
103 setup();
104 testBody();
105 }
106 if (TEST_PROTECT())
107 {
108 teardown();
109 }
110 if (TEST_PROTECT())
111 {
112 UnityPointer_UndoAllSets();
113 }
114 UnityConcludeFixtureTest();
115 }
116 }
117
UnityIgnoreTest(const char * printableName,const char * group,const char * name)118 void UnityIgnoreTest(const char* printableName, const char* group, const char* name)
119 {
120 if (testSelected(name) && groupSelected(group))
121 {
122 Unity.NumberOfTests++;
123 Unity.TestIgnores++;
124 if (UnityFixture.Verbose)
125 {
126 UnityPrint(printableName);
127 UNITY_PRINT_EOL();
128 }
129 else if (UnityFixture.Silent)
130 {
131 /* Do Nothing */
132 }
133 else
134 {
135 UNITY_OUTPUT_CHAR('!');
136 }
137 }
138 }
139
140 /*-------------------------------------------------------- */
141 /*Automatic pointer restoration functions */
142 struct PointerPair
143 {
144 void** pointer;
145 void* old_value;
146 };
147
148 static struct PointerPair pointer_store[UNITY_MAX_POINTERS];
149 static int pointer_index = 0;
150
UnityPointer_Init(void)151 void UnityPointer_Init(void)
152 {
153 pointer_index = 0;
154 }
155
UnityPointer_Set(void ** pointer,void * newValue,UNITY_LINE_TYPE line)156 void UnityPointer_Set(void** pointer, void* newValue, UNITY_LINE_TYPE line)
157 {
158 if (pointer_index >= UNITY_MAX_POINTERS)
159 {
160 UNITY_TEST_FAIL(line, "Too many pointers set");
161 }
162 else
163 {
164 pointer_store[pointer_index].pointer = pointer;
165 pointer_store[pointer_index].old_value = *pointer;
166 *pointer = newValue;
167 pointer_index++;
168 }
169 }
170
UnityPointer_UndoAllSets(void)171 void UnityPointer_UndoAllSets(void)
172 {
173 while (pointer_index > 0)
174 {
175 pointer_index--;
176 *(pointer_store[pointer_index].pointer) =
177 pointer_store[pointer_index].old_value;
178 }
179 }
180
UnityGetCommandLineOptions(int argc,const char * argv[])181 int UnityGetCommandLineOptions(int argc, const char* argv[])
182 {
183 int i;
184 UnityFixture.Verbose = 0;
185 UnityFixture.Silent = 0;
186 UnityFixture.GroupFilter = 0;
187 UnityFixture.NameFilter = 0;
188 UnityFixture.RepeatCount = 1;
189
190 if (argc == 1)
191 return 0;
192
193 for (i = 1; i < argc; )
194 {
195 if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
196 {
197 /* Usage */
198 UnityPrint("Runs a series of unit tests.");
199 UNITY_PRINT_EOL();
200 UNITY_PRINT_EOL();
201 UnityPrint("When no flag is specified, all tests are run.");
202 UNITY_PRINT_EOL();
203 UNITY_PRINT_EOL();
204 UnityPrint("Optional flags:");
205 UNITY_PRINT_EOL();
206 UnityPrint(" -v Verbose output: show all tests executed even if they pass");
207 UNITY_PRINT_EOL();
208 UnityPrint(" -s Silent mode: minimal output showing only test failures");
209 UNITY_PRINT_EOL();
210 UnityPrint(" -g NAME Only run tests in groups that contain the string NAME");
211 UNITY_PRINT_EOL();
212 UnityPrint(" -n NAME Only run tests whose name contains the string NAME");
213 UNITY_PRINT_EOL();
214 UnityPrint(" -r NUMBER Repeatedly run all tests NUMBER times");
215 UNITY_PRINT_EOL();
216 UnityPrint(" -h, --help Display this help message");
217 UNITY_PRINT_EOL();
218 UNITY_PRINT_EOL();
219 #ifdef UNITY_CUSTOM_HELP_MSG
220 /* User-defined help message, e.g. to point to project-specific documentation */
221 UnityPrint(UNITY_CUSTOM_HELP_MSG);
222 UNITY_PRINT_EOL();
223 #else
224 /* Default help suffix if a custom one is not defined */
225 UnityPrint("More information about Unity: https://www.throwtheswitch.org/unity");
226 UNITY_PRINT_EOL();
227 #endif
228 return 1; /* Exit without running the tests */
229 }
230 else if (strcmp(argv[i], "-v") == 0)
231 {
232 UnityFixture.Verbose = 1;
233 i++;
234 }
235 else if (strcmp(argv[i], "-s") == 0)
236 {
237 UnityFixture.Silent = 1;
238 i++;
239 }
240 else if (strcmp(argv[i], "-g") == 0)
241 {
242 i++;
243 if (i >= argc)
244 return 1;
245 UnityFixture.GroupFilter = argv[i];
246 i++;
247 }
248 else if (strcmp(argv[i], "-n") == 0)
249 {
250 i++;
251 if (i >= argc)
252 return 1;
253 UnityFixture.NameFilter = argv[i];
254 i++;
255 }
256 else if (strcmp(argv[i], "-r") == 0)
257 {
258 UnityFixture.RepeatCount = 2;
259 i++;
260 if (i < argc)
261 {
262 if (*(argv[i]) >= '0' && *(argv[i]) <= '9')
263 {
264 unsigned int digit = 0;
265 UnityFixture.RepeatCount = 0;
266 while (argv[i][digit] >= '0' && argv[i][digit] <= '9')
267 {
268 UnityFixture.RepeatCount *= 10;
269 UnityFixture.RepeatCount += (unsigned int)argv[i][digit++] - '0';
270 }
271 i++;
272 }
273 }
274 }
275 else
276 {
277 /* ignore unknown parameter */
278 i++;
279 }
280 }
281 return 0;
282 }
283
UnityConcludeFixtureTest(void)284 void UnityConcludeFixtureTest(void)
285 {
286 if (Unity.CurrentTestIgnored)
287 {
288 Unity.TestIgnores++;
289 UNITY_PRINT_EOL();
290 }
291 else if (!Unity.CurrentTestFailed)
292 {
293 if (UnityFixture.Verbose)
294 {
295 UnityPrint(" ");
296 UnityPrint(UnityStrPass);
297 UNITY_EXEC_TIME_STOP();
298 UNITY_PRINT_EXEC_TIME();
299 UNITY_PRINT_EOL();
300 }
301 }
302 else /* Unity.CurrentTestFailed */
303 {
304 Unity.TestFailures++;
305 UNITY_PRINT_EOL();
306 }
307
308 Unity.CurrentTestFailed = 0;
309 Unity.CurrentTestIgnored = 0;
310 }
311