Pico Headers
Loading...
Searching...
No Matches
pico_unit.h
Go to the documentation of this file.
1
62#ifndef PICO_UNIT_H
63#define PICO_UNIT_H
64
65#include <stdbool.h> /* bool, true, false */
66#include <stddef.h> /* NULL */
67#include <string.h> /* strcmp */
68
69#ifdef __cplusplus
70extern "C" {
71#endif
72
78#define TEST_CASE(name) static bool name(void)
79
89#define REQUIRE(expr) \
90 do { \
91 if (!pu_require((expr) ? true : false, (#expr), __FILE__, __LINE__)) \
92 return false; \
93 } while(false)
94
103#define RUN_TEST_CASE(test_fp) (pu_run_test(#test_fp, test_fp))
104
110#define TEST_SUITE(name) void name(void)
111
118#define RUN_TEST_SUITE(suite_fp) pu_run_suite(#suite_fp, suite_fp)
119
123typedef void (*pu_setup_fn)(void);
124
136void pu_setup(pu_setup_fn setup_fp, pu_setup_fn teardown_fp);
137
141void pu_clear_setup(void);
142
146void pu_display_colors(bool enabled);
147
151void pu_display_time(bool enabled);
152
156void pu_print_stats(void);
157
163bool pu_test_failed(void);
164
165/*
166 * WARNING: These functions are not meant to be called directly. Use the macros
167 * instead.
168 */
169typedef bool (*pu_test_fn)(void);
170typedef void (*pu_suite_fn)(void);
171
175bool pu_require(bool passed,
176 const char* const expr,
177 const char* const file,
178 int line);
179
183void pu_run_test(const char* const name, pu_test_fn test_fp);
184
188void pu_run_suite(const char* const name, pu_suite_fn suite_fp);
189
190#ifdef __cplusplus
191}
192#endif
193
194#endif // PICO_UNIT_H
195
196#ifdef PICO_UNIT_IMPLEMENTATION
197
198#include <stdio.h> /* printf */
199
200#ifndef PICO_UNIT_NO_CLOCK
201#include <time.h> /* clock_t, clock */
202#endif // PICO_UNIT_NO_CLOCK
203
204#define TERM_COLOR_CODE 0x1B
205#define TERM_COLOR_RED "[1;31m"
206#define TERM_COLOR_GREEN "[1;32m"
207#define TERM_COLOR_BOLD "[1m"
208#define TERM_COLOR_RESET "[0m"
209
210static unsigned pu_num_asserts = 0;
211static unsigned pu_num_passed = 0;
212static unsigned pu_num_failed = 0;
213static unsigned pu_num_suites = 0;
214static bool pu_colors = false;
215static bool pu_time = false;
216
217static pu_setup_fn pu_setup_fp = NULL;
218static pu_setup_fn pu_teardown_fp = NULL;
219
220void
221pu_setup (pu_setup_fn fp_setup, pu_setup_fn fp_teardown)
222{
223 pu_setup_fp = fp_setup;
224 pu_teardown_fp = fp_teardown;
225}
226
227void
228pu_clear_setup (void)
229{
230 pu_setup_fp = NULL;
231 pu_teardown_fp = NULL;
232}
233
234void
235pu_display_colors (bool enabled)
236{
237 pu_colors = enabled;
238}
239
240void
241pu_display_time (bool enabled)
242{
243 pu_time = enabled;
244}
245
246bool
247pu_test_failed(void)
248{
249 return (pu_num_failed != 0);
250}
251
252bool
253pu_require(bool passed,
254 const char* const expr,
255 const char* const file,
256 int line)
257{
258 pu_num_asserts++;
259
260 if (passed)
261 {
262 return true;
263 }
264
265 if (pu_colors)
266 {
267 printf("(%c%sFAILED%c%s: %s (%d): %s)\n",
268 TERM_COLOR_CODE, TERM_COLOR_RED,
269 TERM_COLOR_CODE, TERM_COLOR_RESET,
270 file, line, expr);
271 }
272 else
273 {
274 printf("(FAILED: %s (%d): %s)\n", file, line, expr);
275 }
276
277 return false;
278}
279
280void
281pu_run_test (const char* const name, pu_test_fn test_fp)
282{
283 if (NULL != pu_setup_fp)
284 {
285 pu_setup_fp();
286 }
287
288 printf("Running: %s ", name);
289
290 #ifndef PICO_UNIT_NO_CLOCK
291
292 clock_t start_time = 0;
293 clock_t end_time = 0;
294
295 if (pu_time)
296 {
297 start_time = clock();
298 }
299
300 #endif // PICO_UNIT_NO_CLOCK
301
302 if (!test_fp())
303 {
304 pu_num_failed++;
305
306 if (NULL != pu_teardown_fp)
307 {
308 pu_teardown_fp();
309 }
310
311 return;
312 }
313
314 #ifndef PICO_UNIT_NO_CLOCK
315
316 if (pu_time)
317 {
318 end_time = clock();
319 }
320
321 #endif // PICO_UNIT_NO_CLOCK
322
323 if (pu_colors)
324 {
325 printf("(%c%sOK%c%s)", TERM_COLOR_CODE, TERM_COLOR_GREEN,
326 TERM_COLOR_CODE, TERM_COLOR_RESET);
327 }
328 else
329 {
330 printf("(OK)");
331 }
332
333 #ifndef PICO_UNIT_NO_CLOCK
334
335 if (pu_time)
336 {
337 printf(" (%f secs)", (double)(end_time - start_time) / CLOCKS_PER_SEC);
338 }
339
340 #endif // PICO_UNIT_NO_CLOCK
341
342 printf("\n");
343
344 pu_num_passed++;
345
346 if (NULL != pu_teardown_fp)
347 {
348 pu_teardown_fp();
349 }
350}
351
352void
353pu_run_suite (const char* const name, pu_suite_fn suite_fp)
354{
355 printf("===============================================================\n");
356
357 if (pu_colors)
358 {
359 printf("%c%sRunning: %s%c%s\n", TERM_COLOR_CODE, TERM_COLOR_BOLD,
360 name,
361 TERM_COLOR_CODE, TERM_COLOR_RESET);
362 }
363 else
364 {
365 printf("Running: %s\n", name);
366 }
367
368 printf("---------------------------------------------------------------\n");
369 suite_fp();
370 pu_num_suites++;
371}
372
373void
374pu_print_stats (void)
375{
376 printf("===============================================================\n");
377
378 if (pu_colors)
379 {
380 printf("Summary: Passed: %c%s%u%c%s "
381 "Failed: %c%s%u%c%s "
382 "Total: %u Suites: %u "
383 "Asserts: %u\n",
384 TERM_COLOR_CODE, TERM_COLOR_GREEN, pu_num_passed,
385 TERM_COLOR_CODE, TERM_COLOR_RESET,
386 TERM_COLOR_CODE, TERM_COLOR_RED, pu_num_failed,
387 TERM_COLOR_CODE, TERM_COLOR_RESET,
388 pu_num_passed + pu_num_failed,
389 pu_num_suites, pu_num_asserts);
390 }
391 else
392 {
393 printf("Summary: Passed: %u "
394 "Failed: %u "
395 "Total: %u Suites: %u "
396 "Asserts: %u\n",
397 pu_num_passed,
398 pu_num_failed,
399 pu_num_passed + pu_num_failed,
400 pu_num_suites, pu_num_asserts);
401 }
402}
403
404
405#endif // PICO_UNIT_IMPLEMENTATION
406
407/*
408 ----------------------------------------------------------------------------
409 This software is available under two licenses (A) or (B). You may choose
410 either one as you wish:
411 ----------------------------------------------------------------------------
412
413 (A) The zlib License
414
415 Copyright (c) 2021 James McLean
416
417 This software is provided 'as-is', without any express or implied warranty.
418 In no event will the authors be held liable for any damages arising from the
419 use of this software.
420
421 Permission is granted to anyone to use this software for any purpose,
422 including commercial applications, and to alter it and redistribute it
423 freely, subject to the following restrictions:
424
425 1. The origin of this software must not be misrepresented; you must not
426 claim that you wrote the original software. If you use this software in a
427 product, an acknowledgment in the product documentation would be appreciated
428 but is not required.
429
430 2. Altered source versions must be plainly marked as such, and must not be
431 misrepresented as being the original software.
432
433 3. This notice may not be removed or altered from any source distribution.
434
435 ----------------------------------------------------------------------------
436
437 (B) Public Domain (www.unlicense.org)
438
439 This is free and unencumbered software released into the public domain.
440
441 Anyone is free to copy, modify, publish, use, compile, sell, or distribute
442 this software, either in source code form or as a compiled binary, for any
443 purpose, commercial or non-commercial, and by any means.
444
445 In jurisdictions that recognize copyright laws, the author or authors of
446 this software dedicate any and all copyright interest in the software to the
447 public domain. We make this dedication for the benefit of the public at
448 large and to the detriment of our heirs and successors. We intend this
449 dedication to be an overt act of relinquishment in perpetuity of all present
450 and future rights to this software under copyright law.
451
452 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
453 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
454 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
455 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
456 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
457 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
458*/
459
460// EoF
void pu_clear_setup(void)
Disables the setup and teardown functions by setting them to NULL.
bool(* pu_test_fn)(void)
Definition pico_unit.h:169
void(* pu_suite_fn)(void)
Definition pico_unit.h:170
void pu_run_test(const char *const name, pu_test_fn test_fp)
Used internally.
void pu_run_suite(const char *const name, pu_suite_fn suite_fp)
Used internally.
bool pu_require(bool passed, const char *const expr, const char *const file, int line)
Used internally.
void pu_print_stats(void)
Prints test statistics.
void pu_display_colors(bool enabled)
Turns on terminal colors. NOTE: Off by default.
void(* pu_setup_fn)(void)
Functions that are run before or after a number of unit tests execute.
Definition pico_unit.h:123
void pu_display_time(bool enabled)
Turns on time measurement. NOTE: Off by default.
bool pu_test_failed(void)
Check whether at least one test failed.
void pu_setup(pu_setup_fn setup_fp, pu_setup_fn teardown_fp)
Sets the current setup and teardown functions.