summaryrefslogtreecommitdiffstats
path: root/library/cpp/testing
diff options
context:
space:
mode:
Diffstat (limited to 'library/cpp/testing')
-rw-r--r--library/cpp/testing/unittest/registar.h106
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