From e1f9d9ca1ef3c69da3b887b0af298be0aea4a5f9 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Wed, 23 Oct 2024 00:20:05 +0200 Subject: More work on testing framework --- .bazelrc | 2 +- MODULE.bazel.lock | 12 ++++---- asl/format.cpp | 5 ++++ asl/format.hpp | 2 ++ asl/testing/testing.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++---- asl/testing/testing.hpp | 35 +++++++++++++++++++---- asl/tests/option_tests.cpp | 27 +++++++++++++++++- asl/utility.hpp | 2 +- 8 files changed, 135 insertions(+), 21 deletions(-) diff --git a/.bazelrc b/.bazelrc index 5a043b0..9a745cb 100644 --- a/.bazelrc +++ b/.bazelrc @@ -17,4 +17,4 @@ build --cxxopt=-Wno-extra-semi-stmt build --cxxopt=-Wno-extra-semi build --cxxopt=-Wno-global-constructors -test --test_output=errors +test --test_output=all diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 21b358e..d62a47c 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -64,19 +64,19 @@ "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": { "general": { "bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=", - "usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=", + "usagesDigest": "+hz7IHWN6A1oVJJWNDB6yZRG+RYhF76wAYItpAeIUIg=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, "generatedRepoSpecs": { - "local_config_apple_cc": { + "local_config_apple_cc_toolchains": { "bzlFile": "@@apple_support~//crosstool:setup.bzl", - "ruleClassName": "_apple_cc_autoconf", + "ruleClassName": "_apple_cc_autoconf_toolchains", "attributes": {} }, - "local_config_apple_cc_toolchains": { + "local_config_apple_cc": { "bzlFile": "@@apple_support~//crosstool:setup.bzl", - "ruleClassName": "_apple_cc_autoconf_toolchains", + "ruleClassName": "_apple_cc_autoconf", "attributes": {} } }, @@ -92,7 +92,7 @@ "@@platforms//host:extension.bzl%host_platform": { "general": { "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=", - "usagesDigest": "meSzxn3DUCcYEhq4HQwExWkWtU4EjriRBQLsZN+Q0SU=", + "usagesDigest": "pCYpDQmqMbmiiPI1p2Kd3VLm5T48rRAht5WdW0X2GlA=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, diff --git a/asl/format.cpp b/asl/format.cpp index ff565bd..99ad9da 100644 --- a/asl/format.cpp +++ b/asl/format.cpp @@ -70,6 +70,11 @@ void asl::format_internals::format( f.write(begin, fmt - begin); } +void asl::AslFormat(formatter& f, const char* str) +{ + f.write(str, static_cast(__builtin_strlen(str))); +} + void asl::AslFormat(formatter& f, float) { f.write("", 7); // @Todo Float formatting diff --git a/asl/format.hpp b/asl/format.hpp index b4cb439..386a39c 100644 --- a/asl/format.hpp +++ b/asl/format.hpp @@ -81,6 +81,8 @@ void AslFormat(formatter& f, const char (&str)[N]) f.write(str, N - 1); } +void AslFormat(formatter& f, const char* str); + void AslFormat(formatter& f, float); void AslFormat(formatter& f, double); diff --git a/asl/testing/testing.cpp b/asl/testing/testing.cpp index a2fe152..e07cde8 100644 --- a/asl/testing/testing.cpp +++ b/asl/testing/testing.cpp @@ -1,14 +1,73 @@ #include "asl/testing/testing.hpp" -int asl::testing::register_test( - const char* suite_name, - const char* case_name, - TestFunction* fn) +#include + +static asl::testing::Test* g_head = nullptr; +static asl::testing::Test* g_tail = nullptr; + +void asl::testing::register_test(Test* test) { - return 0; + if (g_head == nullptr && g_tail == nullptr) + { + g_head = test; + g_tail = test; + } + else + { + g_tail->m_next = test; + test->m_prev = asl::exchange(g_tail, test); + } +} + +static bool g_current_test_fail = false; + +void asl::testing::report_failure(const char* msg, const char* file, int line) +{ + asl::eprint("--------------------------------------------------------------\n"); + asl::eprint("Test assertion failed at {}, line {}:\n", file, line); + asl::eprint(" {}:\n", msg); + asl::eprint("--------------------------------------------------------------\n"); + g_current_test_fail = true; } -int main(int argc, char* argv[]) +#define RESET "\x1b[0m" +#define RED "\x1b[0;31m" +#define GREEN "\x1b[0;32m" + +int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) { + int fail = 0; + int pass = 0; + + for (auto* it = g_head; it != nullptr; it = it->m_next) + { + asl::eprint(GREEN "[ RUN ]" RESET " {}\n", it->m_case_name); + + g_current_test_fail = false; + it->m_fn(); + + if (!g_current_test_fail) + { + asl::eprint(GREEN "[ OK ]" RESET " {}\n", it->m_case_name); + pass += 1; + } + else + { + asl::eprint(RED "[ FAILED ]" RESET " {}\n", it->m_case_name); + fail += 1; + } + } + + asl::eprint(GREEN "[----------]" RESET " {} test(s) run\n", fail + pass); + + if (fail == 0) + { + asl::eprint(GREEN "[ PASSED ]" RESET " Good job!\n"); + } + else + { + asl::eprint(RED "[ FAILED ]" RESET " {} test(s) failed\n", fail); + } + return 0; } diff --git a/asl/testing/testing.hpp b/asl/testing/testing.hpp index a489d61..db2a64a 100644 --- a/asl/testing/testing.hpp +++ b/asl/testing/testing.hpp @@ -1,15 +1,38 @@ #pragma once +#include + namespace asl::testing { +struct Test; + +void register_test(Test*); + +void report_failure(const char* msg, const char* file, int line); + using TestFunction = void(); -int register_test(const char* suite_name, const char* case_name, TestFunction* fn); + +struct Test +{ + const char* m_case_name; + TestFunction* m_fn; + Test* m_next{}; + Test* m_prev{}; + + constexpr explicit Test(const char* case_name, TestFunction* fn) + : m_case_name{case_name} + , m_fn{fn} + { + register_test(this); + } +}; } // namespace asl::testing -#define ASL_TEST(SUITE, CASE) \ - static void asl_test_fn_##SUITE##_##CASE(); \ - static const int asl_test_##SUITE##_##CASE = ::asl::testing::register_test( \ - #SUITE, #CASE, asl_test_fn_##SUITE##_##CASE); \ - void asl_test_fn_##SUITE##_##CASE() +#define ASL_TEST(CASE) \ + static void asl_test_fn_##CASE(); \ + static ::asl::testing::Test asl_test_##CASE( \ + #CASE, \ + asl_test_fn_##CASE); \ + void asl_test_fn_##CASE() diff --git a/asl/tests/option_tests.cpp b/asl/tests/option_tests.cpp index 7de1f9c..a42592a 100644 --- a/asl/tests/option_tests.cpp +++ b/asl/tests/option_tests.cpp @@ -24,7 +24,32 @@ static_assert(asl::move_assignable>); static_assert(asl::move_assignable>); static_assert(!asl::move_assignable>); -ASL_TEST(Option, cheese) +ASL_TEST(Option_cheese) +{ + asl::option a; + asl::option b; + + a = ASL_MOVE(b); +} + +ASL_TEST(Option_cheese2) +{ + asl::option a; + asl::option b; + + a = ASL_MOVE(b); +} + +ASL_TEST(Option_cheese3) +{ + asl::option a; + asl::option b; + + a = ASL_MOVE(b); + asl::testing::report_failure("OH NO", __FILE__, __LINE__); +} + +ASL_TEST(Option_cheese4) { asl::option a; asl::option b; diff --git a/asl/utility.hpp b/asl/utility.hpp index 2d9ef05..d54d965 100644 --- a/asl/utility.hpp +++ b/asl/utility.hpp @@ -14,7 +14,7 @@ template T exchange(T& obj, U&& new_value) { T old_value = ASL_MOVE(obj); - obj = ASL_FORWARD(new_value); + obj = ASL_FWD(new_value); return old_value; } -- cgit