From 552af8920df24e16738dbb1cb6b46dd52de7804c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uriel=20Garc=C3=ADa=20Rivas?= Date: Mon, 7 Dec 2020 17:23:54 -0600 Subject: [PATCH] Added AnyMatch, AllMatch and NoneMatch --- src/CMakeLists.txt | 1 + src/catch2/matchers/catch_matchers_all.hpp | 1 + .../matchers/catch_matchers_quantifiers.hpp | 109 ++++++++++++ .../Baselines/automake.sw.approved.txt | 1 + .../Baselines/compact.sw.approved.txt | 18 ++ .../Baselines/console.std.approved.txt | 4 +- .../Baselines/console.sw.approved.txt | 127 +++++++++++++- .../SelfTest/Baselines/junit.sw.approved.txt | 5 +- .../Baselines/sonarqube.sw.approved.txt | 3 + tests/SelfTest/Baselines/tap.sw.approved.txt | 38 +++- .../Baselines/teamcity.sw.approved.txt | 2 + tests/SelfTest/Baselines/xml.sw.approved.txt | 164 +++++++++++++++++- .../UsageTests/MatchersRanges.tests.cpp | 55 ++++++ 13 files changed, 518 insertions(+), 10 deletions(-) create mode 100644 src/catch2/matchers/catch_matchers_quantifiers.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e19bd639..15fe1e7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,6 +88,7 @@ set(INTERNAL_HEADERS ${SOURCES_DIR}/matchers/catch_matchers_exception.hpp ${SOURCES_DIR}/matchers/catch_matchers_floating_point.hpp ${SOURCES_DIR}/matchers/catch_matchers_predicate.hpp + ${SOURCES_DIR}/matchers/catch_matchers_quantifiers.hpp ${SOURCES_DIR}/matchers/catch_matchers_string.hpp ${SOURCES_DIR}/matchers/catch_matchers_templated.hpp ${SOURCES_DIR}/matchers/catch_matchers_vector.hpp diff --git a/src/catch2/matchers/catch_matchers_all.hpp b/src/catch2/matchers/catch_matchers_all.hpp index 6466b8ab..3c0bb9f5 100644 --- a/src/catch2/matchers/catch_matchers_all.hpp +++ b/src/catch2/matchers/catch_matchers_all.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/src/catch2/matchers/catch_matchers_quantifiers.hpp b/src/catch2/matchers/catch_matchers_quantifiers.hpp new file mode 100644 index 00000000..09a8c128 --- /dev/null +++ b/src/catch2/matchers/catch_matchers_quantifiers.hpp @@ -0,0 +1,109 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED +#define CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED + +#include + +#include + +namespace Catch { + namespace Matchers { + // Matcher for checking that all elements in range matches a given matcher. + template + class AllMatchMatcher final : public MatcherGenericBase { + Matcher m_matcher; + public: + AllMatchMatcher(Matcher matcher): + m_matcher(std::move(matcher)) + {} + + std::string describe() const override { + return "all match " + m_matcher.describe(); + } + + template + bool match(RangeLike&& rng) const { + for (auto&& elem : rng) { + if (!m_matcher.match(elem)) { + return false; + } + } + return true; + } + }; + + // Matcher for checking that no element in range matches a given matcher. + template + class NoneMatchMatcher final : public MatcherGenericBase { + Matcher m_matcher; + public: + NoneMatchMatcher(Matcher matcher): + m_matcher(std::move(matcher)) + {} + + std::string describe() const override { + return "none match " + m_matcher.describe(); + } + + template + bool match(RangeLike&& rng) const { + for (auto&& elem : rng) { + if (m_matcher.match(elem)) { + return false; + } + } + return true; + } + }; + + // Matcher for checking that at least one element in range matches a given matcher. + template + class AnyMatchMatcher final : public MatcherGenericBase { + Matcher m_matcher; + public: + AnyMatchMatcher(Matcher matcher): + m_matcher(std::move(matcher)) + {} + + std::string describe() const override { + return "any match " + m_matcher.describe(); + } + + template + bool match(RangeLike&& rng) const { + for (auto&& elem : rng) { + if (m_matcher.match(elem)) { + return true; + } + } + return false; + } + }; + + // Creates a matcher that checks whether a range contains element matching a matcher + template + AllMatchMatcher AllMatch(Matcher&& matcher) { + return { std::forward(matcher) }; + } + + // Creates a matcher that checks whether no element in a range matches a matcher. + template + NoneMatchMatcher NoneMatch(Matcher&& matcher) { + return { std::forward(matcher) }; + } + + // Creates a matcher that checks whether any element in a range matches a matcher. + template + AnyMatchMatcher AnyMatch(Matcher&& matcher) { + return { std::forward(matcher) }; + } + } +} + +#endif // CATCH_MATCHERS_QUANTIFIERS_HPP_INCLUDED diff --git a/tests/SelfTest/Baselines/automake.sw.approved.txt b/tests/SelfTest/Baselines/automake.sw.approved.txt index 45e62ac5..4b51b804 100644 --- a/tests/SelfTest/Baselines/automake.sw.approved.txt +++ b/tests/SelfTest/Baselines/automake.sw.approved.txt @@ -238,6 +238,7 @@ Message from section two :test-result: FAIL Unexpected exceptions can be translated :test-result: PASS Upcasting special member functions :test-result: PASS Usage of the SizeIs range matcher +:test-result: PASS Usage of the quantifiers matchers :test-result: PASS Use a custom approx :test-result: PASS Variadic macros :test-result: PASS Vector Approx matcher diff --git a/tests/SelfTest/Baselines/compact.sw.approved.txt b/tests/SelfTest/Baselines/compact.sw.approved.txt index bbb50a93..a50cc6e3 100644 --- a/tests/SelfTest/Baselines/compact.sw.approved.txt +++ b/tests/SelfTest/Baselines/compact.sw.approved.txt @@ -1668,6 +1668,24 @@ MatchersRanges.tests.cpp:: passed: arr, !SizeIs(!Lt(3)) for: { 0, 0 MatchersRanges.tests.cpp:: passed: map, SizeIs(3) for: { {?}, {?}, {?} } has size == 3 MatchersRanges.tests.cpp:: passed: unrelated::ADL_size{}, SizeIs(12) for: {?} has size == 12 MatchersRanges.tests.cpp:: passed: has_size{}, SizeIs(13) for: {?} has size == 13 +MatchersRanges.tests.cpp:: passed: int_arr_arr, AllMatch(Contains(0)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match contains element 0 +MatchersRanges.tests.cpp:: passed: int_arr_arr, AllMatch(SizeIs(5)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match has size == 5 +MatchersRanges.tests.cpp:: passed: string_vector, AllMatch(StartsWith("C")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match starts with: "C" +MatchersRanges.tests.cpp:: passed: string_vector, AllMatch(EndsWith("+")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match ends with: "+" +MatchersRanges.tests.cpp:: passed: int_vectors_list, AllMatch(!IsEmpty()) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match not is empty +MatchersRanges.tests.cpp:: passed: int_vectors_list, AllMatch(SizeIs(2)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match has size == 2 +MatchersRanges.tests.cpp:: passed: int_arr_arr, AnyMatch(Contains(-2)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } any match contains element -2 +MatchersRanges.tests.cpp:: passed: int_arr_arr, AnyMatch(SizeIs(5)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } any match has size == 5 +MatchersRanges.tests.cpp:: passed: string_vector, AnyMatch(StartsWith("CMak")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match starts with: "CMak" +MatchersRanges.tests.cpp:: passed: string_vector, AnyMatch(EndsWith("++")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match ends with: "++" +MatchersRanges.tests.cpp:: passed: int_vectors_list, AnyMatch(Contains(4)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match contains element 4 +MatchersRanges.tests.cpp:: passed: int_vectors_list, AnyMatch(SizeIs(2)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match has size == 2 +MatchersRanges.tests.cpp:: passed: int_arr_arr, NoneMatch(Contains(-6)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } none match contains element -6 +MatchersRanges.tests.cpp:: passed: int_arr_arr, NoneMatch(SizeIs(42)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } none match has size == 42 +MatchersRanges.tests.cpp:: passed: string_vector, NoneMatch(StartsWith("abd")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match starts with: "abd" +MatchersRanges.tests.cpp:: passed: string_vector, NoneMatch(EndsWith("#!--")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match ends with: "#!--" +MatchersRanges.tests.cpp:: passed: int_vectors_list, NoneMatch(IsEmpty()) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match is empty +MatchersRanges.tests.cpp:: passed: int_vectors_list, NoneMatch(SizeIs(3)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match has size == 3 Approx.tests.cpp:: passed: d == approx( 1.23 ) for: 1.23 == Approx( 1.23 ) Approx.tests.cpp:: passed: d == approx( 1.22 ) for: 1.23 == Approx( 1.22 ) Approx.tests.cpp:: passed: d == approx( 1.24 ) for: 1.23 == Approx( 1.24 ) diff --git a/tests/SelfTest/Baselines/console.std.approved.txt b/tests/SelfTest/Baselines/console.std.approved.txt index 2440a763..acd627ee 100644 --- a/tests/SelfTest/Baselines/console.std.approved.txt +++ b/tests/SelfTest/Baselines/console.std.approved.txt @@ -1380,6 +1380,6 @@ due to unexpected exception with message: Why would you throw a std::string? =============================================================================== -test cases: 351 | 277 passed | 70 failed | 4 failed as expected -assertions: 1992 | 1840 passed | 131 failed | 21 failed as expected +test cases: 352 | 278 passed | 70 failed | 4 failed as expected +assertions: 2010 | 1858 passed | 131 failed | 21 failed as expected diff --git a/tests/SelfTest/Baselines/console.sw.approved.txt b/tests/SelfTest/Baselines/console.sw.approved.txt index d8a60b83..2dd42716 100644 --- a/tests/SelfTest/Baselines/console.sw.approved.txt +++ b/tests/SelfTest/Baselines/console.sw.approved.txt @@ -12286,6 +12286,129 @@ MatchersRanges.tests.cpp:: PASSED: with expansion: {?} has size == 13 +------------------------------------------------------------------------------- +Usage of the quantifiers matchers + Usage of the AllMatch range matcher +------------------------------------------------------------------------------- +MatchersRanges.tests.cpp: +............................................................................... + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_arr_arr, AllMatch(Contains(0)) ) +with expansion: + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 + }, { 1, 0, 0, -1, 5 } } all match contains element 0 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_arr_arr, AllMatch(SizeIs(5)) ) +with expansion: + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 + }, { 1, 0, 0, -1, 5 } } all match has size == 5 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( string_vector, AllMatch(StartsWith("C")) ) +with expansion: + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match starts with: + "C" + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( string_vector, AllMatch(EndsWith("+")) ) +with expansion: + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match ends with: + "+" + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_vectors_list, AllMatch(!IsEmpty()) ) +with expansion: + { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match not is empty + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_vectors_list, AllMatch(SizeIs(2)) ) +with expansion: + { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match has size == 2 + +------------------------------------------------------------------------------- +Usage of the quantifiers matchers + Usage of the AnyMatch range matcher +------------------------------------------------------------------------------- +MatchersRanges.tests.cpp: +............................................................................... + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_arr_arr, AnyMatch(Contains(-2)) ) +with expansion: + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 + }, { 1, 0, 0, -1, 5 } } any match contains element -2 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_arr_arr, AnyMatch(SizeIs(5)) ) +with expansion: + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 + }, { 1, 0, 0, -1, 5 } } any match has size == 5 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( string_vector, AnyMatch(StartsWith("CMak")) ) +with expansion: + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match starts with: + "CMak" + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( string_vector, AnyMatch(EndsWith("++")) ) +with expansion: + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match ends with: + "++" + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_vectors_list, AnyMatch(Contains(4)) ) +with expansion: + { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match contains element 4 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_vectors_list, AnyMatch(SizeIs(2)) ) +with expansion: + { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match has size == 2 + +------------------------------------------------------------------------------- +Usage of the quantifiers matchers + Usage of the NoneMatch range matcher +------------------------------------------------------------------------------- +MatchersRanges.tests.cpp: +............................................................................... + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_arr_arr, NoneMatch(Contains(-6)) ) +with expansion: + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 + }, { 1, 0, 0, -1, 5 } } none match contains element -6 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_arr_arr, NoneMatch(SizeIs(42)) ) +with expansion: + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 + }, { 1, 0, 0, -1, 5 } } none match has size == 42 + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( string_vector, NoneMatch(StartsWith("abd")) ) +with expansion: + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match starts + with: "abd" + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( string_vector, NoneMatch(EndsWith("#!--")) ) +with expansion: + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match ends with: + "#!--" + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_vectors_list, NoneMatch(IsEmpty()) ) +with expansion: + { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match is empty + +MatchersRanges.tests.cpp:: PASSED: + REQUIRE_THAT( int_vectors_list, NoneMatch(SizeIs(3)) ) +with expansion: + { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match has size == 3 + ------------------------------------------------------------------------------- Use a custom approx ------------------------------------------------------------------------------- @@ -15681,6 +15804,6 @@ Misc.tests.cpp: Misc.tests.cpp:: PASSED: =============================================================================== -test cases: 351 | 261 passed | 86 failed | 4 failed as expected -assertions: 2009 | 1840 passed | 148 failed | 21 failed as expected +test cases: 352 | 262 passed | 86 failed | 4 failed as expected +assertions: 2027 | 1858 passed | 148 failed | 21 failed as expected diff --git a/tests/SelfTest/Baselines/junit.sw.approved.txt b/tests/SelfTest/Baselines/junit.sw.approved.txt index 21464c62..214e03e8 100644 --- a/tests/SelfTest/Baselines/junit.sw.approved.txt +++ b/tests/SelfTest/Baselines/junit.sw.approved.txt @@ -1,7 +1,7 @@ - + @@ -1283,6 +1283,9 @@ Exception.tests.cpp: + + + diff --git a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt index 96ebb9a0..ed78a3a9 100644 --- a/tests/SelfTest/Baselines/sonarqube.sw.approved.txt +++ b/tests/SelfTest/Baselines/sonarqube.sw.approved.txt @@ -1268,6 +1268,9 @@ Matchers.tests.cpp: + + + diff --git a/tests/SelfTest/Baselines/tap.sw.approved.txt b/tests/SelfTest/Baselines/tap.sw.approved.txt index c07c22bd..3b32341b 100644 --- a/tests/SelfTest/Baselines/tap.sw.approved.txt +++ b/tests/SelfTest/Baselines/tap.sw.approved.txt @@ -3179,6 +3179,42 @@ ok {test-number} - map, SizeIs(3) for: { {?}, {?}, {?} } has size == 3 ok {test-number} - unrelated::ADL_size{}, SizeIs(12) for: {?} has size == 12 # Usage of the SizeIs range matcher ok {test-number} - has_size{}, SizeIs(13) for: {?} has size == 13 +# Usage of the quantifiers matchers +ok {test-number} - int_arr_arr, AllMatch(Contains(0)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match contains element 0 +# Usage of the quantifiers matchers +ok {test-number} - int_arr_arr, AllMatch(SizeIs(5)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match has size == 5 +# Usage of the quantifiers matchers +ok {test-number} - string_vector, AllMatch(StartsWith("C")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match starts with: "C" +# Usage of the quantifiers matchers +ok {test-number} - string_vector, AllMatch(EndsWith("+")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match ends with: "+" +# Usage of the quantifiers matchers +ok {test-number} - int_vectors_list, AllMatch(!IsEmpty()) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match not is empty +# Usage of the quantifiers matchers +ok {test-number} - int_vectors_list, AllMatch(SizeIs(2)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match has size == 2 +# Usage of the quantifiers matchers +ok {test-number} - int_arr_arr, AnyMatch(Contains(-2)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } any match contains element -2 +# Usage of the quantifiers matchers +ok {test-number} - int_arr_arr, AnyMatch(SizeIs(5)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } any match has size == 5 +# Usage of the quantifiers matchers +ok {test-number} - string_vector, AnyMatch(StartsWith("CMak")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match starts with: "CMak" +# Usage of the quantifiers matchers +ok {test-number} - string_vector, AnyMatch(EndsWith("++")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match ends with: "++" +# Usage of the quantifiers matchers +ok {test-number} - int_vectors_list, AnyMatch(Contains(4)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match contains element 4 +# Usage of the quantifiers matchers +ok {test-number} - int_vectors_list, AnyMatch(SizeIs(2)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match has size == 2 +# Usage of the quantifiers matchers +ok {test-number} - int_arr_arr, NoneMatch(Contains(-6)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } none match contains element -6 +# Usage of the quantifiers matchers +ok {test-number} - int_arr_arr, NoneMatch(SizeIs(42)) for: { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } none match has size == 42 +# Usage of the quantifiers matchers +ok {test-number} - string_vector, NoneMatch(StartsWith("abd")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match starts with: "abd" +# Usage of the quantifiers matchers +ok {test-number} - string_vector, NoneMatch(EndsWith("#!--")) for: { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match ends with: "#!--" +# Usage of the quantifiers matchers +ok {test-number} - int_vectors_list, NoneMatch(IsEmpty()) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match is empty +# Usage of the quantifiers matchers +ok {test-number} - int_vectors_list, NoneMatch(SizeIs(3)) for: { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match has size == 3 # Use a custom approx ok {test-number} - d == approx( 1.23 ) for: 1.23 == Approx( 1.23 ) # Use a custom approx @@ -4010,5 +4046,5 @@ ok {test-number} - q3 == 23. for: 23.0 == 23.0 ok {test-number} - # xmlentitycheck ok {test-number} - -1..2009 +1..2027 diff --git a/tests/SelfTest/Baselines/teamcity.sw.approved.txt b/tests/SelfTest/Baselines/teamcity.sw.approved.txt index b9da3591..09b426b7 100644 --- a/tests/SelfTest/Baselines/teamcity.sw.approved.txt +++ b/tests/SelfTest/Baselines/teamcity.sw.approved.txt @@ -579,6 +579,8 @@ Exception.tests.cpp:|nunexpected exception with message:|n "3.14"' ##teamcity[testFinished name='Upcasting special member functions' duration="{duration}"] ##teamcity[testStarted name='Usage of the SizeIs range matcher'] ##teamcity[testFinished name='Usage of the SizeIs range matcher' duration="{duration}"] +##teamcity[testStarted name='Usage of the quantifiers matchers'] +##teamcity[testFinished name='Usage of the quantifiers matchers' duration="{duration}"] ##teamcity[testStarted name='Use a custom approx'] ##teamcity[testFinished name='Use a custom approx' duration="{duration}"] ##teamcity[testStarted name='Variadic macros'] diff --git a/tests/SelfTest/Baselines/xml.sw.approved.txt b/tests/SelfTest/Baselines/xml.sw.approved.txt index 928d2a70..a9de7c7e 100644 --- a/tests/SelfTest/Baselines/xml.sw.approved.txt +++ b/tests/SelfTest/Baselines/xml.sw.approved.txt @@ -14620,6 +14620,162 @@ There is no extra whitespace here + +
+ + + int_arr_arr, AllMatch(Contains(0)) + + + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match contains element 0 + + + + + int_arr_arr, AllMatch(SizeIs(5)) + + + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } all match has size == 5 + + + + + string_vector, AllMatch(StartsWith("C")) + + + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match starts with: "C" + + + + + string_vector, AllMatch(EndsWith("+")) + + + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } all match ends with: "+" + + + + + int_vectors_list, AllMatch(!IsEmpty()) + + + { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match not is empty + + + + + int_vectors_list, AllMatch(SizeIs(2)) + + + { { 1, 2 }, { 3, 4 }, { 5, 6 } } all match has size == 2 + + + +
+
+ + + int_arr_arr, AnyMatch(Contains(-2)) + + + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } any match contains element -2 + + + + + int_arr_arr, AnyMatch(SizeIs(5)) + + + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } any match has size == 5 + + + + + string_vector, AnyMatch(StartsWith("CMak")) + + + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match starts with: "CMak" + + + + + string_vector, AnyMatch(EndsWith("++")) + + + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } any match ends with: "++" + + + + + int_vectors_list, AnyMatch(Contains(4)) + + + { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match contains element 4 + + + + + int_vectors_list, AnyMatch(SizeIs(2)) + + + { { 1, 2 }, { 3, 4 }, { 5, 6 } } any match has size == 2 + + + +
+
+ + + int_arr_arr, NoneMatch(Contains(-6)) + + + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } none match contains element -6 + + + + + int_arr_arr, NoneMatch(SizeIs(42)) + + + { { 0, 1, 2, 3, 5 }, { 4, -3, -2, 5, 0 }, { 0, 0, 0, 5, 0 }, { 0, -5, 0, 5, 0 }, { 1, 0, 0, -1, 5 } } none match has size == 42 + + + + + string_vector, NoneMatch(StartsWith("abd")) + + + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match starts with: "abd" + + + + + string_vector, NoneMatch(EndsWith("#!--")) + + + { "Command+", "Catch2+", "CMake+", "C++", "Console+" } none match ends with: "#!--" + + + + + int_vectors_list, NoneMatch(IsEmpty()) + + + { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match is empty + + + + + int_vectors_list, NoneMatch(SizeIs(3)) + + + { { 1, 2 }, { 3, 4 }, { 5, 6 } } none match has size == 3 + + + +
+ +
@@ -18598,9 +18754,9 @@ loose text artifact - - + + - - + + diff --git a/tests/SelfTest/UsageTests/MatchersRanges.tests.cpp b/tests/SelfTest/UsageTests/MatchersRanges.tests.cpp index 505057d3..13b546e3 100644 --- a/tests/SelfTest/UsageTests/MatchersRanges.tests.cpp +++ b/tests/SelfTest/UsageTests/MatchersRanges.tests.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -217,3 +219,56 @@ TEST_CASE("Usage of the SizeIs range matcher", "[matchers][templated][size]") { REQUIRE_THAT(has_size{}, SizeIs(13)); } } + +TEST_CASE("Usage of the quantifiers matchers", "[matchers][templated][quantifiers]") { + using Catch::Matchers::AllMatch; + using Catch::Matchers::AnyMatch; + using Catch::Matchers::Contains; + using Catch::Matchers::EndsWith; + using Catch::Matchers::IsEmpty; + using Catch::Matchers::NoneMatch; + using Catch::Matchers::SizeIs; + using Catch::Matchers::StartsWith; + std::array, 5> int_arr_arr{{ + {{ 0, 1, 2, 3, 5 }}, + {{ 4,-3,-2, 5, 0 }}, + {{ 0, 0, 0, 5, 0 }}, + {{ 0,-5, 0, 5, 0 }}, + {{ 1, 0, 0,-1, 5 }} + }}; + std::vector string_vector{ "Command+", "Catch2+", "CMake+", "C++", "Console+" }; + std::list> int_vectors_list{ { 1, 2 }, { 3, 4 }, { 5, 6 } }; + + SECTION("Usage of the AllMatch range matcher") { + REQUIRE_THAT(int_arr_arr, AllMatch(Contains(0))); + REQUIRE_THAT(int_arr_arr, AllMatch(SizeIs(5))); + + REQUIRE_THAT(string_vector, AllMatch(StartsWith("C"))); + REQUIRE_THAT(string_vector, AllMatch(EndsWith("+"))); + + REQUIRE_THAT(int_vectors_list, AllMatch(!IsEmpty())); + REQUIRE_THAT(int_vectors_list, AllMatch(SizeIs(2))); + } + + SECTION("Usage of the AnyMatch range matcher") { + REQUIRE_THAT(int_arr_arr, AnyMatch(Contains(-2))); + REQUIRE_THAT(int_arr_arr, AnyMatch(SizeIs(5))); + + REQUIRE_THAT(string_vector, AnyMatch(StartsWith("CMak"))); + REQUIRE_THAT(string_vector, AnyMatch(EndsWith("++"))); + + REQUIRE_THAT(int_vectors_list, AnyMatch(Contains(4))); + REQUIRE_THAT(int_vectors_list, AnyMatch(SizeIs(2))); + } + + SECTION("Usage of the NoneMatch range matcher") { + REQUIRE_THAT(int_arr_arr, NoneMatch(Contains(-6))); + REQUIRE_THAT(int_arr_arr, NoneMatch(SizeIs(42))); + + REQUIRE_THAT(string_vector, NoneMatch(StartsWith("abd"))); + REQUIRE_THAT(string_vector, NoneMatch(EndsWith("#!--"))); + + REQUIRE_THAT(int_vectors_list, NoneMatch(IsEmpty())); + REQUIRE_THAT(int_vectors_list, NoneMatch(SizeIs(3))); + } +}