feat(test): major qol improvements
This commit is contained in:
parent
e30965c607
commit
ce569204d2
5 changed files with 137 additions and 93 deletions
|
|
@ -49,6 +49,7 @@ void print_help()
|
||||||
auto main(i32 argc, char **argv) -> i32
|
auto main(i32 argc, char **argv) -> i32
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
lt::log::set_min_severity(lt::log::Level::test);
|
||||||
auto raw_arguments = std::span<char *>(argv, argc);
|
auto raw_arguments = std::span<char *>(argv, argc);
|
||||||
|
|
||||||
auto options = lt::test::Registry::Options {};
|
auto options = lt::test::Registry::Options {};
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@ export void expect_unreachable(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed unreachable expectation:\n"
|
"unreachable reached: {}:{}",
|
||||||
"\tlocation: {}:{}",
|
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
source_location.line()
|
source_location.line()
|
||||||
),
|
),
|
||||||
|
|
@ -48,12 +47,7 @@ export constexpr void expect_throw(
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format("did not throw: {}:{}", source_location.file_name(), source_location.line()),
|
||||||
"Failed throwing expectation:\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
source_location.file_name(),
|
|
||||||
source_location.line()
|
|
||||||
),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,10 +63,7 @@ export constexpr void expect_eq(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed equality expectation:\n"
|
"expect_eq: {} == {} @ {}:{}",
|
||||||
"\tactual: {}\n"
|
|
||||||
"\texpected: {}\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
std::to_underlying<decltype(lhs)>(lhs),
|
std::to_underlying<decltype(lhs)>(lhs),
|
||||||
std::to_underlying<decltype(rhs)>(rhs),
|
std::to_underlying<decltype(rhs)>(rhs),
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
|
|
@ -85,10 +76,7 @@ export constexpr void expect_eq(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed equality expectation:\n"
|
"expect_eq: {} == {} @ {}:{}",
|
||||||
"\tactual: {}\n"
|
|
||||||
"\texpected: {}\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
lhs,
|
lhs,
|
||||||
rhs,
|
rhs,
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
|
|
@ -108,10 +96,47 @@ export constexpr void expect_ne(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed un-equality expectation:\n"
|
"expect_ne: {} != {} @ {}:{}",
|
||||||
"\tactual: {}\n"
|
lhs,
|
||||||
"\texpected: {}\n"
|
rhs,
|
||||||
"\tlocation: {}:{}",
|
source_location.file_name(),
|
||||||
|
source_location.line()
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export constexpr void expect_le(
|
||||||
|
Testable auto lhs,
|
||||||
|
Testable auto rhs,
|
||||||
|
std::source_location source_location = std::source_location::current()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (lhs > rhs)
|
||||||
|
{
|
||||||
|
throw std::runtime_error {
|
||||||
|
std::format(
|
||||||
|
"expect_le: {} <= {} @ {}:{}",
|
||||||
|
lhs,
|
||||||
|
rhs,
|
||||||
|
source_location.file_name(),
|
||||||
|
source_location.line()
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export constexpr void expect_ge(
|
||||||
|
Testable auto lhs,
|
||||||
|
Testable auto rhs,
|
||||||
|
std::source_location source_location = std::source_location::current()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (lhs < rhs)
|
||||||
|
{
|
||||||
|
throw std::runtime_error {
|
||||||
|
std::format(
|
||||||
|
"expect_ge: {} >= {} @ {}:{}",
|
||||||
lhs,
|
lhs,
|
||||||
rhs,
|
rhs,
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
|
|
@ -130,10 +155,7 @@ export constexpr void expect_true(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed true expectation:\n"
|
"expect_true: {} @ {}:{}",
|
||||||
"\tactual: {}\n"
|
|
||||||
"\texpected: true\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
expression,
|
expression,
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
source_location.line()
|
source_location.line()
|
||||||
|
|
@ -151,10 +173,7 @@ export constexpr void expect_false(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed false expectation:\n"
|
"expect_false: {} @ {}:{}",
|
||||||
"\tactual: {}\n"
|
|
||||||
"\texpected: true\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
expression,
|
expression,
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
source_location.line()
|
source_location.line()
|
||||||
|
|
@ -172,34 +191,7 @@ export constexpr void expect_not_nullptr(
|
||||||
{
|
{
|
||||||
throw std::runtime_error {
|
throw std::runtime_error {
|
||||||
std::format(
|
std::format(
|
||||||
"Failed true expectation:\n"
|
"expect_not_nullptr: @ {}:{}",
|
||||||
"\tactual: nullptr\n"
|
|
||||||
"\texpected: not nullptr\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
source_location.file_name(),
|
|
||||||
source_location.line()
|
|
||||||
),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export constexpr void expect_le(
|
|
||||||
Testable auto lhs,
|
|
||||||
Testable auto rhs,
|
|
||||||
std::source_location source_location = std::source_location::current()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (lhs > rhs)
|
|
||||||
{
|
|
||||||
throw std::runtime_error {
|
|
||||||
std::format(
|
|
||||||
"Failed false expectation:\n"
|
|
||||||
"\tactual: {}\n"
|
|
||||||
"\texpected: >= {}\n"
|
|
||||||
"\tlocation: {}:{}",
|
|
||||||
lhs,
|
|
||||||
rhs,
|
|
||||||
source_location.file_name(),
|
source_location.file_name(),
|
||||||
source_location.line()
|
source_location.line()
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
export module test.registry;
|
export module test.registry;
|
||||||
|
|
||||||
|
import logger;
|
||||||
import preliminary;
|
import preliminary;
|
||||||
import test.expects;
|
import test.expects;
|
||||||
|
|
||||||
|
|
@ -204,17 +205,17 @@ namespace lt::test {
|
||||||
++instance().m_failed_case_count;
|
++instance().m_failed_case_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] /* static */ auto Registry::should_return_on_failure() -> bool
|
/* static */ [[nodiscard]] auto Registry::should_return_on_failure() -> bool
|
||||||
{
|
{
|
||||||
return instance().m_options.stop_on_fail;
|
return instance().m_options.stop_on_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] /* static */ auto Registry::get_options() -> const Options &
|
/* static */ [[nodiscard]] auto Registry::get_options() -> const Options &
|
||||||
{
|
{
|
||||||
return instance().m_options;
|
return instance().m_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] /* static */ auto Registry::get_case_regex() -> const std::regex &
|
/* static */ [[nodiscard]] auto Registry::get_case_regex() -> const std::regex &
|
||||||
{
|
{
|
||||||
return instance().m_case_regex;
|
return instance().m_case_regex;
|
||||||
}
|
}
|
||||||
|
|
@ -231,6 +232,30 @@ auto Registry::run_all_impl() -> i32
|
||||||
{
|
{
|
||||||
if (std::regex_search(name, regex))
|
if (std::regex_search(name, regex))
|
||||||
{
|
{
|
||||||
|
auto padding_left = std::string {};
|
||||||
|
padding_left.resize((79 - std::strlen(name)) / 2u - 1u);
|
||||||
|
for (auto &ch : padding_left)
|
||||||
|
{
|
||||||
|
ch = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
auto padding_right = std::string {};
|
||||||
|
padding_right.resize((79 - std::strlen(name)) / 2u);
|
||||||
|
if (std::strlen(name) % 2 == 0)
|
||||||
|
{
|
||||||
|
padding_right.resize(padding_right.size() + 1);
|
||||||
|
}
|
||||||
|
for (auto &ch : padding_right)
|
||||||
|
{
|
||||||
|
ch = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
log::test(
|
||||||
|
"\033[1;33m*{}{}{}-*\033[0m",
|
||||||
|
std::string { padding_left },
|
||||||
|
std::string_view { name },
|
||||||
|
std::string { padding_right }
|
||||||
|
);
|
||||||
suite();
|
suite();
|
||||||
increment_matched_suite_count();
|
increment_matched_suite_count();
|
||||||
}
|
}
|
||||||
|
|
@ -245,12 +270,12 @@ auto Registry::run_all_impl() -> i32
|
||||||
{
|
{
|
||||||
if (m_options.stop_on_fail)
|
if (m_options.stop_on_fail)
|
||||||
{
|
{
|
||||||
std::println("Quitting due to options.stop_on_fail == true");
|
log::info("Quitting due to options.stop_on_fail == true");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::println("Uncaught exception when running suite:");
|
log::test("Uncaught exception when running suite:");
|
||||||
std::println("\twhat: {}", exp.what());
|
log::test("\twhat: {}", exp.what());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -259,32 +284,32 @@ auto Registry::run_all_impl() -> i32
|
||||||
{
|
{
|
||||||
case ExecutionPolicy::normal:
|
case ExecutionPolicy::normal:
|
||||||
{
|
{
|
||||||
std::println("[-------STATS------]");
|
// log::test("[-------STATS------]");
|
||||||
|
//
|
||||||
|
// log::test("suites:");
|
||||||
|
// log::test("\ttotal: {}", (i32)m_total_suite_count);
|
||||||
|
// log::test("\tpassed: {}", (i32)m_passed_suite_count);
|
||||||
|
// log::test("\tfailed: {}", (i32)m_failed_suite_count);
|
||||||
|
// log::test("\tmatched: {}", (i32)m_matched_suite_count);
|
||||||
|
// log::test("\tskipped: {}", (i32)m_skipped_suite_count);
|
||||||
|
//
|
||||||
|
// log::test("tests:");
|
||||||
|
// log::test("\ttotal: {}", (i32)m_total_case_count);
|
||||||
|
// log::test("\tpassed: {}", (i32)m_passed_case_count);
|
||||||
|
// log::test("\tfailed: {}", (i32)m_failed_case_count);
|
||||||
|
// log::test("\tmatched: {}", (i32)m_matched_case_count);
|
||||||
|
// log::test("\tskipped: {}", (i32)m_skipped_case_count);
|
||||||
|
|
||||||
std::println("suites:");
|
// log::test("________________________________________________________________");
|
||||||
std::println("\ttotal: {}", m_total_suite_count);
|
|
||||||
std::println("\tpassed: {}", m_passed_suite_count);
|
|
||||||
std::println("\tfailed: {}", m_failed_suite_count);
|
|
||||||
std::println("\tmatched: {}", m_matched_suite_count);
|
|
||||||
std::println("\tskipped: {}", m_skipped_suite_count);
|
|
||||||
|
|
||||||
std::println("tests:");
|
|
||||||
std::println("\ttotal: {}", m_total_case_count);
|
|
||||||
std::println("\tpassed: {}", m_passed_case_count);
|
|
||||||
std::println("\tfailed: {}", m_failed_case_count);
|
|
||||||
std::println("\tmatched: {}", m_matched_case_count);
|
|
||||||
std::println("\tskipped: {}", m_skipped_case_count);
|
|
||||||
|
|
||||||
std::println("________________________________________________________________");
|
|
||||||
|
|
||||||
return m_failed_case_count;
|
return m_failed_case_count;
|
||||||
}
|
}
|
||||||
case ExecutionPolicy::stats:
|
case ExecutionPolicy::stats:
|
||||||
{
|
{
|
||||||
std::println("[-------STATS------]");
|
log::test("[-------STATS------]");
|
||||||
std::println("Total suite count: {}", m_total_suite_count);
|
log::test("Total suite count: {}", (i32)m_total_suite_count);
|
||||||
std::println("Total test count: {}", m_total_case_count);
|
log::test("Total test count: {}", (i32)m_total_case_count);
|
||||||
std::println("________________________________________________________________");
|
log::test("________________________________________________________________");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -295,12 +320,12 @@ auto Registry::run_all_impl() -> i32
|
||||||
|
|
||||||
void Registry::print_options()
|
void Registry::print_options()
|
||||||
{
|
{
|
||||||
std::println("stop-on-failure: {}", m_options.stop_on_fail);
|
// log::info("stop-on-failure: {}", static_cast<bool>(m_options.stop_on_fail));
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry::Registry()
|
Registry::Registry()
|
||||||
{
|
{
|
||||||
std::println("________________________________________________________________");
|
// log::info("________________________________________________________________");
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] /* static */ auto Registry::instance() -> Registry &
|
[[nodiscard]] /* static */ auto Registry::instance() -> Registry &
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ export module test.test;
|
||||||
import test.expects;
|
import test.expects;
|
||||||
import test.registry;
|
import test.registry;
|
||||||
import preliminary;
|
import preliminary;
|
||||||
|
import logger;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
// ----------* INTERFACE *--------- //
|
// ----------* INTERFACE *--------- //
|
||||||
|
|
@ -12,7 +14,7 @@ namespace lt::test {
|
||||||
class TestCase
|
class TestCase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestCase(std::string_view name);
|
TestCase(std::string name);
|
||||||
|
|
||||||
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
// NOLINTNEXTLINE(misc-unconventional-assign-operator)
|
||||||
auto operator=(std::invocable auto test) const -> void;
|
auto operator=(std::invocable auto test) const -> void;
|
||||||
|
|
@ -21,7 +23,7 @@ private:
|
||||||
void run_normal(std::invocable auto test) const;
|
void run_normal(std::invocable auto test) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string_view m_name;
|
std::string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TestSuite
|
struct TestSuite
|
||||||
|
|
@ -68,16 +70,26 @@ void TestCase::run_normal(std::invocable auto test) const
|
||||||
}
|
}
|
||||||
Registry::increment_matched_case_count();
|
Registry::increment_matched_case_count();
|
||||||
|
|
||||||
std::println("[Running-----------] --> ");
|
auto padding = std::string {};
|
||||||
std::println("{}", m_name);
|
padding.resize(79 - m_name.size());
|
||||||
|
for (auto &ch : padding)
|
||||||
|
{
|
||||||
|
ch = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
test();
|
test();
|
||||||
}
|
}
|
||||||
catch (const std::exception &exp)
|
catch (const std::exception &exp)
|
||||||
{
|
{
|
||||||
std::println("{}", exp.what());
|
log::test(
|
||||||
std::println("[-----------FAIL !!]");
|
"\033[1;31m{}{} | {}\033[0m",
|
||||||
|
std::string_view { m_name },
|
||||||
|
std::string { padding },
|
||||||
|
std::string { exp.what() }
|
||||||
|
);
|
||||||
|
|
||||||
Registry::increment_failed_case_count();
|
Registry::increment_failed_case_count();
|
||||||
|
|
||||||
if (Registry::should_return_on_failure())
|
if (Registry::should_return_on_failure())
|
||||||
|
|
@ -89,7 +101,9 @@ void TestCase::run_normal(std::invocable auto test) const
|
||||||
}
|
}
|
||||||
|
|
||||||
Registry::increment_passed_case_count();
|
Registry::increment_passed_case_count();
|
||||||
std::println("[--------SUCCESS :D]");
|
|
||||||
|
|
||||||
|
log::test("{}{} | \033[1;32mpass\033[0m", std::string_view { m_name }, std::string { padding });
|
||||||
}
|
}
|
||||||
|
|
||||||
TestSuite::TestSuite(auto body)
|
TestSuite::TestSuite(auto body)
|
||||||
|
|
@ -123,8 +137,13 @@ auto operator""_suite(const char *name, size_t size) -> TestSuite
|
||||||
module :private;
|
module :private;
|
||||||
namespace lt::test {
|
namespace lt::test {
|
||||||
|
|
||||||
TestCase::TestCase(std::string_view name): m_name(name)
|
TestCase::TestCase(std::string name): m_name(name)
|
||||||
{
|
{
|
||||||
|
if (m_name.size() > 79u)
|
||||||
|
{
|
||||||
|
m_name.resize(79u - 3);
|
||||||
|
m_name.append("...");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lt::test
|
} // namespace lt::test
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,14 @@
|
||||||
import test;
|
import test;
|
||||||
|
|
||||||
Suite expects = "expects"_suite = []() {
|
Suite expects = "expects"_suite = []() {
|
||||||
Case { "" } = [] {
|
// should be truncated...
|
||||||
|
Case { "berryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy "
|
||||||
|
"long name" }
|
||||||
|
= [] {
|
||||||
|
};
|
||||||
|
|
||||||
|
Case { "this emptiness machine" } = [] {
|
||||||
|
expect_le(9, 6);
|
||||||
};
|
};
|
||||||
|
|
||||||
Case { "expect_unreachable" } = [] {
|
Case { "expect_unreachable" } = [] {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue