Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 141 additions & 5 deletions clar.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
#include <sys/types.h>
#include <sys/stat.h>

#ifndef va_copy
# ifdef __va_copy
# define va_copy(dst, src) __va_copy(dst, src)
# else
# define va_copy(dst, src) ((dst) = (src))
# endif
#endif

#if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_WCHAR__)
/*
* uClibc can optionally be built without wchar support, in which case
Expand Down Expand Up @@ -76,8 +84,10 @@
# define S_ISDIR(x) ((x & _S_IFDIR) != 0)
# endif
# define p_snprintf(buf,sz,fmt,...) _snprintf_s(buf,sz,_TRUNCATE,fmt,__VA_ARGS__)
# define p_vsnprintf _vsnprintf
# else
# define p_snprintf snprintf
# define p_vsnprintf vsnprintf
# endif

# define localtime_r(timer, buf) (localtime_s(buf, timer) == 0 ? buf : NULL)
Expand All @@ -86,6 +96,7 @@
# include <unistd.h>
# define _MAIN_CC
# define p_snprintf snprintf
# define p_vsnprintf vsnprintf
typedef struct stat STAT_T;
#endif

Expand Down Expand Up @@ -699,13 +710,14 @@ void clar__skip(void)
abort_test();
}

void clar__fail(
static void clar__failv(
const char *file,
const char *function,
size_t line,
int should_abort,
const char *error_msg,
const char *description,
int should_abort)
va_list args)
{
struct clar_error *error;

Expand All @@ -725,9 +737,19 @@ void clar__fail(
error->line_number = _clar.invoke_line ? _clar.invoke_line : line;
error->error_msg = error_msg;

if (description != NULL &&
(error->description = strdup(description)) == NULL)
clar_abort("Failed to allocate description.\n");
if (description != NULL) {
va_list args_copy;
int len;

va_copy(args_copy, args);
if ((len = p_vsnprintf(NULL, 0, description, args_copy)) < 0)
clar_abort("Failed to compute description.");
va_end(args_copy);

if ((error->description = calloc(1, len + 1)) == NULL)
clar_abort("Failed to allocate buffer.");
p_vsnprintf(error->description, len + 1, description, args);
}

_clar.total_errors++;
_clar.last_report->status = CL_TEST_FAILURE;
Expand All @@ -736,6 +758,34 @@ void clar__fail(
abort_test();
}

void clar__failf(
const char *file,
const char *function,
size_t line,
int should_abort,
const char *error_msg,
const char *description,
...)
{
va_list args;
va_start(args, description);
clar__failv(file, function, line, should_abort, error_msg,
description, args);
va_end(args);
}

void clar__fail(
const char *file,
const char *function,
size_t line,
const char *error_msg,
const char *description,
int should_abort)
{
clar__failf(file, function, line, should_abort, error_msg,
description ? "%s" : NULL, description);
}

void clar__assert(
int condition,
const char *file,
Expand Down Expand Up @@ -889,6 +939,92 @@ void clar__assert_equal(
clar__fail(file, function, line, err, buf, should_abort);
}

void clar__assert_compare_i(
const char *file,
const char *func,
size_t line,
int should_abort,
enum clar_comparison cmp,
intmax_t value1,
intmax_t value2,
const char *error,
const char *description,
...)
{
int fulfilled;
switch (cmp) {
case CLAR_COMPARISON_EQ:
fulfilled = value1 == value2;
break;
case CLAR_COMPARISON_LT:
fulfilled = value1 < value2;
break;
case CLAR_COMPARISON_LE:
fulfilled = value1 <= value2;
break;
case CLAR_COMPARISON_GT:
fulfilled = value1 > value2;
break;
case CLAR_COMPARISON_GE:
fulfilled = value1 >= value2;
break;
default:
cl_assert(0);
return;
}

if (!fulfilled) {
va_list args;
va_start(args, description);
clar__failv(file, func, line, should_abort, error,
description, args);
va_end(args);
}
}

void clar__assert_compare_u(
const char *file,
const char *func,
size_t line,
int should_abort,
enum clar_comparison cmp,
uintmax_t value1,
uintmax_t value2,
const char *error,
const char *description,
...)
{
int fulfilled;
switch (cmp) {
case CLAR_COMPARISON_EQ:
fulfilled = value1 == value2;
break;
case CLAR_COMPARISON_LT:
fulfilled = value1 < value2;
break;
case CLAR_COMPARISON_LE:
fulfilled = value1 <= value2;
break;
case CLAR_COMPARISON_GT:
fulfilled = value1 > value2;
break;
case CLAR_COMPARISON_GE:
fulfilled = value1 >= value2;
break;
default:
cl_assert(0);
return;
}

if (!fulfilled) {
va_list args;
va_start(args, description);
clar__failv(file, func, line, should_abort, error,
description, args);
va_end(args);
}
}

void cl_set_cleanup(void (*cleanup)(void *), void *opaque)
{
_clar.local_cleanup = cleanup;
Expand Down
74 changes: 71 additions & 3 deletions clar.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef __CLAR_TEST_H__
#define __CLAR_TEST_H__

#include <inttypes.h>
#include <stdlib.h>
#include <limits.h>

Expand Down Expand Up @@ -149,6 +150,7 @@ const char *cl_fixture_basename(const char *fixture_name);
* Forced failure/warning
*/
#define cl_fail(desc) clar__fail(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Test failed.", desc, 1)
#define cl_failf(desc,...) clar__failf(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, 1, "Test failed.", desc, __VA_ARGS__)
#define cl_warning(desc) clar__fail(CLAR_CURRENT_FILE, CLAR_CURRENT_FUNC, CLAR_CURRENT_LINE, "Warning during test execution:", desc, 0)

