mirror of
https://github.com/catchorg/Catch2.git
synced 2024-11-22 13:26:10 +01:00
Add STATIC_REQUIRE assertion
By default, it expands into a `static_assert` + `SUCCEED` pair, but it can also be deferred to runtime by defining `CATCH_CONFIG_RUNTIME_STATIC_REQUIRE`, which causes it to expand into plain old `REQUIRE`. Closes #1362 Closes #1356
This commit is contained in:
parent
0144ae9ad2
commit
054d356332
@ -145,6 +145,15 @@
|
|||||||
|
|
||||||
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
|
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
|
||||||
|
|
||||||
|
#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__ )
|
||||||
|
#else
|
||||||
|
#define CATCH_STATIC_REQUIRE( ... ) CATCH_REQUIRE( __VA_ARGS__ )
|
||||||
|
#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// "BDD-style" convenience wrappers
|
// "BDD-style" convenience wrappers
|
||||||
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
|
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
|
||||||
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
|
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
|
||||||
@ -205,6 +214,14 @@
|
|||||||
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
|
||||||
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
|
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
|
||||||
|
|
||||||
|
#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__ ")" )
|
||||||
|
#else
|
||||||
|
#define STATIC_REQUIRE( ... ) REQUIRE( __VA_ARGS__ )
|
||||||
|
#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
|
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
|
||||||
@ -285,6 +302,9 @@ using Catch::Detail::Approx;
|
|||||||
#define CATCH_THEN( desc )
|
#define CATCH_THEN( desc )
|
||||||
#define CATCH_AND_THEN( desc )
|
#define CATCH_AND_THEN( desc )
|
||||||
|
|
||||||
|
#define CATCH_STATIC_REQUIRE( ... ) (void)(0)
|
||||||
|
#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)
|
||||||
|
|
||||||
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
|
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -335,6 +355,10 @@ using Catch::Detail::Approx;
|
|||||||
#define SUCCEED( ... ) (void)(0)
|
#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____ ))
|
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
|
||||||
|
|
||||||
|
|
||||||
|
#define STATIC_REQUIRE( ... ) (void)(0)
|
||||||
|
#define STATIC_REQUIRE_FALSE( ... ) (void)(0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
|
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
// Test that Catch's prefixed macros compile and run properly.
|
// Test that Catch's prefixed macros compile and run properly.
|
||||||
|
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
|
// This won't provide full coverage, but it might be worth checking
|
||||||
|
// the other branch as well
|
||||||
|
#define CATCH_CONFIG_RUNTIME_STATIC_REQUIRE
|
||||||
#include <catch2/catch.hpp>
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
@ -23,7 +27,7 @@ CATCH_TEST_CASE("PrefixedMacros") {
|
|||||||
CATCH_REQUIRE_THROWS_WITH(this_throws(), "Some msg");
|
CATCH_REQUIRE_THROWS_WITH(this_throws(), "Some msg");
|
||||||
CATCH_REQUIRE_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
|
CATCH_REQUIRE_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
|
||||||
CATCH_REQUIRE_NOTHROW(this_doesnt_throw());
|
CATCH_REQUIRE_NOTHROW(this_doesnt_throw());
|
||||||
|
|
||||||
CATCH_CHECK( 1 == 1 );
|
CATCH_CHECK( 1 == 1 );
|
||||||
CATCH_CHECK_FALSE( 1 != 1 );
|
CATCH_CHECK_FALSE( 1 != 1 );
|
||||||
CATCH_CHECKED_IF( 1 == 1 ) {
|
CATCH_CHECKED_IF( 1 == 1 ) {
|
||||||
@ -31,15 +35,15 @@ CATCH_TEST_CASE("PrefixedMacros") {
|
|||||||
} CATCH_CHECKED_ELSE ( 1 == 1 ) {
|
} CATCH_CHECKED_ELSE ( 1 == 1 ) {
|
||||||
CATCH_SUCCEED("don't care");
|
CATCH_SUCCEED("don't care");
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_CHECK_NOFAIL(1 == 2);
|
CATCH_CHECK_NOFAIL(1 == 2);
|
||||||
|
|
||||||
CATCH_CHECK_THROWS(this_throws());
|
CATCH_CHECK_THROWS(this_throws());
|
||||||
CATCH_CHECK_THROWS_AS(this_throws(), std::runtime_error);
|
CATCH_CHECK_THROWS_AS(this_throws(), std::runtime_error);
|
||||||
CATCH_CHECK_THROWS_WITH(this_throws(), "Some msg");
|
CATCH_CHECK_THROWS_WITH(this_throws(), "Some msg");
|
||||||
CATCH_CHECK_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
|
CATCH_CHECK_THROWS_MATCHES(this_throws(), std::runtime_error, Predicate<std::runtime_error>([](std::runtime_error const&) { return true; }));
|
||||||
CATCH_CHECK_NOTHROW(this_doesnt_throw());
|
CATCH_CHECK_NOTHROW(this_doesnt_throw());
|
||||||
|
|
||||||
CATCH_REQUIRE_THAT("abcd", Equals("abcd"));
|
CATCH_REQUIRE_THAT("abcd", Equals("abcd"));
|
||||||
CATCH_CHECK_THAT("bdef", Equals("bdef"));
|
CATCH_CHECK_THAT("bdef", Equals("bdef"));
|
||||||
|
|
||||||
@ -52,6 +56,9 @@ CATCH_TEST_CASE("PrefixedMacros") {
|
|||||||
CATCH_FAIL_CHECK( "failure" );
|
CATCH_FAIL_CHECK( "failure" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CATCH_STATIC_REQUIRE( std::is_void<void>::value );
|
||||||
|
CATCH_STATIC_REQUIRE_FALSE( std::is_void<int>::value );
|
||||||
}
|
}
|
||||||
|
|
||||||
CATCH_ANON_TEST_CASE() {
|
CATCH_ANON_TEST_CASE() {
|
||||||
|
@ -496,6 +496,8 @@ Exception.tests.cpp:<line number>: failed: unexpected exception with message: 'c
|
|||||||
Tricky.tests.cpp:<line number>: passed: True for: {?}
|
Tricky.tests.cpp:<line number>: passed: True for: {?}
|
||||||
Tricky.tests.cpp:<line number>: passed: !False for: true
|
Tricky.tests.cpp:<line number>: passed: !False for: true
|
||||||
Tricky.tests.cpp:<line number>: passed: !(False) for: !{?}
|
Tricky.tests.cpp:<line number>: passed: !(False) for: !{?}
|
||||||
|
Compilation.tests.cpp:<line number>: passed: with 1 message: 'std::is_void<void>::value'
|
||||||
|
Compilation.tests.cpp:<line number>: passed: with 1 message: '!(std::is_void<int>::value)'
|
||||||
Condition.tests.cpp:<line number>: failed: data.int_seven > 7 for: 7 > 7
|
Condition.tests.cpp:<line number>: failed: data.int_seven > 7 for: 7 > 7
|
||||||
Condition.tests.cpp:<line number>: failed: data.int_seven < 7 for: 7 < 7
|
Condition.tests.cpp:<line number>: failed: data.int_seven < 7 for: 7 < 7
|
||||||
Condition.tests.cpp:<line number>: failed: data.int_seven > 8 for: 7 > 8
|
Condition.tests.cpp:<line number>: failed: data.int_seven > 8 for: 7 > 8
|
||||||
|
@ -1098,6 +1098,6 @@ due to unexpected exception with message:
|
|||||||
Why would you throw a std::string?
|
Why would you throw a std::string?
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 214 | 161 passed | 49 failed | 4 failed as expected
|
test cases: 215 | 162 passed | 49 failed | 4 failed as expected
|
||||||
assertions: 1229 | 1100 passed | 108 failed | 21 failed as expected
|
assertions: 1231 | 1102 passed | 108 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@ -4411,6 +4411,22 @@ PASSED:
|
|||||||
with expansion:
|
with expansion:
|
||||||
!{?}
|
!{?}
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Optionally static assertions
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Compilation.tests.cpp:<line number>
|
||||||
|
...............................................................................
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
with message:
|
||||||
|
std::is_void<void>::value
|
||||||
|
|
||||||
|
Compilation.tests.cpp:<line number>:
|
||||||
|
PASSED:
|
||||||
|
with message:
|
||||||
|
!(std::is_void<int>::value)
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Ordering comparison checks that should fail
|
Ordering comparison checks that should fail
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
@ -10848,6 +10864,6 @@ Misc.tests.cpp:<line number>:
|
|||||||
PASSED:
|
PASSED:
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
test cases: 214 | 148 passed | 62 failed | 4 failed as expected
|
test cases: 215 | 149 passed | 62 failed | 4 failed as expected
|
||||||
assertions: 1243 | 1100 passed | 122 failed | 21 failed as expected
|
assertions: 1245 | 1102 passed | 122 failed | 21 failed as expected
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuitesloose text artifact
|
<testsuitesloose text artifact
|
||||||
>
|
>
|
||||||
<testsuite name="<exe-name>" errors="17" failures="106" tests="1244" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
<testsuite name="<exe-name>" errors="17" failures="106" tests="1246" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||||
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="# A test name that starts with a #" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="#1005: Comparing pointer to int and long (NULL can be either on various systems)" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="#1027" time="{duration}"/>
|
||||||
@ -375,6 +375,7 @@ Exception.tests.cpp:<line number>
|
|||||||
</error>
|
</error>
|
||||||
</testcase>
|
</testcase>
|
||||||
<testcase classname="<exe-name>.global" name="Objects that evaluated in boolean contexts can be checked" time="{duration}"/>
|
<testcase classname="<exe-name>.global" name="Objects that evaluated in boolean contexts can be checked" time="{duration}"/>
|
||||||
|
<testcase classname="<exe-name>.global" name="Optionally static assertions" time="{duration}"/>
|
||||||
<testcase classname="<exe-name>.global" name="Ordering comparison checks that should fail" time="{duration}">
|
<testcase classname="<exe-name>.global" name="Ordering comparison checks that should fail" time="{duration}">
|
||||||
<failure message="7 > 7" type="CHECK">
|
<failure message="7 > 7" type="CHECK">
|
||||||
Condition.tests.cpp:<line number>
|
Condition.tests.cpp:<line number>
|
||||||
|
@ -4409,6 +4409,9 @@
|
|||||||
</Expression>
|
</Expression>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
|
<TestCase name="Optionally static assertions" tags="[compilation]" filename="projects/<exe-name>/UsageTests/Compilation.tests.cpp" >
|
||||||
|
<OverallResult success="true"/>
|
||||||
|
</TestCase>
|
||||||
<TestCase name="Ordering comparison checks that should fail" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
<TestCase name="Ordering comparison checks that should fail" tags="[.][failing]" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
<Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
<Expression success="false" type="CHECK" filename="projects/<exe-name>/UsageTests/Condition.tests.cpp" >
|
||||||
<Original>
|
<Original>
|
||||||
@ -11333,7 +11336,7 @@ loose text artifact
|
|||||||
</Section>
|
</Section>
|
||||||
<OverallResult success="true"/>
|
<OverallResult success="true"/>
|
||||||
</TestCase>
|
</TestCase>
|
||||||
<OverallResults successes="1100" failures="123" expectedFailures="21"/>
|
<OverallResults successes="1102" failures="123" expectedFailures="21"/>
|
||||||
</Group>
|
</Group>
|
||||||
<OverallResults successes="1100" failures="122" expectedFailures="21"/>
|
<OverallResults successes="1102" failures="122" expectedFailures="21"/>
|
||||||
</Catch>
|
</Catch>
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
// Setup for #1403 -- look for global overloads of operator << for classes
|
// Setup for #1403 -- look for global overloads of operator << for classes
|
||||||
// in a different namespace.
|
// in a different namespace.
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace foo {
|
namespace foo {
|
||||||
struct helper_1403 {
|
struct helper_1403 {
|
||||||
bool operator==(helper_1403) const { return true; }
|
bool operator==(helper_1403) const { return true; }
|
||||||
@ -25,7 +24,7 @@ std::ostream& operator<<(std::ostream& out, foo::helper_1403 const&) {
|
|||||||
return out << "[1403 helper]";
|
return out << "[1403 helper]";
|
||||||
}
|
}
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@ -174,12 +173,17 @@ namespace { namespace CompilationTests {
|
|||||||
TEST_CASE_METHOD((Fixture_1245<int, int>), "#1245", "[compilation]") {
|
TEST_CASE_METHOD((Fixture_1245<int, int>), "#1245", "[compilation]") {
|
||||||
SUCCEED();
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("#1403", "[compilation]") {
|
TEST_CASE("#1403", "[compilation]") {
|
||||||
::foo::helper_1403 h1, h2;
|
::foo::helper_1403 h1, h2;
|
||||||
REQUIRE(h1 == h2);
|
REQUIRE(h1 == h2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Optionally static assertions", "[compilation]") {
|
||||||
|
STATIC_REQUIRE( std::is_void<void>::value );
|
||||||
|
STATIC_REQUIRE_FALSE( std::is_void<int>::value );
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace CompilationTests
|
}} // namespace CompilationTests
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user