#include #include #include #include class Test { private: std::function complete; public: std::string test_name; Test(std::string name, std::function complete): test_name(name), complete(complete){}; bool evaluate(); }; bool Test::evaluate() { return complete(); } class TestSuite { private: std::string suite_name; std::vector tests; public: TestSuite(std::string); void run(); template TestSuite& eq(std::string, T, T); template TestSuite& neq(std::string, T, T); TestSuite& custom(std::string, std::function); }; TestSuite::TestSuite(std::string name): suite_name(name) { tests = {}; } template TestSuite& TestSuite::eq(std::string test_name, T test_value, T expected_value) { tests.push_back(Test(test_name, [=](){return test_value == expected_value;})); return *this; } template TestSuite& TestSuite::neq(std::string test_name, T test_value, T expected_value) { tests.push_back(Test(test_name, [=](){return test_value != expected_value;})); return *this; } TestSuite& TestSuite::custom(std::string test_name, std::function completness_function) { tests.push_back(Test(test_name, completness_function)); return *this; } void TestSuite::run() { std::cout << "=== " << suite_name << " ===" << std::endl; int completed = 0; int amount = tests.size(); for (int i = 0; i < amount; i++) { try { bool result = tests[i].evaluate(); std::cout << "Running Test " << i + 1 << "/" << amount << " \"" << tests[i].test_name << "\": " << (result ? "SUCCESS" : "FAILED") << std::endl; if (result) completed++; } catch (...) { std::cout << "Test " << i + 1 << "/" << amount << " finished with exception."; } } std::cout << "Tests completed: " << completed << "/" << amount << (completed == amount ? ". Well done!" : "... You've got a job to do") << std::endl; }