From 2d906a92cb82fe65e3cafab6495c0fd12a0ab0ab Mon Sep 17 00:00:00 2001 From: Jozef Grajciar Date: Thu, 8 Nov 2018 07:26:39 +0100 Subject: [PATCH] Add support for templated tests This adds support for templated tests and test methods via `TEMPLATE_TEST_CASE` and `TEMPLATE_TEST_CASE_METHOD` macros. These work mostly just like their regular counterparts*, but take an unlimited** number of types as their last arguments. * Unlike the plain `TEST_CASE*` macros, the `TEMPLATE*` variants require a tag string. ** In practice there is limit of about 300 types. --- include/catch.hpp | 33 + .../internal/catch_compiler_capabilities.h | 10 + include/internal/catch_preprocessor.hpp | 74 ++ include/internal/catch_test_registry.h | 94 ++- include/internal/catch_type_traits.hpp | 38 + projects/CMakeLists.txt | 2 + .../Baselines/compact.sw.approved.txt | 76 +- .../Baselines/console.std.approved.txt | 37 +- .../Baselines/console.sw.approved.txt | 650 ++++++++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 44 +- .../SelfTest/Baselines/xml.sw.approved.txt | 686 +++++++++++++++++- projects/SelfTest/UsageTests/Class.tests.cpp | 18 + projects/SelfTest/UsageTests/Misc.tests.cpp | 40 + 13 files changed, 1786 insertions(+), 16 deletions(-) create mode 100644 include/internal/catch_preprocessor.hpp create mode 100644 include/internal/catch_type_traits.hpp diff --git a/include/catch.hpp b/include/catch.hpp index 84b9f466..c98abf66 100644 --- a/include/catch.hpp +++ b/include/catch.hpp @@ -145,6 +145,15 @@ #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#else +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#endif + + #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) #define CATCH_STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__ , #__VA_ARGS__ ); CATCH_SUCCEED( #__VA_ARGS__ ) #define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); CATCH_SUCCEED( #__VA_ARGS__ ) @@ -214,6 +223,15 @@ #define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ ) #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) +#else +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) ) +#endif + + #if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) #define STATIC_REQUIRE( ... ) static_assert( __VA_ARGS__, #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ ) #define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), "!(" #__VA_ARGS__ ")" ); SUCCEED( "!(" #__VA_ARGS__ ")" ) @@ -292,6 +310,14 @@ using Catch::Detail::Approx; #define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) +#else +#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) ) +#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) ) +#endif + // "BDD-style" convenience wrappers #define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) #define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), className ) @@ -355,6 +381,13 @@ using Catch::Detail::Approx; #define SUCCEED( ... ) (void)(0) #define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) +#else +#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) ) ) +#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), className ) ) +#endif #define STATIC_REQUIRE( ... ) (void)(0) #define STATIC_REQUIRE_FALSE( ... ) (void)(0) diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index aa3e599e..41627570 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -136,6 +136,13 @@ # define CATCH_INTERNAL_CONFIG_WINDOWS_SEH # endif +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif + #endif // _MSC_VER //////////////////////////////////////////////////////////////////////////////// @@ -254,6 +261,9 @@ #define CATCH_CATCH_ANON(type) catch (type) #endif +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#endif #endif // TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED diff --git a/include/internal/catch_preprocessor.hpp b/include/internal/catch_preprocessor.hpp new file mode 100644 index 00000000..0bfb660f --- /dev/null +++ b/include/internal/catch_preprocessor.hpp @@ -0,0 +1,74 @@ +/* + * Created by Jozef on 12/11/2018. + * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED + +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif + +#define CATCH_REC_END(...) +#define CATCH_REC_OUT + +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() + +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF + +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) + +#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name, __VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " - " #__VA_ARGS__ +#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name,...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +// MSVC is adding extra space and needs more calls to properly remove () +#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME3(Name,...) Name " -" #__VA_ARGS__ +#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME2(Name, __VA_ARGS__) +#define INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME(Name, ...) INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME1(Name, INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#endif // TWOBLUECUBES_CATCH_PREPROCESSOR_HPP_INCLUDED diff --git a/include/internal/catch_test_registry.h b/include/internal/catch_test_registry.h index 71304483..060cb374 100644 --- a/include/internal/catch_test_registry.h +++ b/include/internal/catch_test_registry.h @@ -12,6 +12,8 @@ #include "catch_interfaces_testcase.h" #include "catch_compiler_capabilities.h" #include "catch_stringref.h" +#include "catch_type_traits.hpp" +#include "catch_preprocessor.hpp" namespace Catch { @@ -47,22 +49,28 @@ struct AutoReg : NonCopyable { } // end namespace Catch -#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) -#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ -#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ -#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF - #if defined(CATCH_CONFIG_DISABLE) #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \ static void TestName() #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ namespace{ \ - struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ void test(); \ }; \ } \ void TestName::test() - + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION( TestName, ... ) \ + template \ + static void TestName() + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \ + namespace{ \ + template \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \ + void test(); \ + }; \ + } \ + template \ + void TestName::test() #endif /////////////////////////////////////////////////////////////////////////////// @@ -85,7 +93,7 @@ struct AutoReg : NonCopyable { #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\ CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ namespace{ \ - struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \ void test(); \ }; \ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ @@ -101,5 +109,75 @@ struct AutoReg : NonCopyable { Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \ CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + /////////////////////////////////////////////////////////////////////////////// + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, ... )\ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + template \ + static void TestFunc();\ + namespace {\ + template \ + struct TestName{\ + template \ + TestName(Ts...names){\ + CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \ + using expander = int[];\ + (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \ + }\ + };\ + INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, __VA_ARGS__) \ + }\ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + template \ + static void TestFunc() + +#if defined(CATCH_CPP17_OR_GREATER) +#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>,"Duplicate type detected in declaration of template test case"); +#else +#define CATCH_INTERNAL_CHECK_UNIQUE_TYPES(...) static_assert(Catch::is_unique<__VA_ARGS__>::value,"Duplicate type detected in declaration of template test case"); +#endif + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____F_U_N_C____ ), Name, Tags, __VA_ARGS__ ) ) +#endif + + #define INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestName, Name, ...)\ + static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\ + TestName(CATCH_REC_LIST_UD(INTERNAL_CATCH_TEMPLATE_UNIQUE_NAME,Name, __VA_ARGS__));\ + return 0;\ + }(); + + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, ... ) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ \ + template \ + struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName ) { \ + void test();\ + };\ + template \ + struct TestNameClass{\ + template \ + TestNameClass(Ts...names){\ + CATCH_INTERNAL_CHECK_UNIQUE_TYPES(CATCH_REC_LIST(INTERNAL_CATCH_REMOVE_PARENS, __VA_ARGS__)) \ + using expander = int[];\ + (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ names, Tags } ), 0)... };/* NOLINT */ \ + }\ + };\ + INTERNAL_CATCH_TEMPLATE_REGISTRY_INITIATE(TestNameClass, Name, __VA_ARGS__)\ + }\ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS\ + template \ + void TestName::test() + +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ + INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) +#else + #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \ + INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____C_L_A_S_S____ ), INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_M_P_L_A_T_E____T_E_S_T____ ) , ClassName, Name, Tags, __VA_ARGS__ ) ) +#endif #endif // TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED diff --git a/include/internal/catch_type_traits.hpp b/include/internal/catch_type_traits.hpp new file mode 100644 index 00000000..88615484 --- /dev/null +++ b/include/internal/catch_type_traits.hpp @@ -0,0 +1,38 @@ +/* + * Created by Jozef on 12/11/2018. + * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED +#define TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED + +namespace Catch{ + +#ifdef CATCH_CPP17_OR_GREATER + template + inline constexpr auto is_unique = std::true_type{}; + + template + inline constexpr auto is_unique = std::bool_constant< + (!std::is_same_v && ...) && is_unique + >{}; +#else + +template +struct is_unique : std::true_type{}; + +template +struct is_unique : std::integral_constant +::value + && is_unique::value + && is_unique::value +>{}; + +#endif +} + +#endif // TWOBLUECUBES_CATCH_TYPE_TRAITS_HPP_INCLUDED diff --git a/projects/CMakeLists.txt b/projects/CMakeLists.txt index ac10793b..aa827673 100644 --- a/projects/CMakeLists.txt +++ b/projects/CMakeLists.txt @@ -123,6 +123,7 @@ set(INTERNAL_HEADERS ${HEADER_DIR}/internal/catch_option.hpp ${HEADER_DIR}/internal/catch_output_redirect.h ${HEADER_DIR}/internal/catch_platform.h + ${HEADER_DIR}/internal/catch_preprocessor.hpp ${HEADER_DIR}/internal/catch_random_number_generator.h ${HEADER_DIR}/internal/catch_reenable_warnings.h ${HEADER_DIR}/internal/catch_reporter_registrars.hpp @@ -153,6 +154,7 @@ set(INTERNAL_HEADERS ${HEADER_DIR}/internal/catch_to_string.hpp ${HEADER_DIR}/internal/catch_tostring.h ${HEADER_DIR}/internal/catch_totals.h + ${HEADER_DIR}/internal/catch_type_traits.hpp ${HEADER_DIR}/internal/catch_uncaught_exceptions.h ${HEADER_DIR}/internal/catch_user_interfaces.h ${HEADER_DIR}/internal/catch_version.h diff --git a/projects/SelfTest/Baselines/compact.sw.approved.txt b/projects/SelfTest/Baselines/compact.sw.approved.txt index 41b63712..496ead91 100644 --- a/projects/SelfTest/Baselines/compact.sw.approved.txt +++ b/projects/SelfTest/Baselines/compact.sw.approved.txt @@ -159,6 +159,12 @@ Generators.tests.cpp:: passed: x < y for: 10 < 109 Generators.tests.cpp:: passed: x < y for: 10 < 110 Class.tests.cpp:: failed: s == "world" for: "hello" == "world" Class.tests.cpp:: passed: s == "hello" for: "hello" == "hello" +Class.tests.cpp:: failed: Template_Fixture::m_a == 2 for: 1.0 == 2 +Class.tests.cpp:: failed: Template_Fixture::m_a == 2 for: 1.0f == 2 +Class.tests.cpp:: failed: Template_Fixture::m_a == 2 for: 1 == 2 +Class.tests.cpp:: passed: Template_Fixture::m_a == 1 for: 1.0 == 1 +Class.tests.cpp:: passed: Template_Fixture::m_a == 1 for: 1.0f == 1 +Class.tests.cpp:: passed: Template_Fixture::m_a == 1 for: 1 == 1 Class.tests.cpp:: failed: m_a == 2 for: 1 == 2 Class.tests.cpp:: passed: m_a == 1 for: 1 == 1 Approx.tests.cpp:: passed: d == 1.23_a for: 1.23 == Approx( 1.23 ) @@ -871,6 +877,74 @@ TagAlias.tests.cpp:: passed: registry.add( "[no ampersat]", "", Cat TagAlias.tests.cpp:: passed: registry.add( "[the @ is not at the start]", "", Catch::SourceLineInfo( "file", 3 ) ) TagAlias.tests.cpp:: passed: registry.add( "@no square bracket at start]", "", Catch::SourceLineInfo( "file", 3 ) ) TagAlias.tests.cpp:: passed: registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 10 for: 10 == 10 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.capacity() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 10 for: 10 == 10 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.capacity() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 10 for: 10 == 10 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.capacity() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 10 for: 10 == 10 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.capacity() == 0 for: 0 == 0 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 10 for: 10 >= 10 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 +Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 +Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 VariadicMacros.tests.cpp:: passed: with 1 message: 'no assertions' Tricky.tests.cpp:: passed: 0x == bit30and31 for: 3221225472 (0x) == 3221225472 Message.tests.cpp:: failed - but was ok: 1 == 2 @@ -1313,5 +1387,5 @@ Misc.tests.cpp:: passed: v.size() == 5 for: 5 == 5 Misc.tests.cpp:: passed: v.capacity() >= 5 for: 5 >= 5 Misc.tests.cpp:: passed: Misc.tests.cpp:: passed: -Failed 62 test cases, failed 122 assertions. +Failed 65 test cases, failed 125 assertions. diff --git a/projects/SelfTest/Baselines/console.std.approved.txt b/projects/SelfTest/Baselines/console.std.approved.txt index 50632eb9..f48a98ec 100644 --- a/projects/SelfTest/Baselines/console.std.approved.txt +++ b/projects/SelfTest/Baselines/console.std.approved.txt @@ -92,6 +92,39 @@ Class.tests.cpp:: FAILED: with expansion: "hello" == "world" +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that fails - double +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: FAILED: + REQUIRE( Template_Fixture::m_a == 2 ) +with expansion: + 1.0 == 2 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that fails - float +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: FAILED: + REQUIRE( Template_Fixture::m_a == 2 ) +with expansion: + 1.0f == 2 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that fails - int +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: FAILED: + REQUIRE( Template_Fixture::m_a == 2 ) +with expansion: + 1 == 2 + ------------------------------------------------------------------------------- A TEST_CASE_METHOD based test run that fails ------------------------------------------------------------------------------- @@ -1093,6 +1126,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 216 | 163 passed | 49 failed | 4 failed as expected -assertions: 1234 | 1105 passed | 108 failed | 21 failed as expected +test cases: 226 | 170 passed | 52 failed | 4 failed as expected +assertions: 1308 | 1176 passed | 111 failed | 21 failed as expected diff --git a/projects/SelfTest/Baselines/console.sw.approved.txt b/projects/SelfTest/Baselines/console.sw.approved.txt index 4aae2012..e99ea050 100644 --- a/projects/SelfTest/Baselines/console.sw.approved.txt +++ b/projects/SelfTest/Baselines/console.sw.approved.txt @@ -1577,6 +1577,72 @@ Class.tests.cpp:: PASSED: with expansion: "hello" == "hello" +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that fails - double +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: FAILED: + REQUIRE( Template_Fixture::m_a == 2 ) +with expansion: + 1.0 == 2 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that fails - float +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: FAILED: + REQUIRE( Template_Fixture::m_a == 2 ) +with expansion: + 1.0f == 2 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that fails - int +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: FAILED: + REQUIRE( Template_Fixture::m_a == 2 ) +with expansion: + 1 == 2 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - double +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: PASSED: + REQUIRE( Template_Fixture::m_a == 1 ) +with expansion: + 1.0 == 1 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - float +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: PASSED: + REQUIRE( Template_Fixture::m_a == 1 ) +with expansion: + 1.0f == 1 + +------------------------------------------------------------------------------- +A TEMPLATE_TEST_CASE_METHOD based test run that succeeds - int +------------------------------------------------------------------------------- +Class.tests.cpp: +............................................................................... + +Class.tests.cpp:: PASSED: + REQUIRE( Template_Fixture::m_a == 1 ) +with expansion: + 1 == 1 + ------------------------------------------------------------------------------- A TEST_CASE_METHOD based test run that fails ------------------------------------------------------------------------------- @@ -6573,6 +6639,586 @@ TagAlias.tests.cpp:: PASSED: TagAlias.tests.cpp:: PASSED: CHECK_THROWS( registry.add( "[@no square bracket at end", "", Catch::SourceLineInfo( "file", 3 ) ) ) +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float + resizing bigger changes size and capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 10 ) +with expansion: + 10 == 10 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float + resizing smaller changes size but not capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float + resizing smaller changes size but not capacity + We can use the 'swap trick' to reset the capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float + reserving bigger changes capacity but not size +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - float + reserving smaller does not change size or capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int + resizing bigger changes size and capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 10 ) +with expansion: + 10 == 10 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int + resizing smaller changes size but not capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int + resizing smaller changes size but not capacity + We can use the 'swap trick' to reset the capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int + reserving bigger changes capacity but not size +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - int + reserving smaller does not change size or capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string + resizing bigger changes size and capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 10 ) +with expansion: + 10 == 10 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string + resizing smaller changes size but not capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string + resizing smaller changes size but not capacity + We can use the 'swap trick' to reset the capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string + reserving bigger changes capacity but not size +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::string + reserving smaller does not change size or capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple + resizing bigger changes size and capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 10 ) +with expansion: + 10 == 10 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple + resizing smaller changes size but not capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 0 ) +with expansion: + 0 == 0 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple + resizing smaller changes size but not capacity + We can use the 'swap trick' to reset the capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() == 0 ) +with expansion: + 0 == 0 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple + reserving bigger changes capacity but not size +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 10 ) +with expansion: + 10 >= 10 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + +------------------------------------------------------------------------------- +TemplateTest: vectors can be sized and resized - std::tuple + reserving smaller does not change size or capacity +------------------------------------------------------------------------------- +Misc.tests.cpp: +............................................................................... + +Misc.tests.cpp:: PASSED: + REQUIRE( v.size() == 5 ) +with expansion: + 5 == 5 + +Misc.tests.cpp:: PASSED: + REQUIRE( v.capacity() >= 5 ) +with expansion: + 5 >= 5 + ------------------------------------------------------------------------------- Test case with one argument ------------------------------------------------------------------------------- @@ -9786,6 +10432,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 216 | 150 passed | 62 failed | 4 failed as expected -assertions: 1248 | 1105 passed | 122 failed | 21 failed as expected +test cases: 226 | 157 passed | 65 failed | 4 failed as expected +assertions: 1322 | 1176 passed | 125 failed | 21 failed as expected diff --git a/projects/SelfTest/Baselines/junit.sw.approved.txt b/projects/SelfTest/Baselines/junit.sw.approved.txt index b62c62aa..5984b3db 100644 --- a/projects/SelfTest/Baselines/junit.sw.approved.txt +++ b/projects/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -77,6 +77,24 @@ Class.tests.cpp: + + +Class.tests.cpp: + + + + +Class.tests.cpp: + + + + +Class.tests.cpp: + + + + + Class.tests.cpp: @@ -596,6 +614,30 @@ Misc.tests.cpp: + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/projects/SelfTest/Baselines/xml.sw.approved.txt b/projects/SelfTest/Baselines/xml.sw.approved.txt index 00ea5f76..d89b4e18 100644 --- a/projects/SelfTest/Baselines/xml.sw.approved.txt +++ b/projects/SelfTest/Baselines/xml.sw.approved.txt @@ -1347,6 +1347,72 @@ + + + + Template_Fixture<TestType>::m_a == 2 + + + 1.0 == 2 + + + + + + + + Template_Fixture<TestType>::m_a == 2 + + + 1.0f == 2 + + + + + + + + Template_Fixture<TestType>::m_a == 2 + + + 1 == 2 + + + + + + + + Template_Fixture<TestType>::m_a == 1 + + + 1.0 == 1 + + + + + + + + Template_Fixture<TestType>::m_a == 1 + + + 1.0f == 1 + + + + + + + + Template_Fixture<TestType>::m_a == 1 + + + 1 == 1 + + + + @@ -7691,6 +7757,622 @@ Message from section two + + + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 10 + + + 10 == 10 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 0 + + + 0 == 0 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.capacity() == 0 + + + 0 == 0 + + + +
+ +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + + +
+ +
+ + + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 10 + + + 10 == 10 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 0 + + + 0 == 0 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.capacity() == 0 + + + 0 == 0 + + + +
+ +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + + +
+ +
+ + + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 10 + + + 10 == 10 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 0 + + + 0 == 0 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.capacity() == 0 + + + 0 == 0 + + + +
+ +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + + +
+ +
+ + + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 10 + + + 10 == 10 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 0 + + + 0 == 0 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.capacity() == 0 + + + 0 == 0 + + + +
+ +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 10 + + + 10 >= 10 + + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + +
+ + + v.size() == 5 + + + 5 == 5 + + + + + v.capacity() >= 5 + + + 5 >= 5 + + + +
+ +
@@ -11369,7 +12051,7 @@ loose text artifact
- + - + diff --git a/projects/SelfTest/UsageTests/Class.tests.cpp b/projects/SelfTest/UsageTests/Class.tests.cpp index c19a5172..6f9bd85e 100644 --- a/projects/SelfTest/UsageTests/Class.tests.cpp +++ b/projects/SelfTest/UsageTests/Class.tests.cpp @@ -39,6 +39,13 @@ struct Fixture int m_a; }; +template< typename T > +struct Template_Fixture { + Template_Fixture(): m_a(1) {} + + T m_a; +}; + #endif @@ -51,6 +58,10 @@ TEST_CASE_METHOD( Fixture, "A TEST_CASE_METHOD based test run that succeeds", "[ REQUIRE( m_a == 1 ); } +TEMPLATE_TEST_CASE_METHOD(Template_Fixture, "A TEMPLATE_TEST_CASE_METHOD based test run that succeeds", "[class][template]", int, float, double) { + REQUIRE( Template_Fixture::m_a == 1 ); +} + // We should be able to write our tests within a different namespace namespace Inner { @@ -58,6 +69,13 @@ namespace Inner { REQUIRE( m_a == 2 ); } + + TEMPLATE_TEST_CASE_METHOD(Template_Fixture,"A TEMPLATE_TEST_CASE_METHOD based test run that fails", "[.][class][template][failing]", int, float, double) + { + REQUIRE( Template_Fixture::m_a == 2 ); + } } + + }} // namespace ClassTests diff --git a/projects/SelfTest/UsageTests/Misc.tests.cpp b/projects/SelfTest/UsageTests/Misc.tests.cpp index 820e8019..0c3dae1e 100644 --- a/projects/SelfTest/UsageTests/Misc.tests.cpp +++ b/projects/SelfTest/UsageTests/Misc.tests.cpp @@ -261,6 +261,46 @@ TEST_CASE( "vectors can be sized and resized", "[vector]" ) { } } +TEMPLATE_TEST_CASE( "TemplateTest: vectors can be sized and resized", "[vector][template]", int, float, std::string, (std::tuple) ) { + + std::vector v( 5 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + + SECTION( "resizing bigger changes size and capacity" ) { + v.resize( 10 ); + + REQUIRE( v.size() == 10 ); + REQUIRE( v.capacity() >= 10 ); + } + SECTION( "resizing smaller changes size but not capacity" ) { + v.resize( 0 ); + + REQUIRE( v.size() == 0 ); + REQUIRE( v.capacity() >= 5 ); + + SECTION( "We can use the 'swap trick' to reset the capacity" ) { + std::vector empty; + empty.swap( v ); + + REQUIRE( v.capacity() == 0 ); + } + } + SECTION( "reserving bigger changes capacity but not size" ) { + v.reserve( 10 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 10 ); + } + SECTION( "reserving smaller does not change size or capacity" ) { + v.reserve( 0 ); + + REQUIRE( v.size() == 5 ); + REQUIRE( v.capacity() >= 5 ); + } +} + // https://github.com/philsquared/Catch/issues/166 TEST_CASE("A couple of nested sections followed by a failure", "[failing][.]") { SECTION("Outer")