Browse Source

test: make LolUnit's output match CppUnit's more closely.

legacy
Sam Hocevar sam 13 years ago
parent
commit
579f77bded
2 changed files with 111 additions and 39 deletions
  1. +108
    -37
      src/lol/unit.h
  2. +3
    -2
      test/lol-test.cpp

+ 108
- 37
src/lol/unit.h View File

@@ -17,6 +17,7 @@
#define __LOL_UNIT_H__ #define __LOL_UNIT_H__


#include <iostream> #include <iostream>
#include <sstream>
#include <cstdio> #include <cstdio>
#include <cmath> #include <cmath>


@@ -34,7 +35,7 @@ public:
virtual void tearDown(void) {}; virtual void tearDown(void) {};


protected: protected:
FixtureBase() : m_next(NULL), m_tests(0), m_fails(0) {}
FixtureBase() : m_next(NULL), m_testcases(0), m_failcases(0) {}
virtual ~FixtureBase() {} virtual ~FixtureBase() {}


/* The FixtureBase class keeps track of all instanciated children /* The FixtureBase class keeps track of all instanciated children
@@ -53,13 +54,16 @@ protected:
return head; return head;
} }


virtual int RunFixture() = 0;
virtual void RunFixture() = 0;


/* Prevent compiler complaints about unreachable code */ /* Prevent compiler complaints about unreachable code */
static inline bool True() { return true; } static inline bool True() { return true; }


FixtureBase *m_next; FixtureBase *m_next;
int m_tests, m_fails;
int m_testcases, m_failcases;
int m_asserts, m_failure;
char const *m_fixturename, *m_currentname;
std::stringstream m_errorlog;
}; };


template<class T> class Fixture : protected FixtureBase template<class T> class Fixture : protected FixtureBase
@@ -71,13 +75,13 @@ public:
{ {
public: public:
void (FixtureClass::* m_fun)(); void (FixtureClass::* m_fun)();
char const *m_name;
char const *m_testname;
TestCase *m_next; TestCase *m_next;


static void AddTestCase(TestCase *that, char const *name, static void AddTestCase(TestCase *that, char const *name,
void (FixtureClass::*fun)()) void (FixtureClass::*fun)())
{ {
that->m_name = name;
that->m_testname = name;
that->m_fun = fun; that->m_fun = fun;
GetOrSetTestCase(that); GetOrSetTestCase(that);
} }
@@ -89,14 +93,20 @@ public:
} }


/* Run all test cases in this fixture. */ /* Run all test cases in this fixture. */
virtual int RunFixture()
virtual void RunFixture()
{ {
for (TestCase *head = GetOrSetTestCase(); head; head = head->m_next)
m_errorlog.str("");
m_testcases = 0;
m_failcases = 0;
for (TestCase *c = GetOrSetTestCase(); c; c = c->m_next)
{ {
(static_cast<FixtureClass *>(this)->*head->m_fun)();
std::cout << ".";
m_testcases++;
m_asserts = 0;
m_failure = false;
m_currentname = c->m_testname;
(static_cast<FixtureClass *>(this)->*c->m_fun)();
std::cout << (m_failure ? 'F' : '.');
} }
return 0;
} }


/* Each Fixture class specialisation keeps track of its instanciated /* Each Fixture class specialisation keeps track of its instanciated
@@ -117,22 +127,53 @@ public:
class TestRunner class TestRunner
{ {
public: public:
int Run()
bool Run()
{ {
int ret = 0;
for (FixtureBase *head = FixtureBase::GetOrSetTest(); head; head = head->m_next)
bool ret = true;
std::stringstream errors("");
int failcases = 0, testcases = 0;

for (FixtureBase *f = FixtureBase::GetOrSetTest(); f; f = f->m_next)
{ {
head->setUp();
if (head->RunFixture())
ret = 1;
head->tearDown();
f->setUp();
f->RunFixture();
f->tearDown();

errors << f->m_errorlog.str();
testcases += f->m_testcases;
failcases += f->m_failcases;
} }
std::cout << std::endl; std::cout << std::endl;

std::cout << std::endl << std::endl;
if (failcases)
{
std::cout << "!!!FAILURES!!!" << std::endl;
std::cout << "Test Results:" << std::endl;
std::cout << "Run: " << testcases
<< " Failures: " << failcases
<< " Errors: 0" << std::endl; /* TODO: handle errors */

std::cout << errors.str();
ret = false;
}
else
{
std::cout << "OK (" << testcases << " tests)" << std::endl;
}
std::cout << std::endl << std::endl;

