Riyyi
3 years ago
5 changed files with 127 additions and 121 deletions
@ -0,0 +1,45 @@ |
|||||||
|
#ifndef TEST_CASE_H |
||||||
|
#define TEST_CASE_H |
||||||
|
|
||||||
|
#include <functional> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#define __TEST_CASE_FUNCTION(x) __test##x |
||||||
|
#define __TEST_CASE_STRUCT(x) __testStruct##x |
||||||
|
|
||||||
|
#define TEST_CASE(x) \ |
||||||
|
static void __TEST_CASE_FUNCTION(x)(); \
|
||||||
|
struct __TEST_CASE_STRUCT(x) { \
|
||||||
|
__TEST_CASE_STRUCT(x) \
|
||||||
|
() \
|
||||||
|
{ \
|
||||||
|
Test::TestSuite::the().addCase( \
|
||||||
|
*new Test::TestCase(#x, __TEST_CASE_FUNCTION(x))); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
static struct __TEST_CASE_STRUCT(x) __TEST_CASE_STRUCT(x); \
|
||||||
|
static void __TEST_CASE_FUNCTION(x)() |
||||||
|
|
||||||
|
namespace Test { |
||||||
|
|
||||||
|
using testFunction = std::function<void()>; |
||||||
|
|
||||||
|
class TestCase { |
||||||
|
public: |
||||||
|
TestCase(const char* name, testFunction&& function) |
||||||
|
: m_name(name) |
||||||
|
, m_function(function) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
const char* name() const { return m_name; } |
||||||
|
const testFunction& function() const { return m_function; } |
||||||
|
|
||||||
|
private: |
||||||
|
const char* m_name { nullptr }; |
||||||
|
testFunction m_function; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace Test
|
||||||
|
|
||||||
|
#endif // TEST_CASE_H
|
@ -0,0 +1,40 @@ |
|||||||
|
#include <cstddef> // size_t |
||||||
|
#include <cstdio> // fclose, fopen, printf, stdout |
||||||
|
|
||||||
|
#include "testsuite.h" |
||||||
|
|
||||||
|
namespace Test { |
||||||
|
|
||||||
|
TestSuite::TestSuite(s) |
||||||
|
{ |
||||||
|
m_outputStd = stdout; |
||||||
|
m_outputNull = fopen("/dev/null", "w"); // Windows: nul
|
||||||
|
} |
||||||
|
|
||||||
|
TestSuite::~TestSuite() |
||||||
|
{ |
||||||
|
fclose(m_outputNull); |
||||||
|
} |
||||||
|
|
||||||
|
void TestSuite::run() |
||||||
|
{ |
||||||
|
printf("TestSuite: %d cases have been added!\n", (int)m_cases.size()); |
||||||
|
|
||||||
|
size_t caseFailedCount = 0; |
||||||
|
|
||||||
|
for(auto& testCase : m_cases) { |
||||||
|
printf("%s\n", testCase.name()); |
||||||
|
m_currentTestCasePassed = true; |
||||||
|
|
||||||
|
testCase.function()(); |
||||||
|
|
||||||
|
if (!m_currentTestCasePassed) { |
||||||
|
caseFailedCount++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int percentagePassed = (1 - caseFailedCount / (float)m_cases.size()) * 100; |
||||||
|
printf("Passed %d%% of tests\n", percentagePassed); |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace Test
|
@ -0,0 +1,34 @@ |
|||||||
|
#ifndef TEST_SUITE_H |
||||||
|
#define TEST_SUITE_H |
||||||
|
|
||||||
|
#include <cstdio> // FILE |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
#include "testcase.h" |
||||||
|
#include "util/singleton.h" |
||||||
|
|
||||||
|
namespace Test { |
||||||
|
|
||||||
|
class TestSuite final : public Util::Singleton<TestSuite> { |
||||||
|
public: |
||||||
|
TestSuite(s); |
||||||
|
virtual ~TestSuite(); |
||||||
|
|
||||||
|
void run(); |
||||||
|
void addCase(const TestCase& testCase) { m_cases.push_back(testCase); } |
||||||
|
void currentTestCaseFailed() { m_currentTestCasePassed = false; } |
||||||
|
|
||||||
|
FILE* outputStd() const { return m_outputStd; } |
||||||
|
FILE* outputNull() const { return m_outputNull; } |
||||||
|
|
||||||
|
private: |
||||||
|
bool m_currentTestCasePassed { true }; |
||||||
|
FILE* m_outputStd { nullptr }; |
||||||
|
FILE* m_outputNull { nullptr }; |
||||||
|
|
||||||
|
std::vector<TestCase> m_cases; |
||||||
|
}; |
||||||
|
|
||||||
|
} // namespace Test
|
||||||
|
|
||||||
|
#endif // TEST_SUITE_H
|
Loading…
Reference in new issue