mirror of
				https://github.com/catchorg/Catch2.git
				synced 2025-10-31 12:17:11 +01:00 
			
		
		
		
	| @@ -10,10 +10,33 @@ | ||||
|  | ||||
| #include "catch_matchers.h" | ||||
|  | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace Catch { | ||||
| namespace Matchers { | ||||
|  | ||||
|     namespace Vector { | ||||
|         namespace Detail { | ||||
|             template <typename InputIterator, typename T> | ||||
|             size_t count(InputIterator first, InputIterator last, T const& item) { | ||||
|                 size_t cnt = 0; | ||||
|                 for (; first != last; ++first) { | ||||
|                     if (*first == item) { | ||||
|                         ++cnt; | ||||
|                     } | ||||
|                 } | ||||
|                 return cnt; | ||||
|             } | ||||
|             template <typename InputIterator, typename T> | ||||
|             bool contains(InputIterator first, InputIterator last, T const& item) { | ||||
|                 for (; first != last; ++first) { | ||||
|                     if (*first == item) { | ||||
|                         return true; | ||||
|                     } | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         template<typename T> | ||||
|         struct ContainsElementMatcher : MatcherBase<std::vector<T>> { | ||||
| @@ -89,6 +112,46 @@ namespace Matchers { | ||||
|             std::vector<T> const& m_comparator; | ||||
|         }; | ||||
|  | ||||
|         template<typename T> | ||||
|         struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> { | ||||
|             UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {} | ||||
|             bool match(std::vector<T> const& vec) const override { | ||||
|                 // Note: This is a reimplementation of std::is_permutation, | ||||
|                 //       because I don't want to include <algorithm> inside the common path | ||||
|                 if (m_target.size() != vec.size()) { | ||||
|                     return false; | ||||
|                 } | ||||
|                 auto lfirst = m_target.begin(), llast = m_target.end(); | ||||
|                 auto rfirst = vec.begin(), rlast = vec.end(); | ||||
|                 // Cut common prefix to optimize checking of permuted parts | ||||
|                 while (lfirst != llast && *lfirst != *rfirst) { | ||||
|                     ++lfirst; ++rfirst; | ||||
|                 } | ||||
|                 if (lfirst == llast) { | ||||
|                     return true; | ||||
|                 } | ||||
|  | ||||
|                 for (auto mid = lfirst; mid != llast; ++mid) { | ||||
|                     // Skip already counted items | ||||
|                     if (Detail::contains(lfirst, mid, *mid)) { | ||||
|                         continue; | ||||
|                     } | ||||
|                     size_t num_vec = Detail::count(rfirst, rlast, *mid); | ||||
|                     if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) { | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return true; | ||||
|             } | ||||
|  | ||||
|             std::string describe() const override { | ||||
|                 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); | ||||
|             } | ||||
|         private: | ||||
|             std::vector<T> const& m_target; | ||||
|         }; | ||||
|  | ||||
|     } // namespace Vector | ||||
|  | ||||
|     // The following functions create the actual matcher objects. | ||||
| @@ -109,6 +172,11 @@ namespace Matchers { | ||||
|         return Vector::EqualsMatcher<T>( comparator ); | ||||
|     } | ||||
|  | ||||
|     template<typename T> | ||||
|     Vector::UnorderedEqualsMatcher<T> UnorderedEquals(std::vector<T> const& target) { | ||||
|         return Vector::UnorderedEqualsMatcher<T>(target); | ||||
|     } | ||||
|  | ||||
| } // namespace Matchers | ||||
| } // namespace Catch | ||||
|  | ||||
|   | ||||
| @@ -828,6 +828,10 @@ Matchers.tests.cpp:<line number>: passed: v, VectorContains(1) && VectorContains | ||||
| Matchers.tests.cpp:<line number>: passed: v, Equals(v) for: { 1, 2, 3 } Equals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: passed: empty, Equals(empty) for: {  } Equals: {  } | ||||
| Matchers.tests.cpp:<line number>: passed: v, Equals(v2) for: { 1, 2, 3 } Equals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: passed: v, UnorderedEquals(v) for: { 1, 2, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: passed: empty, UnorderedEquals(empty) for: {  } UnorderedEquals: {  } | ||||
| Matchers.tests.cpp:<line number>: passed: permuted, UnorderedEquals(v) for: { 1, 3, 2 } UnorderedEquals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: passed: permuted, UnorderedEquals(v) for: { 2, 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: failed: v, VectorContains(-1) for: { 1, 2, 3 } Contains: -1 | ||||
| Matchers.tests.cpp:<line number>: failed: empty, VectorContains(1) for: {  } Contains: 1 | ||||
| Matchers.tests.cpp:<line number>: failed: empty, Contains(v) for: {  } Contains: { 1, 2, 3 } | ||||
| @@ -836,6 +840,10 @@ Matchers.tests.cpp:<line number>: failed: v, Equals(v2) for: { 1, 2, 3 } Equals: | ||||
| Matchers.tests.cpp:<line number>: failed: v2, Equals(v) for: { 1, 2 } Equals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: failed: empty, Equals(v) for: {  } Equals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: failed: v, Equals(empty) for: { 1, 2, 3 } Equals: {  } | ||||
| Matchers.tests.cpp:<line number>: failed: v, UnorderedEquals(empty) for: { 1, 2, 3 } UnorderedEquals: {  } | ||||
| Matchers.tests.cpp:<line number>: failed: empty, UnorderedEquals(v) for: {  } UnorderedEquals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: failed: permuted, UnorderedEquals(v) for: { 1, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
| Matchers.tests.cpp:<line number>: failed: permuted, UnorderedEquals(v) for: { 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
| Exception.tests.cpp:<line number>: passed: thisThrows(), std::domain_error | ||||
| Exception.tests.cpp:<line number>: passed: thisDoesntThrow() | ||||
| Exception.tests.cpp:<line number>: passed: thisThrows() | ||||
| @@ -1023,5 +1031,5 @@ Misc.tests.cpp:<line number>: passed: v.size() == 5 for: 5 == 5 | ||||
| Misc.tests.cpp:<line number>: passed: v.capacity() >= 5 for: 5 >= 5 | ||||
| Misc.tests.cpp:<line number>: passed: | ||||
| Misc.tests.cpp:<line number>: passed: | ||||
| Failed 50 test cases, failed 106 assertions. | ||||
| Failed 50 test cases, failed 110 assertions. | ||||
|  | ||||
|   | ||||
| @@ -809,6 +809,33 @@ Matchers.tests.cpp:<line number>: FAILED: | ||||
| with expansion: | ||||
|   { 1, 2, 3 } Equals: {  } | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Vector matchers that fail | ||||
|   UnorderedEquals | ||||
| ------------------------------------------------------------------------------- | ||||
| Matchers.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( v, UnorderedEquals(empty) ) | ||||
| with expansion: | ||||
|   { 1, 2, 3 } UnorderedEquals: {  } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( empty, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   {  } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( permuted, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 1, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( permuted, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| When unchecked exceptions are thrown directly they are always failures | ||||
| ------------------------------------------------------------------------------- | ||||
| @@ -1054,5 +1081,5 @@ with expansion: | ||||
|  | ||||
| =============================================================================== | ||||
| test cases: 191 | 139 passed |  48 failed |  4 failed as expected | ||||
| assertions: 963 | 839 passed | 103 failed | 21 failed as expected | ||||
| assertions: 971 | 843 passed | 107 failed | 21 failed as expected | ||||
|  | ||||
|   | ||||
| @@ -6480,6 +6480,37 @@ PASSED: | ||||
| with expansion: | ||||
|   { 1, 2, 3 } Equals: { 1, 2, 3 } | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Vector matchers | ||||
|   UnorderedEquals | ||||
| ------------------------------------------------------------------------------- | ||||
| Matchers.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: | ||||
| PASSED: | ||||
|   CHECK_THAT( v, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 1, 2, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: | ||||
| PASSED: | ||||
|   CHECK_THAT( empty, UnorderedEquals(empty) ) | ||||
| with expansion: | ||||
|   {  } UnorderedEquals: {  } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: | ||||
| PASSED: | ||||
|   REQUIRE_THAT( permuted, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 1, 3, 2 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: | ||||
| PASSED: | ||||
|   REQUIRE_THAT( permuted, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 2, 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Vector matchers that fail | ||||
|   Contains (element) | ||||
| @@ -6541,6 +6572,33 @@ Matchers.tests.cpp:<line number>: FAILED: | ||||
| with expansion: | ||||
|   { 1, 2, 3 } Equals: {  } | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| Vector matchers that fail | ||||
|   UnorderedEquals | ||||
| ------------------------------------------------------------------------------- | ||||
| Matchers.tests.cpp:<line number> | ||||
| ............................................................................... | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( v, UnorderedEquals(empty) ) | ||||
| with expansion: | ||||
|   { 1, 2, 3 } UnorderedEquals: {  } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( empty, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   {  } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( permuted, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 1, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| Matchers.tests.cpp:<line number>: FAILED: | ||||
|   CHECK_THAT( permuted, UnorderedEquals(v) ) | ||||
| with expansion: | ||||
|   { 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
|  | ||||
| ------------------------------------------------------------------------------- | ||||
| When checked exceptions are thrown they can be expected or unexpected | ||||
| ------------------------------------------------------------------------------- | ||||
| @@ -8057,5 +8115,5 @@ PASSED: | ||||
|  | ||||
| =============================================================================== | ||||
| test cases: 191 | 137 passed |  50 failed |  4 failed as expected | ||||
| assertions: 962 | 835 passed | 106 failed | 21 failed as expected | ||||
| assertions: 970 | 839 passed | 110 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="92" tests="963" hostname="tbd" time="{duration}" timestamp="{iso8601-timestamp}"> | ||||
|   <testsuite name="<exe-name>" errors="15" failures="96" tests="971" 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}"/> | ||||
| @@ -608,6 +608,7 @@ Exception.tests.cpp:<line number> | ||||
|     <testcase classname="<exe-name>.global" name="Vector matchers/Contains (vector)" time="{duration}"/> | ||||
|     <testcase classname="<exe-name>.global" name="Vector matchers/Contains (element), composed" time="{duration}"/> | ||||
|     <testcase classname="<exe-name>.global" name="Vector matchers/Equals" time="{duration}"/> | ||||
|     <testcase classname="<exe-name>.global" name="Vector matchers/UnorderedEquals" time="{duration}"/> | ||||
|     <testcase classname="<exe-name>.global" name="Vector matchers that fail/Contains (element)" time="{duration}"> | ||||
|       <failure message="{ 1, 2, 3 } Contains: -1" type="CHECK_THAT"> | ||||
| Matchers.tests.cpp:<line number> | ||||
| @@ -635,6 +636,20 @@ Matchers.tests.cpp:<line number> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|       <failure message="{ 1, 2, 3 } Equals: {  }" type="CHECK_THAT"> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|     </testcase> | ||||
|     <testcase classname="<exe-name>.global" name="Vector matchers that fail/UnorderedEquals" time="{duration}"> | ||||
|       <failure message="{ 1, 2, 3 } UnorderedEquals: {  }" type="CHECK_THAT"> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|       <failure message="{  } UnorderedEquals: { 1, 2, 3 }" type="CHECK_THAT"> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|       <failure message="{ 1, 3 } UnorderedEquals: { 1, 2, 3 }" type="CHECK_THAT"> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|       <failure message="{ 3, 1 } UnorderedEquals: { 1, 2, 3 }" type="CHECK_THAT"> | ||||
| Matchers.tests.cpp:<line number> | ||||
|       </failure> | ||||
|     </testcase> | ||||
|   | ||||
| @@ -7377,6 +7377,41 @@ Message from section two | ||||
|         </Expression> | ||||
|         <OverallResults successes="3" failures="0" expectedFailures="0"/> | ||||
|       </Section> | ||||
|       <Section name="UnorderedEquals" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|         <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             v, UnorderedEquals(v) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             { 1, 2, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <Expression success="true" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             empty, UnorderedEquals(empty) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             {  } UnorderedEquals: {  } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             permuted, UnorderedEquals(v) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             { 1, 3, 2 } UnorderedEquals: { 1, 2, 3 } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <Expression success="true" type="REQUIRE_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             permuted, UnorderedEquals(v) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             { 2, 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <OverallResults successes="4" failures="0" expectedFailures="0"/> | ||||
|       </Section> | ||||
|       <OverallResult success="true"/> | ||||
|     </TestCase> | ||||
|     <TestCase name="Vector matchers that fail" tags="[.][failing][matchers][vector]" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
| @@ -7453,6 +7488,41 @@ Message from section two | ||||
|         </Expression> | ||||
|         <OverallResults successes="0" failures="4" expectedFailures="0"/> | ||||
|       </Section> | ||||
|       <Section name="UnorderedEquals" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|         <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             v, UnorderedEquals(empty) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             { 1, 2, 3 } UnorderedEquals: {  } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             empty, UnorderedEquals(v) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             {  } UnorderedEquals: { 1, 2, 3 } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             permuted, UnorderedEquals(v) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             { 1, 3 } UnorderedEquals: { 1, 2, 3 } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <Expression success="false" type="CHECK_THAT" filename="projects/<exe-name>/UsageTests/Matchers.tests.cpp" > | ||||
|           <Original> | ||||
|             permuted, UnorderedEquals(v) | ||||
|           </Original> | ||||
|           <Expanded> | ||||
|             { 3, 1 } UnorderedEquals: { 1, 2, 3 } | ||||
|           </Expanded> | ||||
|         </Expression> | ||||
|         <OverallResults successes="0" failures="4" expectedFailures="0"/> | ||||
|       </Section> | ||||
|       <OverallResult success="false"/> | ||||
|     </TestCase> | ||||
|     <TestCase name="When checked exceptions are thrown they can be expected or unexpected" tags="[!throws]" filename="projects/<exe-name>/UsageTests/Exception.tests.cpp" > | ||||
| @@ -8968,7 +9038,7 @@ loose text artifact | ||||
|       </Section> | ||||
|       <OverallResult success="true"/> | ||||
|     </TestCase> | ||||
|     <OverallResults successes="835" failures="107" expectedFailures="21"/> | ||||
|     <OverallResults successes="839" failures="111" expectedFailures="21"/> | ||||
|   </Group> | ||||
|   <OverallResults successes="835" failures="106" expectedFailures="21"/> | ||||
|   <OverallResults successes="839" failures="110" expectedFailures="21"/> | ||||
| </Catch> | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| #include "catch.hpp" | ||||
|  | ||||
| #include <sstream> | ||||
| #include <algorithm> | ||||
|  | ||||
| #ifdef __clang__ | ||||
| #pragma clang diagnostic push | ||||
| @@ -216,6 +217,17 @@ namespace { namespace MatchersTests { | ||||
|                 v2.push_back(3); | ||||
|                 CHECK_THAT(v, Equals(v2)); | ||||
|             } | ||||
|             SECTION("UnorderedEquals") { | ||||
|                 CHECK_THAT(v, UnorderedEquals(v)); | ||||
|                 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)); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         TEST_CASE("Vector matchers that fail", "[matchers][vector][.][failing]") { | ||||
| @@ -247,6 +259,18 @@ namespace { namespace MatchersTests { | ||||
|                 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]") { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Martin Hořeňovský
					Martin Hořeňovský