summaryrefslogtreecommitdiffstats
path: root/docs/reference
diff options
context:
space:
mode:
Diffstat (limited to 'docs/reference')
-rw-r--r--docs/reference/actions.md7
-rw-r--r--docs/reference/matchers.md38
-rw-r--r--docs/reference/testing.md99
3 files changed, 136 insertions, 8 deletions
diff --git a/docs/reference/actions.md b/docs/reference/actions.md
index ab81a12..2ca3a9f 100644
--- a/docs/reference/actions.md
+++ b/docs/reference/actions.md
@@ -24,7 +24,8 @@ provided by GoogleTest. All actions are defined in the `::testing` namespace.
| :--------------------------------- | :-------------------------------------- |
| `Assign(&variable, value)` | Assign `value` to variable. |
| `DeleteArg<N>()` | Delete the `N`-th (0-based) argument, which must be a pointer. |
-| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer`. |
+| `SaveArg<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by copy-assignment. |
+| `SaveArgByMove<N>(pointer)` | Save the `N`-th (0-based) argument to `*pointer` by move-assignment. |
| `SaveArgPointee<N>(pointer)` | Save the value pointed to by the `N`-th (0-based) argument to `*pointer`. |
| `SetArgReferee<N>(value)` | Assign `value` to the variable referenced by the `N`-th (0-based) argument. |
| `SetArgPointee<N>(value)` | Assign `value` to the variable pointed by the `N`-th (0-based) argument. |
@@ -47,8 +48,8 @@ functor, or lambda.
| `InvokeWithoutArgs(object_pointer, &class::method)` | Invoke the method on the object, which takes no arguments. |
| `InvokeArgument<N>(arg1, arg2, ..., argk)` | Invoke the mock function's `N`-th (0-based) argument, which must be a function or a functor, with the `k` arguments. |
-The return value of the invoked function is used as the return value of the
-action.
+The return value of the invoked function (except `InvokeArgument`) is used as
+the return value of the action.
When defining a callable to be used with `Invoke*()`, you can declare any unused
parameters as `Unused`:
diff --git a/docs/reference/matchers.md b/docs/reference/matchers.md
index 243e3f9..8b3d140 100644
--- a/docs/reference/matchers.md
+++ b/docs/reference/matchers.md
@@ -42,6 +42,8 @@ Matcher | Description
| `Lt(value)` | `argument < value` |
| `Ne(value)` | `argument != value` |
| `IsFalse()` | `argument` evaluates to `false` in a Boolean context. |
+| `DistanceFrom(target, m)` | The distance between `argument` and `target` (computed by `abs(argument - target)`) matches `m`. |
+| `DistanceFrom(target, get_distance, m)` | The distance between `argument` and `target` (computed by `get_distance(argument, target)`) matches `m`. |
| `IsTrue()` | `argument` evaluates to `true` in a Boolean context. |
| `IsNull()` | `argument` is a `NULL` pointer (raw or smart). |
| `NotNull()` | `argument` is a non-null pointer (raw or smart). |
@@ -109,6 +111,33 @@ use the regular expression syntax defined
[here](../advanced.md#regular-expression-syntax). All of these matchers, except
`ContainsRegex()` and `MatchesRegex()` work for wide strings as well.
+## Exception Matchers
+
+| Matcher | Description |
+| :---------------------------------------- | :------------------------------- |
+| `Throws<E>()` | The `argument` is a callable object that, when called, throws an exception of the expected type `E`. |
+| `Throws<E>(m)` | The `argument` is a callable object that, when called, throws an exception of type `E` that satisfies the matcher `m`. |
+| `ThrowsMessage<E>(m)` | The `argument` is a callable object that, when called, throws an exception of type `E` with a message that satisfies the matcher `m`. |
+
+Examples:
+
+```cpp
+auto argument = [] { throw std::runtime_error("error msg"); };
+
+// Checks if the lambda throws a `std::runtime_error`.
+EXPECT_THAT(argument, Throws<std::runtime_error>());
+
+// Checks if the lambda throws a `std::runtime_error` with a specific message
+// that matches "error msg".
+EXPECT_THAT(argument,
+ Throws<std::runtime_error>(Property(&std::runtime_error::what,
+ Eq("error msg"))));
+
+// Checks if the lambda throws a `std::runtime_error` with a message that
+// contains "msg".
+EXPECT_THAT(argument, ThrowsMessage<std::runtime_error>(HasSubstr("msg")));
+```
+
## Container Matchers
Most STL-style containers support `==`, so you can use `Eq(expected_container)`
@@ -171,6 +200,11 @@ messages, you can use:
| `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. The method `property()` must take no argument and be declared as `const`. |
| `Property(property_name, &class::property, m)` | The same as the two-parameter version, but provides a better error message.
+{: .callout .warning}
+Warning: Don't use `Property()` against member functions that you do not own,
+because taking addresses of functions is fragile and generally not part of the
+contract of the function.
+
**Notes:**
* You can use `FieldsAre()` to match any type that supports structured
@@ -189,10 +223,6 @@ messages, you can use:
EXPECT_THAT(s, FieldsAre(42, "aloha"));
```
-* Don't use `Property()` against member functions that you do not own, because
- 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
| Matcher | Description |
diff --git a/docs/reference/testing.md b/docs/reference/testing.md
index 3ed5211..ea43721 100644
--- a/docs/reference/testing.md
+++ b/docs/reference/testing.md
@@ -110,7 +110,7 @@ namespace:
| `ValuesIn(container)` or `ValuesIn(begin,end)` | Yields values from a C-style array, an STL-style container, or an iterator range `[begin, end)`. |
| `Bool()` | Yields sequence `{false, true}`. |
| `Combine(g1, g2, ..., gN)` | Yields as `std::tuple` *n*-tuples all combinations (Cartesian product) of the values generated by the given *n* generators `g1`, `g2`, ..., `gN`. |
-| `ConvertGenerator<T>(g)` | Yields values generated by generator `g`, `static_cast` to `T`. |
+| `ConvertGenerator<T>(g)` or `ConvertGenerator(g, func)` | Yields values generated by generator `g`, `static_cast` from `T`. (Note: `T` might not be what you expect. See [*Using ConvertGenerator*](#using-convertgenerator) below.) The second overload uses `func` to perform the conversion. |
The optional last argument *`name_generator`* is a function or functor that
generates custom test name suffixes based on the test parameters. The function
@@ -137,6 +137,103 @@ For more information, see
See also
[`GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST`](#GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST).
+###### Using `ConvertGenerator`
+
+The functions listed in the table above appear to return generators that create
+values of the desired types, but this is not generally the case. Rather, they
+typically return factory objects that convert to the the desired generators.
+This affords some flexibility in allowing you to specify values of types that
+are different from, yet implicitly convertible to, the actual parameter type
+required by your fixture class.
+
+For example, you can do the following with a fixture that requires an `int`
+parameter:
+
+```cpp
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+ testing::Values(1, 1.2)); // Yes, Values() supports heterogeneous argument types.
+```
+
+It might seem obvious that `1.2` &mdash; a `double` &mdash; will be converted to
+an `int` but in actuality it requires some template gymnastics involving the
+indirection described in the previous paragraph.
+
+What if your parameter type is not implicitly convertible from the generated
+type but is *explicitly* convertible? There will be no automatic conversion, but
+you can force it by applying `ConvertGenerator<T>`. The compiler can
+automatically deduce the target type (your fixture's parameter type), but
+because of the aforementioned indirection it cannot decide what the generated
+type should be. You need to tell it, by providing the type `T` explicitly. Thus
+`T` should not be your fixture's parameter type, but rather an intermediate type
+that is supported by the factory object, and which can be `static_cast` to the
+fixture's parameter type:
+
+```cpp
+// The fixture's parameter type.
+class MyParam {
+ public:
+ // Explicit converting ctor.
+ explicit MyParam(const std::tuple<int, bool>& t);
+ ...
+};
+
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+ ConvertGenerator<std::tuple<int, bool>>(Combine(Values(0.1, 1.2), Bool())));
+```
+
+In this example `Combine` supports the generation of `std::tuple<int, bool>>`
+objects (even though the provided values for the first tuple element are
+`double`s) and those `tuple`s get converted into `MyParam` objects by virtue of
+the call to `ConvertGenerator`.
+
+For parameter types that are not convertible from the generated types you can
+provide a callable that does the conversion. The callable accepts an object of
+the generated type and returns an object of the fixture's parameter type. The
+generated type can often be deduced by the compiler from the callable's call
+signature so you do not usually need specify it explicitly (but see a caveat
+below).
+
+```cpp
+// The fixture's parameter type.
+class MyParam {
+ public:
+ MyParam(int, bool);
+ ...
+};
+
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+ ConvertGenerator(Combine(Values(1, 1.2), Bool()),
+ [](const std::tuple<int, bool>& t){
+ const auto [i, b] = t;
+ return MyParam(i, b);
+ }));
+```
+
+The callable may be anything that can be used to initialize a `std::function`
+with the appropriate call signature. Note the callable's return object gets
+`static_cast` to the fixture's parameter type, so it does not have to be of that
+exact type, only convertible to it.
+
+**Caveat:** Consider the following example.
+
+```cpp
+INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,
+ ConvertGenerator(Values(std::string("s")), [](std::string_view s) { ... }));
+```
+
+The `string` argument gets copied into the factory object returned by `Values`.
+Then, because the generated type deduced from the lambda is `string_view`, the
+factory object spawns a generator that holds a `string_view` referencing that
+`string`. Unfortunately, by the time this generator gets invoked, the factory
+object is gone and the `string_view` is dangling.
+
+To overcome this problem you can specify the generated type explicitly:
+`ConvertGenerator<std::string>(Values(std::string("s")), [](std::string_view s)
+{ ... })`. Alternatively, you can change the lambda's signature to take a
+`std::string` or a `const std::string&` (the latter will not leave you with a
+dangling reference because the type deduction strips off the reference and the
+`const`).
+
### TYPED_TEST_SUITE {#TYPED_TEST_SUITE}
`TYPED_TEST_SUITE(`*`TestFixtureName`*`,`*`Types`*`)`