#include "Testing.hpp" #include "Utils.hpp" #include #include using namespace tp; Testing tp::gTesting; void Testing::startTest(const char* name) { MODULE_SANITY_CHECK(gModuleUtils) mCurrent->mSubTests.pushBack(new TestingNode{ {}, {}, name, mCurrent }); mCurrent = mCurrent->mSubTests.last()->data; } void Testing::endTest() { if (mCurrent->mParent) { mCurrent = mCurrent->mParent; } } void Testing::addFailedCheck(const FailedCheck& info) { DEBUG_BREAK(0 && info.expression); auto lastRecord = &mCurrent->mFailedChecks.last()->data; if (lastRecord && lastRecord->failedCheck.file == info.file && lastRecord->failedCheck.line == info.line) { lastRecord->times++; return; } mCurrent->mFailedChecks.pushBack({ info, 1 }); } void Testing::reportState() { mRootTest.updateState(); printf("\n"); mRootTest.report(); } bool Testing::hasFailed() { mRootTest.updateState(); return mRootTest.mHasFailed; } void Testing::setRootName(const char* name) { mRootTest.mName = name; } void Testing::TestingNode::updateState() { for (auto child : mSubTests) { child->updateState(); mHasFailed = child->mHasFailed; if (mHasFailed) return; } mHasFailed = mFailedChecks.length(); } void Testing::TestingNode::report(const char* path) const { if (!mHasFailed) { return; } auto newPath = path ? std::string(path) + "/" + mName : std::string(mName); for (auto check : mFailedChecks) { auto failedCheck = &check.data().failedCheck; auto times = check.data().times; printf("%s Failed - (%s) %s:%llu x%i\n", newPath.c_str(), failedCheck->expression, failedCheck->file, failedCheck->line, (halni) times); } for (const auto& child : mSubTests) { child->report(newPath.c_str()); } } Testing::TestingNode::~TestingNode() { for (const auto& child : mSubTests) { delete child.data(); } }