Download build/_deps/catch2-src/projects/SelfTest/UsageTests/Matchers.tests.cpp from camenduru/thrust: direct link, hf CLI and curl.
- Browser
- Download file 27 kB
-
https://huggingface.co/camenduru/thrust/resolve/main/build/_deps/catch2-src/projects/SelfTest/UsageTests/Matchers.tests.cpp
- Command line
-
hf download hf://camenduru/thrust/build/_deps/catch2-src/projects/SelfTest/UsageTests/Matchers.tests.cpp
-
curl -L -o Matchers.tests.cpp https://huggingface.co/camenduru/thrust/resolve/main/build/_deps/catch2-src/projects/SelfTest/UsageTests/Matchers.tests.cpp
27 kB
| /* | |
| * Created by Phil on 21/02/2017. | |
| * Copyright 2017 Two Blue Cubes Ltd. All rights reserved. | |
| * | |
| * Distributed under the Boost Software License, Version 1.0. (See accompanying | |
| * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
| */ | |
| namespace { namespace MatchersTests { | |
| inline const char *testStringForMatching() { | |
| return "this string contains 'abc' as a substring"; | |
| } | |
| inline const char *testStringForMatching2() { | |
| return "some completely different text that contains one common word"; | |
| } | |
| inline bool alwaysTrue(int) { return true; } | |
| inline bool alwaysFalse(int) { return false; } | |
| struct SpecialException : std::exception { | |
| SpecialException(int i_) : i(i_) {} | |
| char const* what() const noexcept override { | |
| return "SpecialException::what"; | |
| } | |
| int i; | |
| }; | |
| struct DerivedException : std::exception { | |
| char const* what() const noexcept override { | |
| return "DerivedException::what"; | |
| } | |
| }; | |
| void doesNotThrow() {} | |
| [[noreturn]] | |
| void throwsSpecialException(int i) { | |
| throw SpecialException{i}; | |
| } | |
| [[noreturn]] | |
| void throwsAsInt(int i) { | |
| throw i; | |
| } | |
| [[noreturn]] | |
| void throwsDerivedException() { | |
| throw DerivedException{}; | |
| } | |
| class ExceptionMatcher : public Catch::MatcherBase<SpecialException> { | |
| int m_expected; | |
| public: | |
| ExceptionMatcher(int i) : m_expected(i) {} | |
| bool match(SpecialException const &se) const override { | |
| return se.i == m_expected; | |
| } | |
| std::string describe() const override { | |
| std::ostringstream ss; | |
| ss << "special exception has value of " << m_expected; | |
| return ss.str(); | |
| } | |
| }; | |
| using namespace Catch::Matchers; | |
| float nextafter(float from, float to) | |
| { | |
| return ::nextafterf(from, to); | |
| } | |
| double nextafter(double from, double to) | |
| { | |
| return ::nextafter(from, to); | |
| } | |
| using std::nextafter; | |
| TEST_CASE("String matchers", "[matchers]") { | |
| REQUIRE_THAT(testStringForMatching(), Contains("string")); | |
| REQUIRE_THAT(testStringForMatching(), Contains("string", Catch::CaseSensitive::No)); | |
| CHECK_THAT(testStringForMatching(), Contains("abc")); | |
| CHECK_THAT(testStringForMatching(), Contains("aBC", Catch::CaseSensitive::No)); | |
| CHECK_THAT(testStringForMatching(), StartsWith("this")); | |
| CHECK_THAT(testStringForMatching(), StartsWith("THIS", Catch::CaseSensitive::No)); | |
| CHECK_THAT(testStringForMatching(), EndsWith("substring")); | |
| CHECK_THAT(testStringForMatching(), EndsWith(" SuBsTrInG", Catch::CaseSensitive::No)); | |
| } | |
| TEST_CASE("Contains string matcher", "[.][failing][matchers]") { | |
| CHECK_THAT(testStringForMatching(), Contains("not there", Catch::CaseSensitive::No)); | |
| CHECK_THAT(testStringForMatching(), Contains("STRING")); | |
| } | |
| TEST_CASE("StartsWith string matcher", "[.][failing][matchers]") { | |
| CHECK_THAT(testStringForMatching(), StartsWith("This String")); | |
| CHECK_THAT(testStringForMatching(), StartsWith("string", Catch::CaseSensitive::No)); | |
| } | |
| TEST_CASE("EndsWith string matcher", "[.][failing][matchers]") { | |
| CHECK_THAT(testStringForMatching(), EndsWith("Substring")); | |
| CHECK_THAT(testStringForMatching(), EndsWith("this", Catch::CaseSensitive::No)); | |
| } | |
| TEST_CASE("Equals string matcher", "[.][failing][matchers]") { | |
| CHECK_THAT(testStringForMatching(), Equals("this string contains 'ABC' as a substring")); | |
| CHECK_THAT(testStringForMatching(), Equals("something else", Catch::CaseSensitive::No)); | |
| } | |
| TEST_CASE("Equals", "[matchers]") { | |
| CHECK_THAT(testStringForMatching(), Equals("this string contains 'abc' as a substring")); | |
| CHECK_THAT(testStringForMatching(), | |
| Equals("this string contains 'ABC' as a substring", Catch::CaseSensitive::No)); | |
| } | |
| // <regex> does not work in libstdc++ 4.8, so we have to enable these tests only when they | |
| // are expected to pass and cannot have them in baselines | |
| TEST_CASE("Regex string matcher -- libstdc++-4.8 workaround", "[matchers][approvals]") { | |
| // This is fiiiine | |
| // Taken from an answer at | |
| // https://stackoverflow.com/questions/12530406/is-gcc-4-8-or-earlier-buggy-about-regular-expressions | |
| // DJGPP meets the above condition but <regex> does not work properly anyway | |
| 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)); | |
| REQUIRE_THAT(testStringForMatching2(), !Matches("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(), | |
| Contains("string") && | |
| Contains("abc") && | |
| Contains("substring") && | |
| Contains("contains")); | |
| } | |
| TEST_CASE("Matchers can be (AnyOf) composed with the || operator", "[matchers][operators][operator||]") { | |
| CHECK_THAT(testStringForMatching(), Contains("string") || Contains("different") || Contains("random")); | |
| CHECK_THAT(testStringForMatching2(), Contains("string") || Contains("different") || Contains("random")); | |
| } | |
| TEST_CASE("Matchers can be composed with both && and ||", "[matchers][operators][operator||][operator&&]") { | |
| CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("substring")); | |
| } | |
| TEST_CASE("Matchers can be composed with both && and || - failing", | |
| "[matchers][operators][operator||][operator&&][.failing]") { | |
| CHECK_THAT(testStringForMatching(), (Contains("string") || Contains("different")) && Contains("random")); | |
| } | |
| TEST_CASE("Matchers can be negated (Not) with the ! operator", "[matchers][operators][not]") { | |
| CHECK_THAT(testStringForMatching(), !Contains("different")); | |
| } | |
| TEST_CASE("Matchers can be negated (Not) with the ! operator - failing", | |
| "[matchers][operators][not][.failing]") { | |
| CHECK_THAT(testStringForMatching(), !Contains("substring")); | |
| } | |
| template<typename T> | |
| struct CustomAllocator : private std::allocator<T> | |
| { | |
| using size_type = size_t; | |
| using difference_type = ptrdiff_t; | |
| using pointer = T*; | |
| using const_pointer = const T*; | |
| using reference = T&; | |
| using const_reference = const T&; | |
| using value_type = T; | |
| template<typename U> | |
| struct rebind | |
| { using other = CustomAllocator<U>; }; | |
| using propagate_on_container_move_assignment = std::true_type; | |
| using is_always_equal = std::true_type; | |
| CustomAllocator() = default; | |
| CustomAllocator(const CustomAllocator& other) | |
| : std::allocator<T>(other) { } | |
| template<typename U> | |
| CustomAllocator(const CustomAllocator<U>&) { } | |
| ~CustomAllocator() = default; | |
| using std::allocator<T>::address; | |
| using std::allocator<T>::construct; | |
| using std::allocator<T>::max_size; | |
| using std::allocator<T>::destroy; | |
| using std::allocator<T>::allocate; | |
| using std::allocator<T>::deallocate; | |
| }; | |
| TEST_CASE("Vector matchers", "[matchers][vector]") { | |
| std::vector<int> v; | |
| v.push_back(1); | |
| v.push_back(2); | |
| v.push_back(3); | |
| std::vector<int> v2; | |
| v2.push_back(1); | |
| v2.push_back(2); | |
| std::vector<double> v3; | |
| v3.push_back(1); | |
| v3.push_back(2); | |
| v3.push_back(3); | |
| std::vector<double> v4; | |
| v4.push_back(1 + 1e-8); | |
| v4.push_back(2 + 1e-8); | |
| v4.push_back(3 + 1e-8); | |
| std::vector<int, CustomAllocator<int>> v5; | |
| v5.push_back(1); | |
| v5.push_back(2); | |
| v5.push_back(3); | |
| std::vector<int, CustomAllocator<int>> v6; | |
| v6.push_back(1); | |
| v6.push_back(2); | |
| std::vector<int> empty; | |
| SECTION("Contains (element)") { | |
| CHECK_THAT(v, VectorContains(1)); | |
| CHECK_THAT(v, VectorContains(2)); | |
| CHECK_THAT(v5, (VectorContains<int, CustomAllocator<int>>(2))); | |
| } | |
| SECTION("Contains (vector)") { | |
| CHECK_THAT(v, Contains(v2)); | |
| CHECK_THAT(v, Contains<int>({ 1, 2 })); | |
| CHECK_THAT(v5, (Contains<int, std::allocator<int>, CustomAllocator<int>>(v2))); | |
| v2.push_back(3); // now exactly matches | |
| CHECK_THAT(v, Contains(v2)); | |
| CHECK_THAT(v, Contains(empty)); | |
| CHECK_THAT(empty, Contains(empty)); | |
| CHECK_THAT(v5, (Contains<int, std::allocator<int>, CustomAllocator<int>>(v2))); | |
| CHECK_THAT(v5, Contains(v6)); | |
| } | |
| SECTION("Contains (element), composed") { | |
| CHECK_THAT(v, VectorContains(1) && VectorContains(2)); | |
| } | |
| SECTION("Equals") { | |
| // Same vector | |
| CHECK_THAT(v, Equals(v)); | |
| CHECK_THAT(empty, Equals(empty)); | |
| // Different vector with same elements | |
| CHECK_THAT(v, Equals<int>({ 1, 2, 3 })); | |
| v2.push_back(3); | |
| CHECK_THAT(v, Equals(v2)); | |
| CHECK_THAT(v5, (Equals<int, std::allocator<int>, CustomAllocator<int>>(v2))); | |
| v6.push_back(3); | |
| CHECK_THAT(v5, Equals(v6)); | |
| } | |
| SECTION("UnorderedEquals") { | |
| CHECK_THAT(v, UnorderedEquals(v)); | |
| CHECK_THAT(v, UnorderedEquals<int>({ 3, 2, 1 })); | |
| CHECK_THAT(empty, UnorderedEquals(empty)); | |
| auto permuted = v; | |
| std::next_permutation(begin(permuted), end(permuted)); | |
| REQUIRE_THAT(permuted, UnorderedEquals(v)); | |
| std::reverse(begin(permuted), end(permuted)); | |
| REQUIRE_THAT(permuted, UnorderedEquals(v)); | |
| CHECK_THAT(v5, (UnorderedEquals<int, std::allocator<int>, CustomAllocator<int>>(permuted))); | |
| auto v5_permuted = v5; | |
| std::next_permutation(begin(v5_permuted), end(v5_permuted)); | |
| CHECK_THAT(v5_permuted, UnorderedEquals(v5)); | |
| } | |
| } | |
| TEST_CASE("Vector matchers that fail", "[matchers][vector][.][failing]") { | |
| std::vector<int> v; | |
| v.push_back(1); | |
| v.push_back(2); | |
| v.push_back(3); | |
| std::vector<int> v2; | |
| v2.push_back(1); | |
| v2.push_back(2); | |
| std::vector<double> v3; | |
| v3.push_back(1); | |
| v3.push_back(2); | |
| v3.push_back(3); | |
| std::vector<double> v4; | |
| v4.push_back(1.1); | |
| v4.push_back(2.1); | |
| v4.push_back(3.1); | |
| std::vector<int> empty; | |
| SECTION("Contains (element)") { | |
| CHECK_THAT(v, VectorContains(-1)); | |
| CHECK_THAT(empty, VectorContains(1)); | |
| } | |
| SECTION("Contains (vector)") { | |
| CHECK_THAT(empty, Contains(v)); | |
| v2.push_back(4); | |
| CHECK_THAT(v, Contains(v2)); | |
| } | |
| SECTION("Equals") { | |
| CHECK_THAT(v, Equals(v2)); | |
| CHECK_THAT(v2, Equals(v)); | |
| CHECK_THAT(empty, Equals(v)); | |
| CHECK_THAT(v, Equals(empty)); | |
| } | |
| SECTION("UnorderedEquals") { | |
| CHECK_THAT(v, UnorderedEquals(empty)); | |
| CHECK_THAT(empty, UnorderedEquals(v)); | |
| auto permuted = v; | |
| std::next_permutation(begin(permuted), end(permuted)); | |
| permuted.pop_back(); | |
| CHECK_THAT(permuted, UnorderedEquals(v)); | |
| std::reverse(begin(permuted), end(permuted)); | |
| CHECK_THAT(permuted, UnorderedEquals(v)); | |
| } | |
| } | |
| TEST_CASE("Exception matchers that succeed", "[matchers][exceptions][!throws]") { | |
| CHECK_THROWS_MATCHES(throwsSpecialException(1), SpecialException, ExceptionMatcher{1}); | |
| REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, ExceptionMatcher{2}); | |
| } | |
| TEST_CASE("Exception matchers that fail", "[matchers][exceptions][!throws][.failing]") { | |
| SECTION("No exception") { | |
| CHECK_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1}); | |
| REQUIRE_THROWS_MATCHES(doesNotThrow(), SpecialException, ExceptionMatcher{1}); | |
| } | |
| SECTION("Type mismatch") { | |
| CHECK_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1}); | |
| REQUIRE_THROWS_MATCHES(throwsAsInt(1), SpecialException, ExceptionMatcher{1}); | |
| } | |
| SECTION("Contents are wrong") { | |
| CHECK_THROWS_MATCHES(throwsSpecialException(3), SpecialException, ExceptionMatcher{1}); | |
| REQUIRE_THROWS_MATCHES(throwsSpecialException(4), SpecialException, ExceptionMatcher{1}); | |
| } | |
| } | |
| TEST_CASE("Floating point matchers: float", "[matchers][floating-point]") { | |
| SECTION("Relative") { | |
| REQUIRE_THAT(10.f, WithinRel(11.1f, 0.1f)); | |
| REQUIRE_THAT(10.f, !WithinRel(11.2f, 0.1f)); | |
| REQUIRE_THAT( 1.f, !WithinRel(0.f, 0.99f)); | |
| REQUIRE_THAT(-0.f, WithinRel(0.f)); | |
| SECTION("Some subnormal values") { | |
| auto v1 = std::numeric_limits<float>::min(); | |
| auto v2 = v1; | |
| for (int i = 0; i < 5; ++i) { | |
| v2 = std::nextafter(v1, 0.f); | |
| } | |
| REQUIRE_THAT(v1, WithinRel(v2)); | |
| } | |
| } | |
| SECTION("Margin") { | |
| REQUIRE_THAT(1.f, WithinAbs(1.f, 0)); | |
| REQUIRE_THAT(0.f, WithinAbs(1.f, 1)); | |
| REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f)); | |
| REQUIRE_THAT(0.f, !WithinAbs(1.f, 0.99f)); | |
| REQUIRE_THAT(0.f, WithinAbs(-0.f, 0)); | |
| REQUIRE_THAT(11.f, !WithinAbs(10.f, 0.5f)); | |
| REQUIRE_THAT(10.f, !WithinAbs(11.f, 0.5f)); | |
| REQUIRE_THAT(-10.f, WithinAbs(-10.f, 0.5f)); | |
| REQUIRE_THAT(-10.f, WithinAbs(-9.6f, 0.5f)); | |
| } | |
| SECTION("ULPs") { | |
| REQUIRE_THAT(1.f, WithinULP(1.f, 0)); | |
| REQUIRE_THAT(nextafter(1.f, 2.f), WithinULP(1.f, 1)); | |
| REQUIRE_THAT(0.f, WithinULP(nextafter(0.f, 1.f), 1)); | |
| REQUIRE_THAT(1.f, WithinULP(nextafter(1.f, 0.f), 1)); | |
| REQUIRE_THAT(1.f, !WithinULP(nextafter(1.f, 2.f), 0)); | |
| REQUIRE_THAT(1.f, WithinULP(1.f, 0)); | |
| REQUIRE_THAT(-0.f, WithinULP(0.f, 0)); | |
| } | |
| SECTION("Composed") { | |
| REQUIRE_THAT(1.f, WithinAbs(1.f, 0.5) || WithinULP(1.f, 1)); | |
| REQUIRE_THAT(1.f, WithinAbs(2.f, 0.5) || WithinULP(1.f, 0)); | |
| REQUIRE_THAT(0.0001f, WithinAbs(0.f, 0.001f) || WithinRel(0.f, 0.1f)); | |
| } | |
| SECTION("Constructor validation") { | |
| REQUIRE_NOTHROW(WithinAbs(1.f, 0.f)); | |
| REQUIRE_THROWS_AS(WithinAbs(1.f, -1.f), std::domain_error); | |
| REQUIRE_NOTHROW(WithinULP(1.f, 0)); | |
| REQUIRE_THROWS_AS(WithinULP(1.f, static_cast<uint64_t>(-1)), std::domain_error); | |
| REQUIRE_NOTHROW(WithinRel(1.f, 0.f)); | |
| REQUIRE_THROWS_AS(WithinRel(1.f, -0.2f), std::domain_error); | |
| REQUIRE_THROWS_AS(WithinRel(1.f, 1.f), std::domain_error); | |
| } | |
| } | |
| TEST_CASE("Floating point matchers: double", "[matchers][floating-point]") { | |
| SECTION("Relative") { | |
| REQUIRE_THAT(10., WithinRel(11.1, 0.1)); | |
| REQUIRE_THAT(10., !WithinRel(11.2, 0.1)); | |
| REQUIRE_THAT(1., !WithinRel(0., 0.99)); | |
| REQUIRE_THAT(-0., WithinRel(0.)); | |
| SECTION("Some subnormal values") { | |
| auto v1 = std::numeric_limits<double>::min(); | |
| auto v2 = v1; | |
| for (int i = 0; i < 5; ++i) { | |
| v2 = std::nextafter(v1, 0); | |
| } | |
| REQUIRE_THAT(v1, WithinRel(v2)); | |
| } | |
| } | |
| SECTION("Margin") { | |
| REQUIRE_THAT(1., WithinAbs(1., 0)); | |
| REQUIRE_THAT(0., WithinAbs(1., 1)); | |
| REQUIRE_THAT(0., !WithinAbs(1., 0.99)); | |
| REQUIRE_THAT(0., !WithinAbs(1., 0.99)); | |
| REQUIRE_THAT(11., !WithinAbs(10., 0.5)); | |
| REQUIRE_THAT(10., !WithinAbs(11., 0.5)); | |
| REQUIRE_THAT(-10., WithinAbs(-10., 0.5)); | |
| REQUIRE_THAT(-10., WithinAbs(-9.6, 0.5)); | |
| } | |
| SECTION("ULPs") { | |
| REQUIRE_THAT(1., WithinULP(1., 0)); | |
| REQUIRE_THAT(nextafter(1., 2.), WithinULP(1., 1)); | |
| REQUIRE_THAT(0., WithinULP(nextafter(0., 1.), 1)); | |
| REQUIRE_THAT(1., WithinULP(nextafter(1., 0.), 1)); | |
| REQUIRE_THAT(1., !WithinULP(nextafter(1., 2.), 0)); | |
| REQUIRE_THAT(1., WithinULP(1., 0)); | |
| REQUIRE_THAT(-0., WithinULP(0., 0)); | |
| } | |
| SECTION("Composed") { | |
| REQUIRE_THAT(1., WithinAbs(1., 0.5) || WithinULP(2., 1)); | |
| REQUIRE_THAT(1., WithinAbs(2., 0.5) || WithinULP(1., 0)); | |
| REQUIRE_THAT(0.0001, WithinAbs(0., 0.001) || WithinRel(0., 0.1)); | |
| } | |
| SECTION("Constructor validation") { | |
| REQUIRE_NOTHROW(WithinAbs(1., 0.)); | |
| REQUIRE_THROWS_AS(WithinAbs(1., -1.), std::domain_error); | |
| REQUIRE_NOTHROW(WithinULP(1., 0)); | |
| REQUIRE_NOTHROW(WithinRel(1., 0.)); | |
| REQUIRE_THROWS_AS(WithinRel(1., -0.2), std::domain_error); | |
| REQUIRE_THROWS_AS(WithinRel(1., 1.), std::domain_error); | |
| } | |
| } | |
| TEST_CASE("Floating point matchers that are problematic in approvals", "[approvals][matchers][floating-point]") { | |
| REQUIRE_THAT(NAN, !WithinAbs(NAN, 0)); | |
| REQUIRE_THAT(NAN, !(WithinAbs(NAN, 100) || WithinULP(NAN, 123))); | |
| REQUIRE_THAT(NAN, !WithinULP(NAN, 123)); | |
| REQUIRE_THAT(INFINITY, WithinRel(INFINITY)); | |
| REQUIRE_THAT(-INFINITY, !WithinRel(INFINITY)); | |
| REQUIRE_THAT(1., !WithinRel(INFINITY)); | |
| REQUIRE_THAT(INFINITY, !WithinRel(1.)); | |
| REQUIRE_THAT(NAN, !WithinRel(NAN)); | |
| REQUIRE_THAT(1., !WithinRel(NAN)); | |
| REQUIRE_THAT(NAN, !WithinRel(1.)); | |
| } | |
| TEST_CASE("Arbitrary predicate matcher", "[matchers][generic]") { | |
| SECTION("Function pointer") { | |
| REQUIRE_THAT(1, Predicate<int>(alwaysTrue, "always true")); | |
| REQUIRE_THAT(1, !Predicate<int>(alwaysFalse, "always false")); | |
| } | |
| SECTION("Lambdas + different type") { | |
| REQUIRE_THAT("Hello olleH", | |
| Predicate<std::string>( | |
| [] (std::string const& str) -> bool { return str.front() == str.back(); }, | |
| "First and last character should be equal") | |
| ); | |
| REQUIRE_THAT("This wouldn't pass", | |
| !Predicate<std::string>( | |
| [] (std::string const& str) -> bool { return str.front() == str.back(); } | |
| ) | |
| ); | |
| } | |
| } | |
| TEST_CASE("Regression test #1", "[matchers][vector]") { | |
| // At some point, UnorderedEqualsMatcher skipped | |
| // mismatched prefixed before doing the comparison itself | |
| std::vector<char> actual = { 'a', 'b' }; | |
| std::vector<char> expected = { 'c', 'b' }; | |
| CHECK_THAT(actual, !UnorderedEquals(expected)); | |
| } | |
| TEST_CASE("Predicate matcher can accept const char*", "[matchers][compilation]") { | |
| REQUIRE_THAT("foo", Predicate<const char*>([] (const char* const&) { return true; })); | |
| } | |
| TEST_CASE("Vector Approx matcher", "[matchers][approx][vector]") { | |
| using Catch::Matchers::Approx; | |
| SECTION("Empty vector is roughly equal to an empty vector") { | |
| std::vector<double> empty; | |
| REQUIRE_THAT(empty, Approx(empty)); | |
| } | |
| SECTION("Vectors with elements") { | |
| std::vector<double> v1({1., 2., 3.}); | |
| SECTION("A vector is approx equal to itself") { | |
| REQUIRE_THAT(v1, Approx(v1)); | |
| REQUIRE_THAT(v1, Approx<double>({ 1., 2., 3. })); | |
| } | |
| std::vector<double> v2({1.5, 2.5, 3.5}); | |
| SECTION("Different length") { | |
| auto temp(v1); | |
| temp.push_back(4); | |
| REQUIRE_THAT(v1, !Approx(temp)); | |
| } | |
| SECTION("Same length, different elements") { | |
| REQUIRE_THAT(v1, !Approx(v2)); | |
| REQUIRE_THAT(v1, Approx(v2).margin(0.5)); | |
| REQUIRE_THAT(v1, Approx(v2).epsilon(0.5)); | |
| REQUIRE_THAT(v1, Approx(v2).epsilon(0.1).scale(500)); | |
| } | |
| } | |
| } | |
| TEST_CASE("Vector Approx matcher -- failing", "[matchers][approx][vector][.failing]") { | |
| using Catch::Matchers::Approx; | |
| SECTION("Empty and non empty vectors are not approx equal") { | |
| std::vector<double> empty, t1({1, 2}); | |
| CHECK_THAT(empty, Approx(t1)); | |
| } | |
| SECTION("Just different vectors") { | |
| std::vector<double> v1({2., 4., 6.}), v2({1., 3., 5.}); | |
| CHECK_THAT(v1, Approx(v2)); | |
| } | |
| } | |
| TEST_CASE("Exceptions matchers", "[matchers][exceptions][!throws]") { | |
| REQUIRE_THROWS_MATCHES(throwsDerivedException(), DerivedException, Message("DerivedException::what")); | |
| REQUIRE_THROWS_MATCHES(throwsDerivedException(), DerivedException, !Message("derivedexception::what")); | |
| REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, !Message("DerivedException::what")); | |
| REQUIRE_THROWS_MATCHES(throwsSpecialException(2), SpecialException, Message("SpecialException::what")); | |
| } | |
| TEST_CASE("Composed matchers are distinct", "[matchers][composed]") { | |
| auto m1 = Contains("string"); | |
| auto m2 = Contains("random"); | |
| auto composed1 = m1 || m2; | |
| auto m3 = Contains("different"); | |
| auto composed2 = composed1 || m3; | |
| REQUIRE_THAT(testStringForMatching2(), !composed1); | |
| REQUIRE_THAT(testStringForMatching2(), composed2); | |
| } | |
| struct CheckedTestingMatcher : Catch::MatcherBase<int> { | |
| mutable bool matchCalled = false; | |
| bool matchSucceeds = false; | |
| bool match(int const&) const override { | |
| matchCalled = true; | |
| return matchSucceeds; | |
| } | |
| std::string describe() const override { | |
| return "CheckedTestingMatcher set to " + (matchSucceeds ? std::string("succeed") : std::string("fail")); | |
| } | |
| }; | |
| TEST_CASE("Composed matchers shortcircuit", "[matchers][composed]") { | |
| // Check that if first returns false, second is not touched | |
| CheckedTestingMatcher first, second; | |
| SECTION("&&") { | |
| first.matchSucceeds = false; | |
| // This assertion doesn't actually test anything, we just | |
| // want the composed matcher's `match` being called. | |
| CHECK_THAT(1, !(first && second)); | |
| // These two assertions are the important ones | |
| REQUIRE(first.matchCalled); | |
| REQUIRE(!second.matchCalled); | |
| } | |
| // Check that if first returns true, second is not touched | |
| SECTION("||") { | |
| first.matchSucceeds = true; | |
| // This assertion doesn't actually test anything, we just | |
| // want the composed matcher's `match` being called. | |
| CHECK_THAT(1, first || second); | |
| // These two assertions are the important ones | |
| REQUIRE(first.matchCalled); | |
| REQUIRE(!second.matchCalled); | |
| } | |
| } | |
| } } // namespace MatchersTests | |