From d8f9e15954eff159f29376beeafb6ff35231734f Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Sun, 11 Aug 2024 16:16:56 -0700 Subject: [PATCH] Simplify `suite_builder` and `test_caller` This lets us remove some repeated tuple-expansion. --- include/mettle/suite/detail/test_caller.hpp | 52 +++++-------- include/mettle/suite/make_suite.hpp | 85 ++++++++++----------- test/suite/test_test_caller.cpp | 51 ++++++------- 3 files changed, 85 insertions(+), 103 deletions(-) diff --git a/include/mettle/suite/detail/test_caller.hpp b/include/mettle/suite/detail/test_caller.hpp index a5aa420c..803711c2 100644 --- a/include/mettle/suite/detail/test_caller.hpp +++ b/include/mettle/suite/detail/test_caller.hpp @@ -28,7 +28,7 @@ namespace mettle::detail { struct test_caller_base { using function_type = std::function; - void call_test(Args &...args) { + void operator ()(Args &...args) { if(setup) setup(args...); @@ -48,49 +48,37 @@ namespace mettle::detail { function_type setup, teardown, test; }; - template - class test_caller_impl; + template + struct test_caller : test_caller_base { + private: + using base = test_caller_base; + public: + template + test_caller(const Factory &, T &&...t) + : base{std::forward(t)...} {} + }; - template - class test_caller_impl, InChild, OutChild> - : private test_caller_base { + template + struct fixture_test_caller : test_caller_base< + Parent &..., transform_fixture_t & + > { private: - using base = test_caller_base; + using base = test_caller_base< + Parent &..., transform_fixture_t & + >; public: template - test_caller_impl(Factory f, T &&...t) + fixture_test_caller(Factory f, T &&...t) : base{std::forward(t)...}, factory(std::move(f)) {} inline void operator ()(Parent &...args) { - auto &&child = factory.template make(); - base::call_test(args..., child); + auto &&child = factory.template make(); + base::operator ()(args..., child); } Factory factory; }; - template - class test_caller_impl, InChild, void> - : private test_caller_base { - private: - using base = test_caller_base; - public: - template - test_caller_impl(const Factory &, T &&...t) - : base{std::forward(t)...} {} - public: - inline void operator ()(Parent &...args) { - base::call_test(args...); - } - }; - - template - using test_caller = test_caller_impl< - Factory, Parent, Child, transform_fixture_t - >; - } // namespace mettle::detail #endif diff --git a/include/mettle/suite/make_suite.hpp b/include/mettle/suite/make_suite.hpp index 0525a958..4deb9821 100644 --- a/include/mettle/suite/make_suite.hpp +++ b/include/mettle/suite/make_suite.hpp @@ -32,18 +32,6 @@ namespace mettle { return s + " (" + type_name() + ")"; } - template - struct to_func_impl; - - template - struct to_func_impl> { - using type = void(T&...); - }; - - template - using to_func = typename to_func_impl::type; - - template struct wrap_test { using compiled_suite_type = runnable_suite; @@ -72,9 +60,7 @@ namespace mettle { template> struct wrapped_suite { - using type = compiled_suite>; + using type = compiled_suite; }; template @@ -172,7 +158,7 @@ namespace mettle { template - inline compiled_suite> + inline auto make_subsuite(const std::string &name, const attributes &attrs, Args &&...args) { return detail::do_build( @@ -181,7 +167,7 @@ namespace mettle { } template - inline compiled_suite> + inline auto make_subsuite(const std::string &name, Args &&...args) { return detail::do_build( name, {}, std::forward(args)..., detail::identity{} @@ -189,8 +175,7 @@ namespace mettle { } template - inline std::array>, - std::max(sizeof...(Fixture), std::size_t(1))> + inline auto make_subsuites(const std::string &name, const attributes &attrs, Args &&...args) { return detail::do_builds( @@ -199,8 +184,7 @@ namespace mettle { } template - inline std::array>, - std::max(sizeof...(Fixture), std::size_t(1))> + inline auto make_subsuites(const std::string &name, Args &&...args) { return detail::do_builds( name, {}, std::forward(args)..., detail::identity{} @@ -308,39 +292,52 @@ namespace mettle { std::vector> subsuites_; }; - template - struct suite_builder_base_type; + template + requires(std::same_as, void>) + class suite_builder, Fixture> + : public suite_builder_base { + using base = suite_builder_base; + public: + using factory_type = Factory; + using parent_fixture_type = std::tuple; + using parent_fixture_signature = void(ParentFixture&...); + using fixture_type = Fixture; - template - struct suite_builder_base_type, InChild> { - using out_child_type = detail::transform_fixture_t; - using type = std::conditional_t< - std::is_same_v, - suite_builder_base, - suite_builder_base - >; - }; + suite_builder(const std::string &name, const attributes &attrs, + Factory factory) + : base(name, attrs), factory_(factory) {} + private: + using test_caller = detail::test_caller; + + template + friend typename detail::wrapped_suite::type + detail::finalize(Builder &, const Wrap &); - template - using suite_builder_base_t = typename suite_builder_base_type< - Factory, Parent, InChild - >::type; + factory_type factory_; + }; - template - class suite_builder - : public suite_builder_base_t { - using base = suite_builder_base_t; - public: + template + class suite_builder, Fixture> + : public suite_builder_base> { + using base = suite_builder_base< + ParentFixture..., detail::transform_fixture_t + >; + public: using factory_type = Factory; - using parent_fixture_type = ParentFixture; + using parent_fixture_type = std::tuple; + using parent_fixture_signature = void(ParentFixture&...); using fixture_type = Fixture; suite_builder(const std::string &name, const attributes &attrs, Factory factory) : base(name, attrs), factory_(factory) {} private: - using test_caller = detail::test_caller; + using test_caller = detail::fixture_test_caller< + Factory, Fixture, ParentFixture... + >; template friend typename detail::wrapped_suite::type diff --git a/test/suite/test_test_caller.cpp b/test/suite/test_test_caller.cpp index 3b7fe580..8f1f5d49 100644 --- a/test/suite/test_test_caller.cpp +++ b/test/suite/test_test_caller.cpp @@ -3,16 +3,25 @@ using namespace mettle; #include "run_counter.hpp" -template -struct run_counter_from_tuple_t; - -template -struct run_counter_from_tuple_t> { - using type = run_counter; +template typename T, typename Tuple, + template typename Transform> +struct apply_tuple_t; + +template typename T, typename ...Args, + template typename Transform> +struct apply_tuple_t, Transform> { + using type = T...>; }; +template typename T, typename Tuple, + template typename Transform = std::type_identity_t> +using apply_tuple = typename apply_tuple_t::type; + template -using run_counter_from_tuple = typename run_counter_from_tuple_t::type; +using run_counter_from_tuple = apply_tuple< + run_counter, Tuple, std::add_lvalue_reference_t +>; + using namespace mettle::detail; @@ -20,38 +29,26 @@ suite, std::tuple> test_test_caller("test_caller", [](auto &_) { using Fixture = fixture_type_t; - _.test("test with no fixture", [](auto &tup) { + _.test("no fixture", [](auto &tup) { run_counter_from_tuple setup, teardown, test; - test_caller t( + apply_tuple caller( auto_factory, setup, teardown, test ); - std::apply(t, tup); + std::apply(caller, tup); expect("setup run count", setup.runs(), equal_to(1)); expect("test run count", test.runs(), equal_to(1)); expect("teardown run count", teardown.runs(), equal_to(1)); }); - _.test("test with auto fixture", [](auto &tup) { + _.test("fixture", [](auto &tup) { run_counter_from_tuple()) )> setup, teardown, test; - test_caller t( - auto_factory, setup, teardown, test - ); - std::apply(t, tup); - - expect("setup run count", setup.runs(), equal_to(1)); - expect("test run count", test.runs(), equal_to(1)); - expect("teardown run count", teardown.runs(), equal_to(1)); - }); - - _.test("test with type-only fixture", [](auto &tup) { - run_counter_from_tuple setup, teardown, test; - test_caller t( - type_only, setup, teardown, test - ); - std::apply(t, tup); + apply_tuple(), tup) + )> caller(auto_factory, setup, teardown, test); + std::apply(caller, tup); expect("setup run count", setup.runs(), equal_to(1)); expect("test run count", test.runs(), equal_to(1));