This is useful when doing several asserts in one loop, for instance: there isn't always a way to deduce the loop index from the assert failure, so these macros allow the user to give more context information.legacy
@@ -17,6 +17,7 @@ | |||||
#define __LOL_UNIT_H__ | #define __LOL_UNIT_H__ | ||||
#include <iostream> | #include <iostream> | ||||
#include <iomanip> | |||||
#include <sstream> | #include <sstream> | ||||
#include <cstdio> | #include <cstdio> | ||||
#include <cmath> | #include <cmath> | ||||
@@ -63,7 +64,7 @@ protected: | |||||
int m_testcases, m_failcases; | int m_testcases, m_failcases; | ||||
int m_asserts, m_failure; | int m_asserts, m_failure; | ||||
char const *m_fixturename, *m_currentname; | char const *m_fixturename, *m_currentname; | ||||
std::stringstream m_errorlog; | |||||
std::stringstream m_errorlog, m_context; | |||||
}; | }; | ||||
template<class T> class Fixture : protected FixtureBase | template<class T> class Fixture : protected FixtureBase | ||||
@@ -105,6 +106,7 @@ public: | |||||
m_asserts = 0; | m_asserts = 0; | ||||
m_failure = false; | m_failure = false; | ||||
m_currentname = c->m_testname; | m_currentname = c->m_testname; | ||||
m_context.str(""); | |||||
(static_cast<FixtureClass *>(this)->*c->m_fun)(); | (static_cast<FixtureClass *>(this)->*c->m_fun)(); | ||||
std::cout << (m_failure ? 'F' : '.'); | std::cout << (m_failure ? 'F' : '.'); | ||||
} | } | ||||
@@ -226,9 +228,10 @@ public: | |||||
<< " (F) line: " << __LINE__ << " " \ | << " (F) line: " << __LINE__ << " " \ | ||||
<< __FILE__ << std::endl; \ | << __FILE__ << std::endl; \ | ||||
m_errorlog << "equality assertion failed" << std::endl; \ | m_errorlog << "equality assertion failed" << std::endl; \ | ||||
m_errorlog << "- Expected: " << (a) << std::endl; \ | |||||
m_errorlog << "- Actual : " << (b) << std::endl; \ | |||||
m_errorlog << "- Expected: " << #a << " = " << (a) << std::endl; \ | |||||
m_errorlog << "- Actual : " << #b << " = " << (b) << std::endl; \ | |||||
m_errorlog << message; \ | m_errorlog << message; \ | ||||
m_errorlog << m_context.str(); \ | |||||
m_failure = true; \ | m_failure = true; \ | ||||
return; \ | return; \ | ||||
} \ | } \ | ||||
@@ -245,10 +248,14 @@ public: | |||||
<< " (F) line: " << __LINE__ << " " \ | << " (F) line: " << __LINE__ << " " \ | ||||
<< __FILE__ << std::endl; \ | << __FILE__ << std::endl; \ | ||||
m_errorlog << "double equality assertion failed" << std::endl; \ | m_errorlog << "double equality assertion failed" << std::endl; \ | ||||
m_errorlog << "- Expected: " << (a) << std::endl; \ | |||||
m_errorlog << "- Actual : " << (b) << std::endl; \ | |||||
m_errorlog << "- Delta : " << (t) << std::endl; \ | |||||
std::streamsize old_prec = m_errorlog.precision(); \ | |||||
m_errorlog << std::setprecision(16); \ | |||||
m_errorlog << "- Expected: " << #a << " = " << (a) << std::endl; \ | |||||
m_errorlog << "- Actual : " << #b << " = " << (b) << std::endl; \ | |||||
m_errorlog << "- Delta : " << #t << " = " << (t) << std::endl; \ | |||||
m_errorlog << std::setprecision(old_prec); \ | |||||
m_errorlog << message; \ | m_errorlog << message; \ | ||||
m_errorlog << m_context.str(); \ | |||||
m_failure = true; \ | m_failure = true; \ | ||||
return; \ | return; \ | ||||
} \ | } \ | ||||
@@ -264,10 +271,20 @@ public: | |||||
<< __FILE__ << std::endl; \ | << __FILE__ << std::endl; \ | ||||
m_errorlog << "forced failure" << std::endl; \ | m_errorlog << "forced failure" << std::endl; \ | ||||
m_errorlog << "- " << message << std::endl; \ | m_errorlog << "- " << message << std::endl; \ | ||||
m_errorlog << m_context.str(); \ | |||||
m_failure = true; \ | m_failure = true; \ | ||||
return; \ | return; \ | ||||
} while(!True()) | } while(!True()) | ||||
#define LOLUNIT_SET_CONTEXT(n) \ | |||||
do { \ | |||||
m_context.str(""); \ | |||||
m_context << "- Context : " << #n << " = " << (n) << std::endl; \ | |||||
} while(!True()) | |||||
#define LOLUNIT_UNSET_CONTEXT(n) \ | |||||
m_context.str("") | |||||
#define LOLUNIT_ASSERT(cond) \ | #define LOLUNIT_ASSERT(cond) \ | ||||
LOLUNIT_ASSERT_GENERIC("", cond) | LOLUNIT_ASSERT_GENERIC("", cond) | ||||
@@ -45,6 +45,7 @@ public: | |||||
{ | { | ||||
half a = (half)pairs[i].f; | half a = (half)pairs[i].f; | ||||
uint16_t b = pairs[i].x; | uint16_t b = pairs[i].x; | ||||
LOLUNIT_SET_CONTEXT(i); | |||||
LOLUNIT_ASSERT_EQUAL(a.bits, b); | LOLUNIT_ASSERT_EQUAL(a.bits, b); | ||||
} | } | ||||
} | } | ||||
@@ -55,6 +56,7 @@ public: | |||||
{ | { | ||||
half a = half::makeaccurate(pairs[i].f); | half a = half::makeaccurate(pairs[i].f); | ||||
uint16_t b = pairs[i].x; | uint16_t b = pairs[i].x; | ||||
LOLUNIT_SET_CONTEXT(i); | |||||
LOLUNIT_ASSERT_EQUAL(a.bits, b); | LOLUNIT_ASSERT_EQUAL(a.bits, b); | ||||
} | } | ||||
} | } | ||||
@@ -65,6 +67,7 @@ public: | |||||
{ | { | ||||
half a = half::makebits(i); | half a = half::makebits(i); | ||||
uint16_t b = i; | uint16_t b = i; | ||||
LOLUNIT_SET_CONTEXT(i); | |||||
LOLUNIT_ASSERT_EQUAL(a.bits, b); | LOLUNIT_ASSERT_EQUAL(a.bits, b); | ||||
} | } | ||||
} | } | ||||
@@ -140,6 +143,7 @@ public: | |||||
{ | { | ||||
for (uint32_t i = 0; i < 0x10000; i++) | for (uint32_t i = 0; i < 0x10000; i++) | ||||
{ | { | ||||
LOLUNIT_SET_CONTEXT(i); | |||||
half h = half::makebits(i); | half h = half::makebits(i); | ||||
if (h.is_nan()) | if (h.is_nan()) | ||||
{ | { | ||||
@@ -165,6 +169,7 @@ public: | |||||
{ | { | ||||
float a = (float)half::makebits(pairs[i].x); | float a = (float)half::makebits(pairs[i].x); | ||||
float b = pairs[i].f; | float b = pairs[i].f; | ||||
LOLUNIT_SET_CONTEXT(i); | |||||
LOLUNIT_ASSERT_EQUAL(a, b); | LOLUNIT_ASSERT_EQUAL(a, b); | ||||
} | } | ||||
@@ -173,6 +178,7 @@ public: | |||||
half h = half::makebits(i); | half h = half::makebits(i); | ||||
float f = (float)h; | float f = (float)h; | ||||
half g = (half)f; | half g = (half)f; | ||||
LOLUNIT_SET_CONTEXT(i); | |||||
if (h.is_nan()) | if (h.is_nan()) | ||||
{ | { | ||||
LOLUNIT_ASSERT(isnan(f)); | LOLUNIT_ASSERT(isnan(f)); | ||||
@@ -301,8 +307,8 @@ HalfTest::TestPair const HalfTest::pairs[] = | |||||
{ 0.125f, 0x3000 }, | { 0.125f, 0x3000 }, | ||||
{ 15.9375f, 0x4bf8 }, | { 15.9375f, 0x4bf8 }, | ||||
{ 31.0f / (1 << 14), 0x17c0 }, /* 0x1.fp-10 */ | { 31.0f / (1 << 14), 0x17c0 }, /* 0x1.fp-10 */ | ||||
{ 31.0f / (1 << 18), 0x07c0 }, /* 0x1.fp-14, denormal */ | |||||
{ 31.0f / (1 << 19), 0x03e0 }, /* 0x1.fp-15, denormal */ | |||||
{ 31.0f / (1 << 18), 0x07c0 }, /* 0x1.fp-14, normal float, denormal half */ | |||||
{ 31.0f / (1 << 19), 0x03e0 }, /* 0x1.fp-15, normal float, denormal half */ | |||||
}; | }; | ||||
} /* namespace lol */ | } /* namespace lol */ | ||||
@@ -37,6 +37,7 @@ public: | |||||
double a = sin(f); | double a = sin(f); | ||||
#endif | #endif | ||||
double b = lol_sin(f); | double b = lol_sin(f); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | ||||
} | } | ||||
@@ -49,6 +50,7 @@ public: | |||||
double a = sin(f); | double a = sin(f); | ||||
#endif | #endif | ||||
double b = lol_sin(f); | double b = lol_sin(f); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | ||||
} | } | ||||
} | } | ||||
@@ -64,6 +66,7 @@ public: | |||||
double a = cos(f); | double a = cos(f); | ||||
#endif | #endif | ||||
double b = lol_cos(f); | double b = lol_cos(f); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | ||||
} | } | ||||
@@ -76,6 +79,7 @@ public: | |||||
double a = cos(f); | double a = cos(f); | ||||
#endif | #endif | ||||
double b = lol_cos(f); | double b = lol_cos(f); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(f) * 1e-11); | ||||
} | } | ||||
} | } | ||||
@@ -94,6 +98,7 @@ public: | |||||
#endif | #endif | ||||
double b1, b2; | double b1, b2; | ||||
lol_sincos(f, &b1, &b2); | lol_sincos(f, &b1, &b2); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, fabs(f) * 1e-11); | ||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, fabs(f) * 1e-11); | ||||
} | } | ||||
@@ -110,6 +115,7 @@ public: | |||||
#endif | #endif | ||||
double b1, b2; | double b1, b2; | ||||
lol_sincos(f, &b1, &b2); | lol_sincos(f, &b1, &b2); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, fabs(f) * 1e-11); | ||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, fabs(f) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, fabs(f) * 1e-11); | ||||
} | } | ||||
@@ -126,6 +132,7 @@ public: | |||||
double a = tan(f); | double a = tan(f); | ||||
#endif | #endif | ||||
double b = lol_tan(f); | double b = lol_tan(f); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
if (fabs(a) > 1e4) | if (fabs(a) > 1e4) | ||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(a) * fabs(a) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(a) * fabs(a) * 1e-11); | ||||
else if (fabs(a) > 1.0) | else if (fabs(a) > 1.0) | ||||
@@ -143,6 +150,7 @@ public: | |||||
double a = tan(f); | double a = tan(f); | ||||
#endif | #endif | ||||
double b = lol_tan(f); | double b = lol_tan(f); | ||||
LOLUNIT_SET_CONTEXT(f); | |||||
if (fabs(a) > 1e4) | if (fabs(a) > 1e4) | ||||
LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(a) * fabs(a) * 1e-11); | LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, fabs(a) * fabs(a) * 1e-11); | ||||
else if (fabs(a) > 1.0) | else if (fabs(a) > 1.0) | ||||