From 8f722d690802b3a523a74bc924ed44ba1b1acbbd Mon Sep 17 00:00:00 2001 From: cyborg1811m Date: Mon, 22 Apr 2024 11:24:40 +0200 Subject: [PATCH] implemented test_suite --- test/CMakeLists.txt | 3 + test/common_helper/test_define_test.hpp | 151 +++++++++++++----- .../const_vector_constructor.test.cpp | 54 +++---- 3 files changed, 138 insertions(+), 70 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 022643b..6d3216b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,7 +1,10 @@ cmake_minimum_required(VERSION 3.26) +set(CMAKE_CXX_STANDARD 23) + add_library(test_common INTERFACE) target_include_directories(test_common INTERFACE common_helper) target_link_libraries(test_common INTERFACE const_container) +target_compile_options(test_common INTERFACE -fconcepts-diagnostics-depth=2) # for debugging add_subdirectory(const_vector) diff --git a/test/common_helper/test_define_test.hpp b/test/common_helper/test_define_test.hpp index 270ea1f..2fde5d4 100644 --- a/test/common_helper/test_define_test.hpp +++ b/test/common_helper/test_define_test.hpp @@ -5,75 +5,140 @@ #ifndef CONST_CONTAINER_TEST_DEFINE_TEST_HPP_ #define CONST_CONTAINER_TEST_DEFINE_TEST_HPP_ +#include #include #include +#include +#include #include #include "test_ret_val.h" +#include "CompileOptional.h" -template -struct test_def_base { - using FuncType = Func; - - const char *name; - Func func; - - constexpr test_def_base(const char * name, Func func) : name(name), func(func) {} - - virtual constexpr std::invoke_result_t operator()() { return std::apply(func, std::make_tuple()); } +template +struct quick_test_def; + +enum class EvalFlag { RUNTIME, CONSTEVAL, RUNTIME_CONSTEVAL }; + +class test_definition { + public: + [[nodiscard]] virtual constexpr ret_val_s evaluate() const = 0; + + [[nodiscard]] virtual const char *name() const = 0; + [[nodiscard]] virtual EvalFlag evalFlag() const = 0; + [[nodiscard]] virtual const ret_val_s &c_res() const = 0; }; template -struct test_definition : public test_def_base { - using base = test_def_base; - static constexpr std::size_t ARG_SIZE = sizeof...(Args); +class test_definition_impl : public test_definition { + public: + using FuncType = Func; + static constexpr std::size_t ARG_SIZE = sizeof...(Args); - std::tuple args; + constexpr test_definition_impl(const char *name, Func func, EvalFlag evalFlag, Args ...args) + : _name(name), _func(func), _evalFlag(evalFlag), _args(std::make_tuple(std::forward(args)...)), + _c_res(_name, ReturnCode::FAILED, "Could not be evaluated at compile time") { + if consteval { + if (evalFlag == EvalFlag::RUNTIME_CONSTEVAL || evalFlag == EvalFlag::CONSTEVAL) { + _c_res = evaluate(); + } + } + } - constexpr test_definition(const char *name, Func func, Args ...args) - : test_def_base(name, func), args(std::make_tuple(args...)) {} - - constexpr std::invoke_result_t operator()() override { return std::apply(base::func, args); } -}; + [[nodiscard]] constexpr ret_val_s evaluate() const override { return std::apply(_func, _args); } + [[nodiscard]] const char *name() const override { return _name; } + [[nodiscard]] EvalFlag evalFlag() const override { return _evalFlag; } + [[nodiscard]] const ret_val_s &c_res() const override{ return _c_res; } -struct test_suite_base { - const char *name; + private: + const char *_name; + EvalFlag _evalFlag; + Func _func; + std::tuple _args; + ret_val_s _c_res; }; template - requires (sizeof...(TestDefs) == 0 || (std::derived_from> && ...)) -struct test_suite : public test_suite_base { - - static constexpr std::size_t TEST_NR = sizeof...(TestDefs); - - std::tuple tests; - - constexpr test_suite(const char *name, std::tuple tests) : test_suite_base(name), tests(tests) {} - - constexpr ret_val run() { + requires (sizeof...(TestDefs) == 0 || (std::derived_from && ...)) +class test_suite { + + public: + static constexpr std::size_t TEST_NR = sizeof...(TestDefs); + + constexpr test_suite(const char *name, std::tuple tests) : _name(name), _tests(tests) {} - std::vector v; - std::apply([&v](auto&& ...args) { ((v.push_back(args())), ...); }, tests); - - ret_val ret = { name }; - std::ranges::move(v, ret.vals.begin()); - - return ret; - } + int run() const { + + auto test_arr = expand_test_tuple(_tests, std::make_index_sequence()); + + std::cout << test_arr.size() << "\n"; + + std::cout << "--------------\n"; + + for (auto [i, test_ref] : std::ranges::views::enumerate(test_arr)) { + const auto& test = test_ref.get(); + + std::cout << "Running Test: \"" << test.name() << "\"\n"; + if (test.evalFlag() == EvalFlag::RUNTIME || test.evalFlag() == EvalFlag::RUNTIME_CONSTEVAL) { + ret_val_s ret; + std::string ret_exc_str; + try { + ret = test.evaluate(); + } catch (std::exception& e) { + ret_exc_str = e.what(); + ret = ret_val_s(test.name(), ReturnCode::FAILED, ret_exc_str.c_str()); + } + + std::cout << "Result of Runtime Evaluation of Test \"" << ret.test_name << "\" (number: " << i + << "): " + << (ret.val == ReturnCode::PASSED ? "PASSED" : "FAILED") << "\n" + << "\t" << ret.msg << "\n"; + } + + if (test.evalFlag() == EvalFlag::CONSTEVAL || test.evalFlag() == EvalFlag::RUNTIME_CONSTEVAL) { + const ret_val_s& ret = test.c_res(); + std::cout << "Result of Consteval Evaluation of Test \"" << ret.test_name << "\" (number: " << i + << "): " + << (ret.val == ReturnCode::PASSED ? "PASSED" : "FAILED") << "\n" + << "\t" << ret.msg << "\n"; + } + } + + return 0; + } + + private: + const char *_name; + std::tuple _tests; + + template + static constexpr auto expand_test_tuple(const auto &tests, std::index_sequence) { + return std::array { + std::reference_wrapper( + dynamic_cast(std::get(tests)) + )... }; + } + + friend class quick_test_def>; }; template struct quick_test_def { Suite current; - + template constexpr auto operator()(const char *name, Func func, Args... args) { - auto test = test_definition(name, func, args...); - auto new_suite = test_suite(current.name, std::tuple_cat(current.tests, std::make_tuple(test))); + return operator()(name, func, EvalFlag::RUNTIME, std::forward(args)...); + } + + template + constexpr auto operator()(const char *name, Func func, EvalFlag evalFlag, Args... args) { + auto test = test_definition_impl(name, func, evalFlag, args...); + auto new_suite = test_suite(current._name, std::tuple_cat(current._tests, std::make_tuple(test))); return quick_test_def { new_suite }; } - + constexpr operator Suite() { return current; } diff --git a/test/const_vector/const_vector_constructor.test.cpp b/test/const_vector/const_vector_constructor.test.cpp index 869b19f..f10a8bd 100644 --- a/test/const_vector/const_vector_constructor.test.cpp +++ b/test/const_vector/const_vector_constructor.test.cpp @@ -1,40 +1,40 @@ -#include -#include - #include #include "test_define_test.hpp" #include "test_util.hpp" #include "test_ret_val.h" -test_suite tests = define_tests("Tests") - ("Test1", [](){ +constexpr test_suite tests = define_tests("Tests") + ("Test Runtime", [](int = 1) constexpr{ - return TEST_PASS("Test1", "PASS"); - }); - -constexpr auto test_func(const char *name) { - - auto ret_val = run_tests(name, - [](){ - - return TEST_PASS("Test1", "PASS"); - }); - - - return ret_val; -} + return TEST_PASS("Test Runtime", "PASS"); + }, EvalFlag::RUNTIME) + ("Test Consteval 1", [](char = 2) constexpr { + if (std::is_constant_evaluated()) { + return TEST_PASS("Test Consteval", "PASS"); + } else { + return TEST_FAIL("Test Consteval", "FAIL"); + } + }, EvalFlag::CONSTEVAL) + ("Test Consteval", [](char = 2) constexpr { + //std::cout << ""; + if (std::is_constant_evaluated()) { + return TEST_PASS("Test Consteval", "PASS"); + } else { + return TEST_FAIL("Test Consteval", "FAIL"); + } + }, EvalFlag::CONSTEVAL) + ("Test Runtime Consteval", [](short = 3) constexpr{ + if (std::is_constant_evaluated()) { + return TEST_PASS("Test Consteval Runtime", "PASS Consteval"); + } else { + return TEST_PASS("Test Consteval", "PASS Runtime"); + } + }, EvalFlag::RUNTIME_CONSTEVAL); int main() { - auto ret = test_func("Test 1"); - - auto cret = consteval_caller(test_func, "Consteval Test"); - - report(ret); - report(cret); - auto sret = tests.run(); - report(sret); + tests.run(); return 0; } \ No newline at end of file