#define cl_skip() clar__skip()
Expand All @@ -168,9 +170,34 @@ const char *cl_fixture_basename(const char *fixture_name);
#define cl_assert_equal_wcsn(wcs1,wcs2,len) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2, 1, "%.*ls", (wcs1), (wcs2), (int)(len))
#define cl_assert_equal_wcsn_(wcs1,wcs2,len,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,"String mismatch: " #wcs1 " != " #wcs2 " (" #note ")", 1, "%.*ls", (wcs1), (wcs2), (int)(len))

#define cl_assert_equal_i(i1,i2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#i1 " != " #i2, 1, "%d", (int)(i1), (int)(i2))
#define cl_assert_equal_i_(i1,i2,note) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#i1 " != " #i2 " (" #note ")", 1, "%d", (i1), (i2))
#define cl_assert_equal_i_fmt(i1,i2,fmt) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#i1 " != " #i2, 1, (fmt), (int)(i1), (int)(i2))
/* The following three macros are essentially deprecated now in favor of the macros in subsequent blocks. */
#define cl_assert_equal_i(i1,i2) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))
#define cl_assert_equal_i_(i1,i2,note) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2 " (" #note ")","%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))
#define cl_assert_equal_i_fmt(i1,i2,fmt) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,#i1 " != " #i2, fmt " != " fmt, (int)(i1), (int)(i2))

#define cl_assert_compare_i(i1,i2,cmp,error,description,...) clar__assert_compare_i(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(i1),(i2),error,description,__VA_ARGS__)
#define cl_assert_eq_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #i1 " == " #i2,description,__VA_ARGS__)
#define cl_assert_eq_i(i1,i2) cl_assert_eq_i_(i1,i2,"%"PRIdMAX " != %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))
#define cl_assert_lt_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #i1 " < " #i2,description,__VA_ARGS__)
#define cl_assert_lt_i(i1,i2) cl_assert_lt_i_(i1,i2,"%"PRIdMAX " >= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))
#define cl_assert_le_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #i1 " <= " #i2,description,__VA_ARGS__)
#define cl_assert_le_i(i1,i2) cl_assert_le_i_(i1,i2,"%"PRIdMAX " > %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))
#define cl_assert_gt_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #i1 " > " #i2,description,__VA_ARGS__)
#define cl_assert_gt_i(i1,i2) cl_assert_gt_i_(i1,i2,"%"PRIdMAX " <= %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))
#define cl_assert_ge_i_(i1,i2,description,...) cl_assert_compare_i(i1,i2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #i1 " >= " #i2,description,__VA_ARGS__)
#define cl_assert_ge_i(i1,i2) cl_assert_ge_i_(i1,i2,"%"PRIdMAX " < %"PRIdMAX,(intmax_t)(i1),(intmax_t)(i2))

