feat(test): add option parsing && the --stop-on-fail & -h options
This commit is contained in:
parent
cce627a350
commit
723ade84ea
2 changed files with 93 additions and 9 deletions
|
@ -1,15 +1,59 @@
|
||||||
#include <test/test.hpp>
|
#include <test/test.hpp>
|
||||||
|
|
||||||
auto main() -> int32_t
|
using namespace ::lt::test;
|
||||||
|
using namespace ::lt::test::details;
|
||||||
|
|
||||||
|
void parse_option(std::string_view option, Registry::Options &options)
|
||||||
|
{
|
||||||
|
if (option == "--stop-on-fail")
|
||||||
|
{
|
||||||
|
options.stop_on_fail = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw std::invalid_argument { std::format("Invalid argument: {}", option) };
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_help()
|
||||||
|
{
|
||||||
|
std::println("Options: ");
|
||||||
|
std::println("--stop-on-fail --> Stops executing the remaining tests on first failure");
|
||||||
|
std::println("--stats --> Print statistics about the tests without running any");
|
||||||
|
std::println("--help | -h --> ~You just used it! :D");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto main(int32_t argc, char **argv) -> int32_t
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using namespace ::lt::test;
|
auto raw_arguments = std::span<char *>(argv, argc);
|
||||||
using namespace ::lt::test::details;
|
|
||||||
|
|
||||||
return Registry::run_all();
|
auto options = Registry::Options {};
|
||||||
|
for (auto idx = 0; auto &raw_argument : raw_arguments)
|
||||||
|
{
|
||||||
|
// First argument is the "cwd'
|
||||||
|
if (idx++ == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto argument = std::string_view(raw_argument);
|
||||||
|
|
||||||
|
if (argument == "-h" || argument == "--help")
|
||||||
|
{
|
||||||
|
print_help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argument.starts_with("--") || argument.starts_with("-"))
|
||||||
|
{
|
||||||
|
parse_option(argument, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Registry::run_all(options);
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
catch (const std::exception &exp)
|
||||||
{
|
{
|
||||||
std::cout << "Terminated after uncaught exception:\n"; // NOLINT
|
std::cout << "Terminated after uncaught exception:\n";
|
||||||
std::cout << "exception.what: " << exp.what();
|
std::cout << "exception.what: " << exp.what();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,11 @@ namespace details {
|
||||||
class Registry
|
class Registry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
struct Options
|
||||||
|
{
|
||||||
|
bool stop_on_fail = false;
|
||||||
|
};
|
||||||
|
|
||||||
using FuzzFunction = int32_t (*)(const uint8_t *, size_t);
|
using FuzzFunction = int32_t (*)(const uint8_t *, size_t);
|
||||||
using SuiteFunction = void (*)();
|
using SuiteFunction = void (*)();
|
||||||
|
|
||||||
|
@ -30,11 +35,29 @@ public:
|
||||||
instance().m_fuzz_harness = suite;
|
instance().m_fuzz_harness = suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
static auto run_all() -> int32_t
|
static auto run_all(Options options) -> int32_t
|
||||||
{
|
{
|
||||||
|
instance().m_options = options;
|
||||||
|
instance().print_options();
|
||||||
|
|
||||||
for (auto &test : instance().m_suites)
|
for (auto &test : instance().m_suites)
|
||||||
{
|
{
|
||||||
test();
|
try
|
||||||
|
{
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
catch (const std::exception &exp)
|
||||||
|
{
|
||||||
|
if (options.stop_on_fail)
|
||||||
|
{
|
||||||
|
std::println("Quitting due to options.stop_on_fail == true");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::println("Uncaught exception when running suite:");
|
||||||
|
std::println("\twhat: {}", exp.what());
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Ran " << instance().m_failed_count + instance().m_pasesed_count << " tests:\n"
|
std::cout << "Ran " << instance().m_failed_count + instance().m_pasesed_count << " tests:\n"
|
||||||
|
@ -67,7 +90,17 @@ public:
|
||||||
++instance().m_failed_count;
|
++instance().m_failed_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static auto should_return_on_failure() -> bool
|
||||||
|
{
|
||||||
|
return instance().m_options.stop_on_fail;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void print_options()
|
||||||
|
{
|
||||||
|
std::println("stop-on-failure: {}", m_options.stop_on_fail);
|
||||||
|
}
|
||||||
|
|
||||||
Registry()
|
Registry()
|
||||||
{
|
{
|
||||||
std::cout << "________________________________________________________________\n";
|
std::cout << "________________________________________________________________\n";
|
||||||
|
@ -79,6 +112,8 @@ private:
|
||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Options m_options {};
|
||||||
|
|
||||||
std::vector<SuiteFunction> m_suites;
|
std::vector<SuiteFunction> m_suites;
|
||||||
|
|
||||||
FuzzFunction m_fuzz_harness {};
|
FuzzFunction m_fuzz_harness {};
|
||||||
|
@ -92,7 +127,8 @@ private:
|
||||||
|
|
||||||
struct Case
|
struct Case
|
||||||
{
|
{
|
||||||
auto operator=(std::invocable auto test) -> void // NOLINT
|
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
||||||
|
auto operator=(std::invocable auto test) -> void
|
||||||
{
|
{
|
||||||
std::cout << "[Running-----------] --> ";
|
std::cout << "[Running-----------] --> ";
|
||||||
std::cout << name << '\n';
|
std::cout << name << '\n';
|
||||||
|
@ -106,7 +142,11 @@ struct Case
|
||||||
std::cout << exp.what() << "\n";
|
std::cout << exp.what() << "\n";
|
||||||
std::cout << "[-----------FAIL !!]" << "\n\n";
|
std::cout << "[-----------FAIL !!]" << "\n\n";
|
||||||
details::Registry::increment_failed_count();
|
details::Registry::increment_failed_count();
|
||||||
return; // TODO(Light): Should we run the remaining tests after a failure?
|
|
||||||
|
if (details::Registry::should_return_on_failure())
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
details::Registry::increment_passed_count();
|
details::Registry::increment_passed_count();
|
||||||
|
|
Loading…
Add table
Reference in a new issue