Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
catch_matchers_vector.h
Go to the documentation of this file.
1/*
2 * Created by Phil Nash on 21/02/2017.
3 * Copyright (c) 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#ifndef TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
9#define TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
10
11#include "catch_matchers.h"
12#include "catch_approx.h"
13
14#include <algorithm>
15
16namespace Catch {
17namespace Matchers {
18
19 namespace Vector {
20 template<typename T>
21 struct ContainsElementMatcher : MatcherBase<std::vector<T>> {
22
23 ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}
24
25 bool match(std::vector<T> const &v) const override {
26 for (auto const& el : v) {
27 if (el == m_comparator) {
28 return true;
29 }
30 }
31 return false;
32 }
33
34 std::string describe() const override {
35 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
36 }
37
39 };
40
41 template<typename T>
42 struct ContainsMatcher : MatcherBase<std::vector<T>> {
43
44 ContainsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
45
46 bool match(std::vector<T> const &v) const override {
47 // !TBD: see note in EqualsMatcher
48 if (m_comparator.size() > v.size())
49 return false;
50 for (auto const& comparator : m_comparator) {
51 auto present = false;
52 for (const auto& el : v) {
53 if (el == comparator) {
54 present = true;
55 break;
56 }
57 }
58 if (!present) {
59 return false;
60 }
61 }
62 return true;
63 }
64 std::string describe() const override {
65 return "Contains: " + ::Catch::Detail::stringify( m_comparator );
66 }
67
68 std::vector<T> const& m_comparator;
69 };
70
71 template<typename T>
72 struct EqualsMatcher : MatcherBase<std::vector<T>> {
73
74 EqualsMatcher(std::vector<T> const &comparator) : m_comparator( comparator ) {}
75
76 bool match(std::vector<T> const &v) const override {
77 // !TBD: This currently works if all elements can be compared using !=
78 // - a more general approach would be via a compare template that defaults
79 // to using !=. but could be specialised for, e.g. std::vector<T> etc
80 // - then just call that directly
81 if (m_comparator.size() != v.size())
82 return false;
83 for (std::size_t i = 0; i < v.size(); ++i)
84 if (m_comparator[i] != v[i])
85 return false;
86 return true;
87 }
88 std::string describe() const override {
89 return "Equals: " + ::Catch::Detail::stringify( m_comparator );
90 }
91 std::vector<T> const& m_comparator;
92 };
93
94 template<typename T>
95 struct ApproxMatcher : MatcherBase<std::vector<T>> {
96
97 ApproxMatcher(std::vector<T> const& comparator) : m_comparator( comparator ) {}
98
99 bool match(std::vector<T> const &v) const override {
100 if (m_comparator.size() != v.size())
101 return false;
102 for (std::size_t i = 0; i < v.size(); ++i)
103 if (m_comparator[i] != approx(v[i]))
104 return false;
105 return true;
106 }
107 std::string describe() const override {
108 return "is approx: " + ::Catch::Detail::stringify( m_comparator );
109 }
110 template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
111 ApproxMatcher& epsilon( T const& newEpsilon ) {
112 approx.epsilon(newEpsilon);
113 return *this;
114 }
115 template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
116 ApproxMatcher& margin( T const& newMargin ) {
117 approx.margin(newMargin);
118 return *this;
119 }
120 template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
121 ApproxMatcher& scale( T const& newScale ) {
122 approx.scale(newScale);
123 return *this;
124 }
125
126 std::vector<T> const& m_comparator;
128 };
129
130 template<typename T>
131 struct UnorderedEqualsMatcher : MatcherBase<std::vector<T>> {
132 UnorderedEqualsMatcher(std::vector<T> const& target) : m_target(target) {}
133 bool match(std::vector<T> const& vec) const override {
134 // Note: This is a reimplementation of std::is_permutation,
135 // because I don't want to include <algorithm> inside the common path
136 if (m_target.size() != vec.size()) {
137 return false;
138 }
139 return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());
140 }
141
142 std::string describe() const override {
143 return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target);
144 }
145 private:
146 std::vector<T> const& m_target;
147 };
148
149 } // namespace Vector
150
151 // The following functions create the actual matcher objects.
152 // This allows the types to be inferred
153
154 template<typename T>
155 Vector::ContainsMatcher<T> Contains( std::vector<T> const& comparator ) {
156 return Vector::ContainsMatcher<T>( comparator );
157 }
158
159 template<typename T>
161 return Vector::ContainsElementMatcher<T>( comparator );
162 }
163
164 template<typename T>
165 Vector::EqualsMatcher<T> Equals( std::vector<T> const& comparator ) {
166 return Vector::EqualsMatcher<T>( comparator );
167 }
168
169 template<typename T>
170 Vector::ApproxMatcher<T> Approx( std::vector<T> const& comparator ) {
171 return Vector::ApproxMatcher<T>( comparator );
172 }
173
174 template<typename T>
177 }
178
179} // namespace Matchers
180} // namespace Catch
181
182#endif // TWOBLUECUBES_CATCH_MATCHERS_VECTOR_H_INCLUDED
Approx & epsilon(T const &newEpsilon)
Approx & margin(T const &newMargin)
Approx & scale(T const &newScale)
static Approx custom()
std::string stringify(const T &e)
StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity)
Vector::ApproxMatcher< T > Approx(std::vector< T > const &comparator)
Vector::ContainsElementMatcher< T > VectorContains(T const &comparator)
Vector::UnorderedEqualsMatcher< T > UnorderedEquals(std::vector< T > const &target)
StdString::ContainsMatcher Contains(std::string const &str, CaseSensitive::Choice caseSensitivity)
#define T(meth, val, expected)
ApproxMatcher & epsilon(T const &newEpsilon)
ApproxMatcher & margin(T const &newMargin)
ApproxMatcher(std::vector< T > const &comparator)
ApproxMatcher & scale(T const &newScale)
bool match(std::vector< T > const &v) const override
bool match(std::vector< T > const &v) const override
ContainsMatcher(std::vector< T > const &comparator)
bool match(std::vector< T > const &v) const override
bool match(std::vector< T > const &v) const override
EqualsMatcher(std::vector< T > const &comparator)
bool match(std::vector< T > const &vec) const override