#ifndef __UnitTesting__
#define __UnitTesting__
#include <ostream>
#include "Forwards.hpp"
#include "Lib/Stack.hpp"
namespace Test {
using namespace Lib;
typedef void (*TestProc)();
class TestUnit
{
public:
TestUnit(std::string const&);
struct Test
{
Test() {}
Test(TestProc proc, const char* name) : proc(proc), name(name) {}
TestProc proc;
const char* name;
};
void add(Test);
bool run(std::ostream& out);
bool runTestsWithNameSubstring(std::string const& pref, std::ostream& out);
bool runTest(std::string const& name);
bool hasTest(std::string const& name);
friend std::ostream& operator<<(std::ostream& out, TestUnit const& t)
{ return out << t._name << t._tests; }
std::string const& id() const { return _name; }
Stack<Test> const& tests() { return _tests; }
private:
Test* findTest(std::string const& testCase);
bool spawnTest(TestProc proc);
Stack<Test> _tests;
std::string _name;
};
class UnitTesting
{
static UnitTesting* _instance;
Stack<TestUnit> _units;
UnitTesting() : _units(), _singleThreaded(false) {}
bool _singleThreaded;
public:
static UnitTesting& instance();
bool add(std::string const& testUnit, TestUnit::Test test);
TestUnit* findUnit(std::string const& id);
bool listTests(Stack<std::string>const& args);
bool run(Stack<std::string>const& args);
bool runUnit(std::string const& args);
bool runTest(std::string const& unit, std::string const& testCase);
void setSingleThreaded(bool b) { _singleThreaded = b; }
bool getSingleThreaded() { return _singleThreaded; }
};
std::ostream& operator<<(std::ostream& out, TestUnit::Test const& t);
class TestAdder
{
public:
TestAdder(const char* unit, TestProc proc, const char* name);
};
#define EXPAND(a) a
#define _CAT(a,b) a ## b
#define CAT(a,b) EXPAND(_CAT(a,b))
#define __TEST_ADDER(name) CAT(CAT(CAT(__addTest__, UNIT_ID), __), name)
#define __TEST_FN_NAME(name) CAT(CAT(CAT(__testFn__ , UNIT_ID), __), name)
#define TEST_FUN(name) \
void __TEST_FN_NAME(name)(); \
Test::TestAdder __TEST_ADDER(name)(UNIT_ID_STR, __TEST_FN_NAME(name), #name); \
void __TEST_FN_NAME(name)()
}
int main(int argc, const char** argv);
#endif