From 7a5dc3aa8b1d474290031025a11dc2fab889e239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Z=C3=A1hradn=C3=ADk?= Date: Sat, 7 Sep 2024 13:16:01 +0200 Subject: [PATCH] Remove legacy SimpleTest framework --- src/testing/SimpleTest.cpp | 177 ------------------------ src/testing/SimpleTest.h | 275 ------------------------------------- 2 files changed, 452 deletions(-) delete mode 100644 src/testing/SimpleTest.cpp delete mode 100644 src/testing/SimpleTest.h diff --git a/src/testing/SimpleTest.cpp b/src/testing/SimpleTest.cpp deleted file mode 100644 index c7730f4..0000000 --- a/src/testing/SimpleTest.cpp +++ /dev/null @@ -1,177 +0,0 @@ - -#include "../IoAbstraction.h" -#include "SimpleTest.h" -#include "../IoLogging.h" -#include "TextUtilities.h" -#include - -namespace SimpleTest { - - const char* niceStatus(TestStatus s) { - switch(s) { - case NOT_RUN: - return "Not run"; - case RUNNING: - return "Running"; - case FAILED: - return "Failed"; - case PASSED: - return "Passed"; - case IGNORED: - return "Ignored"; - default: - return "????"; - } - } - - UnitTestExecutor *UnitTestExecutor::currentlyRunning = nullptr; - - void UnitTestExecutor::exec() { - currentlyRunning = this; - testStatus = RUNNING; - serlogF2(SER_DEBUG, "Starting test ", testName); - setup(); - performTest(); - teardown(); - if (testStatus != FAILED) { - testStatus = PASSED; - } - serlogF3(SER_DEBUG, "Test ", testName, niceStatus(testStatus)); - currentlyRunning = nullptr; - } - - void UnitTestExecutor::setFailed(PGM_TYPE file, int line, const char *reason) { - testStatus = FAILED; - failureReason.withFileAndLine(file, line); - } - - void UnitTestExecutor::init(const char *name, bool ignored) { - testName = name; - if (ignored) { - testStatus = IGNORED; - } else { - TestManager::getInstance()->addTest(this); - } - } - - TestManager* TestManager::instance = nullptr; - - void TestManager::printSummary() { - int total = testsRecorded.count(); - int ignored = 0; - int failed = 0; - int passed = 0; - int unknown = 0; - - for (auto tst: testsRecorded) { - if (tst.getTest()->getTestStatus() == PASSED) passed++; - else if (tst.getTest()->getTestStatus() == IGNORED) ignored++; - else if (tst.getTest()->getTestStatus() == SimpleTest::FAILED) failed++; - else unknown++; - } - - if (unknown == 0) { - char sz[50]; - strncpy(sz, "total=", sizeof sz); - fastltoa(sz, total, 5, NOT_PADDED, sizeof sz); - strncat(sz, ", passed=", sizeof(sz) - strlen(sz) - 1); - fastltoa(sz, passed, 5, NOT_PADDED, sizeof sz); - strncat(sz, ", failed=", sizeof(sz) - strlen(sz) - 1); - fastltoa(sz, failed, 5, NOT_PADDED, sizeof sz); - strncat(sz, ", ignored=", sizeof(sz) - strlen(sz) - 1); - fastltoa(sz, ignored, 5, NOT_PADDED, sizeof sz); - serlogF2(SER_DEBUG, "Tests finished - ", sz); - } - - if(failed > 0) { - serlogF(SER_DEBUG, "T E S T S F A I L E D") - } - } - - void TestManager::begin() { - serlogF(SER_DEBUG, "==== 8< ==== 8< ==== START EXECUTION ==== 8< ==== 8< ===="); - serlogF3(SER_DEBUG, "Starting test execution on ", testsRecorded.count(), "tests"); - currentIndex = 0; - needsSummary = true; - - if(serLevelEnabled(SER_IOA_DEBUG)) { - serlogF(SER_IOA_DEBUG, "The following tests were added"); - for(auto t : testsRecorded) { - serlogF2(SER_IOA_DEBUG, "Test: ", t.getTest()->getTestName()) - } - } - } - - void TestManager::runLoop() { - if((bsize_t)currentIndex < testsRecorded.count()) { - auto t = testsRecorded.itemAtIndex(currentIndex); - if (t->getTest()->getTestStatus() != IGNORED && (filterPredicate == nullptr || filterPredicate(t->getTest()))) { - t->getTest()->exec(); - } - currentIndex = currentIndex + 1; - } else if(needsSummary) { - needsSummary = false; - printSummary(); - } - } - - TestManager *TestManager::getInstance() { - if(instance == nullptr) { - instance = new TestManager(); - } - return instance; - } -} - -namespace STestInternal { - void assertBoolInternal(PGM_TYPE file, int line, bool valid, const char* reason) { - auto current = SimpleTest::UnitTestExecutor::getCurrentTest(); - if(current == nullptr || current->getTestStatus() != SimpleTest::RUNNING) return; - - if(!valid) { - current->setFailed(file, line, reason); - serlogF4(SER_DEBUG, "Assertion failure at ", file, ", line", line ); - serlogF2(SER_DEBUG, "Detail: ", reason); - } - } - - void assertFloatInternal(PGM_TYPE file, int line, float x, float y, float allowable) { - auto current = SimpleTest::UnitTestExecutor::getCurrentTest(); - if(current == nullptr || current->getTestStatus() != SimpleTest::RUNNING) return; - - if(tcFltAbs(x - y) > allowable) { - current->setFailed(file, line, "flt!="); - serlogF4(SER_DEBUG, "Assertion failure at ", file, ", line", line ); - serlogF4(SER_DEBUG, "Detail: ", x, "==", y); - } - } - - void internalEquality(PGM_TYPE file, int line, bool eq, uint32_t x, uint32_t y, const char* how) { - auto current = SimpleTest::UnitTestExecutor::getCurrentTest(); - if(current == nullptr || current->getTestStatus() != SimpleTest::RUNNING) return; - - if(!eq) { - current->setFailed(file, line, how); - serlogF4(SER_DEBUG, "Assertion failure at ", file, ", line", line); - serlogF4(SER_DEBUG, "Details: ", y, how, x); - } - } - - void assertStringInternal(PGM_TYPE file, int line, const char* x, const char* y) { - auto current = SimpleTest::UnitTestExecutor::getCurrentTest(); - if(current == nullptr || current->getTestStatus() != SimpleTest::RUNNING) return; - - if(strcmp(x, y) != 0) { - current->setFailed(file, line, "=="); - serlogF4(SER_DEBUG, "Assertion failure at ", file, ", line", line); - serlogF4(SER_DEBUG, "Details: ", x, "eq", y); - } - } - - void failInternal(PGM_TYPE file, int line, const char* reason) { - auto current = SimpleTest::UnitTestExecutor::getCurrentTest(); - if(current == nullptr || current->getTestStatus() != SimpleTest::RUNNING) return; - current->setFailed(file, line, "fail()"); - serlogF4(SER_DEBUG, "Assertion failure at ", file, line, "fail() was called"); - } -} \ No newline at end of file diff --git a/src/testing/SimpleTest.h b/src/testing/SimpleTest.h deleted file mode 100644 index 4c84d6b..0000000 --- a/src/testing/SimpleTest.h +++ /dev/null @@ -1,275 +0,0 @@ -#ifndef IOA_SIMPLE_TEST_H -#define IOA_SIMPLE_TEST_H - -/** - * @file SimpleTest.h - a very simple test framework for all platforms that IoAbstraction supports using testmanager as - * the executor queue. This is enough of a test framework for me to test my libraries, it may well be enough for you - * as well, but it is far from complete. Unfortunately, aunit just does not work on the boards I need to test on, I've - * excused it for a long time, but now it's more than half and will get worse as more boards move to the API. This - * replaces enough to just about do the job for our stuff. - */ - -#include -#include -#include -#include - -#define FAIL_REASON_SIZE 32 - -#ifdef __AVR__ -#include -#define FromPgm(x) F(x) -#define PGM_TYPE const __FlashStringHelper* -#else -#define FromPgm(x) (x) -#define PGM_TYPE const char* -#endif - -namespace SimpleTest { - - enum TestStatus { - NOT_RUN, RUNNING, FAILED, PASSED, IGNORED - }; - - const char* niceStatus(TestStatus s); - - class FailureInfo { - private: - PGM_TYPE file; - int line = 0; - public: - FailureInfo() {} - void withFileAndLine(PGM_TYPE f, int l) { - file = f; - line = l; - } - }; - - class UnitTestExecutor { - private: - static UnitTestExecutor *currentlyRunning; - TestStatus testStatus = NOT_RUN; - FailureInfo failureReason; - const char* testName; - public: - void init(const char* name, bool ignored = false); - - virtual void performTest() = 0; - - TestStatus getTestStatus() const { return testStatus; } - const char* getTestName() const { return testName; } - - void exec(); - void setFailed(PGM_TYPE file, int line, const char* reason); - - virtual void setup() {} - virtual void teardown() {} - - static UnitTestExecutor* getCurrentTest() { - return currentlyRunning; - } - }; - - class ExecutionWithId { - private: - uint16_t key; - UnitTestExecutor* executor; - public: - ExecutionWithId(): key(-1), executor(nullptr) {} - ExecutionWithId(const ExecutionWithId& other) = default; - ExecutionWithId& operator=(const ExecutionWithId& other) = default; - ExecutionWithId(uint16_t key, UnitTestExecutor* exec): key(key), executor(exec) {} - - uint16_t getKey() const { return key; } - UnitTestExecutor* getTest() { return executor; } - }; - - /** - * Implement this predicate to be able to filter out tests based on the name or any other parameter. - * You are given a reference to the test and can return true = run test, false = dont run. - */ - typedef bool (*TestFilterPredicate)(UnitTestExecutor* theTest); - - class TestManager { - private: - BtreeList testsRecorded; - static TestManager* instance; - int currentIndex = 0; - bool needsSummary = true; - TestFilterPredicate filterPredicate = nullptr; - - TestManager(): testsRecorded(32) {} - - public: - static TestManager* getInstance(); - - void begin(); - - void runLoop(); - - void addTest(UnitTestExecutor* t) { - testsRecorded.add(ExecutionWithId(testsRecorded.count(), t)); - } - - void printSummary(); - - void setTestFilterPredicate(TestFilterPredicate predicate) { - filterPredicate = predicate; - } - }; - - inline void startTesting() { - TestManager::getInstance()->begin(); - } -} - -namespace STestInternal { - - void internalEquality(PGM_TYPE file, int line, bool success, uint32_t x, uint32_t y, const char *how); - - void assertStringInternal(PGM_TYPE file, int line, const char *x, const char *y); - - void failInternal(PGM_TYPE file, int line, const char *reason); - - void assertBoolInternal(PGM_TYPE file, int line, bool valid, const char *reason); - - void assertFloatInternal(PGM_TYPE file, int line, float x, float y, float allowable); - - inline void assertEqualityInternal(PGM_TYPE file, int line, short x, short y) { - internalEquality(file, line, x == y, x, y, "=="); - } - inline void assertEqualityInternal(PGM_TYPE file, int line, unsigned short x, unsigned short y) { - internalEquality(file, line, x == y, x, y, "=="); - } - - inline void assertEqualityInternal(PGM_TYPE file, int line, int x, int y) { - internalEquality(file, line, x == y, x, y, "=="); - } - inline void assertEqualityInternal(PGM_TYPE file, int line, unsigned int x, unsigned int y) { - internalEquality(file, line, x == y, x, y, "=="); - } - - inline void assertEqualityInternal(PGM_TYPE file, int line, long x, long y) { - internalEquality(file, line, x == y, x, y, "=="); - } - inline void assertEqualityInternal(PGM_TYPE file, int line, unsigned long x, unsigned long y) { - internalEquality(file, line, x == y, x, y, "=="); - } - - inline void assertNonEqualityInternal(PGM_TYPE file, int line, short x, short y) { - internalEquality(file, line, x != y, x, y, "!="); - } - inline void assertNonEqualityInternal(PGM_TYPE file, int line, unsigned short x, unsigned short y) { - internalEquality(file, line, x != y, x, y, "!="); - } - - inline void assertNonEqualityInternal(PGM_TYPE file, int line, int x, int y) { - internalEquality(file, line, x != y, x, y, "!="); - } - inline void assertNonEqualityInternal(PGM_TYPE file, int line, unsigned int x, unsigned int y) { - internalEquality(file, line, x != y, x, y, "!="); - } - - inline void assertNonEqualityInternal(PGM_TYPE file, int line, long x, long y) { - internalEquality(file, line, x != y, x, y, "!="); - } - inline void assertNonEqualityInternal(PGM_TYPE file, int line, unsigned long x, unsigned long y) { - internalEquality(file, line, x != y, x, y, "!="); - } - - - inline void assertLessInternal(PGM_TYPE file, int line, short x, short y) { - internalEquality(file, line, y < x, x, y, "<"); - } - inline void assertLessInternal(PGM_TYPE file, int line, unsigned short x, unsigned short y) { - internalEquality(file, line, y < x, x, y, "<"); - } - inline void assertLessInternal(PGM_TYPE file, int line, int x, int y) { - internalEquality(file, line, y < x, x, y, "<"); - } - inline void assertLessInternal(PGM_TYPE file, int line, unsigned int x, unsigned int y) { - internalEquality(file, line, y < x, x, y, "<"); - } - inline void assertLessInternal(PGM_TYPE file, int line, long x, long y) { - internalEquality(file, line, y < x, x, y, "<"); - } - inline void assertLessInternal(PGM_TYPE file, int line, unsigned long x, unsigned long y) { - internalEquality(file, line, y < x, x, y, "<"); - } - - inline void assertMoreInternal(PGM_TYPE file, int line, short x, short y) { - internalEquality(file, line, y > x, x, y, ">"); - } - inline void assertMoreInternal(PGM_TYPE file, int line, unsigned short x, unsigned short y) { - internalEquality(file, line, y > x, x, y, ">"); - } - inline void assertMoreInternal(PGM_TYPE file, int line, int x, int y) { - internalEquality(file, line, y > x, x, y, ">"); - } - inline void assertMoreInternal(PGM_TYPE file, int line, unsigned int x, unsigned int y) { - internalEquality(file, line, y > x, x, y, ">"); - } - inline void assertMoreInternal(PGM_TYPE file, int line, long x, long y) { - internalEquality(file, line, y > x, x, y, ">"); - } - inline void assertMoreInternal(PGM_TYPE file, int line, unsigned long x, unsigned long y) { - internalEquality(file, line, y > x, x, y, ">"); - } - - // pointers - - inline void assertEqualityInternal(PGM_TYPE file, int line, const void* x, const void* y) { - internalEquality(file, line, x == y, (int)x, (int)y, "=="); - } - - inline void assertNonEqualityInternal(PGM_TYPE file, int line, const void* x, const void* y) { - internalEquality(file, line, x != y, (int)x, (int)y, "!="); - } - - inline void assertEqualityInternal(PGM_TYPE file, int line, const char* x, const char* y) { - assertStringInternal(file, line, x, y); - } -} - -#define assertTrue(actual) STestInternal::assertBoolInternal(FromPgm(__FILE__), __LINE__, actual, "True") -#define assertFalse(actual) STestInternal::assertBoolInternal(FromPgm(__FILE__), __LINE__, !(actual), "False") -#define assertEquals(expected, actual) STestInternal::assertEqualityInternal(FromPgm(__FILE__), __LINE__, expected, actual) -#define assertNotEquals(expected, actual) STestInternal::assertNonEqualityInternal(FromPgm(__FILE__), __LINE__, expected, actual) -#define assertLessThan(expected, actual) STestInternal::assertLessInternal(FromPgm(__FILE__), __LINE__, expected, actual) -#define assertMoreThan(expected, actual) STestInternal::assertMoreInternal(FromPgm(__FILE__), __LINE__, expected, actual) -#define assertStringEquals(expected, actual) STestInternal::assertStringInternal(FromPgm(__FILE__), __LINE__, expected, actual) -#define assertFloatNear(expected, actual, allowable) STestInternal::assertFloatInternal(FromPgm(__FILE__), __LINE__, expected, actual, allowable) -#define fail(reason) STestInternal::failInternal(FromPgm(__FILE__), __LINE__, reason) - -#define testi(name, ignored) \ -class UnitTest_##name : public SimpleTest::UnitTestExecutor {\ -public:\ - UnitTest_##name();\ - void performTest() override;\ -} unitTest_##name##_instance;\ -UnitTest_##name :: UnitTest_##name() {\ - init(#name, ignored); \ -}\ -void UnitTest_##name::performTest() - -#define testFi(testClass, name, ignored) \ -class testClass ## _ ## name : public testClass {\ -public:\ - testClass ## _ ## name();\ - void performTest() override;\ -} testClass ## _ ## name ## _instance;\ -testClass ## _ ## name :: testClass ## _ ## name() {\ - init(#name, ignored); \ -}\ -void testClass ## _ ## name :: performTest() - -#define test(name) testi(name, false) -#define testF(clazz, name) testFi(clazz, name, false) - -#ifdef IOA_USE_ARDUINO -#define DEFAULT_TEST_RUNLOOP void loop() { TestManager::getInstance()->runLoop(); } -#else -#define DEFAULT_TEST_RUNLOOP int main() { setup(); while(1) {TestManager::getInstance()->runLoop();} } -#endif //IOA_USE_ARDUINO - -#endif //IOA_SIMPLE_TEST_H