Expand the test macros framework
- Add an _NOSTREAM variant for each macro (except for SG_TEST_FAIL, that doesn't take any argument, and for SG_VERIFY, which doesn't attempt to print its argument to a stream---doesn't sound very useful). So, if a and b can be output to a stream (without any undesirable side effect, of course), use for instance SG_CHECK_EQUAL(a, b); otherwise, use SG_CHECK_EQUAL_NOSTREAM(a, b). - Add test macros SG_CHECK_IS_NULL, SG_CHECK_IS_NULL_NOSTREAM, SG_CHECK_IS_NOT_NULL and SG_CHECK_IS_NOT_NULL_NOSTREAM. - Add a few comments.
This commit is contained in:
parent
c9bb6102c0
commit
6662800deb
@ -1,3 +1,5 @@
|
||||
// -*- coding: utf-8 -*-
|
||||
|
||||
#ifndef SG_MISC_TEST_MACROS_HXX
|
||||
#define SG_MISC_TEST_MACROS_HXX
|
||||
|
||||
@ -5,6 +7,7 @@
|
||||
#include <cmath> // for std::fabs()
|
||||
|
||||
|
||||
// Assertion-like test
|
||||
#define SG_VERIFY(a) \
|
||||
if (!(a)) { \
|
||||
std::cerr << "failed: " << #a << std::endl; \
|
||||
@ -12,70 +15,163 @@
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_EQUAL(a, b) \
|
||||
// Internal macro (implementation detail). 'a' and 'b' don't always support
|
||||
// operator<<. This is why we use (a0) and (b0) after '<<', otherwise in such
|
||||
// cases the test couldn't be compiled, even if 'stream' is false.
|
||||
#define SG_CHECK_EQUAL0(a, b, stream, a0, b0) \
|
||||
if ( !((a) == (b)) ) { \
|
||||
std::cerr << "failed: " << #a << " == " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_EQUAL_EP(a, b) \
|
||||
// Test macros for user consumption. The _NOSTREAM variant is for cases where
|
||||
// 'a' or 'b' doesn't support operator<< (or where using it would have
|
||||
// undesirable side effects).
|
||||
#define SG_CHECK_EQUAL(a, b) SG_CHECK_EQUAL0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_EQUAL_NOSTREAM(a, b) SG_CHECK_EQUAL0((a), (b), false, "", "")
|
||||
|
||||
// “Approximate equality” test (EP stands for “epsilon”)
|
||||
#define SG_CHECK_EQUAL_EP0(a, b, stream, a0, b0) \
|
||||
if (std::fabs((a) - (b)) > SG_EPSILON) { \
|
||||
std::cerr << "failed: " << #a << " ~= " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_EQUAL_EP(a, b) SG_CHECK_EQUAL_EP0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_EQUAL_EP_NOSTREAM(a, b) \
|
||||
SG_CHECK_EQUAL_EP0((a), (b), false, "", "")
|
||||
|
||||
// Same as SG_CHECK_EQUAL_EP*, except the “epsilon” can be chosen by the caller
|
||||
#define SG_CHECK_EQUAL_EP2_0(a, b, ep, stream, a0, b0) \
|
||||
if (std::fabs((a) - (b)) > (ep)) { \
|
||||
std::cerr << "failed: " << #a << " ~= " << #b << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_EQUAL_EP2(a, b, ep) \
|
||||
if (std::fabs((a) - (b)) > (ep)) { \
|
||||
std::cerr << "failed: " << #a << " ~= " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
SG_CHECK_EQUAL_EP2_0((a), (b), ep, true, (a), (b))
|
||||
#define SG_CHECK_EQUAL_EP2_NOSTREAM(a, b) \
|
||||
SG_CHECK_EQUAL_EP2_0((a), (b), ep, false, "", "")
|
||||
|
||||
#define SG_CHECK_NE(a, b) \
|
||||
// “Non-equal” test
|
||||
#define SG_CHECK_NE0(a, b, stream, a0, b0) \
|
||||
if ( !((a) != (b)) ) { \
|
||||
std::cerr << "failed: " << #a << " != " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_LT(a, b) \
|
||||
#define SG_CHECK_NE(a, b) SG_CHECK_NE0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_NE_NOSTREAM(a, b) SG_CHECK_NE0((a), (b), false, "", "")
|
||||
|
||||
// “Lower than” test
|
||||
#define SG_CHECK_LT0(a, b, stream, a0, b0) \
|
||||
if ( !((a) < (b)) ) { \
|
||||
std::cerr << "failed: " << #a << " < " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_LE(a, b) \
|
||||
#define SG_CHECK_LT(a, b) SG_CHECK_LT0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_LT_NOSTREAM(a, b) SG_CHECK_LT0((a), (b), false, "", "")
|
||||
|
||||
// “Lower than or equal” test
|
||||
#define SG_CHECK_LE0(a, b, stream, a0, b0) \
|
||||
if ( !((a) <= (b)) ) { \
|
||||
std::cerr << "failed: " << #a << " <= " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_GT(a, b) \
|
||||
#define SG_CHECK_LE(a, b) SG_CHECK_LE0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_LE_NOSTREAM(a, b) SG_CHECK_LE0((a), (b), false, "", "")
|
||||
|
||||
// “Greater than” test
|
||||
#define SG_CHECK_GT0(a, b, stream, a0, b0) \
|
||||
if ( !((a) > (b)) ) { \
|
||||
std::cerr << "failed: " << #a << " > " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_GE(a, b) \
|
||||
#define SG_CHECK_GT(a, b) SG_CHECK_GT0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_GT_NOSTREAM(a, b) SG_CHECK_GT0((a), (b), false, "", "")
|
||||
|
||||
// “Greater than or equal” test
|
||||
#define SG_CHECK_GE0(a, b, stream, a0, b0) \
|
||||
if ( !((a) >= (b)) ) { \
|
||||
std::cerr << "failed: " << #a << " >= " << #b << std::endl; \
|
||||
std::cerr << "\tgot '" << (a) << "' and '" << (b) << "'" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "' and '" << (b0) << "'" \
|
||||
<< std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_GE(a, b) SG_CHECK_GE0((a), (b), true, (a), (b))
|
||||
#define SG_CHECK_GE_NOSTREAM(a, b) SG_CHECK_GE0((a), (b), false, "", "")
|
||||
|
||||
// “Is NULL” test
|
||||
#define SG_CHECK_IS_NULL0(a, stream, a0) \
|
||||
if ( !((a) == nullptr) ) { \
|
||||
std::cerr << "failed: " << #a << " == nullptr" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "'" << std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_IS_NULL(a) SG_CHECK_IS_NULL0((a), true, (a))
|
||||
#define SG_CHECK_IS_NULL_NOSTREAM(a) SG_CHECK_IS_NULL0((a), false, "")
|
||||
|
||||
// “Is not NULL” test
|
||||
#define SG_CHECK_IS_NOT_NULL0(a, stream, a0) \
|
||||
if ( !((a) != nullptr) ) { \
|
||||
std::cerr << "failed: " << #a << " != nullptr" << std::endl; \
|
||||
if (stream) { \
|
||||
std::cerr << "\tgot '" << (a0) << "'" << std::endl; \
|
||||
}; \
|
||||
std::cerr << "\tat " << __FILE__ << ":" << __LINE__ << std::endl; \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define SG_CHECK_IS_NOT_NULL(a) SG_CHECK_IS_NOT_NULL0((a), true, (a))
|
||||
#define SG_CHECK_IS_NOT_NULL_NOSTREAM(a) SG_CHECK_IS_NOT_NULL0((a), false, "")
|
||||
|
||||
// “Always failing” test
|
||||
#define SG_TEST_FAIL(msg) \
|
||||
std::cerr << "failure: " << msg; \
|
||||
exit(1);
|
||||
|
Loading…
Reference in New Issue
Block a user