return ret; return ret;
} }
}; };


#define LOLUNIT_FIXTURE(FixtureName) \ #define LOLUNIT_FIXTURE(FixtureName) \
class FixtureName; \
static char const *LolUnitFixtureName(FixtureName *p) \
{ \
(void)p; \
return #FixtureName; \
} \
class FixtureName : public lol::Fixture<FixtureName> class FixtureName : public lol::Fixture<FixtureName>


#define LOLUNIT_TEST(TestCaseName) \ #define LOLUNIT_TEST(TestCaseName) \
@@ -145,36 +186,66 @@ public:
(void (FixtureClass::*)()) &FixtureClass::TestCaseName); \ (void (FixtureClass::*)()) &FixtureClass::TestCaseName); \
} \ } \
}; \ }; \
TestCase##TestCaseName test_case_##TestCaseName; \
TestCase##TestCaseName lol_unit_test_case_##TestCaseName; \
void TestCaseName() void TestCaseName()


#define LOLUNIT_SETUP_FIXTURE(ClassName) \ #define LOLUNIT_SETUP_FIXTURE(ClassName) \
ClassName ClassName##Test_Instance; ClassName ClassName##Test_Instance;


#define LOLUNIT_ASSERT(cond) \ #define LOLUNIT_ASSERT(cond) \
do { if (True() && !(cond)) \
{ \
std::cout << "FAIL! " #cond << std::endl; \
return; \
} } while(!True())
do { \
m_asserts++; \
if (True() && !(cond)) \
{ \
m_errorlog << std::endl << std::endl; \
m_errorlog << ++m_failcases << ") test: " \
<< LolUnitFixtureName(this) << "::" << m_currentname \
<< " (F) line: " << __LINE__ << " " \
<< __FILE__ << std::endl; \
m_errorlog << "assertion failed" << std::endl; \
m_errorlog << "- Expression: " << #cond << std::endl; \
m_failure = true; \
return; \
} \
} while(!True())


#define LOLUNIT_ASSERT_EQUAL(a, b) \ #define LOLUNIT_ASSERT_EQUAL(a, b) \
do { if (True() && (a) != (b)) \
{ \
std::cout << "FAIL! " #a " != " #b << std::endl; \
std::cout << "expected: " << (a) << std::endl; \
std::cout << "returned: " << (b) << std::endl; \
return; \
} } while(!True())
do { \
m_asserts++; \
if (True() && (a) != (b)) \
{ \
m_errorlog << std::endl << std::endl; \
m_errorlog << ++m_failcases << ") test: " \
<< LolUnitFixtureName(this) << "::" << m_currentname \
<< " (F) line: " << __LINE__ << " " \
<< __FILE__ << std::endl; \
m_errorlog << "equality assertion failed" << std::endl; \
m_errorlog << "- Expected: " << (b) << std::endl; \
m_errorlog << "- Actual : " << (a) << std::endl; \
m_errorlog << message; \
m_failure = true; \
return; \
} \
} while(!True())


#define LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, t) \ #define LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, t) \
do { if (True() && fabs((a) - (b)) > fabs((t))) \
{ \
std::cout << "FAIL! " #a " != " #b << std::endl; \
std::cout << "expected: " << (a) << std::endl; \
std::cout << "returned: " << (b) << std::endl; \
return; \
} } while(!True())
do { \
m_asserts++; \
if (True() && fabs((a) - (b)) > fabs((t))) \
{ \
m_errorlog << std::endl << std::endl; \
m_errorlog << ++m_failcases << ") test: " \
<< LolUnitFixtureName(this) << "::" << m_currentname \
<< " (F) line: " << __LINE__ << " " \
<< __FILE__ << std::endl; \
m_errorlog << "double equality assertion failed" << std::endl; \
m_errorlog << "- Expected: " << (b) << std::endl; \
m_errorlog << "- Actual : " << (a) << std::endl; \
m_errorlog << "- Delta : " << (t) << std::endl; \
m_failure = true; \
return; \
} \
} while(!True())


} /* namespace lol */ } /* namespace lol */




+ 3
- 2
test/lol-test.cpp View File

@@ -13,13 +13,14 @@
#endif #endif


#include <cstdio> #include <cstdio>
#include <cstdlib>


#include <lol/unit.h> #include <lol/unit.h>


int main(void) int main(void)
{ {
lol::TestRunner runner; lol::TestRunner runner;
int ret = !runner.Run();
return ret;
bool success = runner.Run();
return success ? EXIT_SUCCESS : EXIT_FAILURE;
} }



Loading…
Cancel
Save