1<a id="top"></a> 2# Matchers 3 4Matchers are an alternative way to do assertions which are easily extensible and composable. 5This makes them well suited to use with more complex types (such as collections) or your own custom types. 6Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks. 7 8## In use 9 10Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments. 11The first argument is the thing (object or value) under test. The second part is a match _expression_, 12which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators. 13 14For example, to assert that a string ends with a certain substring: 15 16 ```c++ 17using Catch::Matchers::EndsWith; // or Catch::EndsWith 18std::string str = getStringFromSomewhere(); 19REQUIRE_THAT( str, EndsWith( "as a service" ) ); 20 ``` 21 22The matcher objects can take multiple arguments, allowing more fine tuning. 23The built-in string matchers, for example, take a second argument specifying whether the comparison is 24case sensitive or not: 25 26```c++ 27REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) ); 28 ``` 29 30And matchers can be combined: 31 32```c++ 33REQUIRE_THAT( str, 34 EndsWith( "as a service" ) || 35 (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); 36``` 37 38## Built in matchers 39Catch currently provides some matchers, they are in the `Catch::Matchers` and `Catch` namespaces. 40 41### String matchers 42The string matchers are `StartsWith`, `EndsWith`, `Contains`, `Equals` and `Matches`. The first four match a literal (sub)string against a result, while `Matches` takes and matches an ECMAScript regex. Do note that `Matches` matches the string as a whole, meaning that "abc" will not match against "abcd", but "abc.*" will. 43 44Each of the provided `std::string` matchers also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive). 45 46 47### Vector matchers 48The vector matchers are `Contains`, `VectorContains` and `Equals`. `VectorContains` looks for a single element in the matched vector, `Contains` looks for a set (vector) of elements inside the matched vector. 49 50### Floating point matchers 51The floating point matchers are `WithinULP` and `WithinAbs`. `WithinAbs` accepts floating point numbers that are within a certain margin of target. `WithinULP` performs an [ULP](https://en.wikipedia.org/wiki/Unit_in_the_last_place)-based comparison of two floating point numbers and accepts them if they are less than certain number of ULPs apart. 52 53Do note that ULP-based checks only make sense when both compared numbers are of the same type and `WithinULP` will use type of its argument as the target type. This means that `WithinULP(1.f, 1)` will expect to compare `float`s, but `WithinULP(1., 1)` will expect to compare `double`s. 54 55 56### Generic matchers 57Catch also aims to provide a set of generic matchers. Currently this set 58contains only a matcher that takes arbitrary callable predicate and applies 59it onto the provided object. 60 61Because of type inference limitations, the argument type of the predicate 62has to be provided explicitly. Example: 63```cpp 64REQUIRE_THAT("Hello olleH", 65 Predicate<std::string>( 66 [] (std::string const& str) -> bool { return str.front() == str.back(); }, 67 "First and last character should be equal") 68); 69``` 70 71The second argument is an optional description of the predicate, and is 72used only during reporting of the result. 73 74 75## Custom matchers 76It's easy to provide your own matchers to extend Catch or just to work with your own types. 77 78You need to provide two things: 791. A matcher class, derived from `Catch::MatcherBase<T>` - where `T` is the type being tested. 80The constructor takes and stores any arguments needed (e.g. something to compare against) and you must 81override two methods: `match()` and `describe()`. 822. A simple builder function. This is what is actually called from the test code and allows overloading. 83 84Here's an example for asserting that an integer falls within a given range 85(note that it is all inline for the sake of keeping the example short): 86 87```c++ 88// The matcher class 89class IntRange : public Catch::MatcherBase<int> { 90 int m_begin, m_end; 91public: 92 IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {} 93 94 // Performs the test for this matcher 95 bool match( int const& i ) const override { 96 return i >= m_begin && i <= m_end; 97 } 98 99 // Produces a string describing what this matcher does. It should 100 // include any provided data (the begin/ end in this case) and 101 // be written as if it were stating a fact (in the output it will be 102 // preceded by the value under test). 103 virtual std::string describe() const override { 104 std::ostringstream ss; 105 ss << "is between " << m_begin << " and " << m_end; 106 return ss.str(); 107 } 108}; 109 110// The builder function 111inline IntRange IsBetween( int begin, int end ) { 112 return IntRange( begin, end ); 113} 114 115// ... 116 117// Usage 118TEST_CASE("Integers are within a range") 119{ 120 CHECK_THAT( 3, IsBetween( 1, 10 ) ); 121 CHECK_THAT( 100, IsBetween( 1, 10 ) ); 122} 123``` 124 125Running this test gives the following in the console: 126 127``` 128/**/TestFile.cpp:123: FAILED: 129 CHECK_THAT( 100, IsBetween( 1, 10 ) ) 130with expansion: 131 100 is between 1 and 10 132``` 133 134--- 135 136[Home](Readme.md#top) 137