2025-07-15 15:10:25 +03:30
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <concepts>
|
|
|
|
#include <test/expects.hpp>
|
|
|
|
|
|
|
|
namespace lt::test {
|
|
|
|
|
|
|
|
namespace details {
|
|
|
|
|
|
|
|
class Registry
|
|
|
|
{
|
|
|
|
public:
|
2025-07-30 23:02:53 +03:30
|
|
|
using FuzzFunction = int32_t (*)(const uint8_t *, size_t);
|
|
|
|
using SuiteFunction = void (*)();
|
2025-07-15 15:10:25 +03:30
|
|
|
|
2025-07-30 23:02:53 +03:30
|
|
|
static void register_suite(SuiteFunction suite)
|
2025-07-15 15:10:25 +03:30
|
|
|
{
|
|
|
|
instance().m_suites.emplace_back(suite);
|
|
|
|
}
|
|
|
|
|
2025-07-30 23:02:53 +03:30
|
|
|
static void register_fuzz_harness(FuzzFunction suite)
|
|
|
|
{
|
|
|
|
if (instance().m_fuzz_harness)
|
|
|
|
{
|
|
|
|
throw std::logic_error {
|
|
|
|
"Attempting to register fuzz harness while one is already registered",
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
instance().m_fuzz_harness = suite;
|
|
|
|
}
|
|
|
|
|
2025-07-16 12:44:58 +03:30
|
|
|
static auto run_all() -> int32_t
|
2025-07-15 15:10:25 +03:30
|
|
|
{
|
|
|
|
for (auto &test : instance().m_suites)
|
|
|
|
{
|
|
|
|
test();
|
|
|
|
}
|
2025-07-16 12:44:58 +03:30
|
|
|
|
|
|
|
std::cout << "Ran " << instance().m_failed_count + instance().m_pasesed_count << " tests:\n"
|
2025-07-16 13:18:08 +03:30
|
|
|
<< "\tpassed: " << instance().m_pasesed_count << '\n'
|
|
|
|
<< "\tfailed: " << instance().m_failed_count << '\n';
|
2025-07-27 22:52:38 +03:30
|
|
|
std::cout << "________________________________________________________________\n\n\n";
|
2025-07-16 12:44:58 +03:30
|
|
|
|
|
|
|
return instance().m_failed_count;
|
|
|
|
}
|
|
|
|
|
2025-07-30 23:02:53 +03:30
|
|
|
static auto process_fuzz_input(const uint8_t *data, size_t size) -> int32_t
|
|
|
|
{
|
|
|
|
if (!instance().m_fuzz_harness)
|
|
|
|
{
|
|
|
|
throw std::logic_error {
|
|
|
|
"Attempting to process fuzz input with no active harness",
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return instance().m_fuzz_harness(data, size);
|
|
|
|
}
|
|
|
|
|
2025-07-16 12:44:58 +03:30
|
|
|
static void increment_passed_count()
|
|
|
|
{
|
|
|
|
++instance().m_pasesed_count;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void increment_failed_count()
|
|
|
|
{
|
|
|
|
++instance().m_failed_count;
|
2025-07-15 15:10:25 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2025-07-27 22:52:38 +03:30
|
|
|
Registry()
|
|
|
|
{
|
|
|
|
std::cout << "________________________________________________________________\n";
|
|
|
|
}
|
2025-07-15 15:10:25 +03:30
|
|
|
|
|
|
|
[[nodiscard]] static auto instance() -> Registry &
|
|
|
|
{
|
|
|
|
static auto registry = Registry {};
|
|
|
|
return registry;
|
|
|
|
}
|
|
|
|
|
2025-07-30 23:02:53 +03:30
|
|
|
std::vector<SuiteFunction> m_suites;
|
|
|
|
|
|
|
|
FuzzFunction m_fuzz_harness {};
|
2025-07-16 12:44:58 +03:30
|
|
|
|
|
|
|
int32_t m_pasesed_count {};
|
|
|
|
int32_t m_failed_count {};
|
2025-07-15 15:10:25 +03:30
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // namespace details
|
|
|
|
|
2025-07-16 12:44:58 +03:30
|
|
|
struct Case
|
|
|
|
{
|
|
|
|
auto operator=(std::invocable auto test) -> void // NOLINT
|
|
|
|
{
|
2025-07-28 20:45:24 +03:30
|
|
|
std::cout << "[Running-----------] --> ";
|
2025-07-30 23:02:53 +03:30
|
|
|
std::cout << name << '\n';
|
2025-07-16 12:44:58 +03:30
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
test();
|
|
|
|
}
|
|
|
|
catch (const std::exception &exp)
|
|
|
|
{
|
2025-07-28 20:45:24 +03:30
|
|
|
std::cout << exp.what() << "\n";
|
|
|
|
std::cout << "[-----------FAIL !!]" << "\n\n";
|
2025-07-16 12:44:58 +03:30
|
|
|
details::Registry::increment_failed_count();
|
|
|
|
return; // TODO(Light): Should we run the remaining tests after a failure?
|
|
|
|
}
|
|
|
|
|
2025-07-16 13:18:08 +03:30
|
|
|
details::Registry::increment_passed_count();
|
2025-07-28 20:45:24 +03:30
|
|
|
std::cout << "[--------SUCCESS :D]" << "\n\n";
|
2025-07-16 12:44:58 +03:30
|
|
|
}
|
|
|
|
|
|
|
|
std::string_view name;
|
|
|
|
};
|
|
|
|
|
2025-07-15 15:10:25 +03:30
|
|
|
struct TestSuite
|
|
|
|
{
|
|
|
|
template<class TSuite>
|
|
|
|
constexpr TestSuite(TSuite suite)
|
|
|
|
{
|
|
|
|
#ifndef LIGHT_SKIP_TESTS
|
|
|
|
details::Registry::register_suite(+suite);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2025-07-30 23:02:53 +03:30
|
|
|
struct TestFuzzHarness
|
|
|
|
{
|
|
|
|
template<class TestFuzzHarness>
|
|
|
|
constexpr TestFuzzHarness(TestFuzzHarness suite)
|
|
|
|
{
|
|
|
|
#ifndef LIGHT_SKIP_FUZZ_TESTS
|
|
|
|
details::Registry::register_fuzz_harness(+suite);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2025-07-15 15:10:25 +03:30
|
|
|
using Suite = const TestSuite;
|
2025-07-30 23:02:53 +03:30
|
|
|
using FuzzHarness = const TestFuzzHarness;
|
2025-07-15 15:10:25 +03:30
|
|
|
|
|
|
|
} // namespace lt::test
|