diff options
Diffstat (limited to 'docs/reference/matchers.md')
-rw-r--r-- | docs/reference/matchers.md | 84 |
1 files changed, 52 insertions, 32 deletions
diff --git a/docs/reference/matchers.md b/docs/reference/matchers.md index a2ded435..243e3f95 100644 --- a/docs/reference/matchers.md +++ b/docs/reference/matchers.md @@ -8,25 +8,30 @@ A **matcher** matches a *single* argument. You can use it inside `ON_CALL()` or | `EXPECT_THAT(actual_value, matcher)` | Asserts that `actual_value` matches `matcher`. | | `ASSERT_THAT(actual_value, matcher)` | The same as `EXPECT_THAT(actual_value, matcher)`, except that it generates a **fatal** failure. | -{: .callout .note} -**Note:** Although equality matching via `EXPECT_THAT(actual_value, -expected_value)` is supported, prefer to make the comparison explicit via +{: .callout .warning} +**WARNING:** Equality matching via `EXPECT_THAT(actual_value, expected_value)` +is supported, however note that implicit conversions can cause surprising +results. For example, `EXPECT_THAT(some_bool, "some string")` will compile and +may pass unintentionally. + +**BEST PRACTICE:** Prefer to make the comparison explicit via `EXPECT_THAT(actual_value, Eq(expected_value))` or `EXPECT_EQ(actual_value, expected_value)`. Built-in matchers (where `argument` is the function argument, e.g. `actual_value` in the example above, or when used in the context of `EXPECT_CALL(mock_object, method(matchers))`, the arguments of `method`) are -divided into several categories: +divided into several categories. All matchers are defined in the `::testing` +namespace unless otherwise noted. -### Wildcard +## Wildcard Matcher | Description :-------------------------- | :----------------------------------------------- `_` | `argument` can be any value of the correct type. `A<type>()` or `An<type>()` | `argument` can be any value of type `type`. -### Generic Comparison +## Generic Comparison | Matcher | Description | | :--------------------- | :-------------------------------------------------- | @@ -55,9 +60,9 @@ will be changed. `IsTrue` and `IsFalse` are useful when you need to use a matcher, or for types that can be explicitly converted to Boolean, but are not implicitly converted to Boolean. In other cases, you can use the basic -[`EXPECT_TRUE` and `EXPECT_FALSE`](primer.md#basic-assertions) assertions. +[`EXPECT_TRUE` and `EXPECT_FALSE`](assertions.md#boolean) assertions. -### Floating-Point Matchers {#FpMatchers} +## Floating-Point Matchers {#FpMatchers} | Matcher | Description | | :------------------------------- | :--------------------------------- | @@ -81,29 +86,30 @@ user wants. | `NanSensitiveDoubleNear(a_double, max_abs_error)` | `argument` is a `double` value close to `a_double` (absolute error <= `max_abs_error`), treating two NaNs as equal. | | `NanSensitiveFloatNear(a_float, max_abs_error)` | `argument` is a `float` value close to `a_float` (absolute error <= `max_abs_error`), treating two NaNs as equal. | -### String Matchers +## String Matchers The `argument` can be either a C string or a C++ string object: | Matcher | Description | | :---------------------- | :------------------------------------------------- | -| `ContainsRegex(string)` | `argument` matches the given regular expression. | -| `EndsWith(suffix)` | `argument` ends with string `suffix`. | -| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | -| `IsEmpty()` | `argument` is an empty string. | -| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | -| `StartsWith(prefix)` | `argument` starts with string `prefix`. | -| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | -| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | -| `StrEq(string)` | `argument` is equal to `string`. | -| `StrNe(string)` | `argument` is not equal to `string`. | +| `ContainsRegex(string)` | `argument` matches the given regular expression. | +| `EndsWith(suffix)` | `argument` ends with string `suffix`. | +| `HasSubstr(string)` | `argument` contains `string` as a sub-string. | +| `IsEmpty()` | `argument` is an empty string. | +| `MatchesRegex(string)` | `argument` matches the given regular expression with the match starting at the first character and ending at the last character. | +| `StartsWith(prefix)` | `argument` starts with string `prefix`. | +| `StrCaseEq(string)` | `argument` is equal to `string`, ignoring case. | +| `StrCaseNe(string)` | `argument` is not equal to `string`, ignoring case. | +| `StrEq(string)` | `argument` is equal to `string`. | +| `StrNe(string)` | `argument` is not equal to `string`. | +| `WhenBase64Unescaped(m)` | `argument` is a base-64 escaped string whose unescaped string matches `m`. The web-safe format from [RFC 4648](https://www.rfc-editor.org/rfc/rfc4648#section-5) is supported. | `ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They use the regular expression syntax defined -[here](advanced.md#regular-expression-syntax). All of these matchers, except +[here](../advanced.md#regular-expression-syntax). All of these matchers, except `ContainsRegex()` and `MatchesRegex()` work for wide strings as well. -### Container Matchers +## Container Matchers Most STL-style containers support `==`, so you can use `Eq(expected_container)` or simply `expected_container` to match a container exactly. If you want to @@ -115,6 +121,7 @@ messages, you can use: | `BeginEndDistanceIs(m)` | `argument` is a container whose `begin()` and `end()` iterators are separated by a number of increments matching `m`. E.g. `BeginEndDistanceIs(2)` or `BeginEndDistanceIs(Lt(2))`. For containers that define a `size()` method, `SizeIs(m)` may be more efficient. | | `ContainerEq(container)` | The same as `Eq(container)` except that the failure message also includes which elements are in one container but not the other. | | `Contains(e)` | `argument` contains an element that matches `e`, which can be either a value or a matcher. | +| `Contains(e).Times(n)` | `argument` contains elements that match `e`, which can be either a value or a matcher, and the number of matches is `n`, which can be either a value or a matcher. Unlike the plain `Contains` and `Each` this allows to check for arbitrary occurrences including testing for absence with `Contains(e).Times(0)`. | | `Each(e)` | `argument` is a container where *every* element matches `e`, which can be either a value or a matcher. | | `ElementsAre(e0, e1, ..., en)` | `argument` has `n + 1` elements, where the *i*-th element matches `ei`, which can be a value or a matcher. | | `ElementsAreArray({e0, e1, ..., en})`, `ElementsAreArray(a_container)`, `ElementsAreArray(begin, end)`, `ElementsAreArray(array)`, or `ElementsAreArray(array, count)` | The same as `ElementsAre()` except that the expected element values/matchers come from an initializer list, STL-style container, iterator range, or C-style array. | @@ -145,7 +152,6 @@ messages, you can use: one might write: ```cpp - using ::std::get; MATCHER(FooEq, "") { return std::get<0>(arg).Equals(std::get<1>(arg)); } @@ -153,7 +159,7 @@ messages, you can use: EXPECT_THAT(actual_foos, Pointwise(FooEq(), expected_foos)); ``` -### Member Matchers +## Member Matchers | Matcher | Description | | :------------------------------ | :----------------------------------------- | @@ -187,13 +193,14 @@ messages, you can use: taking addresses of functions is fragile and generally not part of the contract of the function. -### Matching the Result of a Function, Functor, or Callback +## Matching the Result of a Function, Functor, or Callback | Matcher | Description | | :--------------- | :------------------------------------------------ | | `ResultOf(f, m)` | `f(argument)` matches matcher `m`, where `f` is a function or functor. | +| `ResultOf(result_description, f, m)` | The same as the two-parameter version, but provides a better error message. -### Pointer Matchers +## Pointer Matchers | Matcher | Description | | :------------------------ | :---------------------------------------------- | @@ -202,7 +209,7 @@ messages, you can use: | `Pointer(m)` | `argument` (either a smart pointer or a raw pointer) contains a pointer that matches `m`. `m` will match against the raw pointer regardless of the type of `argument`. | | `WhenDynamicCastTo<T>(m)` | when `argument` is passed through `dynamic_cast<T>()`, it matches matcher `m`. | -### Multi-argument Matchers {#MultiArgMatchers} +## Multi-argument Matchers {#MultiArgMatchers} Technically, all matchers match a *single* value. A "multi-argument" matcher is just one that matches a *tuple*. The following matchers can be used to match a @@ -225,7 +232,7 @@ reorder them) to participate in the matching: | `AllArgs(m)` | Equivalent to `m`. Useful as syntactic sugar in `.With(AllArgs(m))`. | | `Args<N1, N2, ..., Nk>(m)` | The tuple of the `k` selected (using 0-based indices) arguments matches `m`, e.g. `Args<1, 2>(Eq())`. | -### Composite Matchers +## Composite Matchers You can make a matcher from one or more other matchers: @@ -236,19 +243,20 @@ You can make a matcher from one or more other matchers: | `AnyOf(m1, m2, ..., mn)` | `argument` matches at least one of the matchers `m1` to `mn`. | | `AnyOfArray({m0, m1, ..., mn})`, `AnyOfArray(a_container)`, `AnyOfArray(begin, end)`, `AnyOfArray(array)`, or `AnyOfArray(array, count)` | The same as `AnyOf()` except that the matchers come from an initializer list, STL-style container, iterator range, or C-style array. | | `Not(m)` | `argument` doesn't match matcher `m`. | +| `Conditional(cond, m1, m2)` | Matches matcher `m1` if `cond` evaluates to true, else matches `m2`.| -### Adapters for Matchers +## Adapters for Matchers | Matcher | Description | | :---------------------- | :------------------------------------ | | `MatcherCast<T>(m)` | casts matcher `m` to type `Matcher<T>`. | -| `SafeMatcherCast<T>(m)` | [safely casts](gmock_cook_book.md#casting-matchers) matcher `m` to type `Matcher<T>`. | +| `SafeMatcherCast<T>(m)` | [safely casts](../gmock_cook_book.md#SafeMatcherCast) matcher `m` to type `Matcher<T>`. | | `Truly(predicate)` | `predicate(argument)` returns something considered by C++ to be true, where `predicate` is a function or functor. | `AddressSatisfies(callback)` and `Truly(callback)` take ownership of `callback`, which must be a permanent callback. -### Using Matchers as Predicates {#MatchersAsPredicatesCheat} +## Using Matchers as Predicates {#MatchersAsPredicatesCheat} | Matcher | Description | | :---------------------------- | :------------------------------------------ | @@ -256,9 +264,9 @@ which must be a permanent callback. | `ExplainMatchResult(m, value, result_listener)` | evaluates to `true` if `value` matches `m`, explaining the result to `result_listener`. | | `Value(value, m)` | evaluates to `true` if `value` matches `m`. | -### Defining Matchers +## Defining Matchers -| Matcher | Description | +| Macro | Description | | :----------------------------------- | :------------------------------------ | | `MATCHER(IsEven, "") { return (arg % 2) == 0; }` | Defines a matcher `IsEven()` to match an even number. | | `MATCHER_P(IsDivisibleBy, n, "") { *result_listener << "where the remainder is " << (arg % n); return (arg % n) == 0; }` | Defines a matcher `IsDivisibleBy(n)` to match a number divisible by `n`. | @@ -280,3 +288,15 @@ which must be a permanent callback. return ExplainMatchResult(matcher, arg.nested().property(), result_listener); } ``` + +5. You can use `DescribeMatcher<>` to describe another matcher. For example: + + ```cpp + MATCHER_P(XAndYThat, matcher, + "X that " + DescribeMatcher<int>(matcher, negation) + + (negation ? " or" : " and") + " Y that " + + DescribeMatcher<double>(matcher, negation)) { + return ExplainMatchResult(matcher, arg.x(), result_listener) && + ExplainMatchResult(matcher, arg.y(), result_listener); + } + ``` |