implemented test_suite
This commit is contained in:
parent
d3bbb89e0f
commit
8f722d6908
|
|
@ -1,7 +1,10 @@
|
||||||
cmake_minimum_required(VERSION 3.26)
|
cmake_minimum_required(VERSION 3.26)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
add_library(test_common INTERFACE)
|
add_library(test_common INTERFACE)
|
||||||
target_include_directories(test_common INTERFACE common_helper)
|
target_include_directories(test_common INTERFACE common_helper)
|
||||||
target_link_libraries(test_common INTERFACE const_container)
|
target_link_libraries(test_common INTERFACE const_container)
|
||||||
|
target_compile_options(test_common INTERFACE -fconcepts-diagnostics-depth=2) # for debugging
|
||||||
|
|
||||||
add_subdirectory(const_vector)
|
add_subdirectory(const_vector)
|
||||||
|
|
|
||||||
|
|
@ -5,75 +5,140 @@
|
||||||
#ifndef CONST_CONTAINER_TEST_DEFINE_TEST_HPP_
|
#ifndef CONST_CONTAINER_TEST_DEFINE_TEST_HPP_
|
||||||
#define CONST_CONTAINER_TEST_DEFINE_TEST_HPP_
|
#define CONST_CONTAINER_TEST_DEFINE_TEST_HPP_
|
||||||
|
|
||||||
|
#include <any>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
|
#include <iostream>
|
||||||
|
#include <ranges>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
#include "test_ret_val.h"
|
#include "test_ret_val.h"
|
||||||
|
#include "CompileOptional.h"
|
||||||
|
|
||||||
template<std::invocable Func>
|
template<typename Suite>
|
||||||
struct test_def_base {
|
struct quick_test_def;
|
||||||
using FuncType = Func;
|
|
||||||
|
enum class EvalFlag { RUNTIME, CONSTEVAL, RUNTIME_CONSTEVAL };
|
||||||
const char *name;
|
|
||||||
Func func;
|
class test_definition {
|
||||||
|
public:
|
||||||
constexpr test_def_base(const char * name, Func func) : name(name), func(func) {}
|
[[nodiscard]] virtual constexpr ret_val_s evaluate() const = 0;
|
||||||
|
|
||||||
virtual constexpr std::invoke_result_t<Func> operator()() { return std::apply(func, std::make_tuple()); }
|
[[nodiscard]] virtual const char *name() const = 0;
|
||||||
|
[[nodiscard]] virtual EvalFlag evalFlag() const = 0;
|
||||||
|
[[nodiscard]] virtual const ret_val_s &c_res() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<std::invocable Func, typename ...Args>
|
template<std::invocable Func, typename ...Args>
|
||||||
struct test_definition : public test_def_base<Func> {
|
class test_definition_impl : public test_definition {
|
||||||
using base = test_def_base<Func>;
|
public:
|
||||||
static constexpr std::size_t ARG_SIZE = sizeof...(Args);
|
using FuncType = Func;
|
||||||
|
static constexpr std::size_t ARG_SIZE = sizeof...(Args);
|
||||||
|
|
||||||
std::tuple<Args...> 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)
|
[[nodiscard]] constexpr ret_val_s evaluate() const override { return std::apply(_func, _args); }
|
||||||
: test_def_base<Func>(name, func), args(std::make_tuple(args...)) {}
|
|
||||||
|
|
||||||
constexpr std::invoke_result_t<Func, Args...> operator()() override { return std::apply(base::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 {
|
private:
|
||||||
const char *name;
|
const char *_name;
|
||||||
|
EvalFlag _evalFlag;
|
||||||
|
Func _func;
|
||||||
|
std::tuple<Args...> _args;
|
||||||
|
ret_val_s _c_res;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ...TestDefs>
|
template<typename ...TestDefs>
|
||||||
requires (sizeof...(TestDefs) == 0 || (std::derived_from<TestDefs, test_def_base<typename TestDefs::FuncType>> && ...))
|
requires (sizeof...(TestDefs) == 0 || (std::derived_from<TestDefs, test_definition> && ...))
|
||||||
struct test_suite : public test_suite_base {
|
class test_suite {
|
||||||
|
|
||||||
static constexpr std::size_t TEST_NR = sizeof...(TestDefs);
|
public:
|
||||||
|
static constexpr std::size_t TEST_NR = sizeof...(TestDefs);
|
||||||
std::tuple<TestDefs...> tests;
|
|
||||||
|
constexpr test_suite(const char *name, std::tuple<TestDefs...> tests) : _name(name), _tests(tests) {}
|
||||||
constexpr test_suite(const char *name, std::tuple<TestDefs...> tests) : test_suite_base(name), tests(tests) {}
|
|
||||||
|
|
||||||
constexpr ret_val<TEST_NR> run() {
|
|
||||||
|
|
||||||
std::vector<ret_val_s> v;
|
int run() const {
|
||||||
std::apply([&v](auto&& ...args) { ((v.push_back(args())), ...); }, tests);
|
|
||||||
|
auto test_arr = expand_test_tuple(_tests, std::make_index_sequence<TEST_NR>());
|
||||||
ret_val<TEST_NR> ret = { name };
|
|
||||||
std::ranges::move(v, ret.vals.begin());
|
std::cout << test_arr.size() << "\n";
|
||||||
|
|
||||||
return ret;
|
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<TestDefs...> _tests;
|
||||||
|
|
||||||
|
template<std::size_t ...Is>
|
||||||
|
static constexpr auto expand_test_tuple(const auto &tests, std::index_sequence<Is...>) {
|
||||||
|
return std::array {
|
||||||
|
std::reference_wrapper(
|
||||||
|
dynamic_cast<const test_definition&>(std::get<Is>(tests))
|
||||||
|
)... };
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class quick_test_def<test_suite<TestDefs...>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Suite>
|
template<typename Suite>
|
||||||
struct quick_test_def {
|
struct quick_test_def {
|
||||||
Suite current;
|
Suite current;
|
||||||
|
|
||||||
template<std::invocable Func, typename ...Args>
|
template<std::invocable Func, typename ...Args>
|
||||||
constexpr auto operator()(const char *name, Func func, Args... args) {
|
constexpr auto operator()(const char *name, Func func, Args... args) {
|
||||||
auto test = test_definition(name, func, args...);
|
return operator()(name, func, EvalFlag::RUNTIME, std::forward(args)...);
|
||||||
auto new_suite = test_suite(current.name, std::tuple_cat(current.tests, std::make_tuple(test)));
|
}
|
||||||
|
|
||||||
|
template<std::invocable Func, typename ...Args>
|
||||||
|
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<decltype(new_suite)> { new_suite };
|
return quick_test_def<decltype(new_suite)> { new_suite };
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr operator Suite() {
|
constexpr operator Suite() {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,40 @@
|
||||||
#include <any>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include <const_vector.hpp>
|
#include <const_vector.hpp>
|
||||||
|
|
||||||
#include "test_define_test.hpp"
|
#include "test_define_test.hpp"
|
||||||
#include "test_util.hpp"
|
#include "test_util.hpp"
|
||||||
#include "test_ret_val.h"
|
#include "test_ret_val.h"
|
||||||
|
|
||||||
test_suite tests = define_tests("Tests")
|
constexpr test_suite tests = define_tests("Tests")
|
||||||
("Test1", [](){
|
("Test Runtime", [](int = 1) constexpr{
|
||||||
|
|
||||||
return TEST_PASS("Test1", "PASS");
|
return TEST_PASS("Test Runtime", "PASS");
|
||||||
});
|
}, EvalFlag::RUNTIME)
|
||||||
|
("Test Consteval 1", [](char = 2) constexpr {
|
||||||
constexpr auto test_func(const char *name) {
|
if (std::is_constant_evaluated()) {
|
||||||
|
return TEST_PASS("Test Consteval", "PASS");
|
||||||
auto ret_val = run_tests(name,
|
} else {
|
||||||
[](){
|
return TEST_FAIL("Test Consteval", "FAIL");
|
||||||
|
}
|
||||||
return TEST_PASS("Test1", "PASS");
|
}, EvalFlag::CONSTEVAL)
|
||||||
});
|
("Test Consteval", [](char = 2) constexpr {
|
||||||
|
//std::cout << "";
|
||||||
|
if (std::is_constant_evaluated()) {
|
||||||
return ret_val;
|
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() {
|
int main() {
|
||||||
auto ret = test_func("Test 1");
|
|
||||||
|
|
||||||
auto cret = consteval_caller(test_func, "Consteval Test");
|
|
||||||
|
|
||||||
report(ret);
|
|
||||||
report(cret);
|
|
||||||
|
|
||||||
auto sret = tests.run();
|
tests.run();
|
||||||
report(sret);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue