diff options
| author | John Beard | 2023-01-21 23:33:04 +0000 |
|---|---|---|
| committer | GitHub | 2023-01-22 00:33:04 +0100 |
| commit | efca9a0f1826885c1574ed44fc37c8d82ded4546 (patch) | |
| tree | 1b7284ecb35feae1e7134ccd7eb3503b4e91c991 /src | |
| parent | dd36f83b88f3a3d7796469bb2d91f9af71bfa675 (diff) | |
| download | catch3-efca9a0f1826885c1574ed44fc37c8d82ded4546.tar.gz | |
Added ElementsAre and UnorderedElementsAre (#2377)
Co-authored-by: Garz4 <fancygarz4@gmail.com>
Co-authored-by: Martin Hořeňovský <martin.horenovsky@gmail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/catch2/matchers/catch_matchers_all.hpp | 1 | ||||
| -rw-r--r-- | src/catch2/matchers/catch_matchers_range_equals.hpp | 136 |
3 files changed, 138 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2791fa30..1e1e31b7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -252,6 +252,7 @@ set(MATCHER_HEADERS ${SOURCES_DIR}/matchers/catch_matchers_all.hpp ${SOURCES_DIR}/matchers/catch_matchers_container_properties.hpp ${SOURCES_DIR}/matchers/catch_matchers_contains.hpp + ${SOURCES_DIR}/matchers/catch_matchers_range_equals.hpp ${SOURCES_DIR}/matchers/catch_matchers_exception.hpp ${SOURCES_DIR}/matchers/catch_matchers_floating_point.hpp ${SOURCES_DIR}/matchers/catch_matchers_predicate.hpp diff --git a/src/catch2/matchers/catch_matchers_all.hpp b/src/catch2/matchers/catch_matchers_all.hpp index eadf7082..83fe5386 100644 --- a/src/catch2/matchers/catch_matchers_all.hpp +++ b/src/catch2/matchers/catch_matchers_all.hpp @@ -27,6 +27,7 @@ #include <catch2/matchers/catch_matchers_floating_point.hpp> #include <catch2/matchers/catch_matchers_predicate.hpp> #include <catch2/matchers/catch_matchers_quantifiers.hpp> +#include <catch2/matchers/catch_matchers_range_equals.hpp> #include <catch2/matchers/catch_matchers_string.hpp> #include <catch2/matchers/catch_matchers_templated.hpp> #include <catch2/matchers/catch_matchers_vector.hpp> diff --git a/src/catch2/matchers/catch_matchers_range_equals.hpp b/src/catch2/matchers/catch_matchers_range_equals.hpp new file mode 100644 index 00000000..bc94e696 --- /dev/null +++ b/src/catch2/matchers/catch_matchers_range_equals.hpp @@ -0,0 +1,136 @@ + +// Copyright Catch2 Authors +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// SPDX-License-Identifier: BSL-1.0 +#ifndef CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED +#define CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED + +#include <algorithm> +#include <catch2/matchers/catch_matchers_templated.hpp> +#include <utility> + +namespace Catch { + namespace Matchers { + + /** + * Matcher for checking that an element contains the same + * elements in the same order + */ + template <typename TargetRangeLike, typename Equality> + class RangeEqualsMatcher final : public MatcherGenericBase { + TargetRangeLike m_desired; + Equality m_predicate; + + public: + template <typename TargetRangeLike2, typename Equality2> + RangeEqualsMatcher( TargetRangeLike2&& range, + Equality2&& predicate ): + m_desired( CATCH_FORWARD( range ) ), + m_predicate( CATCH_FORWARD( predicate ) ) {} + + template <typename RangeLike> + bool match( RangeLike&& rng ) const { + using std::begin; + using std::end; + return std::equal( begin(m_desired), + end(m_desired), + begin(rng), + end(rng), + m_predicate ); + } + + std::string describe() const override { + return "elements are " + Catch::Detail::stringify( m_desired ); + } + }; + + /** + * Matcher for checking that an element contains the same + * elements (but not necessarily in the same order) + */ + template <typename TargetRangeLike, typename Equality> + class UnorderedRangeEqualsMatcher final : public MatcherGenericBase { + TargetRangeLike m_desired; + Equality m_predicate; + + public: + template <typename TargetRangeLike2, typename Equality2> + UnorderedRangeEqualsMatcher( TargetRangeLike2&& range, + Equality2&& predicate ): + m_desired( CATCH_FORWARD( range ) ), + m_predicate( CATCH_FORWARD( predicate ) ) {} + + template <typename RangeLike> + bool match( RangeLike&& rng ) const { + using std::begin; + using std::end; + return std::is_permutation( begin( m_desired ), + end( m_desired ), + begin( rng ), + end( rng ), + m_predicate ); + } + + std::string describe() const override { + return "unordered elements are " + + ::Catch::Detail::stringify( m_desired ); + } + }; + + /** + * Creates a matcher that checks if all elements in a range are equal + * to all elements in another range. + * + * Uses `std::equal_to` to do the comparison + */ + template <typename RangeLike> + std::enable_if_t<!Detail::is_matcher<RangeLike>::value, + RangeEqualsMatcher<RangeLike, std::equal_to<>>> + RangeEquals( RangeLike&& range ) { + return { CATCH_FORWARD( range ), std::equal_to<>{} }; + } + + /** + * Creates a matcher that checks if all elements in a range are equal + * to all elements in another range. + * + * Uses to provided predicate `predicate` to do the comparisons + */ + template <typename RangeLike, typename Equality> + RangeEqualsMatcher<RangeLike, Equality> + RangeEquals( RangeLike&& range, Equality&& predicate ) { + return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) }; + } + + /** + * Creates a matcher that checks if all elements in a range are equal + * to all elements in another range, in some permutation + * + * Uses `std::equal_to` to do the comparison + */ + template <typename RangeLike> + std::enable_if_t< + !Detail::is_matcher<RangeLike>::value, + UnorderedRangeEqualsMatcher<RangeLike, std::equal_to<>>> + UnorderedRangeEquals( RangeLike&& range ) { + return { CATCH_FORWARD( range ), std::equal_to<>{} }; + } + + /** + * Creates a matcher that checks if all elements in a range are equal + * to all elements in another range, in some permuation. + * + * Uses to provided predicate `predicate` to do the comparisons + */ + template <typename RangeLike, typename Equality> + UnorderedRangeEqualsMatcher<RangeLike, Equality> + UnorderedRangeEquals( RangeLike&& range, Equality&& predicate ) { + return { CATCH_FORWARD( range ), CATCH_FORWARD( predicate ) }; + } + } // namespace Matchers +} // namespace Catch + +#endif // CATCH_MATCHERS_RANGE_EQUALS_HPP_INCLUDED |