Skip to content

Commit

Permalink
fixed #238 - moved from an anonymous lambda to a call to a helper whe…
Browse files Browse the repository at this point in the history
…re the proper thing is instantiated + now the location of the test file is where it gets instantiated and not where the template was defined
  • Loading branch information
onqtam committed Jun 2, 2019
1 parent 86fccdf commit bd84f9a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 60 deletions.
48 changes: 18 additions & 30 deletions doctest/doctest.h
Expand Up @@ -1288,6 +1288,9 @@ namespace detail {
DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts);
DOCTEST_INTERFACE bool isDebuggerActive();

template<typename T>
int instantiationHelper(const T&) { return 0; }

namespace binaryAssertComparison {
enum Enum
{
Expand Down Expand Up @@ -1923,14 +1926,6 @@ int registerReporter(const char* name, int priority) {
} \
typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)

// for typed tests
#define DOCTEST_REGISTER_TYPED_TEST_CASE_IMPL(func, type, decorators, idx) \
doctest::detail::regTest( \
doctest::detail::TestCase(func, __FILE__, __LINE__, \
doctest_detail_test_suite_ns::getCurrentTestSuite(), \
doctest::detail::type_to_string<type>(), idx) * \
decorators)

#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \
template <typename T> \
static void func(); \
Expand All @@ -1940,15 +1935,19 @@ int registerReporter(const char* name, int priority) {
template <typename Type, typename... Rest> \
struct iter<std::tuple<Type, Rest...>> \
{ \
iter(int line, int index) { \
DOCTEST_REGISTER_TYPED_TEST_CASE_IMPL(func<Type>, Type, dec, line * 1000 + index); \
iter<std::tuple<Rest...>>(line, index + 1); \
iter(const char* file, unsigned line, int index) { \
doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line, \
doctest_detail_test_suite_ns::getCurrentTestSuite(), \
doctest::detail::type_to_string<Type>(), \
int(line) * 1000 + index) \
* dec); \
iter<std::tuple<Rest...>>(file, line, index + 1); \
} \
}; \
template <> \
struct iter<std::tuple<>> \
{ \
iter(int, int) {} \
iter(const char*, unsigned, int) {} \
}; \
} \
template <typename T> \
Expand All @@ -1958,33 +1957,22 @@ int registerReporter(const char* name, int priority) {
DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_))

#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(id, anon, ...) \
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = [] { \
DOCTEST_CAT(id, ITERATOR)<std::tuple<__VA_ARGS__>> DOCTEST_UNUSED DOCTEST_CAT( \
anon, inner_dummy)(__LINE__, 0); \
return 0; \
}(); \
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = \
doctest::detail::instantiationHelper(DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0));\
DOCTEST_GLOBAL_NO_WARNINGS_END()

#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \
DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)

#define DOCTEST_TEST_CASE_TEMPLATE_APPLY_IMPL(id, anon, ...) \
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = [] { \
DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__> DOCTEST_UNUSED DOCTEST_CAT(anon, inner_dummy)( \
__LINE__, 0); \
return 0; \
}(); \
DOCTEST_GLOBAL_NO_WARNINGS_END()

#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \
DOCTEST_TEST_CASE_TEMPLATE_APPLY_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)

#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \
DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \
DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(anon, anon, __VA_ARGS__) \
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \
template <typename T> \
static void anon()

