Skip to content

Commit cf7026f

Browse files
committed
move params out of annotations
1 parent c52ff55 commit cf7026f

File tree

4 files changed

+147
-147
lines changed

4 files changed

+147
-147
lines changed

example/tparams.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@
33

44
namespace demo::params {
55

6+
consteval std::vector<std::tuple<std::meta::info, int>> make_tparams() {
7+
return {{^^double, 13}, {^^short, 14}};
8+
}
9+
610
[[=rsl::test]]
11+
[[=rsl::tparams(make_tparams)]]
712
[[=rsl::tparams({std::tuple{^^int, 10}, {^^float, 21}})]]
8-
constexpr inline auto tparam_gt_5 = []<typename T, int I>() static {
13+
[[=rsl::params({std::tuple{42, 'c'}, {12, 'b'}})]]
14+
constexpr inline auto tparam_gt_5 = []<typename T, int I>(int a, char b) static {
915
ASSERT(I > 5);
1016
};
1117
} // namespace
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#pragma once
2+
#include <tuple>
3+
#include <vector>
4+
#include <meta>
5+
#include <ranges>
6+
7+
#include <rsl/testing/_impl/util.hpp>
8+
9+
namespace rsl::testing {
10+
namespace _testing_impl {
11+
template <typename T, std::meta::info Set>
12+
T param_set_to_tuple() {
13+
constexpr static auto args = [:Set:];
14+
return []<std::size_t... Idx>(std::index_sequence<Idx...>) {
15+
return T{[:args[Idx]:]...};
16+
}(std::make_index_sequence<std::tuple_size_v<T>>{});
17+
}
18+
19+
template <typename T, std::meta::info Sets>
20+
std::vector<T> param_generator() {
21+
std::vector<T> ret;
22+
template for (constexpr auto set : [:Sets:]) {
23+
ret.push_back(param_set_to_tuple<T, set>());
24+
}
25+
return ret;
26+
}
27+
28+
struct TestInstance {
29+
char const* name;
30+
std::meta::info fnc;
31+
};
32+
33+
consteval std::string stringify_targs(std::span<std::meta::info const> args) {
34+
std::string result = "<";
35+
for (std::size_t i = 0; i < args.size(); ++i) {
36+
if (i != 0) {
37+
result += ", ";
38+
}
39+
result += display_string_of(args[i]);
40+
}
41+
result += ">";
42+
return result;
43+
}
44+
45+
template <std::meta::info Sets>
46+
constexpr std::vector<TestInstance> tparam_generator(std::meta::info fnc) {
47+
std::vector<TestInstance> ret;
48+
auto base_name = identifier_of(fnc);
49+
template for (constexpr auto set : [:Sets:]) {
50+
auto name = base_name + stringify_targs([:set:]);
51+
auto instance = substitute(get_operator(fnc, std::meta::operators::op_parentheses), [:set:]);
52+
ret.emplace_back(define_static_string(name), instance);
53+
}
54+
return ret;
55+
}
56+
57+
template <typename... Ts>
58+
consteval std::meta::info reflect_tuple(std::tuple<Ts...> const& tup,
59+
bool reflect_reflections = true) {
60+
std::array<std::meta::info, sizeof...(Ts)> reflected_element;
61+
template for (constexpr auto Idx : std::views::iota(0zu, sizeof...(Ts))) {
62+
if constexpr (std::same_as<Ts...[Idx], std::meta::info>) {
63+
// effectively disallows std::meta::info CTPs for tests, but allows passing
64+
// types etc as reflections
65+
if (!reflect_reflections) {
66+
reflected_element[Idx] = get<Idx>(tup);
67+
continue;
68+
}
69+
}
70+
if constexpr (std::convertible_to<Ts...[Idx], std::string_view>) {
71+
reflected_element[Idx] = std::meta::reflect_constant_string(get<Idx>(tup));
72+
} else {
73+
reflected_element[Idx] = std::meta::reflect_constant(get<Idx>(tup));
74+
}
75+
}
76+
return std::meta::reflect_constant_array(reflected_element);
77+
}
78+
79+
} // namespace _testing_impl
80+
81+
struct Params {
82+
std::meta::info generator;
83+
84+
template <typename... Ts>
85+
consteval explicit Params(std::vector<std::tuple<Ts...>> const& param_sets) {
86+
std::vector<std::meta::info> params = {};
87+
for (auto const& element : param_sets) {
88+
params.push_back(_testing_impl::reflect_tuple(element));
89+
}
90+
91+
auto arg_tuple = substitute(^^std::tuple, {^^Ts...});
92+
generator =
93+
substitute(^^_testing_impl::param_generator,
94+
{arg_tuple, reflect_constant(std::meta::reflect_constant_array(params))});
95+
}
96+
97+
template <typename... Ts>
98+
consteval explicit(false) Params(std::initializer_list<std::tuple<Ts...>> param_sets)
99+
: Params(std::vector<std::tuple<Ts...>>{param_sets}) {}
100+
101+
template <typename... Ts>
102+
consteval Params(std::vector<std::tuple<Ts...>> (*generator)())
103+
: generator(std::meta::reflect_constant(generator)) {}
104+
};
105+
106+
struct TParams {
107+
std::meta::info generator;
108+
109+
template <typename... Ts>
110+
consteval explicit TParams(std::vector<std::tuple<Ts...>> const& param_sets) {
111+
std::vector<std::meta::info> params = {};
112+
for (auto const& element : param_sets) {
113+
params.push_back(_testing_impl::reflect_tuple(element, false));
114+
}
115+
116+
generator = substitute(^^_testing_impl::tparam_generator,
117+
{reflect_constant(std::meta::reflect_constant_array(params))});
118+
}
119+
120+
template <typename... Ts>
121+
consteval explicit(false) TParams(std::initializer_list<std::tuple<Ts...>> param_sets)
122+
: TParams(std::vector<std::tuple<Ts...>>{param_sets}) {}
123+
124+
template <typename... Ts>
125+
consteval explicit(false) TParams(std::vector<std::tuple<Ts...>> (&generator)())
126+
: TParams(generator()) {}
127+
};
128+
} // namespace rsl::testing
Lines changed: 5 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,9 @@
11
#pragma once
2-
32
#include <meta>
4-
#include <tuple>
5-
#include <vector>
6-
#include <ranges>
7-
8-
#include <rsl/testing/_impl/util.hpp>
9-
10-
namespace rsl::testing {
11-
namespace _testing_impl {
12-
template <typename T, std::meta::info Set>
13-
T param_set_to_tuple() {
14-
constexpr static auto args = [:Set:];
15-
return []<std::size_t... Idx>(std::index_sequence<Idx...>) {
16-
return T{[:args[Idx]:]...};
17-
}(std::make_index_sequence<std::tuple_size_v<T>>{});
18-
}
19-
20-
template <typename T, std::meta::info Sets>
21-
std::vector<T> param_generator() {
22-
std::vector<T> ret;
23-
template for (constexpr auto set : [:Sets:]) {
24-
ret.push_back(param_set_to_tuple<T, set>());
25-
}
26-
return ret;
27-
}
28-
29-
struct TestInstance {
30-
char const* name;
31-
std::meta::info fnc;
32-
};
333

34-
consteval std::string stringify_targs(std::span<std::meta::info const> args) {
35-
std::string result = "<";
36-
for (std::size_t i = 0; i < args.size(); ++i) {
37-
if (i != 0) {
38-
result += ", ";
39-
}
40-
result += display_string_of(args[i]);
41-
}
42-
result += ">";
43-
return result;
44-
}
45-
46-
template <std::meta::info Sets>
47-
constexpr std::vector<TestInstance> tparam_generator(std::meta::info fnc) {
48-
std::vector<TestInstance> ret;
49-
auto base_name = identifier_of(fnc);
50-
template for (constexpr auto set : [:Sets:]) {
51-
auto name = base_name + stringify_targs([:set:]);
52-
auto instance = substitute(get_operator(fnc, std::meta::operators::op_parentheses), [:set:]);
53-
ret.emplace_back(define_static_string(name), instance);
54-
}
55-
return ret;
56-
}
57-
58-
template <typename... Ts>
59-
consteval std::meta::info reflect_tuple(std::tuple<Ts...> const& tup,
60-
bool reflect_reflections = true) {
61-
std::array<std::meta::info, sizeof...(Ts)> reflected_element;
62-
template for (constexpr auto Idx : std::views::iota(0zu, sizeof...(Ts))) {
63-
if constexpr (std::same_as<Ts...[Idx], std::meta::info>) {
64-
// effectively disallows std::meta::info CTPs for tests, but allows passing
65-
// types etc as reflections
66-
if (!reflect_reflections) {
67-
reflected_element[Idx] = get<Idx>(tup);
68-
continue;
69-
}
70-
}
71-
if constexpr (std::convertible_to<Ts...[Idx], std::string_view>) {
72-
reflected_element[Idx] = std::meta::reflect_constant_string(get<Idx>(tup));
73-
} else {
74-
reflected_element[Idx] = std::meta::reflect_constant(get<Idx>(tup));
75-
}
76-
}
77-
return std::meta::reflect_constant_array(reflected_element);
78-
}
79-
80-
} // namespace _testing_impl
81-
82-
namespace annotations {
4+
#include "_impl/params.hpp"
835

6+
namespace rsl::testing::annotations {
847
struct TestTag {};
858
constexpr inline TestTag test;
869

@@ -90,73 +13,16 @@ constexpr inline ExpectFailureTag expect_failure;
9013
struct FixtureTag {};
9114
constexpr inline FixtureTag fixture;
9215

93-
struct Params {
94-
std::meta::info generator;
95-
96-
template <typename... Ts>
97-
consteval explicit Params(std::vector<std::tuple<Ts...>> const& param_sets) {
98-
std::vector<std::meta::info> params = {};
99-
for (auto const& element : param_sets) {
100-
params.push_back(_testing_impl::reflect_tuple(element));
101-
}
102-
103-
auto arg_tuple = substitute(^^std::tuple, {^^Ts...});
104-
generator =
105-
substitute(^^_testing_impl::param_generator,
106-
{arg_tuple, reflect_constant(std::meta::reflect_constant_array(params))});
107-
}
108-
109-
template <typename... Ts>
110-
consteval explicit(false) Params(std::initializer_list<std::tuple<Ts...>> param_sets)
111-
: Params(std::vector<std::tuple<Ts...>>{param_sets}) {}
112-
113-
template <typename... Ts>
114-
consteval Params(std::vector<std::tuple<Ts...>> (*generator)())
115-
: generator(std::meta::reflect_constant(generator)) {}
116-
};
117-
118-
struct TParams {
119-
std::meta::info generator;
120-
121-
template <typename... Ts>
122-
consteval explicit TParams(std::vector<std::tuple<Ts...>> const& param_sets) {
123-
std::vector<std::meta::info> params = {};
124-
for (auto const& element : param_sets) {
125-
params.push_back(_testing_impl::reflect_tuple(element, false));
126-
}
127-
128-
generator = substitute(^^_testing_impl::tparam_generator,
129-
{reflect_constant(std::meta::reflect_constant_array(params))});
130-
}
131-
132-
template <typename... Ts>
133-
consteval explicit(false) TParams(std::initializer_list<std::tuple<Ts...>> param_sets)
134-
: TParams(std::vector<std::tuple<Ts...>>{param_sets}) {}
135-
};
136-
13716
using params = Params;
13817
using tparams = TParams;
13918

14019
struct Rename {
141-
char const *value = nullptr;
20+
char const* value = nullptr;
14221

143-
static consteval Rename operator()(std::string_view new_name){
22+
static consteval Rename operator()(std::string_view new_name) {
14423
return Rename(define_static_string(new_name));
14524
}
14625
};
14726
constexpr inline Rename rename{};
14827

149-
} // namespace annotations
150-
151-
template <std::meta::info R>
152-
void make_calls() {
153-
template for (constexpr auto annotation :
154-
std::define_static_array(annotations_of(R, ^^annotations::Params))) {
155-
constexpr static annotations::Params params = extract<annotations::Params>(annotation);
156-
for (auto set : [:params.generator:]()) {
157-
std::apply([:R:], set);
158-
}
159-
}
160-
}
161-
162-
} // namespace rsl
28+
} // namespace rsl::testing::annotations

include/rsl/testing/test.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ class Test {
6666

6767
static std::vector<arg_tuple> expand_parameters() {
6868
std::vector<arg_tuple> arg_sets;
69-
if constexpr (_testing_impl::has_annotation<annotations::Params>(R)) {
69+
if constexpr (_testing_impl::has_annotation<Params>(R)) {
7070
// expand params
7171
template for (constexpr auto annotation :
72-
std::define_static_array(annotations_of(R, ^^annotations::Params))) {
73-
constexpr static annotations::Params params = extract<annotations::Params>(annotation);
72+
std::define_static_array(annotations_of(R, ^^Params))) {
73+
constexpr static Params params = extract<Params>(annotation);
7474
arg_sets.append_range([:params.generator:]());
7575
}
7676
} else {
@@ -82,6 +82,7 @@ class Test {
8282

8383
static void run_one(arg_tuple const& tuple) {
8484
if constexpr (is_class_member(R)) {
85+
// TODO allow fixture ctors to use other fixtures as parameters
8586
auto fixture = [:parent_of(R):]();
8687
std::apply(fixture.[:F.fnc:], tuple);
8788
} else if constexpr (is_variable(R)) {
@@ -128,12 +129,12 @@ class Test {
128129
auto instance = _testing_impl::TestInstance{define_static_string(display_string_of(R)), R};
129130
return {extract<runner_type>(
130131
substitute(^^runner, {std::meta::reflect_constant(instance), reflect_constant(R)}))};
131-
} else if (is_variable(R) && _testing_impl::has_annotation<annotations::TParams>(R)) {
132+
} else if (is_variable(R) && _testing_impl::has_annotation<TParams>(R)) {
132133
std::vector<_testing_impl::TestInstance> instantiations;
133134
using generator_type = std::vector<_testing_impl::TestInstance> (*)(std::meta::info);
134135

135-
for (auto annotation : annotations_of(R, ^^annotations::TParams)) {
136-
auto params = extract<annotations::TParams>(annotation);
136+
for (auto annotation : annotations_of(R, ^^TParams)) {
137+
auto params = extract<TParams>(annotation);
137138
auto generator = extract<generator_type>(params.generator);
138139
instantiations.append_range(generator(R));
139140
}
@@ -189,7 +190,6 @@ consteval TestDef make_test(std::meta::info R) {
189190
} // namespace _testing_impl
190191

191192
struct Reporter;
192-
struct Output;
193193

194194
struct TestNamespace {
195195
std::string_view name;

0 commit comments

Comments
 (0)