improved assertion message for memory assertions
This commit is contained in:
parent
19ebe3d7b6
commit
e15b1af7e0
44
xtest.c
44
xtest.c
|
@ -24,7 +24,7 @@ struct xtest_assert_info assertion_info;
|
||||||
#define XTEST_INDENT 2
|
#define XTEST_INDENT 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char * group_nesting[XTEST_MAX_GROUP_NESTING];
|
const char *group_nesting[XTEST_MAX_GROUP_NESTING];
|
||||||
int group_nesting_pos = 0;
|
int group_nesting_pos = 0;
|
||||||
|
|
||||||
jmp_buf xtest_jmp;
|
jmp_buf xtest_jmp;
|
||||||
|
@ -38,8 +38,6 @@ const char *skip_reason;
|
||||||
int xtest_indent = 0;
|
int xtest_indent = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int expecting_assertion = 0;
|
int expecting_assertion = 0;
|
||||||
int num_tests = 0;
|
int num_tests = 0;
|
||||||
int successful_tests = 0;
|
int successful_tests = 0;
|
||||||
|
@ -55,7 +53,7 @@ int xtest_complete() {
|
||||||
return failed_tests != 0 ? 1 : 0;
|
return failed_tests != 0 ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void subunit_message(const char * name, const char * message, const char * details) {
|
void subunit_message(const char *name, const char *message, const char *details) {
|
||||||
printf("%s: %s", message, name);
|
printf("%s: %s", message, name);
|
||||||
if (details == NULL) {
|
if (details == NULL) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -212,12 +210,12 @@ void xtest_internal_assert(const char *file, int line, const char *func, const c
|
||||||
#define PRINT_ASSERT_MESSAGE(fmt, type) snprintf(assert_message, XTEST_ASSERT_MESSAGE_MAX_LEN, FAIL_ASSERT_FORMAT(fmt), \
|
#define PRINT_ASSERT_MESSAGE(fmt, type) snprintf(assert_message, XTEST_ASSERT_MESSAGE_MAX_LEN, FAIL_ASSERT_FORMAT(fmt), \
|
||||||
expression, invert ? "not " : "", CAST_PTR(type, expected), CAST_PTR(type, actual), file, line)
|
expression, invert ? "not " : "", CAST_PTR(type, expected), CAST_PTR(type, actual), file, line)
|
||||||
|
|
||||||
|
|
||||||
void xtest_fail_assert(const char *expression, const char *file, int line, void *expected,
|
void xtest_fail_assert(const char *expression, const char *file, int line, void *expected,
|
||||||
void *actual, int invert, enum xtest_type type) {
|
void *actual, int invert, enum xtest_type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case xtest_type_bool:
|
case xtest_type_bool:
|
||||||
snprintf(assert_message, XTEST_ASSERT_MESSAGE_MAX_LEN, FAIL_ASSERT_FORMAT("%s"), expression, invert ? "not " : "",
|
snprintf(assert_message, XTEST_ASSERT_MESSAGE_MAX_LEN, FAIL_ASSERT_FORMAT("%s"), expression,
|
||||||
|
invert ? "not " : "",
|
||||||
CAST_PTR(_Bool, expected) ? "true" : "false", CAST_PTR(_Bool, actual) ? "true" : "false", file,
|
CAST_PTR(_Bool, expected) ? "true" : "false", CAST_PTR(_Bool, actual) ? "true" : "false", file,
|
||||||
line);
|
line);
|
||||||
break;
|
break;
|
||||||
|
@ -265,7 +263,8 @@ void xtest_fail_assert(const char *expression, const char *file, int line, void
|
||||||
break;
|
break;
|
||||||
case xtest_type_other:
|
case xtest_type_other:
|
||||||
default:
|
default:
|
||||||
snprintf(assert_message, XTEST_ASSERT_MESSAGE_MAX_LEN, FAIL_ASSERT_FORMAT("%s"), expression, invert ? "not " : "",
|
snprintf(assert_message, XTEST_ASSERT_MESSAGE_MAX_LEN, FAIL_ASSERT_FORMAT("%s"), expression,
|
||||||
|
invert ? "not " : "",
|
||||||
"<value of unknown type>", "<value of unknown type>", file, line);
|
"<value of unknown type>", "<value of unknown type>", file, line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -283,11 +282,38 @@ xtest_assert_float(double expected, double actual, int precision, int invert, co
|
||||||
int equals = diff < epsilon;
|
int equals = diff < epsilon;
|
||||||
int failed = invert == equals; // invert = true: fail if equals, invert = false: fail if not equals
|
int failed = invert == equals; // invert = true: fail if equals, invert = false: fail if not equals
|
||||||
if (!failed) return;
|
if (!failed) return;
|
||||||
snprintf(assert_message, 1024, "assertion failed: %s, expected %s%g but got %g (difference %g, precision %d) (%s:%d)",
|
snprintf(assert_message, 1024,
|
||||||
|
"assertion failed: %s, expected %s%g but got %g (difference %g, precision %d) (%s:%d)",
|
||||||
expression, invert ? "not " : "", expected, actual, diff, precision, file, line);
|
expression, invert ? "not " : "", expected, actual, diff, precision, file, line);
|
||||||
longjmp(xtest_jmp, 1);
|
longjmp(xtest_jmp, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t find_diff_offset(const char *a, const char *b, size_t length) {
|
||||||
|
size_t offset = 0;
|
||||||
|
while (offset < length && *(a + offset) == *(b + offset)) offset++;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xtest_assert_mem(const char *expected, const char *actual, size_t length, int invert, const char *expression,
|
||||||
|
const char *file,
|
||||||
|
int line) {
|
||||||
|
size_t offset = find_diff_offset(expected, actual, length);
|
||||||
|
int equals = offset == length;
|
||||||
|
int failed = invert == equals; // invert = true: fail if equals, invert = false: fail if not equals
|
||||||
|
if (!failed) return;
|
||||||
|
|
||||||
|
if (invert) {
|
||||||
|
snprintf(assert_message, 1024,
|
||||||
|
"assertion failed: %s, expected memory to not match but did (%s:%d)",
|
||||||
|
expression, file, line);
|
||||||
|
} else {
|
||||||
|
snprintf(assert_message, 1024,
|
||||||
|
"assertion failed: %s, expected memory to match but did not (first different byte at offset %zu, expected 0x%2x but got 0x%2x) (%s:%d)",
|
||||||
|
expression, offset, (unsigned int) expected[offset], (unsigned int) actual[offset], file, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
longjmp(xtest_jmp, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void xtest_skip(const char *reason) {
|
void xtest_skip(const char *reason) {
|
||||||
skip_reason = reason;
|
skip_reason = reason;
|
||||||
|
@ -311,4 +337,4 @@ void xtest_internal_end_group() {
|
||||||
|
|
||||||
void xtest_expect_assertion_failure() {
|
void xtest_expect_assertion_failure() {
|
||||||
expecting_assertion = 1;
|
expecting_assertion = 1;
|
||||||
}
|
}
|
||||||
|
|
7
xtest.h
7
xtest.h
|
@ -49,6 +49,9 @@ void
|
||||||
xtest_assert_float(double expected, double actual, int precision, int invert, const char *expression, const char *file,
|
xtest_assert_float(double expected, double actual, int precision, int invert, const char *expression, const char *file,
|
||||||
int line);
|
int line);
|
||||||
|
|
||||||
|
void xtest_assert_mem(const char *expected, const char *actual, size_t length, int invert, const char *expression, const char *file,
|
||||||
|
int line);
|
||||||
|
|
||||||
void xtest_internal_run(xtest_test_fn fn, const char *name, xtest_param *params, xtest_setup_fn setup,
|
void xtest_internal_run(xtest_test_fn fn, const char *name, xtest_param *params, xtest_setup_fn setup,
|
||||||
xtest_teardown_fn teardown);
|
xtest_teardown_fn teardown);
|
||||||
|
|
||||||
|
@ -121,8 +124,8 @@ int xtest_complete();
|
||||||
#define xtest_assert_float_is_not(actual, expected, precision) xtest_assert_float(expected, actual, precision, 1, #actual " is not " #expected, __FILE__, __LINE__)
|
#define xtest_assert_float_is_not(actual, expected, precision) xtest_assert_float(expected, actual, precision, 1, #actual " is not " #expected, __FILE__, __LINE__)
|
||||||
#define xtest_assert_str_is(actual, expected) xtest_assert_(strcmp(actual, expected) == 0, #actual " is " #expected, (const char*)(actual), (const char*)(expected), 0)
|
#define xtest_assert_str_is(actual, expected) xtest_assert_(strcmp(actual, expected) == 0, #actual " is " #expected, (const char*)(actual), (const char*)(expected), 0)
|
||||||
#define xtest_assert_str_is_not(actual, expected) xtest_assert_(strcmp(actual, expected) != 0, #actual " is not " #expected, (const char*)(actual), (const char*)(expected), 1)
|
#define xtest_assert_str_is_not(actual, expected) xtest_assert_(strcmp(actual, expected) != 0, #actual " is not " #expected, (const char*)(actual), (const char*)(expected), 1)
|
||||||
#define xtest_assert_mem_is(actual, expected, len) xtest_assert_(memcmp(actual, expected, len) == 0, #actual " is " #expected " (" #len " bytes)", NULL, NULL, 0)
|
#define xtest_assert_mem_is(actual, expected, len) xtest_assert_mem(expected, actual, len, 0, #actual " is " #expected " (" #len " bytes)", __FILE__, __LINE__)
|
||||||
#define xtest_assert_mem_is_not(actual, expected, len) xtest_assert_(memcmp(actual, expected, len) != 0, #actual " is not " #expected " (" #len " bytes)", NULL, NULL, 1)
|
#define xtest_assert_mem_is_not(actual, expected, len) xtest_assert_mem(expected, actual, len, 1, #actual " is not " #expected " (" #len " bytes)", __FILE__, __LINE__)
|
||||||
|
|
||||||
|
|
||||||
#define XTEST_RUN_MAIN(fn) int main(int argc, char ** argv) { \
|
#define XTEST_RUN_MAIN(fn) int main(int argc, char ** argv) { \
|
||||||
|
|
Loading…
Reference in a new issue