Expand Down Expand Up @@ -3664,7 +3652,7 @@ namespace detail {
const char* type, int template_id) {
m_file = file;
m_line = line;
m_name = nullptr;
m_name = nullptr; // will be later overridden in operator*
m_test_suite = test_suite.m_test_suite;
m_description = test_suite.m_description;
m_skip = test_suite.m_skip;
Expand Down
2 changes: 1 addition & 1 deletion doctest/parts/doctest.cpp
Expand Up @@ -972,7 +972,7 @@ namespace detail {
const char* type, int template_id) {
m_file = file;
m_line = line;
m_name = nullptr;
m_name = nullptr; // will be later overridden in operator*
m_test_suite = test_suite.m_test_suite;
m_description = test_suite.m_description;
m_skip = test_suite.m_skip;
Expand Down
46 changes: 17 additions & 29 deletions doctest/parts/doctest_fwd.h
Expand Up @@ -1285,6 +1285,9 @@ namespace detail {
DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts);
DOCTEST_INTERFACE bool isDebuggerActive();

template<typename T>
int instantiationHelper(const T&) { return 0; }

namespace binaryAssertComparison {
enum Enum
{
Expand Down Expand Up @@ -1920,14 +1923,6 @@ int registerReporter(const char* name, int priority) {
} \
typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)

// for typed tests
#define DOCTEST_REGISTER_TYPED_TEST_CASE_IMPL(func, type, decorators, idx) \
doctest::detail::regTest( \
doctest::detail::TestCase(func, __FILE__, __LINE__, \
doctest_detail_test_suite_ns::getCurrentTestSuite(), \
doctest::detail::type_to_string<type>(), idx) * \
decorators)

#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \
template <typename T> \
static void func(); \
Expand All @@ -1937,15 +1932,19 @@ int registerReporter(const char* name, int priority) {
template <typename Type, typename... Rest> \
struct iter<std::tuple<Type, Rest...>> \
{ \
iter(int line, int index) { \
DOCTEST_REGISTER_TYPED_TEST_CASE_IMPL(func<Type>, Type, dec, line * 1000 + index); \
iter<std::tuple<Rest...>>(line, index + 1); \
iter(const char* file, unsigned line, int index) { \
doctest::detail::regTest(doctest::detail::TestCase(func<Type>, file, line, \
doctest_detail_test_suite_ns::getCurrentTestSuite(), \
doctest::detail::type_to_string<Type>(), \
int(line) * 1000 + index) \
* dec); \
iter<std::tuple<Rest...>>(file, line, index + 1); \
} \
}; \
template <> \
struct iter<std::tuple<>> \
{ \
iter(int, int) {} \
iter(const char*, unsigned, int) {} \
}; \
} \
template <typename T> \
Expand All @@ -1955,33 +1954,22 @@ int registerReporter(const char* name, int priority) {
DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(id, ITERATOR), \
DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_))

#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(id, anon, ...) \
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = [] { \
DOCTEST_CAT(id, ITERATOR)<std::tuple<__VA_ARGS__>> DOCTEST_UNUSED DOCTEST_CAT( \
anon, inner_dummy)(__LINE__, 0); \
return 0; \
}(); \
#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = \
doctest::detail::instantiationHelper(DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__>(__FILE__, __LINE__, 0));\
DOCTEST_GLOBAL_NO_WARNINGS_END()

#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \
DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \
typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)

#define DOCTEST_TEST_CASE_TEMPLATE_APPLY_IMPL(id, anon, ...) \
DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = [] { \
DOCTEST_CAT(id, ITERATOR)<__VA_ARGS__> DOCTEST_UNUSED DOCTEST_CAT(anon, inner_dummy)( \
__LINE__, 0); \
return 0; \
}(); \
DOCTEST_GLOBAL_NO_WARNINGS_END()

#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \
DOCTEST_TEST_CASE_TEMPLATE_APPLY_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_), __VA_ARGS__) \
typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_)

#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \
DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \
DOCTEST_TEST_CASE_TEMPLATE_INVOKE_IMPL(anon, anon, __VA_ARGS__) \
DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(anon, anon, std::tuple<__VA_ARGS__>) \
template <typename T> \
static void anon()

Expand Down
2 changes: 2 additions & 0 deletions examples/all_features/concurrency.cpp
Expand Up @@ -9,6 +9,8 @@ DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN
#include <stdexcept>
DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END

DOCTEST_MSVC_SUPPRESS_WARNING(4626) // assignment operator was implicitly defined as deleted

TEST_CASE("threads...") {
auto call_from_thread = [](int value) {
INFO("print me!");
Expand Down

0 comments on commit bd84f9a

Please sign in to comment.