• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Created by Phil on 21/02/2017.
3  *  Copyright 2017 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9 #include "catch.hpp"
10 
11 #include <sstream>
12 #include <algorithm>
13 
14 #ifdef __clang__
15 #pragma clang diagnostic push
16 #pragma clang diagnostic ignored "-Wweak-vtables"
17 #pragma clang diagnostic ignored "-Wpadded"
18 #endif
19 
20 namespace { namespace MatchersTests {
21 
22 #ifndef CATCH_CONFIG_DISABLE_MATCHERS
23 
24 #ifndef MATCHERS_TEST_HELPERS_INCLUDED // Don't compile this more than once per TU
25 #define MATCHERS_TEST_HELPERS_INCLUDED
26 
testStringForMatching()27     inline const char *testStringForMatching() {
28         return "this string contains 'abc' as a substring";
29     }
30 
testStringForMatching2()31     inline const char *testStringForMatching2() {
32         return "some completely different text that contains one common word";
33     }
34 
alwaysTrue(int)35     inline bool alwaysTrue(int) { return true; }
alwaysFalse(int)36     inline bool alwaysFalse(int) { return false; }
37 
38 
39 #ifdef _MSC_VER
40 #pragma warning(disable:4702) // Unreachable code -- MSVC 19 (VS 2015) sees right through the indirection
41 #endif
42 
43 #include <exception>
44 
45     struct SpecialException : std::exception {
SpecialException__anonb5bcda700111::MatchersTests::SpecialException46         SpecialException(int i_) : i(i_) {}
47 
what__anonb5bcda700111::MatchersTests::SpecialException48         char const* what() const noexcept override {
49             return "SpecialException::what";
50         }
51 
52         int i;
53     };
54 
55 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
doesNotThrow()56     void doesNotThrow() {}
57 
58     [[noreturn]]
throws(int i)59     void throws(int i) {
60         throw SpecialException{i};
61     }
62 
63     [[noreturn]]
throwsAsInt(int i)64     void throwsAsInt(int i) {
65         throw i;
66     }
67 #endif
68 
69     class ExceptionMatcher : public Catch::MatcherBase<SpecialException> {
70         int m_expected;
71     public:
ExceptionMatcher(int i)72         ExceptionMatcher(int i) : m_expected(i) {}
73 
match(SpecialException const & se) const74         bool match(SpecialException const &se) const override {
75             return se.i == m_expected;
76         }
77 
describe() const78         std::string describe() const override {
79             std::ostringstream ss;
80             ss << "special exception has value of " << m_expected;
81             return ss.str();
82         }
83     };
84 
85 #endif
86 
87     using namespace Catch::Matchers;
88 
89 #ifdef __DJGPP__
nextafter(float from,float to)90     float nextafter(float from, float to)
91     {
92         return ::nextafterf(from, to);
93     }
94 
nextafter(double from,double to)95     double nextafter(double from, double to)
96     {
97         return ::nextafter(from, to);
98     }
99 #else
100     using std::nextafter;
101 #endif
102 
103     TEST_CASE("String matchers", "[matchers]") {
104         REQUIRE_THAT(testStringForMatching(), Contains("string"));
105         REQUIRE_THAT(testStringForMatching(), Contains("string", Catch::CaseSensitive::No));
106         CHECK_THAT(testStringForMatching(), Contains("abc"));
107         CHECK_THAT(testStringForMatching(), Contains("aBC", Catch::CaseSensitive::No));
108 
109         CHECK_THAT(testStringForMatching(), StartsWith("this"));
110         CHECK_THAT(testStringForMatching(), StartsWith("THIS", Catch::CaseSensitive::No));
111         CHECK_THAT(testStringForMatching(), EndsWith("substring"));
112         CHECK_THAT(testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No));
113     }
114 
115     TEST_CASE("Contains string matcher", "[.][failing][matchers]") {
116         CHECK_THAT(testStringForMatching(), Contains("not there", Catch::CaseSensitive::No));
117         CHECK_THAT(testStringForMatching(), Contains("STRING"));
118     }
119 
120     TEST_CASE("StartsWith string matcher", "[.][failing][matchers]") {
121         CHECK_THAT(testStringForMatching(), StartsWith("This String"));
122         CHECK_THAT(testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No));
123     }
124 
125     TEST_CASE("EndsWith string matcher", "[.][failing][matchers]") {
126         CHECK_THAT(testStringForMatching(), EndsWith("Substring"));
127         CHECK_THAT(testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No));
128     }
129 
130     TEST_CASE("Equals string matcher", "[.][failing][matchers]") {
131         CHECK_THAT(testStringForMatching(), Equals("this string contains 'ABC' as a substring"));
132         CHECK_THAT(testStringForMatching(), Equals("something else", Catch::CaseSensitive::No));
133     }
134 
135     TEST_CASE("Equals", "[matchers]") {
136         CHECK_THAT(testStringForMatching(), Equals("this string contains 'abc' as a substring"));
137         CHECK_THAT(testStringForMatching(),
138                    Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No));
139     }
140 
141 // <regex> does not work in libstdc++ 4.8, so we have to enable these tests only when they
142 // are expected to pass and cannot have them in baselines
143     TEST_CASE("Regex string matcher -- libstdc++-4.8 workaround", "[matchers][approvals]") {
144 
145 // This is fiiiine
146 // Taken from an answer at
147 // https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions
148 #if (!defined(__GNUC__)) || \
149       (__cplusplus >= 201103L && \
150       (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
151         (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
152           defined(_GLIBCXX_REGEX_STATE_LIMIT) || \
153              (defined(_GLIBCXX_RELEASE) && \
154              _GLIBCXX_RELEASE > 4))))
155 
156 // DJGPP meets the above condition but <regex> does not work properly anyway
157 #ifndef __DJGPP__
158             REQUIRE_THAT(testStringForMatching(), Matches("this string contains 'abc' as a substring"));
159             REQUIRE_THAT(testStringForMatching(),
160                          Matches("this string CONTAINS 'abc' as a substring", Catch::CaseSensitive::No));
161             REQUIRE_THAT(testStringForMatching(), Matches("^this string contains 'abc' as a substring$"));
162             REQUIRE_THAT(testStringForMatching(), Matches("^.* 'abc' .*$"));
163             REQUIRE_THAT(testStringForMatching(), Matches("^.* 'ABC' .*$", Catch::CaseSensitive::No));
164 #endif
165 
166 #endif
167 
168             REQUIRE_THAT(testStringForMatching2(), !Matches("this string contains 'abc' as a substring"));
169         }
170 
171         TEST_CASE("Regex string matcher", "[matchers][.failing]") {
172             CHECK_THAT(testStringForMatching(), Matches("this STRING contains 'abc' as a substring"));
173             CHECK_THAT(testStringForMatching(), Matches("contains 'abc' as a substring"));
174             CHECK_THAT(testStringForMatching(), Matches("this string contains 'abc' as a"));
175         }
176 
177         TEST_CASE("Matchers can be (AllOf) composed with the && operator", "[matchers][operators][operator&&]") {
178             CHECK_THAT(testStringForMatching(),
179                        Contains("string") &&
180                        Contains("abc") &&
181                        Contains("substring") &&
182                        Contains("contains"));
183         }
184 
185         TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]") {
186             CHECK_THAT(testStringForMatching(), Contains("string") || Contains("different") || Contains("random"));
187             CHECK_THAT(testStringForMatching2(), Contains("string") || Contains("different") || Contains("random"));
188         }
189 
190         TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]") {
191             CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("substring"));
192         }
193 
194         TEST_CASE("Matchers can be composed with both && and || - failing",
195                   "[matchers][operators][operator||][operator&&][.failing]") {
196             CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random"));
197         }
198 
199         TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]") {
200             CHECK_THAT(testStringForMatching(), !Contains("different"));
201         }
202 
203         TEST_CASE("Matchers can be negated (Not) with the ! operator - failing",
204                   "[matchers][operators][not][.failing]") {
205             CHECK_THAT(testStringForMatching(), !Contains("substring"));
206         }
207 
208         TEST_CASE("Vector matchers", "[matchers][vector]") {
209             std::vector<int> v;
210             v.push_back(1);
211             v.push_back(2);
212             v.push_back(3);
213 
214             std::vector<int> v2;
215             v2.push_back(1);
216             v2.push_back(2);
217 
218             std::vector<int> empty;
219 
220             SECTION("Contains (element)") {
221                 CHECK_THAT(v, VectorContains(1));
222                 CHECK_THAT(v, VectorContains(2));
223             }
224             SECTION("Contains (vector)") {
225                 CHECK_THAT(v, Contains(v2));
226                 v2.push_back(3); // now exactly matches
227                 CHECK_THAT(v, Contains(v2));
228 
229                 CHECK_THAT(v, Contains(empty));
230                 CHECK_THAT(empty, Contains(empty));
231             }
232             SECTION("Contains (element), composed") {
233                 CHECK_THAT(v, VectorContains(1) && VectorContains(2));
234             }
235 
236             SECTION("Equals") {
237 
238                 // Same vector
239                 CHECK_THAT(v, Equals(v));
240 
241                 CHECK_THAT(empty, Equals(empty));
242 
243                 // Different vector with same elements
244                 v2.push_back(3);
245                 CHECK_THAT(v, Equals(v2));
246             }
247             SECTION("UnorderedEquals") {
248                 CHECK_THAT(v, UnorderedEquals(v));
249                 CHECK_THAT(empty, UnorderedEquals(empty));
250 
251                 auto permuted = v;
252                 std::next_permutation(begin(permuted), end(permuted));
253                 REQUIRE_THAT(permuted, UnorderedEquals(v));
254 
255                 std::reverse(begin(permuted), end(permuted));
256                 REQUIRE_THAT(permuted, UnorderedEquals(v));
257             }
258         }
259 
260         TEST_CASE("Vector matchers that fail", "[matchers][vector][.][failing]") {
261             std::vector<int> v;
262             v.push_back(1);
263             v.push_back(2);
264             v.push_back(3);
265 
266             std::vector<int> v2;
267             v2.push_back(1);
268             v2.push_back(2);
269 
270             std::vector<int> empty;
271 
272             SECTION("Contains (element)") {
273                 CHECK_THAT(v, VectorContains(-1));
274                 CHECK_THAT(empty, VectorContains(1));
275             }
276             SECTION("Contains (vector)") {
277                 CHECK_THAT(empty, Contains(v));
278                 v2.push_back(4);
279                 CHECK_THAT(v, Contains(v2));
280             }
281 
282             SECTION("Equals") {
283 
284                 CHECK_THAT(v, Equals(v2));
285                 CHECK_THAT(v2, Equals(v));
286                 CHECK_THAT(empty, Equals(v));
287                 CHECK_THAT(v, Equals(empty));
288             }
289             SECTION("UnorderedEquals") {
290                 CHECK_THAT(v, UnorderedEquals(empty));
291                 CHECK_THAT(empty, UnorderedEquals(v));
292 
293                 auto permuted = v;
294                 std::next_permutation(begin(permuted), end(permuted));
295                 permuted.pop_back();
296                 CHECK_THAT(permuted, UnorderedEquals(v));
297 
298                 std::reverse(begin(permuted), end(permuted));
299                 CHECK_THAT(permuted, UnorderedEquals(v));
300             }
301         }
302 
303 #if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)
304         TEST_CASE("Exception matchers that succeed", "[matchers][exceptions][!throws]") {
305             CHECK_THROWS_MATCHES(throws(1), SpecialException, ExceptionMatcher{1});
306             REQUIRE_THROWS_MATCHES(throws(2), SpecialException, ExceptionMatcher{2});
307         }
308 
309         TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.failing]") {
310             SECTION("No exception") {
311                 CHECK_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1});
312                 REQUIRE_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1});
313             }
314             SECTION("Type mismatch") {
315                 CHECK_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
316                 REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1});
317             }
318             SECTION("Contents are wrong") {
319                 CHECK_THROWS_MATCHES(throws(3), SpecialException, ExceptionMatcher{1});
320                 REQUIRE_THROWS_MATCHES(throws(4), SpecialException, ExceptionMatcher{1});
321             }
322         }
323 #endif
324 
325         TEST_CASE("Floating point matchers: float", "[matchers][floating-point]") {
326             SECTION("Margin") {
327                 REQUIRE_THAT(1.f, WithinAbs(1.f, 0));
328                 REQUIRE_THAT(0.f, WithinAbs(1.f, 1));
329 
330                 REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f));
331                 REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f));
332 
333                 REQUIRE_THAT(0.f, WithinAbs(-0.f, 0));
334                 REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
335 
336                 REQUIRE_THAT(11.f, !WithinAbs(10.f, 0.5f));
337                 REQUIRE_THAT(10.f, !WithinAbs(11.f, 0.5f));
338                 REQUIRE_THAT(-10.f, WithinAbs(-10.f, 0.5f));
339                 REQUIRE_THAT(-10.f, WithinAbs(-9.6f, 0.5f));
340             }
341             SECTION("ULPs") {
342                 REQUIRE_THAT(1.f, WithinULP(1.f, 0));
343 
344                 REQUIRE_THAT(nextafter(1.f, 2.f), WithinULP(1.f, 1));
345                 REQUIRE_THAT(nextafter(1.f, 0.f), WithinULP(1.f, 1));
346                 REQUIRE_THAT(nextafter(1.f, 2.f), !WithinULP(1.f, 0));
347 
348                 REQUIRE_THAT(1.f, WithinULP(1.f, 0));
349                 REQUIRE_THAT(-0.f, WithinULP(0.f, 0));
350 
351                 REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
352             }
353             SECTION("Composed") {
354                 REQUIRE_THAT(1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1));
355                 REQUIRE_THAT(1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0));
356 
357                 REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
358             }
359             SECTION("Constructor validation") {
360                 REQUIRE_NOTHROW(WithinAbs(1.f, 0.f));
361                 REQUIRE_THROWS_AS(WithinAbs(1.f, -1.f), std::domain_error);
362 
363                 REQUIRE_NOTHROW(WithinULP(1.f, 0));
364                 REQUIRE_THROWS_AS(WithinULP(1.f, -1), std::domain_error);
365             }
366         }
367 
368         TEST_CASE("Floating point matchers: double", "[matchers][floating-point]") {
369             SECTION("Margin") {
370                 REQUIRE_THAT(1., WithinAbs(1., 0));
371                 REQUIRE_THAT(0., WithinAbs(1., 1));
372 
373                 REQUIRE_THAT(0., !WithinAbs(1., 0.99));
374                 REQUIRE_THAT(0., !WithinAbs(1., 0.99));
375 
376                 REQUIRE_THAT(NAN, !WithinAbs(NAN, 0));
377 
378                 REQUIRE_THAT(11., !WithinAbs(10., 0.5));
379                 REQUIRE_THAT(10., !WithinAbs(11., 0.5));
380                 REQUIRE_THAT(-10., WithinAbs(-10., 0.5));
381                 REQUIRE_THAT(-10., WithinAbs(-9.6, 0.5));
382             }
383             SECTION("ULPs") {
384                 REQUIRE_THAT(1., WithinULP(1., 0));
385 
386                 REQUIRE_THAT(nextafter(1., 2.), WithinULP(1., 1));
387                 REQUIRE_THAT(nextafter(1., 0.), WithinULP(1., 1));
388                 REQUIRE_THAT(nextafter(1., 2.), !WithinULP(1., 0));
389 
390                 REQUIRE_THAT(1., WithinULP(1., 0));
391                 REQUIRE_THAT(-0., WithinULP(0., 0));
392 
393                 REQUIRE_THAT(NAN, !WithinULP(NAN, 123));
394             }
395             SECTION("Composed") {
396                 REQUIRE_THAT(1., WithinAbs(1., 0.5) || WithinULP(2., 1));
397                 REQUIRE_THAT(1., WithinAbs(2., 0.5) || WithinULP(1., 0));
398 
399                 REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123)));
400             }
401             SECTION("Constructor validation") {
402                 REQUIRE_NOTHROW(WithinAbs(1., 0.));
403                 REQUIRE_THROWS_AS(WithinAbs(1., -1.), std::domain_error);
404 
405                 REQUIRE_NOTHROW(WithinULP(1., 0));
406                 REQUIRE_THROWS_AS(WithinULP(1., -1), std::domain_error);
407             }
408         }
409 
410         TEST_CASE("Arbitrary predicate matcher", "[matchers][generic]") {
411             SECTION("Function pointer") {
412                 REQUIRE_THAT(1,  Predicate<int>(alwaysTrue, "always true"));
413                 REQUIRE_THAT(1, !Predicate<int>(alwaysFalse, "always false"));
414             }
415             SECTION("Lambdas + different type") {
416                 REQUIRE_THAT("Hello olleH",
417                              Predicate<std::string>(
__anonb5bcda700202(std::string const& str) 418                                  [] (std::string const& str) -> bool { return str.front() == str.back(); },
419                                  "First and last character should be equal")
420                 );
421 
422                 REQUIRE_THAT("This wouldn't pass",
423                              !Predicate<std::string>(
__anonb5bcda700302(std::string const& str) 424                                  [] (std::string const& str) -> bool { return str.front() == str.back(); }
425                              )
426                 );
427             }
428         }
429 
430         TEST_CASE("Regression test #1", "[matchers][vector]") {
431             // At some point, UnorderedEqualsMatcher skipped
432             // mismatched prefixed before doing the comparison itself
433             std::vector<char> actual = { 'a', 'b' };
434             std::vector<char> expected = { 'c', 'b' };
435 
436             CHECK_THAT(actual, !UnorderedEquals(expected));
437         }
438 
439         TEST_CASE("Predicate matcher can accept const char*", "[matchers][compilation]") {
__anonb5bcda700402(const char* const&) 440             REQUIRE_THAT("foo", Predicate<const char*>([] (const char* const&) { return true; }));
441         }
442 
443 } } // namespace MatchersTests
444 
445 #endif // CATCH_CONFIG_DISABLE_MATCHERS
446 
447 #ifdef __clang__
448 #pragma clang diagnostic pop
449 #endif
450