diff options
Diffstat (limited to 'library/cpp/testing')
| -rw-r--r-- | library/cpp/testing/unittest/registar.h | 106 |
1 files changed, 103 insertions, 3 deletions
diff --git a/library/cpp/testing/unittest/registar.h b/library/cpp/testing/unittest/registar.h index b7909a0245b..a526f5aa184 100644 --- a/library/cpp/testing/unittest/registar.h +++ b/library/cpp/testing/unittest/registar.h @@ -12,6 +12,7 @@ #include <util/generic/typetraits.h> #include <util/generic/vector.h> #include <util/generic/yexception.h> +#include <util/generic/serialized_enum.h> #include <util/string/builder.h> #include <util/string/cast.h> @@ -27,6 +28,8 @@ #include <cmath> #include <cstdio> #include <functional> +#include <tuple> +#include <utility> extern bool CheckExceptionMessage(const char*, TString&); @@ -941,6 +944,42 @@ public: \ bool Failed_ = false; }; + template <class... Es> + TString BuildParamTestName(const char* base, const Es&... es) { + TString s = base; + ((s += "-", s += ToString(es)), ...); + return s; + } + + template <class F> + void ForEachProductRanges(F&& f) { + std::invoke(std::forward<F>(f)); + } + + template <class F, class FirstRange, class... RestRanges> + void ForEachProductRanges(F&& f, const FirstRange& first, const RestRanges&... rest) { + for (auto&& x : first) { + auto bound = std::bind_front(std::forward<F>(f), x); + ForEachProductRanges(std::move(bound), rest...); + } + } + + template <class... Enums, class F> + void ForEachEnums(F&& f) { + ForEachProductRanges(std::forward<F>(f), GetEnumAllValues<Enums>()...); + } + + template <class Tuple, size_t... I> + TString BuildParamTestNameFromTupleImpl(const char* base, const Tuple& t, std::index_sequence<I...>) { + return BuildParamTestName(base, std::get<I>(t)...); + } + + template <class Tuple> + TString BuildParamTestNameFromTuple(const char* base, const Tuple& t) { + return BuildParamTestNameFromTupleImpl( + base, t, std::make_index_sequence<std::tuple_size_v<Tuple>>{}); + } + #define UNIT_TEST_SUITE_REGISTRATION(T) \ static const ::NUnitTest::TTestBaseFactory<T> Y_GENERATE_UNIQUE_ID(UTREG_); @@ -1056,9 +1095,70 @@ public: \ Y_UNIT_TEST_IMPL_REGISTER(N, FF, F) \ void TTestCase##N::Execute_(NUnitTest::TTestContext& ut_context Y_DECLARE_UNUSED) -#define Y_UNIT_TEST(N) Y_UNIT_TEST_IMPL(N, false, TCurrentTestCase) -#define Y_UNIT_TEST_F(N, F) Y_UNIT_TEST_IMPL(N, false, F) -#define SIMPLE_UNIT_FORKED_TEST(N) Y_UNIT_TEST_IMPL(N, true, TCurrentTestCase) +#define Y_UNIT_TEST_ENUM_IMPL(N, FF, F, ...) \ + struct TTestCase##N : public F { \ + using Types = std::tuple<__VA_ARGS__>; \ + Types Args; \ + TString ParametrizedTestName; \ + explicit TTestCase##N(Types args) \ + : Args(std::move(args)) \ + , ParametrizedTestName(::NUnitTest::BuildParamTestNameFromTuple(#N, Args)) \ + { \ + Name_ = ParametrizedTestName.c_str(); \ + ForceFork_ = FF; \ + File_ = nullptr; \ + Line_ = 0; \ + } \ + static THolder<NUnitTest::TBaseTestCase> Create(Types args) { \ + return ::MakeHolder<TTestCase##N>(std::move(args)); \ + } \ + void Execute_(NUnitTest::TTestContext&) override; \ + template <size_t I> \ + decltype(auto) Arg() const { \ + return std::get<I>(Args); \ + } \ + }; \ + struct TTestRegistration##N { \ + TTestRegistration##N() { \ + ::NUnitTest::ForEachEnums<__VA_ARGS__>([&](auto... items) { \ + TCurrentTest::AddTest([=] { \ + return TTestCase##N::Create(typename TTestCase##N::Types(items...)); \ + }); \ + }); \ + } \ + }; \ + static const TTestRegistration##N testRegistration##N; \ + void TTestCase##N::Execute_(NUnitTest::TTestContext& ut_context Y_DECLARE_UNUSED) + +#define Y_UNIT_TEST_ENUM_IMPL_LINE(N, FF, F, ...) \ + Y_UNIT_TEST_ENUM_IMPL(N, FF, F, __VA_ARGS__) + +#define Y_UNIT_TEST(N, ...) \ + Y_UNIT_TEST_DISPATCH_##__VA_OPT__(ENUMS)(N __VA_OPT__(,) __VA_ARGS__) + +#define Y_UNIT_TEST_DISPATCH_(N) \ + Y_UNIT_TEST_IMPL(N, false, TCurrentTestCase) + +#define Y_UNIT_TEST_DISPATCH_ENUMS(N, ...) \ + Y_UNIT_TEST_ENUM_IMPL_LINE(N, false, TCurrentTestCase, __VA_ARGS__) + +#define Y_UNIT_TEST_F(N, F, ...) \ + Y_UNIT_TEST_F_DISPATCH_##__VA_OPT__(ENUMS)(N, F __VA_OPT__(,) __VA_ARGS__) + +#define Y_UNIT_TEST_F_DISPATCH_(N, F) \ + Y_UNIT_TEST_IMPL(N, false, F) + +#define Y_UNIT_TEST_F_DISPATCH_ENUMS(N, F, ...) \ + Y_UNIT_TEST_ENUM_IMPL_LINE(N, false, F, __VA_ARGS__) + +#define SIMPLE_UNIT_FORKED_TEST(N, ...) \ + SIMPLE_UNIT_FORKED_TEST_DISPATCH_##__VA_OPT__(ENUMS)(N __VA_OPT__(,) __VA_ARGS__) + +#define SIMPLE_UNIT_FORKED_TEST_DISPATCH_(N) \ + Y_UNIT_TEST_IMPL(N, true, TCurrentTestCase) + +#define SIMPLE_UNIT_FORKED_TEST_DISPATCH_ENUMS(N, ...) \ + Y_UNIT_TEST_ENUM_IMPL_LINE(N, true, TCurrentTestCase, __VA_ARGS__) #define Y_UNIT_TEST_SUITE_IMPLEMENTATION(N) \ namespace NTestSuite##N |
