Wrap all uses in min and max in extra parentheses
[catch.git] / docs / matchers.md
blob5daf68d7c6f792dc78e26676e06a8cc34e73b838
1 # Matchers
3 Matchers are an alternative way to do assertions which are easily extensible and composable.
4 This makes them well suited to use with more complex types (such as collections) or your own custom types.
5 Matchers were first popularised by the [Hamcrest](https://en.wikipedia.org/wiki/Hamcrest) family of frameworks.
7 ## In use
9 Matchers are introduced with the `REQUIRE_THAT` or `CHECK_THAT` macros, which take two arguments.
10 The first argument is the thing (object or value) under test. The second part is a match _expression_,
11 which consists of either a single matcher or one or more matchers combined using `&&`, `||` or `!` operators.
13 For example, to assert that a string ends with a certain substring:
15  ```c++
16 using Catch::Matchers::EndsWith; // or Catch::EndsWith
17 std::string str = getStringFromSomewhere();
18 REQUIRE_THAT( str, EndsWith( "as a service" ) ); 
19  ```
21 The matcher objects can take multiple arguments, allowing more fine tuning.
22 The built-in string matchers, for example, take a second argument specifying whether the comparison is
23 case sensitive or not:
25 ```c++
26 REQUIRE_THAT( str, EndsWith( "as a service", Catch::CaseSensitive::No ) ); 
27  ```
29 And matchers can be combined:
31 ```c++
32 REQUIRE_THAT( str, 
33     EndsWith( "as a service" ) || 
34     (StartsWith( "Big data" ) && !Contains( "web scale" ) ) ); 
35 ```
37 ## Built in matchers
38 Currently Catch has some string matchers and some vector matchers. They are in the `Catch::Matchers` and `Catch` namespaces.
39 The string matchers are `StartsWith`, `EndsWith`, `Contains` and `Equals`. Each of them also takes an optional second argument, that decides case sensitivity (by-default, they are case sensitive).
40 The 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.
43 ## Custom matchers
44 It's easy to provide your own matchers to extend Catch or just to work with your own types.
46 You need to provide two things: 
47 1. A matcher class, derived from `Catch::MatcherBase<T>` - where `T` is the type being tested.
48 The constructor takes and stores any arguments needed (e.g. something to compare against) and you must
49 override two methods: `match()` and `describe()`. 
50 2. A simple builder function. This is what is actually called from the test code and allows overloading.
52 Here's an example for asserting that an integer falls within a given range
53 (note that it is all inline for the sake of keeping the example short):
55 ```c++
56 // The matcher class
57 class IntRange : public Catch::MatcherBase<int> {
58     int m_begin, m_end;
59 public:
60     IntRange( int begin, int end ) : m_begin( begin ), m_end( end ) {}
62     // Performs the test for this matcher
63     virtual bool match( int const& i ) const override {
64         return i >= m_begin && i <= m_end;
65     }
67     // Produces a string describing what this matcher does. It should
68     // include any provided data (the begin/ end in this case) and
69     // be written as if it were stating a fact (in the output it will be
70     // preceded by the value under test).
71     virtual std::string describe() const {
72         std::ostringstream ss;
73         ss << "is between " << m_begin << " and " << m_end;
74         return ss.str();
75     }
78 // The builder function
79 inline IntRange IsBetween( int begin, int end ) {
80     return IntRange( begin, end );
83 // ...
85 // Usage
86 TEST_CASE("Integers are within a range")
88     CHECK_THAT( 3, IsBetween( 1, 10 ) );
89     CHECK_THAT( 100, IsBetween( 1, 10 ) );
91 ```
93 Running this test gives the following in the console:
95 ```
96 /**/TestFile.cpp:123: FAILED:
97   CHECK_THAT( 100, IsBetween( 1, 10 ) )
98 with expansion:
99   100 is between 1 and 10
104 [Home](Readme.md)