mirror of
https://github.com/catchorg/Catch2.git
synced 2024-12-23 03:43:28 +01:00
parent
a06b6dc3ea
commit
b0857e846f
@ -39,7 +39,10 @@ REQUIRE_THAT( str,
|
||||
Catch currently provides some matchers, they are in the `Catch::Matchers` and `Catch` namespaces.
|
||||
|
||||
### String matchers
|
||||
The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
||||
The string matchers are `StartsWith`, `EndsWith`, `Contains`, `Equals` and `Matches`. The first four match a literal (sub)string against a result, while `Matches` takes and matches an ECMAScript regex. Do note that `Matches` matches the string as a whole, meaning that "abc" will not match against "abcd", but "abc.*" will.
|
||||
|
||||
Each of the provided `std::string` matchers also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
|
||||
|
||||
|
||||
### Vector matchers
|
||||
The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector.
|
||||
|
@ -8,6 +8,9 @@
|
||||
|
||||
#include "catch_matchers_string.h"
|
||||
#include "catch_string_manip.h"
|
||||
#include "catch_tostring.h"
|
||||
|
||||
#include <regex>
|
||||
|
||||
namespace Catch {
|
||||
namespace Matchers {
|
||||
@ -74,6 +77,23 @@ namespace Matchers {
|
||||
return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );
|
||||
}
|
||||
|
||||
|
||||
|
||||
RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}
|
||||
|
||||
bool RegexMatcher::match(std::string const& matchee) const {
|
||||
auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway
|
||||
if (m_caseSensitivity == CaseSensitive::Choice::No) {
|
||||
flags |= std::regex::icase;
|
||||
}
|
||||
auto reg = std::regex(m_regex, flags);
|
||||
return std::regex_match(matchee, reg);
|
||||
}
|
||||
|
||||
std::string RegexMatcher::describe() const {
|
||||
return "matches " + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? " case sensitively" : " case insensitively");
|
||||
}
|
||||
|
||||
} // namespace StdString
|
||||
|
||||
|
||||
@ -90,5 +110,9 @@ namespace Matchers {
|
||||
return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );
|
||||
}
|
||||
|
||||
StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {
|
||||
return StdString::RegexMatcher(regex, caseSensitivity);
|
||||
}
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
@ -52,6 +52,16 @@ namespace Matchers {
|
||||
bool match( std::string const& source ) const override;
|
||||
};
|
||||
|
||||
struct RegexMatcher : MatcherBase<std::string> {
|
||||
RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );
|
||||
bool match( std::string const& matchee ) const override;
|
||||
std::string describe() const override;
|
||||
|
||||
private:
|
||||
std::string m_regex;
|
||||
CaseSensitive::Choice m_caseSensitivity;
|
||||
};
|
||||
|
||||
} // namespace StdString
|
||||
|
||||
|
||||
@ -62,6 +72,7 @@ namespace Matchers {
|
||||
StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );
|
||||
|
||||
} // namespace Matchers
|
||||
} // namespace Catch
|
||||
|
@ -655,6 +655,30 @@ DecompositionTests.cpp:<line number>: FAILED:
|
||||
with expansion:
|
||||
Hey, its truthy!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Regex string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "this STRING contains
|
||||
'abc' as a substring" case sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Matches("contains 'abc' as a substring") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "contains 'abc' as a
|
||||
substring" case sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Matches("this string contains 'abc' as a") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "this string contains
|
||||
'abc' as a" case sensitively
|
||||
|
||||
A string sent directly to stdout
|
||||
A string sent directly to stderr
|
||||
Message from section one
|
||||
@ -1003,6 +1027,6 @@ with expansion:
|
||||
"{?}" == "1"
|
||||
|
||||
===============================================================================
|
||||
test cases: 188 | 137 passed | 47 failed | 4 failed as expected
|
||||
assertions: 940 | 823 passed | 96 failed | 21 failed as expected
|
||||
test cases: 189 | 137 passed | 48 failed | 4 failed as expected
|
||||
assertions: 948 | 828 passed | 99 failed | 21 failed as expected
|
||||
|
||||
|
@ -4343,6 +4343,30 @@ DecompositionTests.cpp:<line number>: FAILED:
|
||||
with expansion:
|
||||
Hey, its truthy!
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Regex string matcher
|
||||
-------------------------------------------------------------------------------
|
||||
MatchersTests.cpp:<line number>
|
||||
...............................................................................
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "this STRING contains
|
||||
'abc' as a substring" case sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Matches("contains 'abc' as a substring") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "contains 'abc' as a
|
||||
substring" case sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>: FAILED:
|
||||
CHECK_THAT( testStringForMatching(), Matches("this string contains 'abc' as a") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "this string contains
|
||||
'abc' as a" case sensitively
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
SUCCEED counts as a test pass
|
||||
-------------------------------------------------------------------------------
|
||||
@ -4646,6 +4670,41 @@ PASSED:
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" ends with: "substring"
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Matches("this string contains 'abc' as a substring") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "this string contains
|
||||
'abc' as a substring" case sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "this string CONTAINS
|
||||
'abc' as a substring" case insensitively
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Matches("^this string contains 'abc' as a substring$") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "^this string contains
|
||||
'abc' as a substring$" case sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Matches("^.* 'abc' .*$") )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "^.* 'abc' .*$" case
|
||||
sensitively
|
||||
|
||||
MatchersTests.cpp:<line number>:
|
||||
PASSED:
|
||||
REQUIRE_THAT( testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No) )
|
||||
with expansion:
|
||||
"this string contains 'abc' as a substring" matches "^.* 'ABC' .*$" case
|
||||
insensitively
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
StringRef
|
||||
Empty string
|
||||
@ -7903,6 +7962,6 @@ MiscTests.cpp:<line number>:
|
||||
PASSED:
|
||||
|
||||
===============================================================================
|
||||
test cases: 188 | 135 passed | 49 failed | 4 failed as expected
|
||||
assertions: 939 | 819 passed | 99 failed | 21 failed as expected
|
||||
test cases: 189 | 135 passed | 50 failed | 4 failed as expected
|
||||
assertions: 947 | 824 passed | 102 failed | 21 failed as expected
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuitesloose text artifact
|
||||
>
|
||||
<testsuite name="<exe-name>" errors="15" failures="85" tests="940" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}">
|
||||
<testsuite name="<exe-name>" errors="15" failures="88" tests="948" 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="#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}"/>
|
||||
@ -480,6 +480,17 @@ MessageTests.cpp:<line number>
|
||||
DecompositionTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="Regex string matcher" time="{duration}">
|
||||
<failure message=""this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message=""this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
<failure message=""this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively" type="CHECK_THAT">
|
||||
MatchersTests.cpp:<line number>
|
||||
</failure>
|
||||
</testcase>
|
||||
<testcase classname="<exe-name>.global" name="SUCCEED counts as a test pass" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.global" name="SUCCESS does not require an argument" time="{duration}"/>
|
||||
<testcase classname="<exe-name>.Fixture" name="Scenario: BDD tests requiring Fixtures to provide commonly-accessed data or methods/Given: No operations precede me" time="{duration}"/>
|
||||
|
@ -5026,6 +5026,33 @@
|
||||
</Expression>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="Regex string matcher" tags="[.][.failing][matchers]" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("this STRING contains 'abc' as a substring")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "this STRING contains 'abc' as a substring" case sensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("contains 'abc' as a substring")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "contains 'abc' as a substring" case sensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("this string contains 'abc' as a")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "this string contains 'abc' as a" case sensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="false"/>
|
||||
</TestCase>
|
||||
<TestCase name="SUCCEED counts as a test pass" tags="[messages]" filename="projects/<exe-name>/MessageTests.cpp" >
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
@ -5321,6 +5348,46 @@ Message from section two
|
||||
"this string contains 'abc' as a substring" ends with: "substring"
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("this string contains 'abc' as a substring")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "this string contains 'abc' as a substring" case sensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No)
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "this string CONTAINS 'abc' as a substring" case insensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("^this string contains 'abc' as a substring$")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "^this string contains 'abc' as a substring$" case sensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("^.* 'abc' .*$")
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "^.* 'abc' .*$" case sensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/MatchersTests.cpp" >
|
||||
<Original>
|
||||
testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No)
|
||||
</Original>
|
||||
<Expanded>
|
||||
"this string contains 'abc' as a substring" matches "^.* 'ABC' .*$" case insensitively
|
||||
</Expanded>
|
||||
</Expression>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<TestCase name="StringRef" tags="[Strings]" filename="projects/<exe-name>/StringRef.tests.cpp" >
|
||||
@ -8764,7 +8831,7 @@ loose text artifact
|
||||
</Section>
|
||||
<OverallResult success="true"/>
|
||||
</TestCase>
|
||||
<OverallResults successes="819" failures="100" expectedFailures="21"/>
|
||||
<OverallResults successes="824" failures="103" expectedFailures="21"/>
|
||||
</Group>
|
||||
<OverallResults successes="819" failures="99" expectedFailures="21"/>
|
||||
<OverallResults successes="824" failures="102" expectedFailures="21"/>
|
||||
</Catch>
|
||||
|
@ -36,6 +36,12 @@ TEST_CASE("String matchers", "[matchers]" )
|
||||
|
||||
CHECK_THAT( testStringForMatching(), StartsWith( "this" ) );
|
||||
CHECK_THAT( testStringForMatching(), EndsWith( "substring" ) );
|
||||
|
||||
REQUIRE_THAT(testStringForMatching(), Matches("this string contains 'abc' as a substring"));
|
||||
REQUIRE_THAT(testStringForMatching(), Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No));
|
||||
REQUIRE_THAT(testStringForMatching(), Matches("^this string contains 'abc' as a substring$"));
|
||||
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'abc' .*$"));
|
||||
REQUIRE_THAT(testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No));
|
||||
}
|
||||
|
||||
TEST_CASE("Contains string matcher", "[.][failing][matchers]")
|
||||
@ -63,6 +69,12 @@ TEST_CASE("Equals", "[matchers]")
|
||||
CHECK_THAT( testStringForMatching(), Equals( "this string contains 'abc' as a substring" ) );
|
||||
}
|
||||
|
||||
TEST_CASE("Regex string matcher", "[matchers][.failing]") {
|
||||
CHECK_THAT( testStringForMatching(), Matches("this STRING contains 'abc' as a substring"));
|
||||
CHECK_THAT( testStringForMatching(), Matches("contains 'abc' as a substring"));
|
||||
CHECK_THAT( testStringForMatching(), Matches("this string contains 'abc' as a"));
|
||||
}
|
||||
|
||||
TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]")
|
||||
{
|
||||
CHECK_THAT( testStringForMatching(),
|
||||
|
Loading…
Reference in New Issue
Block a user