Skip to content

Commit 8fc585c

Browse files
committed
Merge branch 'fix/partially-match-searches'
2 parents 8d3c1fd + 480b081 commit 8fc585c

2 files changed

Lines changed: 43 additions & 4 deletions

File tree

‎include/matchers/strings/match.hpp‎

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,25 @@
77

88
namespace CppSpec::Matchers {
99

10+
// A std::regex keeps no copy of its source, so a pattern given as text is named by that text; one given as a
11+
// std::regex is named only as a regex.
12+
inline std::string describe_pattern(const std::string& pattern) {
13+
return pattern.empty() ? std::string{"a regex"} : "\"" + pattern + "\"";
14+
}
15+
1016
template <typename A>
1117
class Match : public MatcherBase<A, std::regex> {
18+
std::string pattern_;
19+
1220
public:
1321
explicit Match(Expectation<A>& expectation, std::string expected)
14-
: MatcherBase<A, std::regex>(expectation, std::regex(expected)) {}
22+
: MatcherBase<A, std::regex>(expectation, std::regex(expected)), pattern_(std::move(expected)) {}
1523

1624
explicit Match(Expectation<A>& expectation, std::regex expected)
1725
: MatcherBase<A, std::regex>(expectation, expected) {}
1826

1927
std::string verb() override { return "match"; }
28+
std::string description() override { return verb() + " " + describe_pattern(pattern_); }
2029

2130
bool match() override {
2231
std::smatch temp_match;
@@ -26,16 +35,19 @@ class Match : public MatcherBase<A, std::regex> {
2635

2736
template <typename A>
2837
class MatchPartial : public MatcherBase<A, std::regex> {
38+
std::string pattern_;
39+
2940
public:
3041
explicit MatchPartial(Expectation<A>& expectation, std::string expected)
31-
: MatcherBase<A, std::regex>(expectation, std::regex(expected)) {}
42+
: MatcherBase<A, std::regex>(expectation, std::regex(expected)), pattern_(std::move(expected)) {}
3243

3344
explicit MatchPartial(Expectation<A>& expectation, std::regex expected)
3445
: MatcherBase<A, std::regex>(expectation, expected) {}
3546

36-
std::string description() override { return "partially match " + Pretty::to_word(this->expected()); }
47+
std::string description() override { return "partially match " + describe_pattern(pattern_); }
3748

38-
bool match() override { return std::regex_match(this->actual(), this->expected()); }
49+
// A partial match is a match anywhere in the string: a search, not a match of the whole.
50+
bool match() override { return std::regex_search(this->actual(), this->expected()); }
3951
};
4052

4153
} // namespace CppSpec::Matchers

‎spec/matchers/string_spec.cpp‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
using namespace CppSpec;
88

9+
// clang-format off
910
describe string_spec("string matchers", $ {
1011
context("to_start_with (string)", _ {
1112
it("passes when string starts with prefix", _ {
@@ -105,6 +106,32 @@ describe string_spec("string matchers", $ {
105106
});
106107
});
107108

109+
context("to_partially_match (regex search)", _ {
110+
it("passes when the pattern occurs anywhere in the string", _ {
111+
expect(std::string{"the groove differs"}).to_partially_match("groove");
112+
});
113+
114+
it("passes for a pattern at the start or the end", _ {
115+
expect(std::string{"groove differs"}).to_partially_match("^groove");
116+
expect(std::string{"it differs"}).to_partially_match("differs$");
117+
});
118+
119+
it("fails when the pattern does not occur", _ {
120+
expect(std::string{"the groove differs"}).not_().to_partially_match("drum");
121+
});
122+
123+
it("searches with a regex too", _ {
124+
expect(std::string{"OUTPUT 1 DIFFERS"}).to_partially_match(std::regex("output [0-9]", std::regex::icase));
125+
});
126+
127+
it("names a string pattern by its text", _ {
128+
auto e = expect(std::string{"x"});
129+
expect(Matchers::MatchPartial<std::string>(e, "groove").description())
130+
.to_equal(std::string{"partially match \"groove\""});
131+
expect(Matchers::Match<std::string>(e, "gr.*ve").description()).to_equal(std::string{"match \"gr.*ve\""});
132+
});
133+
});
134+
108135
context("string to_contain (char)", _ {
109136
it("finds a character in a string", _ {
110137
expect(std::string{"abcde"}).to_contain('c');

0 commit comments

Comments
 (0)