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