Skip to content

Commit

Permalink
Enable configuration of Catch2 test naming
Browse files Browse the repository at this point in the history
Catch2 produces tests names with spaces by default when using
type-parametric macros like `TEMPLATE_TEST_CASE` and
`TEMPLATE_PRODUCT_TEST_CASE`. For some test-runners that are
incompatible with spaces in test names, this presents a significant
problem: It's possible to define a test that's impossible to run.

This adds a `CATCH_CONFIG_NAME_SEPARATOR` configuration value that can
be used to override the separator string used during test naming.
  • Loading branch information
tophyr committed Dec 4, 2023
1 parent 0520ff4 commit d4c2b39
Show file tree
Hide file tree
Showing 22 changed files with 1,148 additions and 24 deletions.
1 change: 1 addition & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ expand_template(
"#cmakedefine CATCH_CONFIG_FAST_COMPILE": "",
"#cmakedefine CATCH_CONFIG_GETENV": "",
"#cmakedefine CATCH_CONFIG_GLOBAL_NEXTAFTER": "",
"#cmakedefine CATCH_CONFIG_NAME_SEPARATOR": "",
"#cmakedefine CATCH_CONFIG_NO_ANDROID_LOGWRITE": "",
"#cmakedefine CATCH_CONFIG_NO_COLOUR_WIN32": "",
"#cmakedefine CATCH_CONFIG_NO_COUNTER": "",
Expand Down
1 change: 1 addition & 0 deletions src/catch2/catch_user_config.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@

#define CATCH_CONFIG_DEFAULT_REPORTER "@CATCH_CONFIG_DEFAULT_REPORTER@"
#define CATCH_CONFIG_CONSOLE_WIDTH @CATCH_CONFIG_CONSOLE_WIDTH@
#cmakedefine CATCH_CONFIG_NAME_SEPARATOR

// Unlike the macros above, CATCH_CONFIG_FALLBACK_STRINGIFIER does not
// have a good default value, so we cannot always define it, and cannot
Expand Down
18 changes: 12 additions & 6 deletions src/catch2/internal/catch_template_test_registry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif

#ifdef CATCH_CONFIG_NAME_SEPARATOR
#define INTERNAL_CATCH_CONFIG_NAME_SEPARATOR CATCH_CONFIG_NAME_SEPARATOR
#else
#define INTERNAL_CATCH_CONFIG_NAME_SEPARATOR " - "
#endif

#if defined(CATCH_CONFIG_DISABLE)
#define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... ) \
INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))
Expand Down Expand Up @@ -87,7 +93,7 @@
size_t index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)}; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */\
using expander = size_t[]; /* NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays,hicpp-avoid-c-arrays) */\
(void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
(void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name INTERNAL_CATCH_CONFIG_NAME_SEPARATOR + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static const int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
Expand Down Expand Up @@ -135,7 +141,7 @@
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name INTERNAL_CATCH_CONFIG_NAME_SEPARATOR + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */\
} \
}; \
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
Expand Down Expand Up @@ -181,7 +187,7 @@
void reg_tests() { \
size_t index = 0; \
using expander = size_t[]; \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name INTERNAL_CATCH_CONFIG_NAME_SEPARATOR INTERNAL_CATCH_STRINGIZE(TmplList) INTERNAL_CATCH_CONFIG_NAME_SEPARATOR + std::to_string(index), Tags } ), index++)... };/* NOLINT */\
} \
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \
Expand Down Expand Up @@ -217,7 +223,7 @@
size_t index = 0; \
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\
using expander = size_t[];\
(void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
(void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name INTERNAL_CATCH_CONFIG_NAME_SEPARATOR + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
Expand Down Expand Up @@ -267,7 +273,7 @@
constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\
constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\
constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name " - " + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */ \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name INTERNAL_CATCH_CONFIG_NAME_SEPARATOR + std::string(tmpl_types[index / num_types]) + '<' + std::string(types_list[index % num_types]) + '>', Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
Expand Down Expand Up @@ -316,7 +322,7 @@
void reg_tests(){\
size_t index = 0;\
using expander = size_t[];\
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name " - " INTERNAL_CATCH_STRINGIZE(TmplList) " - " + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
(void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName##_catch_sr, Catch::NameAndTags{ Name INTERNAL_CATCH_CONFIG_NAME_SEPARATOR INTERNAL_CATCH_STRINGIZE(TmplList) INTERNAL_CATCH_CONFIG_NAME_SEPARATOR + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \
}\
};\
static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ set(TEST_SOURCES
${SELF_TEST_DIR}/UsageTests/Class.tests.cpp
${SELF_TEST_DIR}/UsageTests/Compilation.tests.cpp
${SELF_TEST_DIR}/UsageTests/Condition.tests.cpp
${SELF_TEST_DIR}/UsageTests/CustomNaming.tests.cpp
${SELF_TEST_DIR}/UsageTests/Decomposition.tests.cpp
${SELF_TEST_DIR}/UsageTests/EnumToString.tests.cpp
${SELF_TEST_DIR}/UsageTests/Exception.tests.cpp
Expand Down
17 changes: 17 additions & 0 deletions tests/SelfTest/Baselines/automake.sw.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ Nor would this
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - Template_Foo<int>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector<float>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector<int>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--Template_Foo<float>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--Template_Foo<int>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--std::vector<float>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--std::vector<int>
:test-result: FAIL A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2<float, 6>
:test-result: FAIL A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2<int, 2>
:test-result: FAIL A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array<float, 6>
Expand All @@ -54,18 +58,28 @@ Nor would this
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2<int,2>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array<float,6>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array<int,2>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--Template_Foo_2<float,6>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--Template_Foo_2<int,2>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--std::array<float,6>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--std::array<int,2>
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD based test run that fails - double
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD based test run that fails - float
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD based test run that fails - int
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test with a custom separator--double
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test with a custom separator--float
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test with a custom separator--int
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 1
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test with a custom separator--1
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test with a custom separator--3
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test with a custom separator--6
:test-result: FAIL A TEST_CASE_METHOD based test run that fails
:test-result: PASS A TEST_CASE_METHOD based test run that succeeds
:test-result: PASS A Template product test case - Foo<float>
Expand Down Expand Up @@ -247,6 +261,9 @@ Message from section two
:test-result: PASS Template test case method with test types specified inside std::tuple - MyTypes - 0
:test-result: PASS Template test case method with test types specified inside std::tuple - MyTypes - 1
:test-result: PASS Template test case method with test types specified inside std::tuple - MyTypes - 2
:test-result: PASS Template test case method with test types specified inside std::tuple with a custom separator--MyTypes--0
:test-result: PASS Template test case method with test types specified inside std::tuple with a custom separator--MyTypes--1
:test-result: PASS Template test case method with test types specified inside std::tuple with a custom separator--MyTypes--2
:test-result: PASS Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0
:test-result: PASS Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1
:test-result: PASS Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0
Expand Down
17 changes: 17 additions & 0 deletions tests/SelfTest/Baselines/automake.sw.multi.approved.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - Template_Foo<int>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector<float>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test run that succeeds - std::vector<int>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--Template_Foo<float>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--Template_Foo<int>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--std::vector<float>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD based test with a custom separator--std::vector<int>
:test-result: FAIL A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2<float, 6>
:test-result: FAIL A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - Template_Foo_2<int, 2>
:test-result: FAIL A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that fails - std::array<float, 6>
Expand All @@ -52,18 +56,28 @@
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - Template_Foo_2<int,2>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array<float,6>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test run that succeeds - std::array<int,2>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--Template_Foo_2<float,6>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--Template_Foo_2<int,2>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--std::array<float,6>
:test-result: PASS A TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG based test with a custom separator--std::array<int,2>
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD based test run that fails - double
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD based test run that fails - float
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD based test run that fails - int
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test with a custom separator--double
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test with a custom separator--float
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD based test with a custom separator--int
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 1
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 3
:test-result: FAIL A TEMPLATE_TEST_CASE_METHOD_SIG based test run that fails - 6
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 1
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 3
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test run that succeeds - 6
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test with a custom separator--1
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test with a custom separator--3
:test-result: PASS A TEMPLATE_TEST_CASE_METHOD_SIG based test with a custom separator--6
:test-result: FAIL A TEST_CASE_METHOD based test run that fails
:test-result: PASS A TEST_CASE_METHOD based test run that succeeds
:test-result: PASS A Template product test case - Foo<float>
Expand Down Expand Up @@ -240,6 +254,9 @@
:test-result: PASS Template test case method with test types specified inside std::tuple - MyTypes - 0
:test-result: PASS Template test case method with test types specified inside std::tuple - MyTypes - 1
:test-result: PASS Template test case method with test types specified inside std::tuple - MyTypes - 2
:test-result: PASS Template test case method with test types specified inside std::tuple with a custom separator--MyTypes--0
:test-result: PASS Template test case method with test types specified inside std::tuple with a custom separator--MyTypes--1
:test-result: PASS Template test case method with test types specified inside std::tuple with a custom separator--MyTypes--2
:test-result: PASS Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 0
:test-result: PASS Template test case with test types specified inside non-copyable and non-movable std::tuple - NonCopyableAndNonMovableTypes - 1
:test-result: PASS Template test case with test types specified inside non-default-constructible std::tuple - MyNonDefaultConstructibleTypes - 0
Expand Down
Loading

0 comments on commit d4c2b39

Please sign in to comment.