#define cl_assert_compare_u(u1,u2,cmp,error,description,...) clar__assert_compare_u(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,1,cmp,(u1),(u2),error,description,__VA_ARGS__)
#define cl_assert_eq_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_EQ,"Expected comparison to hold: " #u1 " == " #u2,description,__VA_ARGS__)
#define cl_assert_eq_u(u1,u2) cl_assert_eq_u_(u1,u2,"%"PRIuMAX " != %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2))
#define cl_assert_lt_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LT,"Expected comparison to hold: " #u1 " < " #u2,description,__VA_ARGS__)
#define cl_assert_lt_u(u1,u2) cl_assert_lt_u_(u1,u2,"%"PRIuMAX " >= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2))
#define cl_assert_le_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_LE,"Expected comparison to hold: " #u1 " <= " #u2,description,__VA_ARGS__)
#define cl_assert_le_u(u1,u2) cl_assert_le_u_(u1,u2,"%"PRIuMAX " > %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2))
#define cl_assert_gt_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GT,"Expected comparison to hold: " #u1 " > " #u2,description,__VA_ARGS__)
#define cl_assert_gt_u(u1,u2) cl_assert_gt_u_(u1,u2,"%"PRIuMAX " <= %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2))
#define cl_assert_ge_u_(u1,u2,description,...) cl_assert_compare_u(u1,u2,CLAR_COMPARISON_GE,"Expected comparison to hold: " #u1 " >= " #u2,description,__VA_ARGS__)
#define cl_assert_ge_u(u1,u2) cl_assert_ge_u_(u1,u2,"%"PRIuMAX " < %"PRIuMAX,(uintmax_t)(u1),(uintmax_t)(u2))

#define cl_assert_equal_b(b1,b2) clar__assert_equal(CLAR_CURRENT_FILE,CLAR_CURRENT_FUNC,CLAR_CURRENT_LINE,#b1 " != " #b2, 1, "%d", (int)((b1) != 0),(int)((b2) != 0))

Expand All @@ -186,6 +213,15 @@ void clar__fail(
const char *description,
int should_abort);

void clar__failf(
const char *file,
const char *func,
size_t line,
int should_abort,
const char *error,
const char *description,
...);

void clar__assert(
int condition,
const char *file,
Expand All @@ -204,6 +240,38 @@ void clar__assert_equal(
const char *fmt,
...);

enum clar_comparison {
CLAR_COMPARISON_EQ,
CLAR_COMPARISON_LT,
CLAR_COMPARISON_LE,
CLAR_COMPARISON_GT,
CLAR_COMPARISON_GE,
};

void clar__assert_compare_i(
const char *file,
const char *func,
size_t line,
int should_abort,
enum clar_comparison cmp,
intmax_t value1,
intmax_t value2,
const char *error,
const char *description,
...);

void clar__assert_compare_u(
const char *file,
const char *func,
size_t line,
int should_abort,
enum clar_comparison cmp,
uintmax_t value1,
uintmax_t value2,
const char *error,
const char *description,
...);

void clar__set_invokepoint(
const char *file,
const char *func,
Expand Down
15 changes: 15 additions & 0 deletions test/expected/quiet
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,18 @@ combined::null_string [file:42]
String mismatch: "expected" != actual ("this one fails")
'expected' != NULL

10) Failure:
combined::failf [file:42]
Test failed.
some reason: foo

11) Failure:
combined::compare_i [file:42]
Expected comparison to hold: two < 1
2 >= 1

12) Failure:
combined::compare_u [file:42]
Expected comparison to hold: two < 1
2 >= 1

17 changes: 16 additions & 1 deletion test/expected/summary_with_filename
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Loaded 1 suites:
Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
FFFFFFFFF
FFFFFFFFFFFF

1) Failure:
combined::1 [file:42]
Expand Down Expand Up @@ -46,4 +46,19 @@ combined::null_string [file:42]
String mismatch: "expected" != actual ("this one fails")
'expected' != NULL

10) Failure:
combined::failf [file:42]
Test failed.
some reason: foo

11) Failure:
combined::compare_i [file:42]
Expected comparison to hold: two < 1
2 >= 1

12) Failure:
combined::compare_u [file:42]
Expected comparison to hold: two < 1
2 >= 1

written summary file to different.xml
17 changes: 16 additions & 1 deletion test/expected/summary_without_filename
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Loaded 1 suites:
Started (test status codes: OK='.' FAILURE='F' SKIPPED='S')
FFFFFFFFF
FFFFFFFFFFFF

1) Failure:
combined::1 [file:42]
Expand Down Expand Up @@ -46,4 +46,19 @@ combined::null_string [file:42]
String mismatch: "expected" != actual ("this one fails")
'expected' != NULL

10) Failure:
combined::failf [file:42]
Test failed.
some reason: foo

11) Failure:
combined::compare_i [file:42]
Expected comparison to hold: two < 1
2 >= 1

12) Failure:
combined::compare_u [file:42]
Expected comparison to hold: two < 1
2 >= 1

written summary file to summary.xml
Loading