Files
Ranieri 5196a6672a Refactor runtime for move speed and better code style (#140)
* feat: added guestBranchKind enum to categorize branch types
feat: added missingFunctionPolicy enum to define behaviors for missing function scenarios
refactor: added handle guest branches and report missing functions
feat lookupFunction to utilize new dispatch logic and improve error handling for unregistered functions

* fix: fix test conflict

* feat: added debug sound driver logs

* feat: emmiter for return

* feat: added recompiler reporter
feat: added strict diagnostics flag for heavy debug calls

* feat: staticc table insted of hashmap for runtime

* feat: back file to ignore

* feat: explode code across helpers and classes

* feat: update codegen test
feat: better guest nop check

* feat: fix link problem on linux

* feat: fix Segmentation fault
2026-07-04 00:43:22 -03:00

212 lines
5.2 KiB
C++

#pragma once
#include <functional>
#include <string>
#include <vector>
#include <map>
#include <iostream>
#include <exception>
class TestCase;
using TestRunnerCallback = std::function<void(TestCase&)>;
using TestBeforeCallback = std::function<void()>;
class TestCase
{
private:
std::map<std::string, TestRunnerCallback> m_cases;
std::vector<std::string> m_failReason;
TestBeforeCallback m_beforeEach;
TestBeforeCallback m_afterEach;
TestBeforeCallback m_before;
TestBeforeCallback m_after;
public:
void Run(const std::string& testName, TestRunnerCallback fn)
{
m_cases[testName] = fn;
}
template<typename T, typename B>
inline void Equals(const T& a, const B& b, const std::string& message)
{
if (!(a == b))
{
m_failReason.emplace_back(message);
}
}
inline void IsTrue(bool condition, const std::string& message)
{
if (!condition)
{
m_failReason.emplace_back(message);
}
}
inline void IsFalse(bool condition, const std::string& message)
{
if (condition)
{
m_failReason.emplace_back(message);
}
}
inline void IsNull(const void* ptr, const std::string& message)
{
if (ptr != nullptr)
{
m_failReason.emplace_back(message);
}
}
inline void IsNotNull(const void* ptr, const std::string& message)
{
if (ptr == nullptr)
{
m_failReason.emplace_back(message);
}
}
inline void Fail(const std::string& message)
{
m_failReason.emplace_back(message);
}
void BeforeEach(const TestBeforeCallback& fn)
{
m_beforeEach = fn;
}
void AfterEach(const TestBeforeCallback& fn)
{
m_afterEach = fn;
}
void Before(const TestBeforeCallback& fn)
{
m_before = fn;
}
void After(const TestBeforeCallback& fn)
{
m_after = fn;
}
void ClearFailures()
{
m_failReason.clear();
}
friend class MiniTest;
};
using TestCaseCallback = std::function<void(TestCase&)>;
class MiniTest
{
private:
inline static std::map<std::string, TestCaseCallback> m_cases;
inline static TestBeforeCallback m_beforeEach;
public:
static void Case(const std::string& caseName, const TestCaseCallback& fn)
{
m_cases[caseName] = fn;
}
static void BeforeEach(const TestBeforeCallback& fn)
{
m_beforeEach = fn;
}
static int Run()
{
int failedCount = 0;
int totalTests = 0;
for (auto& c : m_cases)
{
const std::string& suiteName = c.first;
const TestCaseCallback& suiteCallback = c.second;
std::cout << "\n[Suite]: " << suiteName << std::endl;
TestCase testCase;
suiteCallback(testCase);
if (testCase.m_before)
{
testCase.m_before();
}
for (auto& cc : testCase.m_cases)
{
const std::string& testName = cc.first;
const TestRunnerCallback& testFn = cc.second;
totalTests++;
testCase.ClearFailures();
if (m_beforeEach)
{
m_beforeEach();
}
if (testCase.m_beforeEach)
{
testCase.m_beforeEach();
}
try
{
std::cout << "\033[33m" << " [Run]: " << "\033[0m" << testName << " ";
testFn(testCase);
if (!testCase.m_failReason.empty())
{
failedCount++;
std::cout << "\033[31m" << " [Failed]" << "\033[0m" << std::endl;
for (const auto& reason : testCase.m_failReason)
{
std::cerr << " - " << reason << std::endl;
}
}
else
{
std::cout << "\033[32m" << " [Passed]" << "\033[0m" << std::endl;
}
}
catch (const std::exception& ex)
{
std::cout << " [Error]: " << ex.what() << std::endl;
failedCount++;
}
catch (...)
{
failedCount++;
std::cerr << " [Error]: <unknown>" << std::endl;
}
if (testCase.m_afterEach)
{
testCase.m_afterEach();
}
}
if (testCase.m_after)
{
testCase.m_after();
}
}
std::cout << "\n========================================" << std::endl;
std::cout << "Total Tests: " << totalTests << std::endl;
std::cout << "Passed: " << (totalTests - failedCount) << std::endl;
std::cout << "Failed: " << failedCount << std::endl;
std::cout << "========================================" << std::endl;
return failedCount;
}
};