aboutsummaryrefslogtreecommitdiffstats
path: root/googlemock/docs
diff options
context:
space:
mode:
Diffstat (limited to 'googlemock/docs')
-rw-r--r--googlemock/docs/cheat_sheet.md51
-rw-r--r--googlemock/docs/cook_book.md75
-rw-r--r--googlemock/docs/for_dummies.md2
-rw-r--r--googlemock/docs/pump_manual.md187
4 files changed, 249 insertions, 66 deletions
diff --git a/googlemock/docs/cheat_sheet.md b/googlemock/docs/cheat_sheet.md
index 850963af..1e0541ba 100644
--- a/googlemock/docs/cheat_sheet.md
+++ b/googlemock/docs/cheat_sheet.md
@@ -266,7 +266,7 @@ Matcher | Description
| `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). |
-| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. |
+| `Optional(m)` | `argument` is `optional<>` that contains a value matching `m`. (For testing whether an `optional<>` is set, check for equality with `nullopt`. You may need to use `Eq(nullopt)` if the inner type doesn't have `==`.)|
| `VariantWith<T>(m)` | `argument` is `variant<>` that holds the alternative of type T with a value matching `m`. |
| `Ref(variable)` | `argument` is a reference to `variable`. |
| `TypedEq<type>(value)` | `argument` has type `type` and is equal to `value`. You may need to use this instead of `Eq(value)` when the mock function is overloaded. |
@@ -278,6 +278,12 @@ copy constructor, try wrap it in `ByRef()`, e.g.
`Eq(ByRef(non_copyable_value))`. If you do that, make sure `non_copyable_value`
is not changed afterwards, or the meaning of your matcher 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`](../../googletest/docs/primer#basic-assertions)
+assertions.
+
#### Floating-Point Matchers {#FpMatchers}
<!-- mdformat off(no multiline tables) -->
@@ -287,6 +293,7 @@ is not changed afterwards, or the meaning of your matcher will be changed.
| `FloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as unequal. |
| `NanSensitiveDoubleEq(a_double)` | `argument` is a `double` value approximately equal to `a_double`, treating two NaNs as equal. |
| `NanSensitiveFloatEq(a_float)` | `argument` is a `float` value approximately equal to `a_float`, treating two NaNs as equal. |
+| `IsNan()` | `argument` is any floating-point type with a NaN value. |
<!-- mdformat on -->
The above matchers use ULP-based comparison (the same as used in googletest).
@@ -325,9 +332,9 @@ The `argument` can be either a C string or a C++ string object:
`ContainsRegex()` and `MatchesRegex()` take ownership of the `RE` object. They
use the regular expression syntax defined
-[here](../../googletest/docs/advanced.md#regular-expression-syntax).
-`StrCaseEq()`, `StrCaseNe()`, `StrEq()`, and `StrNe()` work for wide strings as
-well.
+[here](../../googletest/docs/advanced.md#regular-expression-syntax). All of
+these matchers, except `ContainsRegex()` and `MatchesRegex()` work for wide
+strings as well.
#### Container Matchers
@@ -482,7 +489,7 @@ which must be a permanent callback.
| Matcher | 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 macher `IsDivisibleBy(n)` to match a number divisible by `n`. |
+| `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`. |
| `MATCHER_P2(IsBetween, a, b, std::string(negation ? "isn't" : "is") + " between " + PrintToString(a) + " and " + PrintToString(b)) { return a <= arg && arg <= b; }` | Defines a matcher `IsBetween(a, b)` to match a value in the range [`a`, `b`]. |
<!-- mdformat on -->
@@ -502,16 +509,17 @@ which must be a permanent callback.
#### Returning a Value
<!-- mdformat off(no multiline tables) -->
-| | |
-| :-------------------------- | :-------------------------------------------- |
-| `Return()` | Return from a `void` mock function. |
-| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
-| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. |
-| `ReturnNew<T>(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. |
-| `ReturnNull()` | Return a null pointer. |
-| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. |
-| `ReturnRef(variable)` | Return a reference to `variable`. |
-| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. |
+| | |
+| :-------------------------------- | :-------------------------------------------- |
+| `Return()` | Return from a `void` mock function. |
+| `Return(value)` | Return `value`. If the type of `value` is different to the mock function's return type, `value` is converted to the latter type <i>at the time the expectation is set</i>, not when the action is executed. |
+| `ReturnArg<N>()` | Return the `N`-th (0-based) argument. |
+| `ReturnNew<T>(a1, ..., ak)` | Return `new T(a1, ..., ak)`; a different object is created each time. |
+| `ReturnNull()` | Return a null pointer. |
+| `ReturnPointee(ptr)` | Return the value pointed to by `ptr`. |
+| `ReturnRef(variable)` | Return a reference to `variable`. |
+| `ReturnRefOfCopy(value)` | Return a reference to a copy of `value`; the copy lives as long as the action. |
+| `ReturnRoundRobin({a1, ..., ak})` | Each call will return the next `ai` in the list, starting at the beginning when the end of the list is reached. |
<!-- mdformat on -->
#### Side Effects
@@ -612,19 +620,6 @@ composite action - trying to do so will result in a run-time error.
#### Defining Actions
-<table border="1" cellspacing="0" cellpadding="1">
- <tr>
- <td>`struct SumAction {` <br>
- &emsp;`template <typename T>` <br>
- &emsp;`T operator()(T x, Ty) { return x + y; }` <br>
- `};`
- </td>
- <td> Defines a generic functor that can be used as an action summing its
- arguments. </td> </tr>
- <tr>
- </tr>
-</table>
-
<!-- mdformat off(no multiline tables) -->
| | |
| :--------------------------------- | :-------------------------------------- |
diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md
index ea55ab35..51eb94a9 100644
--- a/googlemock/docs/cook_book.md
+++ b/googlemock/docs/cook_book.md
@@ -421,7 +421,7 @@ sadly they are side effects of C++'s limitations):
`NiceMock<StrictMock<MockFoo> >`) is **not** supported.
2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the
destructor of `MockFoo` is not virtual. We would like to fix this, but it
- requires cleaning up existing tests. http://b/28934720 tracks the issue.
+ requires cleaning up existing tests.
3. During the constructor or destructor of `MockFoo`, the mock object is *not*
nice or strict. This may cause surprises if the constructor or destructor
calls a mock method on `this` object. (This behavior, however, is consistent
@@ -1024,9 +1024,8 @@ using ::testing::Lt;
says that the first argument of `InRange()` must not be 0, and must be less than
the second argument.
-The expression inside `With()` must be a matcher of type
-`Matcher< ::std::tuple<A1, ..., An> >`, where `A1`, ..., `An` are the types of
-the function arguments.
+The expression inside `With()` must be a matcher of type `Matcher<std::tuple<A1,
+..., An>>`, where `A1`, ..., `An` are the types of the function arguments.
You can also write `AllArgs(m)` instead of `m` inside `.With()`. The two forms
are equivalent, but `.With(AllArgs(Lt()))` is more readable than `.With(Lt())`.
@@ -1054,8 +1053,8 @@ complete list.
Note that if you want to pass the arguments to a predicate of your own (e.g.
`.With(Args<0, 1>(Truly(&MyPredicate)))`), that predicate MUST be written to
-take a `::std::tuple` as its argument; gMock will pass the `n` selected
-arguments as *one* single tuple to the predicate.
+take a `std::tuple` as its argument; gMock will pass the `n` selected arguments
+as *one* single tuple to the predicate.
### Using Matchers as Predicates
@@ -1331,11 +1330,11 @@ class BarPlusBazEqMatcher : public MatcherInterface<const Foo&> {
return (foo.bar() + foo.baz()) == expected_sum_;
}
- void DescribeTo(::std::ostream* os) const override {
+ void DescribeTo(std::ostream* os) const override {
*os << "bar() + baz() equals " << expected_sum_;
}
- void DescribeNegationTo(::std::ostream* os) const override {
+ void DescribeNegationTo(std::ostream* os) const override {
*os << "bar() + baz() does not equal " << expected_sum_;
}
private:
@@ -2175,7 +2174,7 @@ own precedence order distinct from the `ON_CALL` precedence order.
### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions}
If the built-in actions don't suit you, you can use an existing callable
-(function, `std::function`, method, functor, lambda as an action.
+(function, `std::function`, method, functor, lambda) as an action.
<!-- GOOGLETEST_CM0024 DO NOT DELETE -->
@@ -2203,7 +2202,8 @@ class Helper {
.WillOnce(&CalculateSum)
.WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1)));
EXPECT_CALL(foo, ComplexJob(_))
- .WillOnce(Invoke(&helper, &Helper::ComplexJob));
+ .WillOnce(Invoke(&helper, &Helper::ComplexJob))
+ .WillOnce([] { return true; })
.WillRepeatedly([](int x) { return x > 0; });
foo.Sum(5, 6); // Invokes CalculateSum(5, 6).
@@ -2213,11 +2213,11 @@ class Helper {
```
The only requirement is that the type of the function, etc must be *compatible*
-with the signature of the mock function, meaning that the latter's arguments can
-be implicitly converted to the corresponding arguments of the former, and the
-former's return type can be implicitly converted to that of the latter. So, you
-can invoke something whose type is *not* exactly the same as the mock function,
-as long as it's safe to do so - nice, huh?
+with the signature of the mock function, meaning that the latter's arguments (if
+it takes any) can be implicitly converted to the corresponding arguments of the
+former, and the former's return type can be implicitly converted to that of the
+latter. So, you can invoke something whose type is *not* exactly the same as the
+mock function, as long as it's safe to do so - nice, huh?
**`Note:`{.escaped}**
@@ -2268,19 +2268,20 @@ TEST_F(FooTest, Test) {
### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments
-`Invoke()` is very useful for doing actions that are more complex. It passes the
-mock function's arguments to the function, etc being invoked such that the
-callee has the full context of the call to work with. If the invoked function is
-not interested in some or all of the arguments, it can simply ignore them.
+`Invoke()` passes the mock function's arguments to the function, etc being
+invoked such that the callee has the full context of the call to work with. If
+the invoked function is not interested in some or all of the arguments, it can
+simply ignore them.
Yet, a common pattern is that a test author wants to invoke a function without
-the arguments of the mock function. `Invoke()` allows her to do that using a
-wrapper function that throws away the arguments before invoking an underlining
-nullary function. Needless to say, this can be tedious and obscures the intent
-of the test.
+the arguments of the mock function. She could do that using a wrapper function
+that throws away the arguments before invoking an underlining nullary function.
+Needless to say, this can be tedious and obscures the intent of the test.
-`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except that it
-doesn't pass the mock function's arguments to the callee. Here's an example:
+There are two solutions to this problem. First, you can pass any callable of
+zero args as an action. Alternatively, use `InvokeWithoutArgs()`, which is like
+`Invoke()` except that it doesn't pass the mock function's arguments to the
+callee. Here's an example of each:
```cpp
using ::testing::_;
@@ -2297,7 +2298,7 @@ bool Job2(int n, char c) { ... }
...
MockFoo foo;
EXPECT_CALL(foo, ComplexJob(_))
- .WillOnce(InvokeWithoutArgs(Job1))
+ .WillOnce([] { Job1(); });
.WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a')));
foo.ComplexJob(10); // Invokes Job1().
@@ -3565,7 +3566,7 @@ class MatchResultListener {
MatchResultListener& operator<<(const T& x);
// Returns the underlying ostream.
- ::std::ostream* stream();
+ std::ostream* stream();
};
template <typename T>
@@ -3578,10 +3579,10 @@ class MatcherInterface {
virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
// Describes this matcher to an ostream.
- virtual void DescribeTo(::std::ostream* os) const = 0;
+ virtual void DescribeTo(std::ostream* os) const = 0;
// Describes the negation of this matcher to an ostream.
- virtual void DescribeNegationTo(::std::ostream* os) const;
+ virtual void DescribeNegationTo(std::ostream* os) const;
};
```
@@ -3609,11 +3610,11 @@ class DivisibleBy7Matcher : public MatcherInterface<int> {
return (n % 7) == 0;
}
- void DescribeTo(::std::ostream* os) const override {
+ void DescribeTo(std::ostream* os) const override {
*os << "is divisible by 7";
}
- void DescribeNegationTo(::std::ostream* os) const override {
+ void DescribeNegationTo(std::ostream* os) const override {
*os << "is not divisible by 7";
}
};
@@ -3995,7 +3996,7 @@ ACTION_TEMPLATE(DuplicateArg,
// Note the comma between int and k:
HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
AND_1_VALUE_PARAMS(output)) {
- *output = T(::std::get<k>(args));
+ *output = T(std::get<k>(args));
}
```
@@ -4087,7 +4088,7 @@ class ActionInterface {
//
// For example, if F is int(bool, const string&), then Result would
- // be int, and ArgumentTuple would be ::std::tuple<bool, const string&>.
+ // be int, and ArgumentTuple would be std::tuple<bool, const string&>.
virtual Result Perform(const ArgumentTuple& args) = 0;
};
```
@@ -4102,8 +4103,8 @@ typedef int IncrementMethod(int*);
class IncrementArgumentAction : public ActionInterface<IncrementMethod> {
public:
- int Perform(const ::std::tuple<int*>& args) override {
- int* p = ::std::get<0>(args); // Grabs the first argument.
+ int Perform(const std::tuple<int*>& args) override {
+ int* p = std::get<0>(args); // Grabs the first argument.
return *p++;
}
};
@@ -4148,8 +4149,8 @@ class ReturnSecondArgumentAction {
public:
template <typename Result, typename ArgumentTuple>
Result Perform(const ArgumentTuple& args) const {
- // To get the i-th (0-based) argument, use ::std::get(args).
- return ::std::get<1>(args);
+ // To get the i-th (0-based) argument, use std::get(args).
+ return std::get<1>(args);
}
};
```
diff --git a/googlemock/docs/for_dummies.md b/googlemock/docs/for_dummies.md
index e11c18d9..93cf06f3 100644
--- a/googlemock/docs/for_dummies.md
+++ b/googlemock/docs/for_dummies.md
@@ -213,7 +213,7 @@ specific domain much better than `Foo` does.
Once you have a mock class, using it is easy. The typical work flow is:
1. Import the gMock names from the `testing` namespace such that you can use
- them unqualified (You only have to do it once per file. Remember that
+ them unqualified (You only have to do it once per file). Remember that
namespaces are a good idea.
2. Create some mock objects.
3. Specify your expectations on them (How many times will a method be called?
diff --git a/googlemock/docs/pump_manual.md b/googlemock/docs/pump_manual.md
new file mode 100644
index 00000000..cdf7c57d
--- /dev/null
+++ b/googlemock/docs/pump_manual.md
@@ -0,0 +1,187 @@
+<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
+
+# The Problem
+
+Template and macro libraries often need to define many classes, functions, or
+macros that vary only (or almost only) in the number of arguments they take.
+It's a lot of repetitive, mechanical, and error-prone work.
+
+Our experience is that it's tedious to write custom scripts, which tend to
+reflect the structure of the generated code poorly and are often hard to read
+and edit. For example, a small change needed in the generated code may require
+some non-intuitive, non-trivial changes in the script. This is especially
+painful when experimenting with the code.
+
+This script may be useful for generating meta code, for example a series of
+macros of FOO1, FOO2, etc. Nevertheless, please make it your last resort
+technique by favouring C++ template metaprogramming or variadic macros.
+
+# Our Solution
+
+Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
+Programming, or Practical Utility for Meta Programming, whichever you prefer) is
+a simple meta-programming tool for C++. The idea is that a programmer writes a
+`foo.pump` file which contains C++ code plus meta code that manipulates the C++
+code. The meta code can handle iterations over a range, nested iterations, local
+meta variable definitions, simple arithmetic, and conditional expressions. You
+can view it as a small Domain-Specific Language. The meta language is designed
+to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and
+concise, making Pump code intuitive and easy to maintain.
+
+## Highlights
+
+* The implementation is in a single Python script and thus ultra portable: no
+ build or installation is needed and it works cross platforms.
+* Pump tries to be smart with respect to
+ [Google's style guide](https://github.com/google/styleguide): it breaks long
+ lines (easy to have when they are generated) at acceptable places to fit
+ within 80 columns and indent the continuation lines correctly.
+* The format is human-readable and more concise than XML.
+* The format works relatively well with Emacs' C++ mode.
+
+## Examples
+
+The following Pump code (where meta keywords start with `$`, `[[` and `]]` are
+meta brackets, and `$$` starts a meta comment that ends with the line):
+
+```
+$var n = 3 $$ Defines a meta variable n.
+$range i 0..n $$ Declares the range of meta iterator i (inclusive).
+$for i [[
+ $$ Meta loop.
+// Foo$i does blah for $i-ary predicates.
+$range j 1..i
+template <size_t N $for j [[, typename A$j]]>
+class Foo$i {
+$if i == 0 [[
+ blah a;
+]] $elif i <= 2 [[
+ blah b;
+]] $else [[
+ blah c;
+]]
+};
+
+]]
+```
+
+will be translated by the Pump compiler to:
+
+```cpp
+// Foo0 does blah for 0-ary predicates.
+template <size_t N>
+class Foo0 {
+ blah a;
+};
+
+// Foo1 does blah for 1-ary predicates.
+template <size_t N, typename A1>
+class Foo1 {
+ blah b;
+};
+
+// Foo2 does blah for 2-ary predicates.
+template <size_t N, typename A1, typename A2>
+class Foo2 {
+ blah b;
+};
+
+// Foo3 does blah for 3-ary predicates.
+template <size_t N, typename A1, typename A2, typename A3>
+class Foo3 {
+ blah c;
+};
+```
+
+In another example,
+
+```
+$range i 1..n
+Func($for i + [[a$i]]);
+$$ The text between i and [[ is the separator between iterations.
+```
+
+will generate one of the following lines (without the comments), depending on
+the value of `n`:
+
+```cpp
+Func(); // If n is 0.
+Func(a1); // If n is 1.
+Func(a1 + a2); // If n is 2.
+Func(a1 + a2 + a3); // If n is 3.
+// And so on...
+```
+
+## Constructs
+
+We support the following meta programming constructs:
+
+| `$var id = exp` | Defines a named constant value. `$id` is |
+: : valid util the end of the current meta :
+: : lexical block. :
+| :------------------------------- | :--------------------------------------- |
+| `$range id exp..exp` | Sets the range of an iteration variable, |
+: : which can be reused in multiple loops :
+: : later. :
+| `$for id sep [[ code ]]` | Iteration. The range of `id` must have |
+: : been defined earlier. `$id` is valid in :
+: : `code`. :
+| `$($)` | Generates a single `$` character. |
+| `$id` | Value of the named constant or iteration |
+: : variable. :
+| `$(exp)` | Value of the expression. |
+| `$if exp [[ code ]] else_branch` | Conditional. |
+| `[[ code ]]` | Meta lexical block. |
+| `cpp_code` | Raw C++ code. |
+| `$$ comment` | Meta comment. |
+
+**Note:** To give the user some freedom in formatting the Pump source code, Pump
+ignores a new-line character if it's right after `$for foo` or next to `[[` or
+`]]`. Without this rule you'll often be forced to write very long lines to get
+the desired output. Therefore sometimes you may need to insert an extra new-line
+in such places for a new-line to show up in your output.
+
+## Grammar
+
+```ebnf
+code ::= atomic_code*
+atomic_code ::= $var id = exp
+ | $var id = [[ code ]]
+ | $range id exp..exp
+ | $for id sep [[ code ]]
+ | $($)
+ | $id
+ | $(exp)
+ | $if exp [[ code ]] else_branch
+ | [[ code ]]
+ | cpp_code
+sep ::= cpp_code | empty_string
+else_branch ::= $else [[ code ]]
+ | $elif exp [[ code ]] else_branch
+ | empty_string
+exp ::= simple_expression_in_Python_syntax
+```
+
+## Code
+
+You can find the source code of Pump in [scripts/pump.py](../scripts/pump.py).
+It is still very unpolished and lacks automated tests, although it has been
+successfully used many times. If you find a chance to use it in your project,
+please let us know what you think! We also welcome help on improving Pump.
+
+## Real Examples
+
+You can find real-world applications of Pump in
+[Google Test](https://github.com/google/googletest/tree/master/googletest) and
+[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The
+source file `foo.h.pump` generates `foo.h`.
+
+## Tips
+
+* If a meta variable is followed by a letter or digit, you can separate them
+ using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper`
+ generate `Foo1Helper` when `j` is 1.
+* To avoid extra-long Pump source lines, you can break a line anywhere you
+ want by inserting `[[]]` followed by a new line. Since any new-line
+ character next to `[[` or `]]` is ignored, the generated code won't contain
+ this new line.