32 #ifndef SOLIDUTILS_INCLUDE_UNITTEST_HPP 33 #define SOLIDUTILS_INCLUDE_UNITTEST_HPP 53 volatile int _unittest_numberFailed = 0;
54 volatile int _unittest_numberPassed = 0;
61 class TestFailed :
public std::logic_error
64 TestFailed(std::string
const & str) :
83 ~TestStream() noexcept(false)
87 std::cerr << std::endl;
89 throw TestFailed(
"Unit test failed.");
97 return std::cerr <<
"Test Failed: ";
104 std::ostream & testFail()
112 std::ostream & testEqual(
113 std::string
const & a,
114 std::string
const & b)
117 m_fail = !(a.compare(b) == 0);
124 template<
typename A,
typename B>
125 std::ostream & testEqual(
137 std::ostream & testNearEqual(
140 double const ratio = 1e-6,
141 double const buffer = 1e-9)
143 if (std::abs(a - b) <= buffer) {
145 }
else if (-a == b) {
148 m_fail = std::abs((a-b)/(a+b)) >= ratio;
155 template<
typename A,
typename B>
156 std::ostream & testNotEqual(
168 std::ostream & testTrue(
179 std::ostream & testFalse(
190 template<
typename A,
typename B>
191 std::ostream & testGreater(
203 template<
typename A,
typename B>
204 std::ostream & testGreaterOrEqual(
216 template<
typename A,
typename B>
217 std::ostream & testLess(
229 template<
typename A,
typename B>
230 std::ostream & testLessOrEqual(
244 std::ostringstream m_stream;
255 std::cerr <<
"Test " << name <<
" PASSED." << std::endl;
256 ++_unittest_numberPassed;
258 }
catch (TestFailed
const &) {
259 std::cerr <<
"Test " << name <<
" FAILED." << std::endl;
260 ++_unittest_numberFailed;
277 sl::TestStream().testFail() << "testFail() called at " << __LINE__ << \ 281 #define testEqual(a,b) \ 282 sl::TestStream().testEqual(a,b) << #a << ":'" << (a) \ 283 << "' != " << #b << ":'" << (b) << "' at " << __LINE__ << std::endl 286 #define testNotEqual(a,b) \ 287 sl::TestStream().testNotEqual(a,b) << #a << ":'" << (a) \ 288 << "' == " << #b << ":'" << (b) << "' at " << __LINE__ << std::endl 291 #define testTrue(a) \ 292 sl::TestStream().testTrue(a) << #a << "' is false at: " << __LINE__ \ 296 #define testFalse(a) \ 297 sl::TestStream().testFalse(a) << #a << "' is true at: " << __LINE__ \ 301 #define testGreater(a,b) \ 302 sl::TestStream().testGreater(a,b) << #a << ":'" << (a) << "' <= " << #b \ 303 << ":'" << (b) << "' at " << __LINE__ << std::endl 306 #define testGreaterOrEqual(a,b) \ 307 sl::TestStream().testGreaterOrEqual(a,b) << #a << ":'" << (a) << "' < " << \ 308 #b << ":'" << (b) << "' at " << __LINE__ << std::endl 311 #define testLess(a,b) \ 312 sl::TestStream().testLess(a,b) << #a << ":'" << (a) << "' >= " << #b << \ 313 ":'" << (b) << "' at " << __LINE__ << std::endl 316 #define testLessOrEqual(a,b) \ 317 sl::TestStream().testLessOrEqual(a,b) << #a << ":'" << (a) << "' > " << #b \ 318 << ":'" << (b) << "' at " << __LINE__ << std::endl 321 #define testNearEqual(a, b, c, d) \ 322 sl::TestStream().testNearEqual(a, b, c, d) << #a << ":'" << (a) \ 323 << "' != " << #b << ":'" << (b) << "' at " << __LINE__ << std::endl 326 #define UNITTEST(CLASS, TEST) \ 327 void _unittest_ ## CLASS ## _ ## TEST ## _func(void); \ 328 bool _unittest_ ## CLASS ## _ ## TEST ## _result = \ 330 __FILE__":"#CLASS"->"#TEST, \ 331 _unittest_ ## CLASS ## _ ## TEST ## _func); \ 332 void _unittest_ ## CLASS ## _ ## TEST ## _func(void) \ 348 for (
int i=1; i<argc; ++i) {
349 std::cerr <<
"Unused parameter: " << argv[i] << std::endl;
356 if (sl::_unittest_numberPassed == 0 && \
357 sl::_unittest_numberFailed == 0) {
358 std::cerr <<
"No tests run." << std::endl;
362 std::cout << sl::_unittest_numberPassed <<
" tests passed." << \
364 std::cout << sl::_unittest_numberFailed <<
" tests failed." << \
367 if (sl::_unittest_numberFailed == 0) {