| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
12 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
13 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
14 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
15 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
16 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
17 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
18 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
19 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
20 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
21 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
22 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
23 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
24 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
25 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
26 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
27 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
28 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
29 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
30 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
31 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
32 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
33 |
// This is the main header file a user should include. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
34 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
35 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
36 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
37 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
38 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
39 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
40 |
// This file implements the following syntax: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
41 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
42 |
// ON_CALL(mock_object, Method(...)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
43 |
// .With(...) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
44 |
// .WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
45 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
46 |
// where With() is optional and WillByDefault() must appear exactly |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
47 |
// once. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
48 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
49 |
// EXPECT_CALL(mock_object, Method(...)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
50 |
// .With(...) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
51 |
// .Times(...) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
52 |
// .InSequence(...) * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
53 |
// .WillOnce(...) * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
54 |
// .WillRepeatedly(...) ? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
55 |
// .RetiresOnSaturation() ? ; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
56 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
57 |
// where all clauses are optional and WillOnce() can be repeated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
58 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
59 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
60 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
61 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
62 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
63 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
64 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
65 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
66 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
67 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
68 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
69 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
70 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
71 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
72 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
73 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
74 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
75 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
76 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
77 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
78 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
79 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
80 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
81 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
82 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
83 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
84 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
85 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
86 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
87 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
88 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
89 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
90 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
91 |
// The ACTION* family of macros can be used in a namespace scope to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
92 |
// define custom actions easily. The syntax: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
93 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
94 |
// ACTION(name) { statements; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
95 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
96 |
// will define an action with the given name that executes the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
97 |
// statements. The value returned by the statements will be used as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
98 |
// the return value of the action. Inside the statements, you can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
99 |
// refer to the K-th (0-based) argument of the mock function by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
100 |
// 'argK', and refer to its type by 'argK_type'. For example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
101 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
102 |
// ACTION(IncrementArg1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
103 |
// arg1_type temp = arg1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
104 |
// return ++(*temp); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
105 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
106 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
107 |
// allows you to write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
108 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
109 |
// ...WillOnce(IncrementArg1()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
110 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
111 |
// You can also refer to the entire argument tuple and its type by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
112 |
// 'args' and 'args_type', and refer to the mock function type and its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
113 |
// return type by 'function_type' and 'return_type'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
114 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
115 |
// Note that you don't need to specify the types of the mock function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
116 |
// arguments. However rest assured that your code is still type-safe: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
117 |
// you'll get a compiler error if *arg1 doesn't support the ++ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
118 |
// operator, or if the type of ++(*arg1) isn't compatible with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
119 |
// mock function's return type, for example. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
120 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
121 |
// Sometimes you'll want to parameterize the action. For that you can use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
122 |
// another macro: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
123 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
124 |
// ACTION_P(name, param_name) { statements; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
125 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
126 |
// For example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
127 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
128 |
// ACTION_P(Add, n) { return arg0 + n; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
129 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
130 |
// will allow you to write: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
131 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
132 |
// ...WillOnce(Add(5)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
133 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
134 |
// Note that you don't need to provide the type of the parameter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
135 |
// either. If you need to reference the type of a parameter named |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
136 |
// 'foo', you can write 'foo_type'. For example, in the body of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
137 |
// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
138 |
// of 'n'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
139 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
140 |
// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
141 |
// multi-parameter actions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
142 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
143 |
// For the purpose of typing, you can view |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
144 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
145 |
// ACTION_Pk(Foo, p1, ..., pk) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
146 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
147 |
// as shorthand for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
148 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
149 |
// template <typename p1_type, ..., typename pk_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
150 |
// FooActionPk<p1_type, ..., pk_type> Foo(p1_type p1, ..., pk_type pk) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
151 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
152 |
// In particular, you can provide the template type arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
153 |
// explicitly when invoking Foo(), as in Foo<long, bool>(5, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
154 |
// although usually you can rely on the compiler to infer the types |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
155 |
// for you automatically. You can assign the result of expression |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
156 |
// Foo(p1, ..., pk) to a variable of type FooActionPk<p1_type, ..., |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
157 |
// pk_type>. This can be useful when composing actions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
158 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
159 |
// You can also overload actions with different numbers of parameters: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
160 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
161 |
// ACTION_P(Plus, a) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
162 |
// ACTION_P2(Plus, a, b) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
163 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
164 |
// While it's tempting to always use the ACTION* macros when defining |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
165 |
// a new action, you should also consider implementing ActionInterface |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
166 |
// or using MakePolymorphicAction() instead, especially if you need to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
167 |
// use the action a lot. While these approaches require more work, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
168 |
// they give you more control on the types of the mock function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
169 |
// arguments and the action parameters, which in general leads to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
170 |
// better compiler error messages that pay off in the long run. They |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
171 |
// also allow overloading actions based on parameter types (as opposed |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
172 |
// to just based on the number of parameters). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
173 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
174 |
// CAVEAT: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
175 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
176 |
// ACTION*() can only be used in a namespace scope as templates cannot be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
177 |
// declared inside of a local class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
178 |
// Users can, however, define any local functors (e.g. a lambda) that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
179 |
// can be used as actions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
180 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
181 |
// MORE INFORMATION: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
182 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
183 |
// To learn more about using these macros, please search for 'ACTION' on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
184 |
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
185 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
186 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
187 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
188 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
189 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
190 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
191 |
#ifndef _WIN32_WCE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
192 |
# include <errno.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
193 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
194 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
195 |
#include <algorithm> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
196 |
#include <functional> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
197 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
198 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
199 |
#include <tuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
200 |
#include <type_traits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
201 |
#include <utility> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
202 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
203 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
204 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
205 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
206 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
207 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
208 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
209 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
210 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
211 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
212 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
213 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
214 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
215 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
216 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
217 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
218 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
219 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
220 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
221 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
222 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
223 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
224 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
225 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
226 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
227 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
228 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
229 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
230 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
231 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
232 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
233 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
234 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
235 |
// This file defines some utilities useful for implementing Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
236 |
// Mock. They are subject to change without notice, so please DO NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
237 |
// USE THEM IN USER CODE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
238 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
239 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
240 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
241 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
242 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
243 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
244 |
#include <stdio.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
245 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
246 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
247 |
#include <type_traits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
248 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
249 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
250 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
251 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
252 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
253 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
254 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
255 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
256 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
257 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
258 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
259 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
260 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
261 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
262 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
263 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
264 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
265 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
266 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
267 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
268 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
269 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
270 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
271 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
272 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
273 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
274 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
275 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
277 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
278 |
// Low-level types and utilities for porting Google Mock to various |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
279 |
// platforms. All macros ending with _ and symbols defined in an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
280 |
// internal namespace are subject to change without notice. Code |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
281 |
// outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
282 |
// end with _ are part of Google Mock's public API and can be used by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
283 |
// code outside Google Mock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
285 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
286 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
287 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
288 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
290 |
#include <assert.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
291 |
#include <stdlib.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
292 |
#include <cstdint> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
293 |
#include <iostream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
294 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
295 |
// Most of the utilities needed for porting Google Mock are also |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
296 |
// required for Google Test and are defined in gtest-port.h. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
297 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
298 |
// Note to maintainers: to reduce code duplication, prefer adding |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
299 |
// portability utilities to Google Test's gtest-port.h instead of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
300 |
// here, as Google Mock depends on Google Test. Only add a utility |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
301 |
// here if it's truly specific to Google Mock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
302 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
303 |
#include "gtest/gtest.h" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
304 |
// Copyright 2015, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
305 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
306 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
307 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
308 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
309 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
310 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
311 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
312 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
313 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
314 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
315 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
316 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
317 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
318 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
319 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
320 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
321 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
322 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
323 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
324 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
325 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
326 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
327 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
328 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
329 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
330 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
331 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
332 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
333 |
// Injection point for custom user configurations. See README for details |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
334 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
335 |
// ** Custom implementation starts here ** |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
336 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
337 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
339 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
340 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
342 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
343 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
344 |
// For MS Visual C++, check the compiler version. At least VS 2015 is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
345 |
// required to compile Google Mock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
346 |
#if defined(_MSC_VER) && _MSC_VER < 1900 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
347 |
# error "At least Visual C++ 2015 (14.0) is required to compile Google Mock." |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
348 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
349 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
350 |
// Macro for referencing flags. This is public as we want the user to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
351 |
// use this syntax to reference Google Mock flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
352 |
#define GMOCK_FLAG(name) FLAGS_gmock_##name |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
353 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
354 |
#if !defined(GMOCK_DECLARE_bool_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
355 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
356 |
// Macros for declaring flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
357 |
# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
358 |
# define GMOCK_DECLARE_int32_(name) extern GTEST_API_ int32_t GMOCK_FLAG(name) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
359 |
# define GMOCK_DECLARE_string_(name) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
360 |
extern GTEST_API_ ::std::string GMOCK_FLAG(name) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
361 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
362 |
// Macros for defining flags. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
363 |
# define GMOCK_DEFINE_bool_(name, default_val, doc) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
364 |
GTEST_API_ bool GMOCK_FLAG(name) = (default_val) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
365 |
# define GMOCK_DEFINE_int32_(name, default_val, doc) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
366 |
GTEST_API_ int32_t GMOCK_FLAG(name) = (default_val) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
367 |
# define GMOCK_DEFINE_string_(name, default_val, doc) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
368 |
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
369 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
370 |
#endif // !defined(GMOCK_DECLARE_bool_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
371 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
372 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
373 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
374 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
375 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
376 |
template <typename> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
377 |
class Matcher; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
379 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
381 |
// Silence MSVC C4100 (unreferenced formal parameter) and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
382 |
// C4805('==': unsafe mix of type 'const int' and type 'const bool') |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
383 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
384 |
# pragma warning(push) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
385 |
# pragma warning(disable:4100) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
386 |
# pragma warning(disable:4805) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
387 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
388 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
389 |
// Joins a vector of strings as if they are fields of a tuple; returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
390 |
// the joined string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
391 |
GTEST_API_ std::string JoinAsTuple(const Strings& fields); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
392 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
393 |
// Converts an identifier name to a space-separated list of lower-case |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
394 |
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
395 |
// treated as one word. For example, both "FooBar123" and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
396 |
// "foo_bar_123" are converted to "foo bar 123". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
397 |
GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
398 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
399 |
// GetRawPointer(p) returns the raw pointer underlying p when p is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
400 |
// smart pointer, or returns p itself when p is already a raw pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
401 |
// The following default implementation is for the smart pointer case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
402 |
template <typename Pointer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
403 |
inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
404 |
return p.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
405 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
406 |
// This overloaded version is for the raw pointer case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
407 |
template <typename Element> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
408 |
inline Element* GetRawPointer(Element* p) { return p; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
409 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
410 |
// MSVC treats wchar_t as a native type usually, but treats it as the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
411 |
// same as unsigned short when the compiler option /Zc:wchar_t- is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
412 |
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
413 |
// is a native type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
414 |
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
415 |
// wchar_t is a typedef. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
416 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
417 |
# define GMOCK_WCHAR_T_IS_NATIVE_ 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
418 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
419 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
420 |
// In what follows, we use the term "kind" to indicate whether a type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
421 |
// is bool, an integer type (excluding bool), a floating-point type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
422 |
// or none of them. This categorization is useful for determining |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
423 |
// when a matcher argument type can be safely converted to another |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
424 |
// type in the implementation of SafeMatcherCast. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
425 |
enum TypeKind { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
426 |
kBool, kInteger, kFloatingPoint, kOther |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
427 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
428 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
429 |
// KindOf<T>::value is the kind of type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
430 |
template <typename T> struct KindOf { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
431 |
enum { value = kOther }; // The default kind. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
432 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
433 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
434 |
// This macro declares that the kind of 'type' is 'kind'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
435 |
#define GMOCK_DECLARE_KIND_(type, kind) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
436 |
template <> struct KindOf<type> { enum { value = kind }; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
437 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
438 |
GMOCK_DECLARE_KIND_(bool, kBool); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
439 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
440 |
// All standard integer types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
441 |
GMOCK_DECLARE_KIND_(char, kInteger); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
442 |
GMOCK_DECLARE_KIND_(signed char, kInteger); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
443 |
GMOCK_DECLARE_KIND_(unsigned char, kInteger); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
444 |
GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
445 |
GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
446 |
GMOCK_DECLARE_KIND_(int, kInteger); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
447 |
GMOCK_DECLARE_KIND_(unsigned int, kInteger); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
448 |
GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
449 |
GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
450 |
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
451 |
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
452 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
453 |
#if GMOCK_WCHAR_T_IS_NATIVE_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
454 |
GMOCK_DECLARE_KIND_(wchar_t, kInteger); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
455 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
456 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
457 |
// All standard floating-point types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
458 |
GMOCK_DECLARE_KIND_(float, kFloatingPoint); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
459 |
GMOCK_DECLARE_KIND_(double, kFloatingPoint); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
460 |
GMOCK_DECLARE_KIND_(long double, kFloatingPoint); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
462 |
#undef GMOCK_DECLARE_KIND_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
463 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
464 |
// Evaluates to the kind of 'type'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
465 |
#define GMOCK_KIND_OF_(type) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
466 |
static_cast< ::testing::internal::TypeKind>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
467 |
::testing::internal::KindOf<type>::value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
468 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
469 |
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
470 |
// is true if and only if arithmetic type From can be losslessly converted to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
471 |
// arithmetic type To. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
472 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
473 |
// It's the user's responsibility to ensure that both From and To are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
474 |
// raw (i.e. has no CV modifier, is not a pointer, and is not a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
475 |
// reference) built-in arithmetic types, kFromKind is the kind of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
476 |
// From, and kToKind is the kind of To; the value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
477 |
// implementation-defined when the above pre-condition is violated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
478 |
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
479 |
using LosslessArithmeticConvertibleImpl = std::integral_constant< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
480 |
bool, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
481 |
// clang-format off |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
482 |
// Converting from bool is always lossless |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
483 |
(kFromKind == kBool) ? true |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
484 |
// Converting between any other type kinds will be lossy if the type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
485 |
// kinds are not the same. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
486 |
: (kFromKind != kToKind) ? false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
487 |
: (kFromKind == kInteger && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
488 |
// Converting between integers of different widths is allowed so long |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
489 |
// as the conversion does not go from signed to unsigned. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
490 |
(((sizeof(From) < sizeof(To)) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
491 |
!(std::is_signed<From>::value && !std::is_signed<To>::value)) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
492 |
// Converting between integers of the same width only requires the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
493 |
// two types to have the same signedness. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
494 |
((sizeof(From) == sizeof(To)) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
495 |
(std::is_signed<From>::value == std::is_signed<To>::value))) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
496 |
) ? true |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
497 |
// Floating point conversions are lossless if and only if `To` is at least |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
498 |
// as wide as `From`. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
499 |
: (kFromKind == kFloatingPoint && (sizeof(From) <= sizeof(To))) ? true |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
500 |
: false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
501 |
// clang-format on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
502 |
>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
503 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
504 |
// LosslessArithmeticConvertible<From, To>::value is true if and only if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
505 |
// arithmetic type From can be losslessly converted to arithmetic type To. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
506 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
507 |
// It's the user's responsibility to ensure that both From and To are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
508 |
// raw (i.e. has no CV modifier, is not a pointer, and is not a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
509 |
// reference) built-in arithmetic types; the value is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
510 |
// implementation-defined when the above pre-condition is violated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
511 |
template <typename From, typename To> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
512 |
using LosslessArithmeticConvertible = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
513 |
LosslessArithmeticConvertibleImpl<GMOCK_KIND_OF_(From), From, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
514 |
GMOCK_KIND_OF_(To), To>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
515 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
516 |
// This interface knows how to report a Google Mock failure (either |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
517 |
// non-fatal or fatal). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
518 |
class FailureReporterInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
519 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
520 |
// The type of a failure (either non-fatal or fatal). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
521 |
enum FailureType { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
522 |
kNonfatal, kFatal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
523 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
525 |
virtual ~FailureReporterInterface() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
526 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
527 |
// Reports a failure that occurred at the given source file location. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
528 |
virtual void ReportFailure(FailureType type, const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
529 |
const std::string& message) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
530 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
531 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
532 |
// Returns the failure reporter used by Google Mock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
533 |
GTEST_API_ FailureReporterInterface* GetFailureReporter(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
534 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
535 |
// Asserts that condition is true; aborts the process with the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
536 |
// message if condition is false. We cannot use LOG(FATAL) or CHECK() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
537 |
// as Google Mock might be used to mock the log sink itself. We |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
538 |
// inline this function to prevent it from showing up in the stack |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
539 |
// trace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
540 |
inline void Assert(bool condition, const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
541 |
const std::string& msg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
542 |
if (!condition) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
543 |
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
544 |
file, line, msg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
545 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
546 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
547 |
inline void Assert(bool condition, const char* file, int line) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
548 |
Assert(condition, file, line, "Assertion failed."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
549 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
550 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
551 |
// Verifies that condition is true; generates a non-fatal failure if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
552 |
// condition is false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
553 |
inline void Expect(bool condition, const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
554 |
const std::string& msg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
555 |
if (!condition) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
556 |
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
557 |
file, line, msg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
558 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
559 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
560 |
inline void Expect(bool condition, const char* file, int line) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
561 |
Expect(condition, file, line, "Expectation failed."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
563 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
564 |
// Severity level of a log. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
565 |
enum LogSeverity { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
566 |
kInfo = 0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
567 |
kWarning = 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
568 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
569 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
570 |
// Valid values for the --gmock_verbose flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
571 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
572 |
// All logs (informational and warnings) are printed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
573 |
const char kInfoVerbosity[] = "info"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
574 |
// Only warnings are printed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
575 |
const char kWarningVerbosity[] = "warning"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
576 |
// No logs are printed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
577 |
const char kErrorVerbosity[] = "error"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
578 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
579 |
// Returns true if and only if a log with the given severity is visible |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
580 |
// according to the --gmock_verbose flag. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
581 |
GTEST_API_ bool LogIsVisible(LogSeverity severity); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
582 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
583 |
// Prints the given message to stdout if and only if 'severity' >= the level |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
584 |
// specified by the --gmock_verbose flag. If stack_frames_to_skip >= |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
585 |
// 0, also prints the stack trace excluding the top |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
586 |
// stack_frames_to_skip frames. In opt mode, any positive |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
587 |
// stack_frames_to_skip is treated as 0, since we don't know which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
588 |
// function calls will be inlined by the compiler and need to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
589 |
// conservative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
590 |
GTEST_API_ void Log(LogSeverity severity, const std::string& message, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
591 |
int stack_frames_to_skip); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
592 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
593 |
// A marker class that is used to resolve parameterless expectations to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
594 |
// correct overload. This must not be instantiable, to prevent client code from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
595 |
// accidentally resolving to the overload; for example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
596 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
597 |
// ON_CALL(mock, Method({}, nullptr))... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
598 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
599 |
class WithoutMatchers { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
600 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
601 |
WithoutMatchers() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
602 |
friend GTEST_API_ WithoutMatchers GetWithoutMatchers(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
603 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
604 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
605 |
// Internal use only: access the singleton instance of WithoutMatchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
606 |
GTEST_API_ WithoutMatchers GetWithoutMatchers(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
607 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
608 |
// Disable MSVC warnings for infinite recursion, since in this case the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
609 |
// the recursion is unreachable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
610 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
611 |
# pragma warning(push) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
612 |
# pragma warning(disable:4717) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
613 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
614 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
615 |
// Invalid<T>() is usable as an expression of type T, but will terminate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
616 |
// the program with an assertion failure if actually run. This is useful |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
617 |
// when a value of type T is needed for compilation, but the statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
618 |
// will not really be executed (or we don't care if the statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
619 |
// crashes). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
620 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
621 |
inline T Invalid() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
622 |
Assert(false, "", -1, "Internal error: attempt to return invalid value"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
623 |
// This statement is unreachable, and would never terminate even if it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
624 |
// could be reached. It is provided only to placate compiler warnings |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
625 |
// about missing return statements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
626 |
return Invalid<T>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
627 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
628 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
629 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
630 |
# pragma warning(pop) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
631 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
632 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
633 |
// Given a raw type (i.e. having no top-level reference or const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
634 |
// modifier) RawContainer that's either an STL-style container or a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
635 |
// native array, class StlContainerView<RawContainer> has the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
636 |
// following members: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
637 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
638 |
// - type is a type that provides an STL-style container view to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
639 |
// (i.e. implements the STL container concept for) RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
640 |
// - const_reference is a type that provides a reference to a const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
641 |
// RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
642 |
// - ConstReference(raw_container) returns a const reference to an STL-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
643 |
// container view to raw_container, which is a RawContainer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
644 |
// - Copy(raw_container) returns an STL-style container view of a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
645 |
// copy of raw_container, which is a RawContainer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
646 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
647 |
// This generic version is used when RawContainer itself is already an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
648 |
// STL-style container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
649 |
template <class RawContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
650 |
class StlContainerView { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
651 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
652 |
typedef RawContainer type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
653 |
typedef const type& const_reference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
654 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
655 |
static const_reference ConstReference(const RawContainer& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
656 |
static_assert(!std::is_const<RawContainer>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
657 |
"RawContainer type must not be const"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
658 |
return container; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
659 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
660 |
static type Copy(const RawContainer& container) { return container; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
661 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
662 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
663 |
// This specialization is used when RawContainer is a native array type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
664 |
template <typename Element, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
665 |
class StlContainerView<Element[N]> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
666 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
667 |
typedef typename std::remove_const<Element>::type RawElement; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
668 |
typedef internal::NativeArray<RawElement> type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
669 |
// NativeArray<T> can represent a native array either by value or by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
670 |
// reference (selected by a constructor argument), so 'const type' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
671 |
// can be used to reference a const native array. We cannot |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
672 |
// 'typedef const type& const_reference' here, as that would mean |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
673 |
// ConstReference() has to return a reference to a local variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
674 |
typedef const type const_reference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
675 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
676 |
static const_reference ConstReference(const Element (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
677 |
static_assert(std::is_same<Element, RawElement>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
678 |
"Element type must not be const"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
679 |
return type(array, N, RelationToSourceReference()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
680 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
681 |
static type Copy(const Element (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
682 |
return type(array, N, RelationToSourceCopy()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
683 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
684 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
685 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
686 |
// This specialization is used when RawContainer is a native array |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
687 |
// represented as a (pointer, size) tuple. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
688 |
template <typename ElementPointer, typename Size> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
689 |
class StlContainerView< ::std::tuple<ElementPointer, Size> > { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
690 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
691 |
typedef typename std::remove_const< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
692 |
typename std::pointer_traits<ElementPointer>::element_type>::type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
693 |
RawElement; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
694 |
typedef internal::NativeArray<RawElement> type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
695 |
typedef const type const_reference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
696 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
697 |
static const_reference ConstReference( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
698 |
const ::std::tuple<ElementPointer, Size>& array) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
699 |
return type(std::get<0>(array), std::get<1>(array), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
700 |
RelationToSourceReference()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
701 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
702 |
static type Copy(const ::std::tuple<ElementPointer, Size>& array) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
703 |
return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
704 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
705 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
706 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
707 |
// The following specialization prevents the user from instantiating |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
708 |
// StlContainer with a reference type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
709 |
template <typename T> class StlContainerView<T&>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
710 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
711 |
// A type transform to remove constness from the first part of a pair. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
712 |
// Pairs like that are used as the value_type of associative containers, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
713 |
// and this transform produces a similar but assignable pair. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
714 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
715 |
struct RemoveConstFromKey { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
716 |
typedef T type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
717 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
718 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
719 |
// Partially specialized to remove constness from std::pair<const K, V>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
720 |
template <typename K, typename V> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
721 |
struct RemoveConstFromKey<std::pair<const K, V> > { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
722 |
typedef std::pair<K, V> type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
723 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
724 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
725 |
// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
726 |
// reduce code size. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
727 |
GTEST_API_ void IllegalDoDefault(const char* file, int line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
728 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
729 |
template <typename F, typename Tuple, size_t... Idx> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
730 |
auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
731 |
std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
732 |
return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
733 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
734 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
735 |
// Apply the function to a tuple of arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
736 |
template <typename F, typename Tuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
737 |
auto Apply(F&& f, Tuple&& args) -> decltype( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
738 |
ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
739 |
MakeIndexSequence<std::tuple_size< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
740 |
typename std::remove_reference<Tuple>::type>::value>())) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
741 |
return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
742 |
MakeIndexSequence<std::tuple_size< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
743 |
typename std::remove_reference<Tuple>::type>::value>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
744 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
745 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
746 |
// Template struct Function<F>, where F must be a function type, contains |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
747 |
// the following typedefs: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
748 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
749 |
// Result: the function's return type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
750 |
// Arg<N>: the type of the N-th argument, where N starts with 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
751 |
// ArgumentTuple: the tuple type consisting of all parameters of F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
752 |
// ArgumentMatcherTuple: the tuple type consisting of Matchers for all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
753 |
// parameters of F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
754 |
// MakeResultVoid: the function type obtained by substituting void |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
755 |
// for the return type of F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
756 |
// MakeResultIgnoredValue: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
757 |
// the function type obtained by substituting Something |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
758 |
// for the return type of F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
759 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
760 |
struct Function; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
761 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
762 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
763 |
struct Function<R(Args...)> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
764 |
using Result = R; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
765 |
static constexpr size_t ArgumentCount = sizeof...(Args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
766 |
template <size_t I> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
767 |
using Arg = ElemFromList<I, Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
768 |
using ArgumentTuple = std::tuple<Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
769 |
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
770 |
using MakeResultVoid = void(Args...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
771 |
using MakeResultIgnoredValue = IgnoredValue(Args...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
772 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
773 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
774 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
775 |
constexpr size_t Function<R(Args...)>::ArgumentCount; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
776 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
777 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
778 |
# pragma warning(pop) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
779 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
781 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
782 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
783 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
784 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
785 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
786 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
787 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
788 |
// Expands and concatenates the arguments. Constructed macros reevaluate. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
789 |
#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
790 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
791 |
// Expands and stringifies the only argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
792 |
#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
793 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
794 |
// Returns empty. Given a variadic number of arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
795 |
#define GMOCK_PP_EMPTY(...) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
796 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
797 |
// Returns a comma. Given a variadic number of arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
798 |
#define GMOCK_PP_COMMA(...) , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
799 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
800 |
// Returns the only argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
801 |
#define GMOCK_PP_IDENTITY(_1) _1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
802 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
803 |
// Evaluates to the number of arguments after expansion. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
804 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
805 |
// #define PAIR x, y |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
806 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
807 |
// GMOCK_PP_NARG() => 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
808 |
// GMOCK_PP_NARG(x) => 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
809 |
// GMOCK_PP_NARG(x, y) => 2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
810 |
// GMOCK_PP_NARG(PAIR) => 2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
811 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
812 |
// Requires: the number of arguments after expansion is at most 15. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
813 |
#define GMOCK_PP_NARG(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
814 |
GMOCK_PP_INTERNAL_16TH( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
815 |
(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
816 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
817 |
// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
818 |
// returns 0. Requires no more than 15 unprotected commas. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
819 |
#define GMOCK_PP_HAS_COMMA(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
820 |
GMOCK_PP_INTERNAL_16TH( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
821 |
(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
822 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
823 |
// Returns the first argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
824 |
#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD((__VA_ARGS__, unusedArg)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
825 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
826 |
// Returns the tail. A variadic list of all arguments minus the first. Requires |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
827 |
// at least one argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
828 |
#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL((__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
829 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
830 |
// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
831 |
#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
832 |
GMOCK_PP_IDENTITY( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
833 |
GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
834 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
835 |
// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
836 |
// evaluates to `0`. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
837 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
838 |
// Requires: * the number of arguments after expansion is at most 15. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
839 |
// * If the argument is a macro, it must be able to be called with one |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
840 |
// argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
841 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
842 |
// Implementation details: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
843 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
844 |
// There is one case when it generates a compile error: if the argument is macro |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
845 |
// that cannot be called with one argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
846 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
847 |
// #define M(a, b) // it doesn't matter what it expands to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
848 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
849 |
// // Expected: expands to `0`. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
850 |
// // Actual: compile error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
851 |
// GMOCK_PP_IS_EMPTY(M) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
852 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
853 |
// There are 4 cases tested: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
854 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
855 |
// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
856 |
// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
857 |
// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
858 |
// Expected 0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
859 |
// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
860 |
// parenthesis, or is a macro that ()-evaluates to comma. Expected 1. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
861 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
862 |
// We trigger detection on '0001', i.e. on empty. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
863 |
#define GMOCK_PP_IS_EMPTY(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
864 |
GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
865 |
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
866 |
GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
867 |
GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__())) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
868 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
869 |
// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
870 |
#define GMOCK_PP_IF(_Cond, _Then, _Else) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
871 |
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
872 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
873 |
// Similar to GMOCK_PP_IF but takes _Then and _Else in parentheses. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
874 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
875 |
// GMOCK_PP_GENERIC_IF(1, (a, b, c), (d, e, f)) => a, b, c |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
876 |
// GMOCK_PP_GENERIC_IF(0, (a, b, c), (d, e, f)) => d, e, f |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
877 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
878 |
#define GMOCK_PP_GENERIC_IF(_Cond, _Then, _Else) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
879 |
GMOCK_PP_REMOVE_PARENS(GMOCK_PP_IF(_Cond, _Then, _Else)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
880 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
881 |
// Evaluates to the number of arguments after expansion. Identifies 'empty' as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
882 |
// 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
883 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
884 |
// #define PAIR x, y |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
885 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
886 |
// GMOCK_PP_NARG0() => 0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
887 |
// GMOCK_PP_NARG0(x) => 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
888 |
// GMOCK_PP_NARG0(x, y) => 2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
889 |
// GMOCK_PP_NARG0(PAIR) => 2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
890 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
891 |
// Requires: * the number of arguments after expansion is at most 15. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
892 |
// * If the argument is a macro, it must be able to be called with one |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
893 |
// argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
894 |
#define GMOCK_PP_NARG0(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
895 |
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
896 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
897 |
// Expands to 1 if the first argument starts with something in parentheses, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
898 |
// otherwise to 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
899 |
#define GMOCK_PP_IS_BEGIN_PARENS(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
900 |
GMOCK_PP_HEAD(GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
901 |
GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
902 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
903 |
// Expands to 1 is there is only one argument and it is enclosed in parentheses. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
904 |
#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
905 |
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
906 |
GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
907 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
908 |
// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
909 |
#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
910 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
911 |
// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
912 |
// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
913 |
// Requires: * |_Macro| can be called with 3 arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
914 |
// * |_Tuple| expansion has no more than 15 elements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
915 |
#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
916 |
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
917 |
(0, _Macro, _Data, _Tuple) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
918 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
919 |
// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, ) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
920 |
// Empty if _K = 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
921 |
// Requires: * |_Macro| can be called with 3 arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
922 |
// * |_K| literal between 0 and 15 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
923 |
#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
924 |
GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
925 |
(0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
926 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
927 |
// Increments the argument, requires the argument to be between 0 and 15. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
928 |
#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
930 |
// Returns comma if _i != 0. Requires _i to be between 0 and 15. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
931 |
#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
932 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
933 |
// Internal details follow. Do not use any of these symbols outside of this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
934 |
// file or we will break your code. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
935 |
#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , ) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
936 |
#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
937 |
#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
938 |
#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
939 |
#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
940 |
GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
941 |
_1, _2, _3, _4)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
942 |
#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
943 |
#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
944 |
#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
945 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
946 |
// Because of MSVC treating a token with a comma in it as a single token when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
947 |
// passed to another macro, we need to force it to evaluate it as multiple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
948 |
// tokens. We do that by using a "IDENTITY(MACRO PARENTHESIZED_ARGS)" macro. We |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
949 |
// define one per possible macro that relies on this behavior. Note "_Args" must |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
950 |
// be parenthesized. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
951 |
#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
952 |
_10, _11, _12, _13, _14, _15, _16, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
953 |
...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
954 |
_16 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
955 |
#define GMOCK_PP_INTERNAL_16TH(_Args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
956 |
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_16TH _Args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
957 |
#define GMOCK_PP_INTERNAL_INTERNAL_HEAD(_1, ...) _1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
958 |
#define GMOCK_PP_INTERNAL_HEAD(_Args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
959 |
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_HEAD _Args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
960 |
#define GMOCK_PP_INTERNAL_INTERNAL_TAIL(_1, ...) __VA_ARGS__ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
961 |
#define GMOCK_PP_INTERNAL_TAIL(_Args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
962 |
GMOCK_PP_IDENTITY(GMOCK_PP_INTERNAL_INTERNAL_TAIL _Args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
963 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
964 |
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
965 |
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
966 |
#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
967 |
0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
968 |
#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
969 |
#define GMOCK_PP_INTERNAL_INC_0 1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
970 |
#define GMOCK_PP_INTERNAL_INC_1 2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
971 |
#define GMOCK_PP_INTERNAL_INC_2 3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
972 |
#define GMOCK_PP_INTERNAL_INC_3 4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
973 |
#define GMOCK_PP_INTERNAL_INC_4 5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
974 |
#define GMOCK_PP_INTERNAL_INC_5 6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
975 |
#define GMOCK_PP_INTERNAL_INC_6 7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
976 |
#define GMOCK_PP_INTERNAL_INC_7 8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
977 |
#define GMOCK_PP_INTERNAL_INC_8 9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
978 |
#define GMOCK_PP_INTERNAL_INC_9 10 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
979 |
#define GMOCK_PP_INTERNAL_INC_10 11 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
980 |
#define GMOCK_PP_INTERNAL_INC_11 12 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
981 |
#define GMOCK_PP_INTERNAL_INC_12 13 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
982 |
#define GMOCK_PP_INTERNAL_INC_13 14 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
983 |
#define GMOCK_PP_INTERNAL_INC_14 15 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
984 |
#define GMOCK_PP_INTERNAL_INC_15 16 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
985 |
#define GMOCK_PP_INTERNAL_COMMA_IF_0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
986 |
#define GMOCK_PP_INTERNAL_COMMA_IF_1 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
987 |
#define GMOCK_PP_INTERNAL_COMMA_IF_2 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
988 |
#define GMOCK_PP_INTERNAL_COMMA_IF_3 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
989 |
#define GMOCK_PP_INTERNAL_COMMA_IF_4 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
990 |
#define GMOCK_PP_INTERNAL_COMMA_IF_5 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
991 |
#define GMOCK_PP_INTERNAL_COMMA_IF_6 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
992 |
#define GMOCK_PP_INTERNAL_COMMA_IF_7 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
993 |
#define GMOCK_PP_INTERNAL_COMMA_IF_8 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
994 |
#define GMOCK_PP_INTERNAL_COMMA_IF_9 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
995 |
#define GMOCK_PP_INTERNAL_COMMA_IF_10 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
996 |
#define GMOCK_PP_INTERNAL_COMMA_IF_11 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
997 |
#define GMOCK_PP_INTERNAL_COMMA_IF_12 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
998 |
#define GMOCK_PP_INTERNAL_COMMA_IF_13 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
999 |
#define GMOCK_PP_INTERNAL_COMMA_IF_14 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1000 |
#define GMOCK_PP_INTERNAL_COMMA_IF_15 , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1001 |
#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1002 |
_Macro(_i, _Data, _element) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1003 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1004 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1005 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1006 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1007 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1008 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1009 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1010 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1011 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1012 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1013 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1014 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1015 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1016 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1017 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1018 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1019 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1020 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1021 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1022 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1023 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1024 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1025 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1026 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1027 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1028 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1029 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1030 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1031 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1032 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1033 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1034 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1035 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1036 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1037 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1038 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1039 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1040 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1041 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1042 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1043 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1044 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1045 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1046 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1047 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1048 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1049 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1050 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1051 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1052 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1053 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1054 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1055 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1056 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1057 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1058 |
#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1059 |
GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1060 |
GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1061 |
(GMOCK_PP_TAIL _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1062 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1063 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1064 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1065 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1066 |
# pragma warning(push) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1067 |
# pragma warning(disable:4100) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1068 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1070 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1071 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1072 |
// To implement an action Foo, define: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1073 |
// 1. a class FooAction that implements the ActionInterface interface, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1074 |
// 2. a factory function that creates an Action object from a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1075 |
// const FooAction*. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1076 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1077 |
// The two-level delegation design follows that of Matcher, providing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1078 |
// consistency for extension developers. It also eases ownership |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1079 |
// management as Action objects can now be copied like plain values. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1080 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1081 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1082 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1083 |
// BuiltInDefaultValueGetter<T, true>::Get() returns a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1084 |
// default-constructed T value. BuiltInDefaultValueGetter<T, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1085 |
// false>::Get() crashes with an error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1086 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1087 |
// This primary template is used when kDefaultConstructible is true. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1088 |
template <typename T, bool kDefaultConstructible> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1089 |
struct BuiltInDefaultValueGetter { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1090 |
static T Get() { return T(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1091 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1092 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1093 |
struct BuiltInDefaultValueGetter<T, false> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1094 |
static T Get() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1095 |
Assert(false, __FILE__, __LINE__, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1096 |
"Default action undefined for the function return type."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1097 |
return internal::Invalid<T>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1098 |
// The above statement will never be reached, but is required in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1099 |
// order for this function to compile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1100 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1101 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1102 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1103 |
// BuiltInDefaultValue<T>::Get() returns the "built-in" default value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1104 |
// for type T, which is NULL when T is a raw pointer type, 0 when T is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1105 |
// a numeric type, false when T is bool, or "" when T is string or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1106 |
// std::string. In addition, in C++11 and above, it turns a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1107 |
// default-constructed T value if T is default constructible. For any |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1108 |
// other type T, the built-in default T value is undefined, and the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1109 |
// function will abort the process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1110 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1111 |
class BuiltInDefaultValue { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1112 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1113 |
// This function returns true if and only if type T has a built-in default |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1114 |
// value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1115 |
static bool Exists() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1116 |
return ::std::is_default_constructible<T>::value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1117 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1118 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1119 |
static T Get() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1120 |
return BuiltInDefaultValueGetter< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1121 |
T, ::std::is_default_constructible<T>::value>::Get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1122 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1123 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1124 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1125 |
// This partial specialization says that we use the same built-in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1126 |
// default value for T and const T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1127 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1128 |
class BuiltInDefaultValue<const T> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1129 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1130 |
static bool Exists() { return BuiltInDefaultValue<T>::Exists(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1131 |
static T Get() { return BuiltInDefaultValue<T>::Get(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1132 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1133 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1134 |
// This partial specialization defines the default values for pointer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1135 |
// types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1136 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1137 |
class BuiltInDefaultValue<T*> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1138 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1139 |
static bool Exists() { return true; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1140 |
static T* Get() { return nullptr; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1141 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1142 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1143 |
// The following specializations define the default values for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1144 |
// specific types we care about. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1145 |
#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1146 |
template <> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1147 |
class BuiltInDefaultValue<type> { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1148 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1149 |
static bool Exists() { return true; } \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1150 |
static type Get() { return value; } \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1151 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1152 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1153 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1154 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, ""); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1155 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1156 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1157 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1158 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0'); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1159 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1160 |
// There's no need for a default action for signed wchar_t, as that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1161 |
// type is the same as wchar_t for gcc, and invalid for MSVC. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1162 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1163 |
// There's also no need for a default action for unsigned wchar_t, as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1164 |
// that type is the same as unsigned int for gcc, and invalid for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1165 |
// MSVC. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1166 |
#if GMOCK_WCHAR_T_IS_NATIVE_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1167 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1168 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1169 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1170 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1171 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1172 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1173 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1174 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1175 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1176 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long long, 0); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1177 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long long, 0); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1178 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1179 |
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1180 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1181 |
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1182 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1183 |
// Simple two-arg form of std::disjunction. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1184 |
template <typename P, typename Q> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1185 |
using disjunction = typename ::std::conditional<P::value, P, Q>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1186 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1187 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1188 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1189 |
// When an unexpected function call is encountered, Google Mock will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1190 |
// let it return a default value if the user has specified one for its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1191 |
// return type, or if the return type has a built-in default value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1192 |
// otherwise Google Mock won't know what value to return and will have |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1193 |
// to abort the process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1194 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1195 |
// The DefaultValue<T> class allows a user to specify the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1196 |
// default value for a type T that is both copyable and publicly |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1197 |
// destructible (i.e. anything that can be used as a function return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1198 |
// type). The usage is: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1199 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1200 |
// // Sets the default value for type T to be foo. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1201 |
// DefaultValue<T>::Set(foo); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1202 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1203 |
class DefaultValue { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1204 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1205 |
// Sets the default value for type T; requires T to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1206 |
// copy-constructable and have a public destructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1207 |
static void Set(T x) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1208 |
delete producer_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1209 |
producer_ = new FixedValueProducer(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1210 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1211 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1212 |
// Provides a factory function to be called to generate the default value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1213 |
// This method can be used even if T is only move-constructible, but it is not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1214 |
// limited to that case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1215 |
typedef T (*FactoryFunction)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1216 |
static void SetFactory(FactoryFunction factory) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1217 |
delete producer_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1218 |
producer_ = new FactoryValueProducer(factory); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1219 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1220 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1221 |
// Unsets the default value for type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1222 |
static void Clear() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1223 |
delete producer_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1224 |
producer_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1225 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1226 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1227 |
// Returns true if and only if the user has set the default value for type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1228 |
static bool IsSet() { return producer_ != nullptr; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1229 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1230 |
// Returns true if T has a default return value set by the user or there |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1231 |
// exists a built-in default value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1232 |
static bool Exists() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1233 |
return IsSet() || internal::BuiltInDefaultValue<T>::Exists(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1234 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1235 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1236 |
// Returns the default value for type T if the user has set one; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1237 |
// otherwise returns the built-in default value. Requires that Exists() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1238 |
// is true, which ensures that the return value is well-defined. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1239 |
static T Get() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1240 |
return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1241 |
: producer_->Produce(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1242 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1243 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1244 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1245 |
class ValueProducer { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1246 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1247 |
virtual ~ValueProducer() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1248 |
virtual T Produce() = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1249 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1250 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1251 |
class FixedValueProducer : public ValueProducer { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1252 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1253 |
explicit FixedValueProducer(T value) : value_(value) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1254 |
T Produce() override { return value_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1255 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1256 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1257 |
const T value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1258 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1259 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1260 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1261 |
class FactoryValueProducer : public ValueProducer { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1262 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1263 |
explicit FactoryValueProducer(FactoryFunction factory) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1264 |
: factory_(factory) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1265 |
T Produce() override { return factory_(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1266 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1267 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1268 |
const FactoryFunction factory_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1269 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1270 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1272 |
static ValueProducer* producer_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1273 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1275 |
// This partial specialization allows a user to set default values for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1276 |
// reference types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1277 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1278 |
class DefaultValue<T&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1279 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1280 |
// Sets the default value for type T&. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1281 |
static void Set(T& x) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1282 |
address_ = &x; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1283 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1285 |
// Unsets the default value for type T&. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1286 |
static void Clear() { address_ = nullptr; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1287 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1288 |
// Returns true if and only if the user has set the default value for type T&. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1289 |
static bool IsSet() { return address_ != nullptr; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1290 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1291 |
// Returns true if T has a default return value set by the user or there |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1292 |
// exists a built-in default value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1293 |
static bool Exists() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1294 |
return IsSet() || internal::BuiltInDefaultValue<T&>::Exists(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1295 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1296 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1297 |
// Returns the default value for type T& if the user has set one; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1298 |
// otherwise returns the built-in default value if there is one; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1299 |
// otherwise aborts the process. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1300 |
static T& Get() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1301 |
return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1302 |
: *address_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1303 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1305 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1306 |
static T* address_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1307 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1308 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1309 |
// This specialization allows DefaultValue<void>::Get() to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1310 |
// compile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1311 |
template <> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1312 |
class DefaultValue<void> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1313 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1314 |
static bool Exists() { return true; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1315 |
static void Get() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1316 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1318 |
// Points to the user-set default value for type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1319 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1320 |
typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1321 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1322 |
// Points to the user-set default value for type T&. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1323 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1324 |
T* DefaultValue<T&>::address_ = nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1325 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1326 |
// Implement this interface to define an action for function type F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1327 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1328 |
class ActionInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1329 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1330 |
typedef typename internal::Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1331 |
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1332 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1333 |
ActionInterface() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1334 |
virtual ~ActionInterface() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1335 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1336 |
// Performs the action. This method is not const, as in general an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1337 |
// action can have side effects and be stateful. For example, a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1338 |
// get-the-next-element-from-the-collection action will need to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1339 |
// remember the current element. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1340 |
virtual Result Perform(const ArgumentTuple& args) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1342 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1343 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1344 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1346 |
// An Action<F> is a copyable and IMMUTABLE (except by assignment) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1347 |
// object that represents an action to be taken when a mock function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1348 |
// of type F is called. The implementation of Action<T> is just a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1349 |
// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1350 |
// You can view an object implementing ActionInterface<F> as a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1351 |
// concrete action (including its current state), and an Action<F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1352 |
// object as a handle to it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1353 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1354 |
class Action { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1355 |
// Adapter class to allow constructing Action from a legacy ActionInterface. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1356 |
// New code should create Actions from functors instead. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1357 |
struct ActionAdapter { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1358 |
// Adapter must be copyable to satisfy std::function requirements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1359 |
::std::shared_ptr<ActionInterface<F>> impl_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1360 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1361 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1362 |
typename internal::Function<F>::Result operator()(Args&&... args) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1363 |
return impl_->Perform( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1364 |
::std::forward_as_tuple(::std::forward<Args>(args)...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1365 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1366 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1367 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1368 |
template <typename G> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1369 |
using IsCompatibleFunctor = std::is_constructible<std::function<F>, G>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1370 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1371 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1372 |
typedef typename internal::Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1373 |
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1374 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1375 |
// Constructs a null Action. Needed for storing Action objects in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1376 |
// STL containers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1377 |
Action() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1379 |
// Construct an Action from a specified callable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1380 |
// This cannot take std::function directly, because then Action would not be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1381 |
// directly constructible from lambda (it would require two conversions). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1382 |
template < |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1383 |
typename G, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1384 |
typename = typename std::enable_if<internal::disjunction< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1385 |
IsCompatibleFunctor<G>, std::is_constructible<std::function<Result()>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1386 |
G>>::value>::type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1387 |
Action(G&& fun) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1388 |
Init(::std::forward<G>(fun), IsCompatibleFunctor<G>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1389 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1390 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1391 |
// Constructs an Action from its implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1392 |
explicit Action(ActionInterface<F>* impl) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1393 |
: fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1394 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1395 |
// This constructor allows us to turn an Action<Func> object into an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1396 |
// Action<F>, as long as F's arguments can be implicitly converted |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1397 |
// to Func's and Func's return type can be implicitly converted to F's. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1398 |
template <typename Func> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1399 |
explicit Action(const Action<Func>& action) : fun_(action.fun_) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1400 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1401 |
// Returns true if and only if this is the DoDefault() action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1402 |
bool IsDoDefault() const { return fun_ == nullptr; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1403 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1404 |
// Performs the action. Note that this method is const even though |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1405 |
// the corresponding method in ActionInterface is not. The reason |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1406 |
// is that a const Action<F> means that it cannot be re-bound to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1407 |
// another concrete action, not that the concrete action it binds to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1408 |
// cannot change state. (Think of the difference between a const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1409 |
// pointer and a pointer to const.) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1410 |
Result Perform(ArgumentTuple args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1411 |
if (IsDoDefault()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1412 |
internal::IllegalDoDefault(__FILE__, __LINE__); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1413 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1414 |
return internal::Apply(fun_, ::std::move(args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1415 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1416 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1417 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1418 |
template <typename G> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1419 |
friend class Action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1420 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1421 |
template <typename G> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1422 |
void Init(G&& g, ::std::true_type) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1423 |
fun_ = ::std::forward<G>(g); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1424 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1425 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1426 |
template <typename G> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1427 |
void Init(G&& g, ::std::false_type) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1428 |
fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1429 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1431 |
template <typename FunctionImpl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1432 |
struct IgnoreArgs { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1433 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1434 |
Result operator()(const Args&...) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1435 |
return function_impl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1436 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1437 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1438 |
FunctionImpl function_impl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1439 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1440 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1441 |
// fun_ is an empty function if and only if this is the DoDefault() action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1442 |
::std::function<F> fun_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1443 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1445 |
// The PolymorphicAction class template makes it easy to implement a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1446 |
// polymorphic action (i.e. an action that can be used in mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1447 |
// functions of than one type, e.g. Return()). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1448 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1449 |
// To define a polymorphic action, a user first provides a COPYABLE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1450 |
// implementation class that has a Perform() method template: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1451 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1452 |
// class FooAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1453 |
// public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1454 |
// template <typename Result, typename ArgumentTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1455 |
// Result Perform(const ArgumentTuple& args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1456 |
// // Processes the arguments and returns a result, using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1457 |
// // std::get<N>(args) to get the N-th (0-based) argument in the tuple. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1458 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1459 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1460 |
// }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1461 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1462 |
// Then the user creates the polymorphic action using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1463 |
// MakePolymorphicAction(object) where object has type FooAction. See |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1464 |
// the definition of Return(void) and SetArgumentPointee<N>(value) for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1465 |
// complete examples. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1466 |
template <typename Impl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1467 |
class PolymorphicAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1468 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1469 |
explicit PolymorphicAction(const Impl& impl) : impl_(impl) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1471 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1472 |
operator Action<F>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1473 |
return Action<F>(new MonomorphicImpl<F>(impl_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1474 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1475 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1476 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1477 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1478 |
class MonomorphicImpl : public ActionInterface<F> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1479 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1480 |
typedef typename internal::Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1481 |
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1482 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1483 |
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1484 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1485 |
Result Perform(const ArgumentTuple& args) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1486 |
return impl_.template Perform<Result>(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1487 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1488 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1489 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1490 |
Impl impl_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1491 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1492 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1493 |
Impl impl_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1494 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1495 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1496 |
// Creates an Action from its implementation and returns it. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1497 |
// created Action object owns the implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1498 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1499 |
Action<F> MakeAction(ActionInterface<F>* impl) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1500 |
return Action<F>(impl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1501 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1502 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1503 |
// Creates a polymorphic action from its implementation. This is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1504 |
// easier to use than the PolymorphicAction<Impl> constructor as it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1505 |
// doesn't require you to explicitly write the template argument, e.g. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1506 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1507 |
// MakePolymorphicAction(foo); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1508 |
// vs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1509 |
// PolymorphicAction<TypeOfFoo>(foo); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1510 |
template <typename Impl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1511 |
inline PolymorphicAction<Impl> MakePolymorphicAction(const Impl& impl) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1512 |
return PolymorphicAction<Impl>(impl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1513 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1514 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1515 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1516 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1517 |
// Helper struct to specialize ReturnAction to execute a move instead of a copy |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1518 |
// on return. Useful for move-only types, but could be used on any type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1519 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1520 |
struct ByMoveWrapper { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1521 |
explicit ByMoveWrapper(T value) : payload(std::move(value)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1522 |
T payload; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1523 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1525 |
// Implements the polymorphic Return(x) action, which can be used in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1526 |
// any function that returns the type of x, regardless of the argument |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1527 |
// types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1528 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1529 |
// Note: The value passed into Return must be converted into |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1530 |
// Function<F>::Result when this action is cast to Action<F> rather than |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1531 |
// when that action is performed. This is important in scenarios like |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1532 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1533 |
// MOCK_METHOD1(Method, T(U)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1534 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1535 |
// { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1536 |
// Foo foo; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1537 |
// X x(&foo); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1538 |
// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1539 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1540 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1541 |
// In the example above the variable x holds reference to foo which leaves |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1542 |
// scope and gets destroyed. If copying X just copies a reference to foo, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1543 |
// that copy will be left with a hanging reference. If conversion to T |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1544 |
// makes a copy of foo, the above code is safe. To support that scenario, we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1545 |
// need to make sure that the type conversion happens inside the EXPECT_CALL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1546 |
// statement, and conversion of the result of Return to Action<T(U)> is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1547 |
// good place for that. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1548 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1549 |
// The real life example of the above scenario happens when an invocation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1550 |
// of gtl::Container() is passed into Return. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1551 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1552 |
template <typename R> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1553 |
class ReturnAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1554 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1555 |
// Constructs a ReturnAction object from the value to be returned. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1556 |
// 'value' is passed by value instead of by const reference in order |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1557 |
// to allow Return("string literal") to compile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1558 |
explicit ReturnAction(R value) : value_(new R(std::move(value))) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1559 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1560 |
// This template type conversion operator allows Return(x) to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1561 |
// used in ANY function that returns x's type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1562 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1563 |
operator Action<F>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1564 |
// Assert statement belongs here because this is the best place to verify |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1565 |
// conditions on F. It produces the clearest error messages |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1566 |
// in most compilers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1567 |
// Impl really belongs in this scope as a local class but can't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1568 |
// because MSVC produces duplicate symbols in different translation units |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1569 |
// in this case. Until MS fixes that bug we put Impl into the class scope |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1570 |
// and put the typedef both here (for use in assert statement) and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1571 |
// in the Impl class. But both definitions must be the same. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1572 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1573 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1574 |
!std::is_reference<Result>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1575 |
use_ReturnRef_instead_of_Return_to_return_a_reference); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1576 |
static_assert(!std::is_void<Result>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1577 |
"Can't use Return() on an action expected to return `void`."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1578 |
return Action<F>(new Impl<R, F>(value_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1579 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1580 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1581 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1582 |
// Implements the Return(x) action for a particular function type F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1583 |
template <typename R_, typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1584 |
class Impl : public ActionInterface<F> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1585 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1586 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1587 |
typedef typename Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1588 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1589 |
// The implicit cast is necessary when Result has more than one |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1590 |
// single-argument constructor (e.g. Result is std::vector<int>) and R |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1591 |
// has a type conversion operator template. In that case, value_(value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1592 |
// won't compile as the compiler doesn't known which constructor of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1593 |
// Result to call. ImplicitCast_ forces the compiler to convert R to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1594 |
// Result without considering explicit constructors, thus resolving the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1595 |
// ambiguity. value_ is then initialized using its copy constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1596 |
explicit Impl(const std::shared_ptr<R>& value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1597 |
: value_before_cast_(*value), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1598 |
value_(ImplicitCast_<Result>(value_before_cast_)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1599 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1600 |
Result Perform(const ArgumentTuple&) override { return value_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1601 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1602 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1603 |
GTEST_COMPILE_ASSERT_(!std::is_reference<Result>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1604 |
Result_cannot_be_a_reference_type); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1605 |
// We save the value before casting just in case it is being cast to a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1606 |
// wrapper type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1607 |
R value_before_cast_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1608 |
Result value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1609 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1610 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1611 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1612 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1613 |
// Partially specialize for ByMoveWrapper. This version of ReturnAction will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1614 |
// move its contents instead. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1615 |
template <typename R_, typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1616 |
class Impl<ByMoveWrapper<R_>, F> : public ActionInterface<F> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1617 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1618 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1619 |
typedef typename Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1621 |
explicit Impl(const std::shared_ptr<R>& wrapper) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1622 |
: performed_(false), wrapper_(wrapper) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1623 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1624 |
Result Perform(const ArgumentTuple&) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1625 |
GTEST_CHECK_(!performed_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1626 |
<< "A ByMove() action should only be performed once."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1627 |
performed_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1628 |
return std::move(wrapper_->payload); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1629 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1630 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1631 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1632 |
bool performed_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1633 |
const std::shared_ptr<R> wrapper_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1634 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1635 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1636 |
const std::shared_ptr<R> value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1637 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1638 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1639 |
// Implements the ReturnNull() action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1640 |
class ReturnNullAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1641 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1642 |
// Allows ReturnNull() to be used in any pointer-returning function. In C++11 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1643 |
// this is enforced by returning nullptr, and in non-C++11 by asserting a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1644 |
// pointer type on compile time. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1645 |
template <typename Result, typename ArgumentTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1646 |
static Result Perform(const ArgumentTuple&) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1647 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1648 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1649 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1650 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1651 |
// Implements the Return() action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1652 |
class ReturnVoidAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1653 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1654 |
// Allows Return() to be used in any void-returning function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1655 |
template <typename Result, typename ArgumentTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1656 |
static void Perform(const ArgumentTuple&) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1657 |
static_assert(std::is_void<Result>::value, "Result should be void."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1658 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1659 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1660 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1661 |
// Implements the polymorphic ReturnRef(x) action, which can be used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1662 |
// in any function that returns a reference to the type of x, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1663 |
// regardless of the argument types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1664 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1665 |
class ReturnRefAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1666 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1667 |
// Constructs a ReturnRefAction object from the reference to be returned. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1668 |
explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1669 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1670 |
// This template type conversion operator allows ReturnRef(x) to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1671 |
// used in ANY function that returns a reference to x's type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1672 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1673 |
operator Action<F>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1674 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1675 |
// Asserts that the function return type is a reference. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1676 |
// catches the user error of using ReturnRef(x) when Return(x) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1677 |
// should be used, and generates some helpful error message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1678 |
GTEST_COMPILE_ASSERT_(std::is_reference<Result>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1679 |
use_Return_instead_of_ReturnRef_to_return_a_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1680 |
return Action<F>(new Impl<F>(ref_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1681 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1682 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1683 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1684 |
// Implements the ReturnRef(x) action for a particular function type F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1685 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1686 |
class Impl : public ActionInterface<F> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1687 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1688 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1689 |
typedef typename Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1690 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1691 |
explicit Impl(T& ref) : ref_(ref) {} // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1692 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1693 |
Result Perform(const ArgumentTuple&) override { return ref_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1694 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1695 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1696 |
T& ref_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1697 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1699 |
T& ref_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1700 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1701 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1702 |
// Implements the polymorphic ReturnRefOfCopy(x) action, which can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1703 |
// used in any function that returns a reference to the type of x, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1704 |
// regardless of the argument types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1705 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1706 |
class ReturnRefOfCopyAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1707 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1708 |
// Constructs a ReturnRefOfCopyAction object from the reference to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1709 |
// be returned. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1710 |
explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1711 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1712 |
// This template type conversion operator allows ReturnRefOfCopy(x) to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1713 |
// used in ANY function that returns a reference to x's type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1714 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1715 |
operator Action<F>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1716 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1717 |
// Asserts that the function return type is a reference. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1718 |
// catches the user error of using ReturnRefOfCopy(x) when Return(x) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1719 |
// should be used, and generates some helpful error message. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1720 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1721 |
std::is_reference<Result>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1722 |
use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1723 |
return Action<F>(new Impl<F>(value_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1724 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1725 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1726 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1727 |
// Implements the ReturnRefOfCopy(x) action for a particular function type F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1728 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1729 |
class Impl : public ActionInterface<F> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1730 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1731 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1732 |
typedef typename Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1734 |
explicit Impl(const T& value) : value_(value) {} // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1735 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1736 |
Result Perform(const ArgumentTuple&) override { return value_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1737 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1738 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1739 |
T value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1740 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1741 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1742 |
const T value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1743 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1744 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1745 |
// Implements the polymorphic ReturnRoundRobin(v) action, which can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1746 |
// used in any function that returns the element_type of v. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1747 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1748 |
class ReturnRoundRobinAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1749 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1750 |
explicit ReturnRoundRobinAction(std::vector<T> values) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1751 |
GTEST_CHECK_(!values.empty()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1752 |
<< "ReturnRoundRobin requires at least one element."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1753 |
state_->values = std::move(values); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1754 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1755 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1756 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1757 |
T operator()(Args&&...) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1758 |
return state_->Next(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1759 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1760 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1761 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1762 |
struct State { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1763 |
T Next() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1764 |
T ret_val = values[i++]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1765 |
if (i == values.size()) i = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1766 |
return ret_val; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1767 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1768 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1769 |
std::vector<T> values; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1770 |
size_t i = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1771 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1772 |
std::shared_ptr<State> state_ = std::make_shared<State>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1773 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1774 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1775 |
// Implements the polymorphic DoDefault() action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1776 |
class DoDefaultAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1777 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1778 |
// This template type conversion operator allows DoDefault() to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1779 |
// used in any function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1780 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1781 |
operator Action<F>() const { return Action<F>(); } // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1782 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1783 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1784 |
// Implements the Assign action to set a given pointer referent to a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1785 |
// particular value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1786 |
template <typename T1, typename T2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1787 |
class AssignAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1788 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1789 |
AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1790 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1791 |
template <typename Result, typename ArgumentTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1792 |
void Perform(const ArgumentTuple& /* args */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1793 |
*ptr_ = value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1794 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1795 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1796 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1797 |
T1* const ptr_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1798 |
const T2 value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1799 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1800 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1801 |
#if !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1802 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1803 |
// Implements the SetErrnoAndReturn action to simulate return from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1804 |
// various system calls and libc functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1805 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1806 |
class SetErrnoAndReturnAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1807 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1808 |
SetErrnoAndReturnAction(int errno_value, T result) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1809 |
: errno_(errno_value), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1810 |
result_(result) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1811 |
template <typename Result, typename ArgumentTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1812 |
Result Perform(const ArgumentTuple& /* args */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1813 |
errno = errno_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1814 |
return result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1815 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1816 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1817 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1818 |
const int errno_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1819 |
const T result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1820 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1821 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1822 |
#endif // !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1823 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1824 |
// Implements the SetArgumentPointee<N>(x) action for any function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1825 |
// whose N-th argument (0-based) is a pointer to x's type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1826 |
template <size_t N, typename A, typename = void> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1827 |
struct SetArgumentPointeeAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1828 |
A value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1829 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1830 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1831 |
void operator()(const Args&... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1832 |
*::std::get<N>(std::tie(args...)) = value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1833 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1834 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1835 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1836 |
// Implements the Invoke(object_ptr, &Class::Method) action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1837 |
template <class Class, typename MethodPtr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1838 |
struct InvokeMethodAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1839 |
Class* const obj_ptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1840 |
const MethodPtr method_ptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1841 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1842 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1843 |
auto operator()(Args&&... args) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1844 |
-> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1845 |
return (obj_ptr->*method_ptr)(std::forward<Args>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1846 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1847 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1848 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1849 |
// Implements the InvokeWithoutArgs(f) action. The template argument |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1850 |
// FunctionImpl is the implementation type of f, which can be either a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1851 |
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1852 |
// Action<F> as long as f's type is compatible with F. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1853 |
template <typename FunctionImpl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1854 |
struct InvokeWithoutArgsAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1855 |
FunctionImpl function_impl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1856 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1857 |
// Allows InvokeWithoutArgs(f) to be used as any action whose type is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1858 |
// compatible with f. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1859 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1860 |
auto operator()(const Args&...) -> decltype(function_impl()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1861 |
return function_impl(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1862 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1863 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1864 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1865 |
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1866 |
template <class Class, typename MethodPtr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1867 |
struct InvokeMethodWithoutArgsAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1868 |
Class* const obj_ptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1869 |
const MethodPtr method_ptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1870 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1871 |
using ReturnType = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1872 |
decltype((std::declval<Class*>()->*std::declval<MethodPtr>())()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1873 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1874 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1875 |
ReturnType operator()(const Args&...) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1876 |
return (obj_ptr->*method_ptr)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1877 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1878 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1879 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1880 |
// Implements the IgnoreResult(action) action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1881 |
template <typename A> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1882 |
class IgnoreResultAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1883 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1884 |
explicit IgnoreResultAction(const A& action) : action_(action) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1885 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1886 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1887 |
operator Action<F>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1888 |
// Assert statement belongs here because this is the best place to verify |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1889 |
// conditions on F. It produces the clearest error messages |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1890 |
// in most compilers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1891 |
// Impl really belongs in this scope as a local class but can't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1892 |
// because MSVC produces duplicate symbols in different translation units |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1893 |
// in this case. Until MS fixes that bug we put Impl into the class scope |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1894 |
// and put the typedef both here (for use in assert statement) and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1895 |
// in the Impl class. But both definitions must be the same. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1896 |
typedef typename internal::Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1897 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1898 |
// Asserts at compile time that F returns void. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1899 |
static_assert(std::is_void<Result>::value, "Result type should be void."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1900 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1901 |
return Action<F>(new Impl<F>(action_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1902 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1903 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1904 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1905 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1906 |
class Impl : public ActionInterface<F> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1907 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1908 |
typedef typename internal::Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1909 |
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1910 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1911 |
explicit Impl(const A& action) : action_(action) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1912 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1913 |
void Perform(const ArgumentTuple& args) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1914 |
// Performs the action and ignores its result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1915 |
action_.Perform(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1916 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1917 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1918 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1919 |
// Type OriginalFunction is the same as F except that its return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1920 |
// type is IgnoredValue. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1921 |
typedef typename internal::Function<F>::MakeResultIgnoredValue |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1922 |
OriginalFunction; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1923 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1924 |
const Action<OriginalFunction> action_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1925 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1926 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1927 |
const A action_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1928 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1930 |
template <typename InnerAction, size_t... I> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1931 |
struct WithArgsAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1932 |
InnerAction action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1933 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1934 |
// The inner action could be anything convertible to Action<X>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1935 |
// We use the conversion operator to detect the signature of the inner Action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1936 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1937 |
operator Action<R(Args...)>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1938 |
using TupleType = std::tuple<Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1939 |
Action<R(typename std::tuple_element<I, TupleType>::type...)> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1940 |
converted(action); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1941 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1942 |
return [converted](Args... args) -> R { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1943 |
return converted.Perform(std::forward_as_tuple( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1944 |
std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1945 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1946 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1947 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1949 |
template <typename... Actions> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1950 |
struct DoAllAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1951 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1952 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1953 |
using NonFinalType = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1954 |
typename std::conditional<std::is_scalar<T>::value, T, const T&>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1955 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1956 |
template <typename ActionT, size_t... I> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1957 |
std::vector<ActionT> Convert(IndexSequence<I...>) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1958 |
return {ActionT(std::get<I>(actions))...}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1959 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1960 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1961 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1962 |
std::tuple<Actions...> actions; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1963 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1964 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1965 |
operator Action<R(Args...)>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1966 |
struct Op { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1967 |
std::vector<Action<void(NonFinalType<Args>...)>> converted; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1968 |
Action<R(Args...)> last; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1969 |
R operator()(Args... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1970 |
auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1971 |
for (auto& a : converted) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1972 |
a.Perform(tuple_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1973 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1974 |
return last.Perform(std::move(tuple_args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1975 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1976 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1977 |
return Op{Convert<Action<void(NonFinalType<Args>...)>>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1978 |
MakeIndexSequence<sizeof...(Actions) - 1>()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1979 |
std::get<sizeof...(Actions) - 1>(actions)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1980 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1981 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1982 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1983 |
template <typename T, typename... Params> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1984 |
struct ReturnNewAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1985 |
T* operator()() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1986 |
return internal::Apply( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1987 |
[](const Params&... unpacked_params) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1988 |
return new T(unpacked_params...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1989 |
}, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1990 |
params); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1991 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1992 |
std::tuple<Params...> params; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1993 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1994 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1995 |
template <size_t k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1996 |
struct ReturnArgAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1997 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1998 |
auto operator()(const Args&... args) const -> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
1999 |
typename std::tuple_element<k, std::tuple<Args...>>::type { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2000 |
return std::get<k>(std::tie(args...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2001 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2002 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2003 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2004 |
template <size_t k, typename Ptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2005 |
struct SaveArgAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2006 |
Ptr pointer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2007 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2008 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2009 |
void operator()(const Args&... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2010 |
*pointer = std::get<k>(std::tie(args...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2011 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2012 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2013 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2014 |
template <size_t k, typename Ptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2015 |
struct SaveArgPointeeAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2016 |
Ptr pointer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2017 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2018 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2019 |
void operator()(const Args&... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2020 |
*pointer = *std::get<k>(std::tie(args...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2021 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2022 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2023 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2024 |
template <size_t k, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2025 |
struct SetArgRefereeAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2026 |
T value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2027 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2028 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2029 |
void operator()(Args&&... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2030 |
using argk_type = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2031 |
typename ::std::tuple_element<k, std::tuple<Args...>>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2032 |
static_assert(std::is_lvalue_reference<argk_type>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2033 |
"Argument must be a reference type."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2034 |
std::get<k>(std::tie(args...)) = value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2035 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2036 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2037 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2038 |
template <size_t k, typename I1, typename I2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2039 |
struct SetArrayArgumentAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2040 |
I1 first; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2041 |
I2 last; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2042 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2043 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2044 |
void operator()(const Args&... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2045 |
auto value = std::get<k>(std::tie(args...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2046 |
for (auto it = first; it != last; ++it, (void)++value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2047 |
*value = *it; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2048 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2049 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2050 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2051 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2052 |
template <size_t k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2053 |
struct DeleteArgAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2054 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2055 |
void operator()(const Args&... args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2056 |
delete std::get<k>(std::tie(args...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2057 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2058 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2059 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2060 |
template <typename Ptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2061 |
struct ReturnPointeeAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2062 |
Ptr pointer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2063 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2064 |
auto operator()(const Args&...) const -> decltype(*pointer) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2065 |
return *pointer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2066 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2067 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2068 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2069 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2070 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2071 |
struct ThrowAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2072 |
T exception; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2073 |
// We use a conversion operator to adapt to any return type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2074 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2075 |
operator Action<R(Args...)>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2076 |
T copy = exception; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2077 |
return [copy](Args...) -> R { throw copy; }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2078 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2079 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2080 |
#endif // GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2081 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2082 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2083 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2084 |
// An Unused object can be implicitly constructed from ANY value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2085 |
// This is handy when defining actions that ignore some or all of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2086 |
// mock function arguments. For example, given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2087 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2088 |
// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2089 |
// MOCK_METHOD3(Bar, double(int index, double x, double y)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2090 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2091 |
// instead of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2092 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2093 |
// double DistanceToOriginWithLabel(const string& label, double x, double y) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2094 |
// return sqrt(x*x + y*y); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2095 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2096 |
// double DistanceToOriginWithIndex(int index, double x, double y) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2097 |
// return sqrt(x*x + y*y); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2098 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2099 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2100 |
// EXPECT_CALL(mock, Foo("abc", _, _)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2101 |
// .WillOnce(Invoke(DistanceToOriginWithLabel)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2102 |
// EXPECT_CALL(mock, Bar(5, _, _)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2103 |
// .WillOnce(Invoke(DistanceToOriginWithIndex)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2104 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2105 |
// you could write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2106 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2107 |
// // We can declare any uninteresting argument as Unused. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2108 |
// double DistanceToOrigin(Unused, double x, double y) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2109 |
// return sqrt(x*x + y*y); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2110 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2111 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2112 |
// EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2113 |
// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2114 |
typedef internal::IgnoredValue Unused; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2115 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2116 |
// Creates an action that does actions a1, a2, ..., sequentially in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2117 |
// each invocation. All but the last action will have a readonly view of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2118 |
// arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2119 |
template <typename... Action> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2120 |
internal::DoAllAction<typename std::decay<Action>::type...> DoAll( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2121 |
Action&&... action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2122 |
return {std::forward_as_tuple(std::forward<Action>(action)...)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2123 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2124 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2125 |
// WithArg<k>(an_action) creates an action that passes the k-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2126 |
// (0-based) argument of the mock function to an_action and performs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2127 |
// it. It adapts an action accepting one argument to one that accepts |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2128 |
// multiple arguments. For convenience, we also provide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2129 |
// WithArgs<k>(an_action) (defined below) as a synonym. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2130 |
template <size_t k, typename InnerAction> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2131 |
internal::WithArgsAction<typename std::decay<InnerAction>::type, k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2132 |
WithArg(InnerAction&& action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2133 |
return {std::forward<InnerAction>(action)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2134 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2135 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2136 |
// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2137 |
// the selected arguments of the mock function to an_action and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2138 |
// performs it. It serves as an adaptor between actions with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2139 |
// different argument lists. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2140 |
template <size_t k, size_t... ks, typename InnerAction> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2141 |
internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2142 |
WithArgs(InnerAction&& action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2143 |
return {std::forward<InnerAction>(action)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2144 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2145 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2146 |
// WithoutArgs(inner_action) can be used in a mock function with a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2147 |
// non-empty argument list to perform inner_action, which takes no |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2148 |
// argument. In other words, it adapts an action accepting no |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2149 |
// argument to one that accepts (and ignores) arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2150 |
template <typename InnerAction> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2151 |
internal::WithArgsAction<typename std::decay<InnerAction>::type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2152 |
WithoutArgs(InnerAction&& action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2153 |
return {std::forward<InnerAction>(action)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2154 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2155 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2156 |
// Creates an action that returns 'value'. 'value' is passed by value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2157 |
// instead of const reference - otherwise Return("string literal") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2158 |
// will trigger a compiler error about using array as initializer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2159 |
template <typename R> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2160 |
internal::ReturnAction<R> Return(R value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2161 |
return internal::ReturnAction<R>(std::move(value)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2162 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2163 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2164 |
// Creates an action that returns NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2165 |
inline PolymorphicAction<internal::ReturnNullAction> ReturnNull() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2166 |
return MakePolymorphicAction(internal::ReturnNullAction()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2167 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2168 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2169 |
// Creates an action that returns from a void function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2170 |
inline PolymorphicAction<internal::ReturnVoidAction> Return() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2171 |
return MakePolymorphicAction(internal::ReturnVoidAction()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2172 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2173 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2174 |
// Creates an action that returns the reference to a variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2175 |
template <typename R> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2176 |
inline internal::ReturnRefAction<R> ReturnRef(R& x) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2177 |
return internal::ReturnRefAction<R>(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2178 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2179 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2180 |
// Prevent using ReturnRef on reference to temporary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2181 |
template <typename R, R* = nullptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2182 |
internal::ReturnRefAction<R> ReturnRef(R&&) = delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2183 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2184 |
// Creates an action that returns the reference to a copy of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2185 |
// argument. The copy is created when the action is constructed and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2186 |
// lives as long as the action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2187 |
template <typename R> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2188 |
inline internal::ReturnRefOfCopyAction<R> ReturnRefOfCopy(const R& x) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2189 |
return internal::ReturnRefOfCopyAction<R>(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2190 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2191 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2192 |
// Modifies the parent action (a Return() action) to perform a move of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2193 |
// argument instead of a copy. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2194 |
// Return(ByMove()) actions can only be executed once and will assert this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2195 |
// invariant. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2196 |
template <typename R> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2197 |
internal::ByMoveWrapper<R> ByMove(R x) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2198 |
return internal::ByMoveWrapper<R>(std::move(x)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2199 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2200 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2201 |
// Creates an action that returns an element of `vals`. Calling this action will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2202 |
// repeatedly return the next value from `vals` until it reaches the end and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2203 |
// will restart from the beginning. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2204 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2205 |
internal::ReturnRoundRobinAction<T> ReturnRoundRobin(std::vector<T> vals) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2206 |
return internal::ReturnRoundRobinAction<T>(std::move(vals)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2207 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2208 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2209 |
// Creates an action that returns an element of `vals`. Calling this action will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2210 |
// repeatedly return the next value from `vals` until it reaches the end and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2211 |
// will restart from the beginning. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2212 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2213 |
internal::ReturnRoundRobinAction<T> ReturnRoundRobin( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2214 |
std::initializer_list<T> vals) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2215 |
return internal::ReturnRoundRobinAction<T>(std::vector<T>(vals)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2216 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2217 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2218 |
// Creates an action that does the default action for the give mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2219 |
inline internal::DoDefaultAction DoDefault() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2220 |
return internal::DoDefaultAction(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2221 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2222 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2223 |
// Creates an action that sets the variable pointed by the N-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2224 |
// (0-based) function argument to 'value'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2225 |
template <size_t N, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2226 |
internal::SetArgumentPointeeAction<N, T> SetArgPointee(T value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2227 |
return {std::move(value)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2228 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2229 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2230 |
// The following version is DEPRECATED. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2231 |
template <size_t N, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2232 |
internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2233 |
return {std::move(value)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2234 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2235 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2236 |
// Creates an action that sets a pointer referent to a given value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2237 |
template <typename T1, typename T2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2238 |
PolymorphicAction<internal::AssignAction<T1, T2> > Assign(T1* ptr, T2 val) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2239 |
return MakePolymorphicAction(internal::AssignAction<T1, T2>(ptr, val)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2240 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2241 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2242 |
#if !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2243 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2244 |
// Creates an action that sets errno and returns the appropriate error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2245 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2246 |
PolymorphicAction<internal::SetErrnoAndReturnAction<T> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2247 |
SetErrnoAndReturn(int errval, T result) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2248 |
return MakePolymorphicAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2249 |
internal::SetErrnoAndReturnAction<T>(errval, result)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2250 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2251 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2252 |
#endif // !GTEST_OS_WINDOWS_MOBILE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2254 |
// Various overloads for Invoke(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2255 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2256 |
// Legacy function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2257 |
// Actions can now be implicitly constructed from callables. No need to create |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2258 |
// wrapper objects. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2259 |
// This function exists for backwards compatibility. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2260 |
template <typename FunctionImpl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2261 |
typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2262 |
return std::forward<FunctionImpl>(function_impl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2263 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2264 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2265 |
// Creates an action that invokes the given method on the given object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2266 |
// with the mock function's arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2267 |
template <class Class, typename MethodPtr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2268 |
internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2269 |
MethodPtr method_ptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2270 |
return {obj_ptr, method_ptr}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2271 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2272 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2273 |
// Creates an action that invokes 'function_impl' with no argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2274 |
template <typename FunctionImpl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2275 |
internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2276 |
InvokeWithoutArgs(FunctionImpl function_impl) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2277 |
return {std::move(function_impl)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2278 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2279 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2280 |
// Creates an action that invokes the given method on the given object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2281 |
// with no argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2282 |
template <class Class, typename MethodPtr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2283 |
internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2284 |
Class* obj_ptr, MethodPtr method_ptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2285 |
return {obj_ptr, method_ptr}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2286 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2287 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2288 |
// Creates an action that performs an_action and throws away its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2289 |
// result. In other words, it changes the return type of an_action to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2290 |
// void. an_action MUST NOT return void, or the code won't compile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2291 |
template <typename A> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2292 |
inline internal::IgnoreResultAction<A> IgnoreResult(const A& an_action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2293 |
return internal::IgnoreResultAction<A>(an_action); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2294 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2296 |
// Creates a reference wrapper for the given L-value. If necessary, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2297 |
// you can explicitly specify the type of the reference. For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2298 |
// suppose 'derived' is an object of type Derived, ByRef(derived) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2299 |
// would wrap a Derived&. If you want to wrap a const Base& instead, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2300 |
// where Base is a base class of Derived, just write: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2301 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2302 |
// ByRef<const Base>(derived) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2303 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2304 |
// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2305 |
// However, it may still be used for consistency with ByMove(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2306 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2307 |
inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2308 |
return ::std::reference_wrapper<T>(l_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2309 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2311 |
// The ReturnNew<T>(a1, a2, ..., a_k) action returns a pointer to a new |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2312 |
// instance of type T, constructed on the heap with constructor arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2313 |
// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2314 |
template <typename T, typename... Params> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2315 |
internal::ReturnNewAction<T, typename std::decay<Params>::type...> ReturnNew( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2316 |
Params&&... params) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2317 |
return {std::forward_as_tuple(std::forward<Params>(params)...)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2318 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2319 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2320 |
// Action ReturnArg<k>() returns the k-th argument of the mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2321 |
template <size_t k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2322 |
internal::ReturnArgAction<k> ReturnArg() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2323 |
return {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2324 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2325 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2326 |
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2327 |
// mock function to *pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2328 |
template <size_t k, typename Ptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2329 |
internal::SaveArgAction<k, Ptr> SaveArg(Ptr pointer) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2330 |
return {pointer}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2331 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2332 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2333 |
// Action SaveArgPointee<k>(pointer) saves the value pointed to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2334 |
// by the k-th (0-based) argument of the mock function to *pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2335 |
template <size_t k, typename Ptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2336 |
internal::SaveArgPointeeAction<k, Ptr> SaveArgPointee(Ptr pointer) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2337 |
return {pointer}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2338 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2339 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2340 |
// Action SetArgReferee<k>(value) assigns 'value' to the variable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2341 |
// referenced by the k-th (0-based) argument of the mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2342 |
template <size_t k, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2343 |
internal::SetArgRefereeAction<k, typename std::decay<T>::type> SetArgReferee( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2344 |
T&& value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2345 |
return {std::forward<T>(value)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2346 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2347 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2348 |
// Action SetArrayArgument<k>(first, last) copies the elements in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2349 |
// source range [first, last) to the array pointed to by the k-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2350 |
// (0-based) argument, which can be either a pointer or an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2351 |
// iterator. The action does not take ownership of the elements in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2352 |
// source range. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2353 |
template <size_t k, typename I1, typename I2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2354 |
internal::SetArrayArgumentAction<k, I1, I2> SetArrayArgument(I1 first, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2355 |
I2 last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2356 |
return {first, last}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2357 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2358 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2359 |
// Action DeleteArg<k>() deletes the k-th (0-based) argument of the mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2360 |
// function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2361 |
template <size_t k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2362 |
internal::DeleteArgAction<k> DeleteArg() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2363 |
return {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2364 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2365 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2366 |
// This action returns the value pointed to by 'pointer'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2367 |
template <typename Ptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2368 |
internal::ReturnPointeeAction<Ptr> ReturnPointee(Ptr pointer) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2369 |
return {pointer}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2370 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2371 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2372 |
// Action Throw(exception) can be used in a mock function of any type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2373 |
// to throw the given exception. Any copyable value can be thrown. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2374 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2375 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2376 |
internal::ThrowAction<typename std::decay<T>::type> Throw(T&& exception) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2377 |
return {std::forward<T>(exception)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2378 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2379 |
#endif // GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2381 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2382 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2383 |
// A macro from the ACTION* family (defined later in gmock-generated-actions.h) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2384 |
// defines an action that can be used in a mock function. Typically, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2385 |
// these actions only care about a subset of the arguments of the mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2386 |
// function. For example, if such an action only uses the second |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2387 |
// argument, it can be used in any mock function that takes >= 2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2388 |
// arguments where the type of the second argument is compatible. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2389 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2390 |
// Therefore, the action implementation must be prepared to take more |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2391 |
// arguments than it needs. The ExcessiveArg type is used to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2392 |
// represent those excessive arguments. In order to keep the compiler |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2393 |
// error messages tractable, we define it in the testing namespace |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2394 |
// instead of testing::internal. However, this is an INTERNAL TYPE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2395 |
// and subject to change without notice, so a user MUST NOT USE THIS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2396 |
// TYPE DIRECTLY. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2397 |
struct ExcessiveArg {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2398 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2399 |
// Builds an implementation of an Action<> for some particular signature, using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2400 |
// a class defined by an ACTION* macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2401 |
template <typename F, typename Impl> struct ActionImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2403 |
template <typename Impl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2404 |
struct ImplBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2405 |
struct Holder { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2406 |
// Allows each copy of the Action<> to get to the Impl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2407 |
explicit operator const Impl&() const { return *ptr; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2408 |
std::shared_ptr<Impl> ptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2409 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2410 |
using type = typename std::conditional<std::is_constructible<Impl>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2411 |
Impl, Holder>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2412 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2413 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2414 |
template <typename R, typename... Args, typename Impl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2415 |
struct ActionImpl<R(Args...), Impl> : ImplBase<Impl>::type { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2416 |
using Base = typename ImplBase<Impl>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2417 |
using function_type = R(Args...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2418 |
using args_type = std::tuple<Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2419 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2420 |
ActionImpl() = default; // Only defined if appropriate for Base. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2421 |
explicit ActionImpl(std::shared_ptr<Impl> impl) : Base{std::move(impl)} { } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2422 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2423 |
R operator()(Args&&... arg) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2424 |
static constexpr size_t kMaxArgs = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2425 |
sizeof...(Args) <= 10 ? sizeof...(Args) : 10; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2426 |
return Apply(MakeIndexSequence<kMaxArgs>{}, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2427 |
MakeIndexSequence<10 - kMaxArgs>{}, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2428 |
args_type{std::forward<Args>(arg)...}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2429 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2431 |
template <std::size_t... arg_id, std::size_t... excess_id> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2432 |
R Apply(IndexSequence<arg_id...>, IndexSequence<excess_id...>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2433 |
const args_type& args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2434 |
// Impl need not be specific to the signature of action being implemented; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2435 |
// only the implementing function body needs to have all of the specific |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2436 |
// types instantiated. Up to 10 of the args that are provided by the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2437 |
// args_type get passed, followed by a dummy of unspecified type for the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2438 |
// remainder up to 10 explicit args. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2439 |
static constexpr ExcessiveArg kExcessArg{}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2440 |
return static_cast<const Impl&>(*this).template gmock_PerformImpl< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2441 |
/*function_type=*/function_type, /*return_type=*/R, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2442 |
/*args_type=*/args_type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2443 |
/*argN_type=*/typename std::tuple_element<arg_id, args_type>::type...>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2444 |
/*args=*/args, std::get<arg_id>(args)..., |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2445 |
((void)excess_id, kExcessArg)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2446 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2447 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2448 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2449 |
// Stores a default-constructed Impl as part of the Action<>'s |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2450 |
// std::function<>. The Impl should be trivial to copy. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2451 |
template <typename F, typename Impl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2452 |
::testing::Action<F> MakeAction() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2453 |
return ::testing::Action<F>(ActionImpl<F, Impl>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2454 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2455 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2456 |
// Stores just the one given instance of Impl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2457 |
template <typename F, typename Impl> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2458 |
::testing::Action<F> MakeAction(std::shared_ptr<Impl> impl) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2459 |
return ::testing::Action<F>(ActionImpl<F, Impl>(std::move(impl))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2460 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2462 |
#define GMOCK_INTERNAL_ARG_UNUSED(i, data, el) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2463 |
, const arg##i##_type& arg##i GTEST_ATTRIBUTE_UNUSED_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2464 |
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_ \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2465 |
const args_type& args GTEST_ATTRIBUTE_UNUSED_ GMOCK_PP_REPEAT( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2466 |
GMOCK_INTERNAL_ARG_UNUSED, , 10) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2467 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2468 |
#define GMOCK_INTERNAL_ARG(i, data, el) , const arg##i##_type& arg##i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2469 |
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_ \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2470 |
const args_type& args GMOCK_PP_REPEAT(GMOCK_INTERNAL_ARG, , 10) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2471 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2472 |
#define GMOCK_INTERNAL_TEMPLATE_ARG(i, data, el) , typename arg##i##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2473 |
#define GMOCK_ACTION_TEMPLATE_ARGS_NAMES_ \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2474 |
GMOCK_PP_TAIL(GMOCK_PP_REPEAT(GMOCK_INTERNAL_TEMPLATE_ARG, , 10)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2475 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2476 |
#define GMOCK_INTERNAL_TYPENAME_PARAM(i, data, param) , typename param##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2477 |
#define GMOCK_ACTION_TYPENAME_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2478 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPENAME_PARAM, , params)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2480 |
#define GMOCK_INTERNAL_TYPE_PARAM(i, data, param) , param##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2481 |
#define GMOCK_ACTION_TYPE_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2482 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_PARAM, , params)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2483 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2484 |
#define GMOCK_INTERNAL_TYPE_GVALUE_PARAM(i, data, param) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2485 |
, param##_type gmock_p##i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2486 |
#define GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2487 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_TYPE_GVALUE_PARAM, , params)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2488 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2489 |
#define GMOCK_INTERNAL_GVALUE_PARAM(i, data, param) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2490 |
, std::forward<param##_type>(gmock_p##i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2491 |
#define GMOCK_ACTION_GVALUE_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2492 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GVALUE_PARAM, , params)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2493 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2494 |
#define GMOCK_INTERNAL_INIT_PARAM(i, data, param) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2495 |
, param(::std::forward<param##_type>(gmock_p##i)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2496 |
#define GMOCK_ACTION_INIT_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2497 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_INIT_PARAM, , params)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2498 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2499 |
#define GMOCK_INTERNAL_FIELD_PARAM(i, data, param) param##_type param; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2500 |
#define GMOCK_ACTION_FIELD_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2501 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_FIELD_PARAM, , params) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2502 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2503 |
#define GMOCK_INTERNAL_ACTION(name, full_name, params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2504 |
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2505 |
class full_name { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2506 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2507 |
explicit full_name(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2508 |
: impl_(std::make_shared<gmock_Impl>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2509 |
GMOCK_ACTION_GVALUE_PARAMS_(params))) { } \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2510 |
full_name(const full_name&) = default; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2511 |
full_name(full_name&&) noexcept = default; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2512 |
template <typename F> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2513 |
operator ::testing::Action<F>() const { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2514 |
return ::testing::internal::MakeAction<F>(impl_); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2515 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2516 |
private: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2517 |
class gmock_Impl { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2518 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2519 |
explicit gmock_Impl(GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2520 |
: GMOCK_ACTION_INIT_PARAMS_(params) {} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2521 |
template <typename function_type, typename return_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2522 |
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2523 |
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2524 |
GMOCK_ACTION_FIELD_PARAMS_(params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2525 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2526 |
std::shared_ptr<const gmock_Impl> impl_; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2527 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2528 |
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2529 |
inline full_name<GMOCK_ACTION_TYPE_PARAMS_(params)> name( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2530 |
GMOCK_ACTION_TYPE_GVALUE_PARAMS_(params)) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2531 |
return full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2532 |
GMOCK_ACTION_GVALUE_PARAMS_(params)); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2533 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2534 |
template <GMOCK_ACTION_TYPENAME_PARAMS_(params)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2535 |
template <typename function_type, typename return_type, typename args_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2536 |
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2537 |
return_type full_name<GMOCK_ACTION_TYPE_PARAMS_(params)>::gmock_Impl:: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2538 |
gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2539 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2540 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2542 |
// Similar to GMOCK_INTERNAL_ACTION, but no bound parameters are stored. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2543 |
#define ACTION(name) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2544 |
class name##Action { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2545 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2546 |
explicit name##Action() noexcept {} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2547 |
name##Action(const name##Action&) noexcept {} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2548 |
template <typename F> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2549 |
operator ::testing::Action<F>() const { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2550 |
return ::testing::internal::MakeAction<F, gmock_Impl>(); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2551 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2552 |
private: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2553 |
class gmock_Impl { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2554 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2555 |
template <typename function_type, typename return_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2556 |
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2557 |
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2558 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2559 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2560 |
inline name##Action name() GTEST_MUST_USE_RESULT_; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2561 |
inline name##Action name() { return name##Action(); } \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2562 |
template <typename function_type, typename return_type, typename args_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2563 |
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2564 |
return_type name##Action::gmock_Impl::gmock_PerformImpl( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2565 |
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2566 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2567 |
#define ACTION_P(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2568 |
GMOCK_INTERNAL_ACTION(name, name##ActionP, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2569 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2570 |
#define ACTION_P2(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2571 |
GMOCK_INTERNAL_ACTION(name, name##ActionP2, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2572 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2573 |
#define ACTION_P3(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2574 |
GMOCK_INTERNAL_ACTION(name, name##ActionP3, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2575 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2576 |
#define ACTION_P4(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2577 |
GMOCK_INTERNAL_ACTION(name, name##ActionP4, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2578 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2579 |
#define ACTION_P5(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2580 |
GMOCK_INTERNAL_ACTION(name, name##ActionP5, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2581 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2582 |
#define ACTION_P6(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2583 |
GMOCK_INTERNAL_ACTION(name, name##ActionP6, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2584 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2585 |
#define ACTION_P7(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2586 |
GMOCK_INTERNAL_ACTION(name, name##ActionP7, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2587 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2588 |
#define ACTION_P8(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2589 |
GMOCK_INTERNAL_ACTION(name, name##ActionP8, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2590 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2591 |
#define ACTION_P9(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2592 |
GMOCK_INTERNAL_ACTION(name, name##ActionP9, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2593 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2594 |
#define ACTION_P10(name, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2595 |
GMOCK_INTERNAL_ACTION(name, name##ActionP10, (__VA_ARGS__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2596 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2597 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2598 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2599 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2600 |
# pragma warning(pop) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2601 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2602 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2603 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2604 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2605 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2606 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2607 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2608 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2609 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2610 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2611 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2612 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2613 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2614 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2615 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2616 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2617 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2618 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2619 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2620 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2621 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2622 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2623 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2624 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2625 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2626 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2627 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2628 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2629 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2630 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2631 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2632 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2633 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2634 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2635 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2636 |
// This file implements some commonly used cardinalities. More |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2637 |
// cardinalities can be defined by the user implementing the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2638 |
// CardinalityInterface interface if necessary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2639 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2640 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2641 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2642 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2643 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2644 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2645 |
#include <limits.h> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2646 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2647 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2648 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2649 |
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2650 |
/* class A needs to have dll-interface to be used by clients of class B */) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2651 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2652 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2653 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2654 |
// To implement a cardinality Foo, define: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2655 |
// 1. a class FooCardinality that implements the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2656 |
// CardinalityInterface interface, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2657 |
// 2. a factory function that creates a Cardinality object from a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2658 |
// const FooCardinality*. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2659 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2660 |
// The two-level delegation design follows that of Matcher, providing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2661 |
// consistency for extension developers. It also eases ownership |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2662 |
// management as Cardinality objects can now be copied like plain values. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2663 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2664 |
// The implementation of a cardinality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2665 |
class CardinalityInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2666 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2667 |
virtual ~CardinalityInterface() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2668 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2669 |
// Conservative estimate on the lower/upper bound of the number of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2670 |
// calls allowed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2671 |
virtual int ConservativeLowerBound() const { return 0; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2672 |
virtual int ConservativeUpperBound() const { return INT_MAX; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2673 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2674 |
// Returns true if and only if call_count calls will satisfy this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2675 |
// cardinality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2676 |
virtual bool IsSatisfiedByCallCount(int call_count) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2677 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2678 |
// Returns true if and only if call_count calls will saturate this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2679 |
// cardinality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2680 |
virtual bool IsSaturatedByCallCount(int call_count) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2681 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2682 |
// Describes self to an ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2683 |
virtual void DescribeTo(::std::ostream* os) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2684 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2685 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2686 |
// A Cardinality is a copyable and IMMUTABLE (except by assignment) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2687 |
// object that specifies how many times a mock function is expected to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2688 |
// be called. The implementation of Cardinality is just a std::shared_ptr |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2689 |
// to const CardinalityInterface. Don't inherit from Cardinality! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2690 |
class GTEST_API_ Cardinality { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2691 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2692 |
// Constructs a null cardinality. Needed for storing Cardinality |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2693 |
// objects in STL containers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2694 |
Cardinality() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2695 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2696 |
// Constructs a Cardinality from its implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2697 |
explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2699 |
// Conservative estimate on the lower/upper bound of the number of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2700 |
// calls allowed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2701 |
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2702 |
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2703 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2704 |
// Returns true if and only if call_count calls will satisfy this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2705 |
// cardinality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2706 |
bool IsSatisfiedByCallCount(int call_count) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2707 |
return impl_->IsSatisfiedByCallCount(call_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2708 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2709 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2710 |
// Returns true if and only if call_count calls will saturate this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2711 |
// cardinality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2712 |
bool IsSaturatedByCallCount(int call_count) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2713 |
return impl_->IsSaturatedByCallCount(call_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2714 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2715 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2716 |
// Returns true if and only if call_count calls will over-saturate this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2717 |
// cardinality, i.e. exceed the maximum number of allowed calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2718 |
bool IsOverSaturatedByCallCount(int call_count) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2719 |
return impl_->IsSaturatedByCallCount(call_count) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2720 |
!impl_->IsSatisfiedByCallCount(call_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2721 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2722 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2723 |
// Describes self to an ostream |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2724 |
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2725 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2726 |
// Describes the given actual call count to an ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2727 |
static void DescribeActualCallCountTo(int actual_call_count, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2728 |
::std::ostream* os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2729 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2730 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2731 |
std::shared_ptr<const CardinalityInterface> impl_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2732 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2734 |
// Creates a cardinality that allows at least n calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2735 |
GTEST_API_ Cardinality AtLeast(int n); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2736 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2737 |
// Creates a cardinality that allows at most n calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2738 |
GTEST_API_ Cardinality AtMost(int n); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2739 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2740 |
// Creates a cardinality that allows any number of calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2741 |
GTEST_API_ Cardinality AnyNumber(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2742 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2743 |
// Creates a cardinality that allows between min and max calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2744 |
GTEST_API_ Cardinality Between(int min, int max); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2745 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2746 |
// Creates a cardinality that allows exactly n calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2747 |
GTEST_API_ Cardinality Exactly(int n); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2748 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2749 |
// Creates a cardinality from its implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2750 |
inline Cardinality MakeCardinality(const CardinalityInterface* c) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2751 |
return Cardinality(c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2752 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2753 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2754 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2755 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2756 |
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2757 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2758 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2759 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2760 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2761 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2762 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2763 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2764 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2765 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2766 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2767 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2768 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2769 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2770 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2771 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2772 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2773 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2774 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2775 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2776 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2777 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2778 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2779 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2780 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2781 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2782 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2783 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2784 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2785 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2786 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2787 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2788 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2789 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2790 |
// This file implements MOCK_METHOD. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2791 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2792 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2793 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2794 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2795 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2796 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2797 |
#include <type_traits> // IWYU pragma: keep |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2798 |
#include <utility> // IWYU pragma: keep |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2799 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2800 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2801 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2802 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2803 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2804 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2805 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2806 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2807 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2808 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2809 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2810 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2811 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2812 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2813 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2814 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2815 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2816 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2817 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2818 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2819 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2820 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2821 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2822 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2823 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2824 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2825 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2826 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2827 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2828 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2829 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2830 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2831 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2832 |
// This file implements the ON_CALL() and EXPECT_CALL() macros. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2833 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2834 |
// A user can use the ON_CALL() macro to specify the default action of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2835 |
// a mock method. The syntax is: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2836 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2837 |
// ON_CALL(mock_object, Method(argument-matchers)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2838 |
// .With(multi-argument-matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2839 |
// .WillByDefault(action); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2840 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2841 |
// where the .With() clause is optional. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2842 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2843 |
// A user can use the EXPECT_CALL() macro to specify an expectation on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2844 |
// a mock method. The syntax is: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2845 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2846 |
// EXPECT_CALL(mock_object, Method(argument-matchers)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2847 |
// .With(multi-argument-matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2848 |
// .Times(cardinality) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2849 |
// .InSequence(sequences) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2850 |
// .After(expectations) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2851 |
// .WillOnce(action) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2852 |
// .WillRepeatedly(action) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2853 |
// .RetiresOnSaturation(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2854 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2855 |
// where all clauses are optional, and .InSequence()/.After()/ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2856 |
// .WillOnce() can appear any number of times. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2857 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2858 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2860 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2861 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2862 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2863 |
#include <functional> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2864 |
#include <map> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2865 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2866 |
#include <set> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2867 |
#include <sstream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2868 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2869 |
#include <type_traits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2870 |
#include <utility> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2871 |
#include <vector> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2872 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2873 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2874 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2875 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2876 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2877 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2878 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2879 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2880 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2881 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2882 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2883 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2884 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2885 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2886 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2887 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2888 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2889 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2890 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2891 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2892 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2893 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2894 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2895 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2896 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2897 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2898 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2899 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2900 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2901 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2902 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2903 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2904 |
// The MATCHER* family of macros can be used in a namespace scope to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2905 |
// define custom matchers easily. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2906 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2907 |
// Basic Usage |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2908 |
// =========== |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2909 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2910 |
// The syntax |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2911 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2912 |
// MATCHER(name, description_string) { statements; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2913 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2914 |
// defines a matcher with the given name that executes the statements, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2915 |
// which must return a bool to indicate if the match succeeds. Inside |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2916 |
// the statements, you can refer to the value being matched by 'arg', |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2917 |
// and refer to its type by 'arg_type'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2918 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2919 |
// The description string documents what the matcher does, and is used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2920 |
// to generate the failure message when the match fails. Since a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2921 |
// MATCHER() is usually defined in a header file shared by multiple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2922 |
// C++ source files, we require the description to be a C-string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2923 |
// literal to avoid possible side effects. It can be empty, in which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2924 |
// case we'll use the sequence of words in the matcher name as the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2925 |
// description. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2926 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2927 |
// For example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2928 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2929 |
// MATCHER(IsEven, "") { return (arg % 2) == 0; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2930 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2931 |
// allows you to write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2932 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2933 |
// // Expects mock_foo.Bar(n) to be called where n is even. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2934 |
// EXPECT_CALL(mock_foo, Bar(IsEven())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2935 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2936 |
// or, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2937 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2938 |
// // Verifies that the value of some_expression is even. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2939 |
// EXPECT_THAT(some_expression, IsEven()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2940 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2941 |
// If the above assertion fails, it will print something like: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2942 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2943 |
// Value of: some_expression |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2944 |
// Expected: is even |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2945 |
// Actual: 7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2946 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2947 |
// where the description "is even" is automatically calculated from the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2948 |
// matcher name IsEven. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2949 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2950 |
// Argument Type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2951 |
// ============= |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2952 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2953 |
// Note that the type of the value being matched (arg_type) is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2954 |
// determined by the context in which you use the matcher and is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2955 |
// supplied to you by the compiler, so you don't need to worry about |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2956 |
// declaring it (nor can you). This allows the matcher to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2957 |
// polymorphic. For example, IsEven() can be used to match any type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2958 |
// where the value of "(arg % 2) == 0" can be implicitly converted to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2959 |
// a bool. In the "Bar(IsEven())" example above, if method Bar() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2960 |
// takes an int, 'arg_type' will be int; if it takes an unsigned long, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2961 |
// 'arg_type' will be unsigned long; and so on. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2962 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2963 |
// Parameterizing Matchers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2964 |
// ======================= |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2965 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2966 |
// Sometimes you'll want to parameterize the matcher. For that you |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2967 |
// can use another macro: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2968 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2969 |
// MATCHER_P(name, param_name, description_string) { statements; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2970 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2971 |
// For example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2972 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2973 |
// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2974 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2975 |
// will allow you to write: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2976 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2977 |
// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2978 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2979 |
// which may lead to this message (assuming n is 10): |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2980 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2981 |
// Value of: Blah("a") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2982 |
// Expected: has absolute value 10 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2983 |
// Actual: -9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2984 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2985 |
// Note that both the matcher description and its parameter are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2986 |
// printed, making the message human-friendly. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2987 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2988 |
// In the matcher definition body, you can write 'foo_type' to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2989 |
// reference the type of a parameter named 'foo'. For example, in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2990 |
// body of MATCHER_P(HasAbsoluteValue, value) above, you can write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2991 |
// 'value_type' to refer to the type of 'value'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2992 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2993 |
// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2994 |
// support multi-parameter matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2995 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2996 |
// Describing Parameterized Matchers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2997 |
// ================================= |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2998 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
2999 |
// The last argument to MATCHER*() is a string-typed expression. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3000 |
// expression can reference all of the matcher's parameters and a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3001 |
// special bool-typed variable named 'negation'. When 'negation' is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3002 |
// false, the expression should evaluate to the matcher's description; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3003 |
// otherwise it should evaluate to the description of the negation of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3004 |
// the matcher. For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3005 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3006 |
// using testing::PrintToString; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3007 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3008 |
// MATCHER_P2(InClosedRange, low, hi, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3009 |
// std::string(negation ? "is not" : "is") + " in range [" + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3010 |
// PrintToString(low) + ", " + PrintToString(hi) + "]") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3011 |
// return low <= arg && arg <= hi; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3012 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3013 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3014 |
// EXPECT_THAT(3, InClosedRange(4, 6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3015 |
// EXPECT_THAT(3, Not(InClosedRange(2, 4))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3016 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3017 |
// would generate two failures that contain the text: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3018 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3019 |
// Expected: is in range [4, 6] |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3020 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3021 |
// Expected: is not in range [2, 4] |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3022 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3023 |
// If you specify "" as the description, the failure message will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3024 |
// contain the sequence of words in the matcher name followed by the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3025 |
// parameter values printed as a tuple. For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3026 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3027 |
// MATCHER_P2(InClosedRange, low, hi, "") { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3028 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3029 |
// EXPECT_THAT(3, InClosedRange(4, 6)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3030 |
// EXPECT_THAT(3, Not(InClosedRange(2, 4))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3031 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3032 |
// would generate two failures that contain the text: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3033 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3034 |
// Expected: in closed range (4, 6) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3035 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3036 |
// Expected: not (in closed range (2, 4)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3037 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3038 |
// Types of Matcher Parameters |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3039 |
// =========================== |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3040 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3041 |
// For the purpose of typing, you can view |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3042 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3043 |
// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3044 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3045 |
// as shorthand for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3046 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3047 |
// template <typename p1_type, ..., typename pk_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3048 |
// FooMatcherPk<p1_type, ..., pk_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3049 |
// Foo(p1_type p1, ..., pk_type pk) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3050 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3051 |
// When you write Foo(v1, ..., vk), the compiler infers the types of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3052 |
// the parameters v1, ..., and vk for you. If you are not happy with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3053 |
// the result of the type inference, you can specify the types by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3054 |
// explicitly instantiating the template, as in Foo<long, bool>(5, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3055 |
// false). As said earlier, you don't get to (or need to) specify |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3056 |
// 'arg_type' as that's determined by the context in which the matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3057 |
// is used. You can assign the result of expression Foo(p1, ..., pk) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3058 |
// to a variable of type FooMatcherPk<p1_type, ..., pk_type>. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3059 |
// can be useful when composing matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3060 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3061 |
// While you can instantiate a matcher template with reference types, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3062 |
// passing the parameters by pointer usually makes your code more |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3063 |
// readable. If, however, you still want to pass a parameter by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3064 |
// reference, be aware that in the failure message generated by the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3065 |
// matcher you will see the value of the referenced object but not its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3066 |
// address. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3067 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3068 |
// Explaining Match Results |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3069 |
// ======================== |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3070 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3071 |
// Sometimes the matcher description alone isn't enough to explain why |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3072 |
// the match has failed or succeeded. For example, when expecting a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3073 |
// long string, it can be very helpful to also print the diff between |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3074 |
// the expected string and the actual one. To achieve that, you can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3075 |
// optionally stream additional information to a special variable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3076 |
// named result_listener, whose type is a pointer to class |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3077 |
// MatchResultListener: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3078 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3079 |
// MATCHER_P(EqualsLongString, str, "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3080 |
// if (arg == str) return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3081 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3082 |
// *result_listener << "the difference: " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3083 |
/// << DiffStrings(str, arg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3084 |
// return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3085 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3086 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3087 |
// Overloading Matchers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3088 |
// ==================== |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3089 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3090 |
// You can overload matchers with different numbers of parameters: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3091 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3092 |
// MATCHER_P(Blah, a, description_string1) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3093 |
// MATCHER_P2(Blah, a, b, description_string2) { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3094 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3095 |
// Caveats |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3096 |
// ======= |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3097 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3098 |
// When defining a new matcher, you should also consider implementing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3099 |
// MatcherInterface or using MakePolymorphicMatcher(). These |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3100 |
// approaches require more work than the MATCHER* macros, but also |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3101 |
// give you more control on the types of the value being matched and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3102 |
// the matcher parameters, which may leads to better compiler error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3103 |
// messages when the matcher is used wrong. They also allow |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3104 |
// overloading matchers based on parameter types (as opposed to just |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3105 |
// based on the number of parameters). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3106 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3107 |
// MATCHER*() can only be used in a namespace scope as templates cannot be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3108 |
// declared inside of a local class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3109 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3110 |
// More Information |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3111 |
// ================ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3112 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3113 |
// To learn more about using these macros, please search for 'MATCHER' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3114 |
// on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3115 |
// https://github.com/google/googletest/blob/master/docs/gmock_cook_book.md |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3116 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3117 |
// This file also implements some commonly used argument matchers. More |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3118 |
// matchers can be defined by the user implementing the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3119 |
// MatcherInterface<T> interface if necessary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3120 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3121 |
// See googletest/include/gtest/gtest-matchers.h for the definition of class |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3122 |
// Matcher, class MatcherInterface, and others. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3123 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3124 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3125 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3126 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3127 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3129 |
#include <algorithm> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3130 |
#include <cmath> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3131 |
#include <initializer_list> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3132 |
#include <iterator> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3133 |
#include <limits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3134 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3135 |
#include <ostream> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3136 |
#include <sstream> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3137 |
#include <string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3138 |
#include <type_traits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3139 |
#include <utility> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3140 |
#include <vector> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3141 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3142 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3143 |
// MSVC warning C5046 is new as of VS2017 version 15.8. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3144 |
#if defined(_MSC_VER) && _MSC_VER >= 1915 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3145 |
#define GMOCK_MAYBE_5046_ 5046 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3146 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3147 |
#define GMOCK_MAYBE_5046_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3148 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3149 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3150 |
GTEST_DISABLE_MSC_WARNINGS_PUSH_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3151 |
4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3152 |
clients of class B */ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3153 |
/* Symbol involving type with internal linkage not defined */) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3154 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3155 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3157 |
// To implement a matcher Foo for type T, define: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3158 |
// 1. a class FooMatcherImpl that implements the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3159 |
// MatcherInterface<T> interface, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3160 |
// 2. a factory function that creates a Matcher<T> object from a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3161 |
// FooMatcherImpl*. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3162 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3163 |
// The two-level delegation design makes it possible to allow a user |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3164 |
// to write "v" instead of "Eq(v)" where a Matcher is expected, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3165 |
// is impossible if we pass matchers by pointers. It also eases |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3166 |
// ownership management as Matcher objects can now be copied like |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3167 |
// plain values. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3168 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3169 |
// A match result listener that stores the explanation in a string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3170 |
class StringMatchResultListener : public MatchResultListener { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3171 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3172 |
StringMatchResultListener() : MatchResultListener(&ss_) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3173 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3174 |
// Returns the explanation accumulated so far. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3175 |
std::string str() const { return ss_.str(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3176 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3177 |
// Clears the explanation accumulated so far. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3178 |
void Clear() { ss_.str(""); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3179 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3180 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3181 |
::std::stringstream ss_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3182 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3183 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3184 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3185 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3186 |
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3187 |
// and MUST NOT BE USED IN USER CODE!!! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3188 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3189 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3190 |
// The MatcherCastImpl class template is a helper for implementing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3191 |
// MatcherCast(). We need this helper in order to partially |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3192 |
// specialize the implementation of MatcherCast() (C++ allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3193 |
// class/struct templates to be partially specialized, but not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3194 |
// function templates.). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3195 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3196 |
// This general version is used when MatcherCast()'s argument is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3197 |
// polymorphic matcher (i.e. something that can be converted to a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3198 |
// Matcher but is not one yet; for example, Eq(value)) or a value (for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3199 |
// example, "hello"). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3200 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3201 |
class MatcherCastImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3202 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3203 |
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3204 |
// M can be a polymorphic matcher, in which case we want to use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3205 |
// its conversion operator to create Matcher<T>. Or it can be a value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3206 |
// that should be passed to the Matcher<T>'s constructor. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3207 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3208 |
// We can't call Matcher<T>(polymorphic_matcher_or_value) when M is a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3209 |
// polymorphic matcher because it'll be ambiguous if T has an implicit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3210 |
// constructor from M (this usually happens when T has an implicit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3211 |
// constructor from any type). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3212 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3213 |
// It won't work to unconditionally implicit_cast |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3214 |
// polymorphic_matcher_or_value to Matcher<T> because it won't trigger |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3215 |
// a user-defined conversion from M to T if one exists (assuming M is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3216 |
// a value). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3217 |
return CastImpl(polymorphic_matcher_or_value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3218 |
std::is_convertible<M, Matcher<T>>{}, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3219 |
std::is_convertible<M, T>{}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3220 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3221 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3222 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3223 |
template <bool Ignore> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3224 |
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3225 |
std::true_type /* convertible_to_matcher */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3226 |
std::integral_constant<bool, Ignore>) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3227 |
// M is implicitly convertible to Matcher<T>, which means that either |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3228 |
// M is a polymorphic matcher or Matcher<T> has an implicit constructor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3229 |
// from M. In both cases using the implicit conversion will produce a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3230 |
// matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3231 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3232 |
// Even if T has an implicit constructor from M, it won't be called because |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3233 |
// creating Matcher<T> would require a chain of two user-defined conversions |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3234 |
// (first to create T from M and then to create Matcher<T> from T). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3235 |
return polymorphic_matcher_or_value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3236 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3237 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3238 |
// M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3239 |
// matcher. It's a value of a type implicitly convertible to T. Use direct |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3240 |
// initialization to create a matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3241 |
static Matcher<T> CastImpl(const M& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3242 |
std::false_type /* convertible_to_matcher */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3243 |
std::true_type /* convertible_to_T */) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3244 |
return Matcher<T>(ImplicitCast_<T>(value)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3245 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3246 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3247 |
// M can't be implicitly converted to either Matcher<T> or T. Attempt to use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3248 |
// polymorphic matcher Eq(value) in this case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3249 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3250 |
// Note that we first attempt to perform an implicit cast on the value and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3251 |
// only fall back to the polymorphic Eq() matcher afterwards because the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3252 |
// latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3253 |
// which might be undefined even when Rhs is implicitly convertible to Lhs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3254 |
// (e.g. std::pair<const int, int> vs. std::pair<int, int>). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3255 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3256 |
// We don't define this method inline as we need the declaration of Eq(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3257 |
static Matcher<T> CastImpl(const M& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3258 |
std::false_type /* convertible_to_matcher */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3259 |
std::false_type /* convertible_to_T */); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3260 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3261 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3262 |
// This more specialized version is used when MatcherCast()'s argument |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3263 |
// is already a Matcher. This only compiles when type T can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3264 |
// statically converted to type U. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3265 |
template <typename T, typename U> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3266 |
class MatcherCastImpl<T, Matcher<U> > { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3267 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3268 |
static Matcher<T> Cast(const Matcher<U>& source_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3269 |
return Matcher<T>(new Impl(source_matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3270 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3272 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3273 |
class Impl : public MatcherInterface<T> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3274 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3275 |
explicit Impl(const Matcher<U>& source_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3276 |
: source_matcher_(source_matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3277 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3278 |
// We delegate the matching logic to the source matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3279 |
bool MatchAndExplain(T x, MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3280 |
using FromType = typename std::remove_cv<typename std::remove_pointer< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3281 |
typename std::remove_reference<T>::type>::type>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3282 |
using ToType = typename std::remove_cv<typename std::remove_pointer< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3283 |
typename std::remove_reference<U>::type>::type>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3284 |
// Do not allow implicitly converting base*/& to derived*/&. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3285 |
static_assert( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3286 |
// Do not trigger if only one of them is a pointer. That implies a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3287 |
// regular conversion and not a down_cast. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3288 |
(std::is_pointer<typename std::remove_reference<T>::type>::value != |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3289 |
std::is_pointer<typename std::remove_reference<U>::type>::value) || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3290 |
std::is_same<FromType, ToType>::value || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3291 |
!std::is_base_of<FromType, ToType>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3292 |
"Can't implicitly convert from <base> to <derived>"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3294 |
// Do the cast to `U` explicitly if necessary. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3295 |
// Otherwise, let implicit conversions do the trick. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3296 |
using CastType = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3297 |
typename std::conditional<std::is_convertible<T&, const U&>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3298 |
T&, U>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3299 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3300 |
return source_matcher_.MatchAndExplain(static_cast<CastType>(x), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3301 |
listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3302 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3303 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3304 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3305 |
source_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3306 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3307 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3308 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3309 |
source_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3310 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3311 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3312 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3313 |
const Matcher<U> source_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3314 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3315 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3316 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3317 |
// This even more specialized version is used for efficiently casting |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3318 |
// a matcher to its own type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3319 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3320 |
class MatcherCastImpl<T, Matcher<T> > { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3321 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3322 |
static Matcher<T> Cast(const Matcher<T>& matcher) { return matcher; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3323 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3324 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3325 |
// Template specialization for parameterless Matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3326 |
template <typename Derived> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3327 |
class MatcherBaseImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3328 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3329 |
MatcherBaseImpl() = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3331 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3332 |
operator ::testing::Matcher<T>() const { // NOLINT(runtime/explicit) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3333 |
return ::testing::Matcher<T>(new |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3334 |
typename Derived::template gmock_Impl<T>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3335 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3336 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3337 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3338 |
// Template specialization for Matcher with parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3339 |
template <template <typename...> class Derived, typename... Ts> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3340 |
class MatcherBaseImpl<Derived<Ts...>> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3341 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3342 |
// Mark the constructor explicit for single argument T to avoid implicit |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3343 |
// conversions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3344 |
template <typename E = std::enable_if<sizeof...(Ts) == 1>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3345 |
typename E::type* = nullptr> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3346 |
explicit MatcherBaseImpl(Ts... params) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3347 |
: params_(std::forward<Ts>(params)...) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3348 |
template <typename E = std::enable_if<sizeof...(Ts) != 1>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3349 |
typename = typename E::type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3350 |
MatcherBaseImpl(Ts... params) // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3351 |
: params_(std::forward<Ts>(params)...) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3352 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3353 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3354 |
operator ::testing::Matcher<F>() const { // NOLINT(runtime/explicit) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3355 |
return Apply<F>(MakeIndexSequence<sizeof...(Ts)>{}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3356 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3357 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3358 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3359 |
template <typename F, std::size_t... tuple_ids> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3360 |
::testing::Matcher<F> Apply(IndexSequence<tuple_ids...>) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3361 |
return ::testing::Matcher<F>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3362 |
new typename Derived<Ts...>::template gmock_Impl<F>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3363 |
std::get<tuple_ids>(params_)...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3364 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3365 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3366 |
const std::tuple<Ts...> params_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3367 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3368 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3369 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3370 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3371 |
// In order to be safe and clear, casting between different matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3372 |
// types is done explicitly via MatcherCast<T>(m), which takes a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3373 |
// matcher m and returns a Matcher<T>. It compiles only when T can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3374 |
// statically converted to the argument type of m. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3375 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3376 |
inline Matcher<T> MatcherCast(const M& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3377 |
return internal::MatcherCastImpl<T, M>::Cast(matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3378 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3379 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3380 |
// This overload handles polymorphic matchers and values only since |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3381 |
// monomorphic matchers are handled by the next one. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3382 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3383 |
inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3384 |
return MatcherCast<T>(polymorphic_matcher_or_value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3385 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3386 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3387 |
// This overload handles monomorphic matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3388 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3389 |
// In general, if type T can be implicitly converted to type U, we can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3390 |
// safely convert a Matcher<U> to a Matcher<T> (i.e. Matcher is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3391 |
// contravariant): just keep a copy of the original Matcher<U>, convert the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3392 |
// argument from type T to U, and then pass it to the underlying Matcher<U>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3393 |
// The only exception is when U is a reference and T is not, as the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3394 |
// underlying Matcher<U> may be interested in the argument's address, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3395 |
// is not preserved in the conversion from T to U. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3396 |
template <typename T, typename U> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3397 |
inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3398 |
// Enforce that T can be implicitly converted to U. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3399 |
static_assert(std::is_convertible<const T&, const U&>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3400 |
"T must be implicitly convertible to U"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3401 |
// Enforce that we are not converting a non-reference type T to a reference |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3402 |
// type U. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3403 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3404 |
std::is_reference<T>::value || !std::is_reference<U>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3405 |
cannot_convert_non_reference_arg_to_reference); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3406 |
// In case both T and U are arithmetic types, enforce that the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3407 |
// conversion is not lossy. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3408 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3409 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3410 |
constexpr bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3411 |
constexpr bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3412 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3413 |
kTIsOther || kUIsOther || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3414 |
(internal::LosslessArithmeticConvertible<RawT, RawU>::value), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3415 |
conversion_of_arithmetic_types_must_be_lossless); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3416 |
return MatcherCast<T>(matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3417 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3418 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3419 |
// A<T>() returns a matcher that matches any value of type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3420 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3421 |
Matcher<T> A(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3422 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3423 |
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3424 |
// and MUST NOT BE USED IN USER CODE!!! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3425 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3426 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3427 |
// If the explanation is not empty, prints it to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3428 |
inline void PrintIfNotEmpty(const std::string& explanation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3429 |
::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3430 |
if (explanation != "" && os != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3431 |
*os << ", " << explanation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3432 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3433 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3435 |
// Returns true if the given type name is easy to read by a human. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3436 |
// This is used to decide whether printing the type of a value might |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3437 |
// be helpful. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3438 |
inline bool IsReadableTypeName(const std::string& type_name) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3439 |
// We consider a type name readable if it's short or doesn't contain |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3440 |
// a template or function type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3441 |
return (type_name.length() <= 20 || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3442 |
type_name.find_first_of("<(") == std::string::npos); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3443 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3445 |
// Matches the value against the given matcher, prints the value and explains |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3446 |
// the match result to the listener. Returns the match result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3447 |
// 'listener' must not be NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3448 |
// Value cannot be passed by const reference, because some matchers take a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3449 |
// non-const argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3450 |
template <typename Value, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3451 |
bool MatchPrintAndExplain(Value& value, const Matcher<T>& matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3452 |
MatchResultListener* listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3453 |
if (!listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3454 |
// If the listener is not interested, we do not need to construct the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3455 |
// inner explanation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3456 |
return matcher.Matches(value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3457 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3458 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3459 |
StringMatchResultListener inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3460 |
const bool match = matcher.MatchAndExplain(value, &inner_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3462 |
UniversalPrint(value, listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3463 |
#if GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3464 |
const std::string& type_name = GetTypeName<Value>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3465 |
if (IsReadableTypeName(type_name)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3466 |
*listener->stream() << " (of type " << type_name << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3467 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3468 |
PrintIfNotEmpty(inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3469 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3470 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3471 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3472 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3473 |
// An internal helper class for doing compile-time loop on a tuple's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3474 |
// fields. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3475 |
template <size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3476 |
class TuplePrefix { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3477 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3478 |
// TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3479 |
// if and only if the first N fields of matcher_tuple matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3480 |
// the first N fields of value_tuple, respectively. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3481 |
template <typename MatcherTuple, typename ValueTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3482 |
static bool Matches(const MatcherTuple& matcher_tuple, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3483 |
const ValueTuple& value_tuple) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3484 |
return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3485 |
std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3486 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3487 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3488 |
// TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3489 |
// describes failures in matching the first N fields of matchers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3490 |
// against the first N fields of values. If there is no failure, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3491 |
// nothing will be streamed to os. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3492 |
template <typename MatcherTuple, typename ValueTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3493 |
static void ExplainMatchFailuresTo(const MatcherTuple& matchers, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3494 |
const ValueTuple& values, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3495 |
::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3496 |
// First, describes failures in the first N - 1 fields. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3497 |
TuplePrefix<N - 1>::ExplainMatchFailuresTo(matchers, values, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3498 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3499 |
// Then describes the failure (if any) in the (N - 1)-th (0-based) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3500 |
// field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3501 |
typename std::tuple_element<N - 1, MatcherTuple>::type matcher = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3502 |
std::get<N - 1>(matchers); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3503 |
typedef typename std::tuple_element<N - 1, ValueTuple>::type Value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3504 |
const Value& value = std::get<N - 1>(values); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3505 |
StringMatchResultListener listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3506 |
if (!matcher.MatchAndExplain(value, &listener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3507 |
*os << " Expected arg #" << N - 1 << ": "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3508 |
std::get<N - 1>(matchers).DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3509 |
*os << "\n Actual: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3510 |
// We remove the reference in type Value to prevent the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3511 |
// universal printer from printing the address of value, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3512 |
// isn't interesting to the user most of the time. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3513 |
// matcher's MatchAndExplain() method handles the case when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3514 |
// the address is interesting. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3515 |
internal::UniversalPrint(value, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3516 |
PrintIfNotEmpty(listener.str(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3517 |
*os << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3518 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3519 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3520 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3521 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3522 |
// The base case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3523 |
template <> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3524 |
class TuplePrefix<0> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3525 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3526 |
template <typename MatcherTuple, typename ValueTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3527 |
static bool Matches(const MatcherTuple& /* matcher_tuple */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3528 |
const ValueTuple& /* value_tuple */) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3529 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3530 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3531 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3532 |
template <typename MatcherTuple, typename ValueTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3533 |
static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3534 |
const ValueTuple& /* values */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3535 |
::std::ostream* /* os */) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3536 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3537 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3538 |
// TupleMatches(matcher_tuple, value_tuple) returns true if and only if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3539 |
// all matchers in matcher_tuple match the corresponding fields in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3540 |
// value_tuple. It is a compiler error if matcher_tuple and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3541 |
// value_tuple have different number of fields or incompatible field |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3542 |
// types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3543 |
template <typename MatcherTuple, typename ValueTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3544 |
bool TupleMatches(const MatcherTuple& matcher_tuple, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3545 |
const ValueTuple& value_tuple) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3546 |
// Makes sure that matcher_tuple and value_tuple have the same |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3547 |
// number of fields. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3548 |
GTEST_COMPILE_ASSERT_(std::tuple_size<MatcherTuple>::value == |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3549 |
std::tuple_size<ValueTuple>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3550 |
matcher_and_value_have_different_numbers_of_fields); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3551 |
return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3552 |
value_tuple); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3553 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3554 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3555 |
// Describes failures in matching matchers against values. If there |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3556 |
// is no failure, nothing will be streamed to os. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3557 |
template <typename MatcherTuple, typename ValueTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3558 |
void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3559 |
const ValueTuple& values, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3560 |
::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3561 |
TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3562 |
matchers, values, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3563 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3564 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3565 |
// TransformTupleValues and its helper. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3566 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3567 |
// TransformTupleValuesHelper hides the internal machinery that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3568 |
// TransformTupleValues uses to implement a tuple traversal. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3569 |
template <typename Tuple, typename Func, typename OutIter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3570 |
class TransformTupleValuesHelper { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3571 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3572 |
typedef ::std::tuple_size<Tuple> TupleSize; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3573 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3574 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3575 |
// For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3576 |
// Returns the final value of 'out' in case the caller needs it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3577 |
static OutIter Run(Func f, const Tuple& t, OutIter out) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3578 |
return IterateOverTuple<Tuple, TupleSize::value>()(f, t, out); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3579 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3580 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3581 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3582 |
template <typename Tup, size_t kRemainingSize> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3583 |
struct IterateOverTuple { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3584 |
OutIter operator() (Func f, const Tup& t, OutIter out) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3585 |
*out++ = f(::std::get<TupleSize::value - kRemainingSize>(t)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3586 |
return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3587 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3588 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3589 |
template <typename Tup> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3590 |
struct IterateOverTuple<Tup, 0> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3591 |
OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3592 |
return out; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3593 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3594 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3595 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3596 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3597 |
// Successively invokes 'f(element)' on each element of the tuple 't', |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3598 |
// appending each result to the 'out' iterator. Returns the final value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3599 |
// of 'out'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3600 |
template <typename Tuple, typename Func, typename OutIter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3601 |
OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3602 |
return TransformTupleValuesHelper<Tuple, Func, OutIter>::Run(f, t, out); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3603 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3604 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3605 |
// Implements _, a matcher that matches any value of any |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3606 |
// type. This is a polymorphic matcher, so we need a template type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3607 |
// conversion operator to make it appearing as a Matcher<T> for any |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3608 |
// type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3609 |
class AnythingMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3610 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3611 |
using is_gtest_matcher = void; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3612 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3613 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3614 |
bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3615 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3616 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3617 |
void DescribeTo(std::ostream* os) const { *os << "is anything"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3618 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3619 |
// This is mostly for completeness' sake, as it's not very useful |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3620 |
// to write Not(A<bool>()). However we cannot completely rule out |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3621 |
// such a possibility, and it doesn't hurt to be prepared. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3622 |
*os << "never matches"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3623 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3624 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3625 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3626 |
// Implements the polymorphic IsNull() matcher, which matches any raw or smart |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3627 |
// pointer that is NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3628 |
class IsNullMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3629 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3630 |
template <typename Pointer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3631 |
bool MatchAndExplain(const Pointer& p, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3632 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3633 |
return p == nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3634 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3635 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3636 |
void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3637 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3638 |
*os << "isn't NULL"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3639 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3640 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3641 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3642 |
// Implements the polymorphic NotNull() matcher, which matches any raw or smart |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3643 |
// pointer that is not NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3644 |
class NotNullMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3645 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3646 |
template <typename Pointer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3647 |
bool MatchAndExplain(const Pointer& p, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3648 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3649 |
return p != nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3650 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3651 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3652 |
void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3653 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3654 |
*os << "is NULL"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3655 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3656 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3657 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3658 |
// Ref(variable) matches any argument that is a reference to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3659 |
// 'variable'. This matcher is polymorphic as it can match any |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3660 |
// super type of the type of 'variable'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3661 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3662 |
// The RefMatcher template class implements Ref(variable). It can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3663 |
// only be instantiated with a reference type. This prevents a user |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3664 |
// from mistakenly using Ref(x) to match a non-reference function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3665 |
// argument. For example, the following will righteously cause a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3666 |
// compiler error: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3667 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3668 |
// int n; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3669 |
// Matcher<int> m1 = Ref(n); // This won't compile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3670 |
// Matcher<int&> m2 = Ref(n); // This will compile. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3671 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3672 |
class RefMatcher; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3673 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3674 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3675 |
class RefMatcher<T&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3676 |
// Google Mock is a generic framework and thus needs to support |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3677 |
// mocking any function types, including those that take non-const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3678 |
// reference arguments. Therefore the template parameter T (and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3679 |
// Super below) can be instantiated to either a const type or a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3680 |
// non-const type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3681 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3682 |
// RefMatcher() takes a T& instead of const T&, as we want the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3683 |
// compiler to catch using Ref(const_value) as a matcher for a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3684 |
// non-const reference. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3685 |
explicit RefMatcher(T& x) : object_(x) {} // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3686 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3687 |
template <typename Super> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3688 |
operator Matcher<Super&>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3689 |
// By passing object_ (type T&) to Impl(), which expects a Super&, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3690 |
// we make sure that Super is a super type of T. In particular, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3691 |
// this catches using Ref(const_value) as a matcher for a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3692 |
// non-const reference, as you cannot implicitly convert a const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3693 |
// reference to a non-const reference. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3694 |
return MakeMatcher(new Impl<Super>(object_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3695 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3696 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3697 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3698 |
template <typename Super> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3699 |
class Impl : public MatcherInterface<Super&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3700 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3701 |
explicit Impl(Super& x) : object_(x) {} // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3702 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3703 |
// MatchAndExplain() takes a Super& (as opposed to const Super&) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3704 |
// in order to match the interface MatcherInterface<Super&>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3705 |
bool MatchAndExplain(Super& x, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3706 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3707 |
*listener << "which is located @" << static_cast<const void*>(&x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3708 |
return &x == &object_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3709 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3710 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3711 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3712 |
*os << "references the variable "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3713 |
UniversalPrinter<Super&>::Print(object_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3714 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3715 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3716 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3717 |
*os << "does not reference the variable "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3718 |
UniversalPrinter<Super&>::Print(object_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3719 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3720 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3721 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3722 |
const Super& object_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3723 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3724 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3725 |
T& object_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3726 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3727 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3728 |
// Polymorphic helper functions for narrow and wide string matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3729 |
inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3730 |
return String::CaseInsensitiveCStringEquals(lhs, rhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3731 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3732 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3733 |
inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3734 |
const wchar_t* rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3735 |
return String::CaseInsensitiveWideCStringEquals(lhs, rhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3736 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3737 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3738 |
// String comparison for narrow or wide strings that can have embedded NUL |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3739 |
// characters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3740 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3741 |
bool CaseInsensitiveStringEquals(const StringType& s1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3742 |
const StringType& s2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3743 |
// Are the heads equal? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3744 |
if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3745 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3746 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3747 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3748 |
// Skip the equal heads. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3749 |
const typename StringType::value_type nul = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3750 |
const size_t i1 = s1.find(nul), i2 = s2.find(nul); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3752 |
// Are we at the end of either s1 or s2? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3753 |
if (i1 == StringType::npos || i2 == StringType::npos) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3754 |
return i1 == i2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3755 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3756 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3757 |
// Are the tails equal? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3758 |
return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3759 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3760 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3761 |
// String matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3762 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3763 |
// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3764 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3765 |
class StrEqualityMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3766 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3767 |
StrEqualityMatcher(StringType str, bool expect_eq, bool case_sensitive) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3768 |
: string_(std::move(str)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3769 |
expect_eq_(expect_eq), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3770 |
case_sensitive_(case_sensitive) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3771 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3772 |
#if GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3773 |
bool MatchAndExplain(const internal::StringView& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3774 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3775 |
// This should fail to compile if StringView is used with wide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3776 |
// strings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3777 |
const StringType& str = std::string(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3778 |
return MatchAndExplain(str, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3779 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3780 |
#endif // GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3781 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3782 |
// Accepts pointer types, particularly: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3783 |
// const char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3784 |
// char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3785 |
// const wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3786 |
// wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3787 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3788 |
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3789 |
if (s == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3790 |
return !expect_eq_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3791 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3792 |
return MatchAndExplain(StringType(s), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3793 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3794 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3795 |
// Matches anything that can convert to StringType. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3796 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3797 |
// This is a template, not just a plain function with const StringType&, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3798 |
// because StringView has some interfering non-explicit constructors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3799 |
template <typename MatcheeStringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3800 |
bool MatchAndExplain(const MatcheeStringType& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3801 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3802 |
const StringType s2(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3803 |
const bool eq = case_sensitive_ ? s2 == string_ : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3804 |
CaseInsensitiveStringEquals(s2, string_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3805 |
return expect_eq_ == eq; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3806 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3807 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3808 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3809 |
DescribeToHelper(expect_eq_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3810 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3811 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3812 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3813 |
DescribeToHelper(!expect_eq_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3814 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3815 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3816 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3817 |
void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3818 |
*os << (expect_eq ? "is " : "isn't "); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3819 |
*os << "equal to "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3820 |
if (!case_sensitive_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3821 |
*os << "(ignoring case) "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3822 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3823 |
UniversalPrint(string_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3824 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3825 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3826 |
const StringType string_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3827 |
const bool expect_eq_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3828 |
const bool case_sensitive_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3829 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3830 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3831 |
// Implements the polymorphic HasSubstr(substring) matcher, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3832 |
// can be used as a Matcher<T> as long as T can be converted to a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3833 |
// string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3834 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3835 |
class HasSubstrMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3836 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3837 |
explicit HasSubstrMatcher(const StringType& substring) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3838 |
: substring_(substring) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3839 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3840 |
#if GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3841 |
bool MatchAndExplain(const internal::StringView& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3842 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3843 |
// This should fail to compile if StringView is used with wide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3844 |
// strings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3845 |
const StringType& str = std::string(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3846 |
return MatchAndExplain(str, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3847 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3848 |
#endif // GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3849 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3850 |
// Accepts pointer types, particularly: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3851 |
// const char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3852 |
// char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3853 |
// const wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3854 |
// wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3855 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3856 |
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3857 |
return s != nullptr && MatchAndExplain(StringType(s), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3858 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3860 |
// Matches anything that can convert to StringType. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3861 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3862 |
// This is a template, not just a plain function with const StringType&, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3863 |
// because StringView has some interfering non-explicit constructors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3864 |
template <typename MatcheeStringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3865 |
bool MatchAndExplain(const MatcheeStringType& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3866 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3867 |
return StringType(s).find(substring_) != StringType::npos; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3868 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3869 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3870 |
// Describes what this matcher matches. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3871 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3872 |
*os << "has substring "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3873 |
UniversalPrint(substring_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3874 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3875 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3876 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3877 |
*os << "has no substring "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3878 |
UniversalPrint(substring_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3879 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3880 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3881 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3882 |
const StringType substring_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3883 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3884 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3885 |
// Implements the polymorphic StartsWith(substring) matcher, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3886 |
// can be used as a Matcher<T> as long as T can be converted to a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3887 |
// string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3888 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3889 |
class StartsWithMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3890 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3891 |
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3892 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3893 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3894 |
#if GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3895 |
bool MatchAndExplain(const internal::StringView& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3896 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3897 |
// This should fail to compile if StringView is used with wide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3898 |
// strings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3899 |
const StringType& str = std::string(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3900 |
return MatchAndExplain(str, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3901 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3902 |
#endif // GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3903 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3904 |
// Accepts pointer types, particularly: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3905 |
// const char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3906 |
// char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3907 |
// const wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3908 |
// wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3909 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3910 |
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3911 |
return s != nullptr && MatchAndExplain(StringType(s), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3912 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3913 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3914 |
// Matches anything that can convert to StringType. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3915 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3916 |
// This is a template, not just a plain function with const StringType&, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3917 |
// because StringView has some interfering non-explicit constructors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3918 |
template <typename MatcheeStringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3919 |
bool MatchAndExplain(const MatcheeStringType& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3920 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3921 |
const StringType& s2(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3922 |
return s2.length() >= prefix_.length() && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3923 |
s2.substr(0, prefix_.length()) == prefix_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3924 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3925 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3926 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3927 |
*os << "starts with "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3928 |
UniversalPrint(prefix_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3929 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3930 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3931 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3932 |
*os << "doesn't start with "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3933 |
UniversalPrint(prefix_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3934 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3935 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3936 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3937 |
const StringType prefix_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3938 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3939 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3940 |
// Implements the polymorphic EndsWith(substring) matcher, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3941 |
// can be used as a Matcher<T> as long as T can be converted to a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3942 |
// string. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3943 |
template <typename StringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3944 |
class EndsWithMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3945 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3946 |
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3947 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3948 |
#if GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3949 |
bool MatchAndExplain(const internal::StringView& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3950 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3951 |
// This should fail to compile if StringView is used with wide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3952 |
// strings. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3953 |
const StringType& str = std::string(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3954 |
return MatchAndExplain(str, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3955 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3956 |
#endif // GTEST_INTERNAL_HAS_STRING_VIEW |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3957 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3958 |
// Accepts pointer types, particularly: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3959 |
// const char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3960 |
// char* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3961 |
// const wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3962 |
// wchar_t* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3963 |
template <typename CharType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3964 |
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3965 |
return s != nullptr && MatchAndExplain(StringType(s), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3966 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3967 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3968 |
// Matches anything that can convert to StringType. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3969 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3970 |
// This is a template, not just a plain function with const StringType&, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3971 |
// because StringView has some interfering non-explicit constructors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3972 |
template <typename MatcheeStringType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3973 |
bool MatchAndExplain(const MatcheeStringType& s, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3974 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3975 |
const StringType& s2(s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3976 |
return s2.length() >= suffix_.length() && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3977 |
s2.substr(s2.length() - suffix_.length()) == suffix_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3978 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3979 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3980 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3981 |
*os << "ends with "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3982 |
UniversalPrint(suffix_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3983 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3984 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3985 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3986 |
*os << "doesn't end with "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3987 |
UniversalPrint(suffix_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3988 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3989 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3990 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3991 |
const StringType suffix_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3992 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3993 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3994 |
// Implements a matcher that compares the two fields of a 2-tuple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3995 |
// using one of the ==, <=, <, etc, operators. The two fields being |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3996 |
// compared don't have to have the same type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3997 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3998 |
// The matcher defined here is polymorphic (for example, Eq() can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
3999 |
// used to match a std::tuple<int, short>, a std::tuple<const long&, double>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4000 |
// etc). Therefore we use a template type conversion operator in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4001 |
// implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4002 |
template <typename D, typename Op> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4003 |
class PairMatchBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4004 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4005 |
template <typename T1, typename T2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4006 |
operator Matcher<::std::tuple<T1, T2>>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4007 |
return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4008 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4009 |
template <typename T1, typename T2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4010 |
operator Matcher<const ::std::tuple<T1, T2>&>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4011 |
return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4012 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4013 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4014 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4015 |
static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4016 |
return os << D::Desc(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4017 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4018 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4019 |
template <typename Tuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4020 |
class Impl : public MatcherInterface<Tuple> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4021 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4022 |
bool MatchAndExplain(Tuple args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4023 |
MatchResultListener* /* listener */) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4024 |
return Op()(::std::get<0>(args), ::std::get<1>(args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4025 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4026 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4027 |
*os << "are " << GetDesc; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4028 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4029 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4030 |
*os << "aren't " << GetDesc; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4031 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4032 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4033 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4034 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4035 |
class Eq2Matcher : public PairMatchBase<Eq2Matcher, AnyEq> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4036 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4037 |
static const char* Desc() { return "an equal pair"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4038 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4039 |
class Ne2Matcher : public PairMatchBase<Ne2Matcher, AnyNe> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4040 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4041 |
static const char* Desc() { return "an unequal pair"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4042 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4043 |
class Lt2Matcher : public PairMatchBase<Lt2Matcher, AnyLt> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4044 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4045 |
static const char* Desc() { return "a pair where the first < the second"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4046 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4047 |
class Gt2Matcher : public PairMatchBase<Gt2Matcher, AnyGt> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4048 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4049 |
static const char* Desc() { return "a pair where the first > the second"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4050 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4051 |
class Le2Matcher : public PairMatchBase<Le2Matcher, AnyLe> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4052 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4053 |
static const char* Desc() { return "a pair where the first <= the second"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4054 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4055 |
class Ge2Matcher : public PairMatchBase<Ge2Matcher, AnyGe> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4056 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4057 |
static const char* Desc() { return "a pair where the first >= the second"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4058 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4059 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4060 |
// Implements the Not(...) matcher for a particular argument type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4061 |
// We do not nest it inside the NotMatcher class template, as that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4062 |
// will prevent different instantiations of NotMatcher from sharing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4063 |
// the same NotMatcherImpl<T> class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4064 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4065 |
class NotMatcherImpl : public MatcherInterface<const T&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4066 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4067 |
explicit NotMatcherImpl(const Matcher<T>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4068 |
: matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4070 |
bool MatchAndExplain(const T& x, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4071 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4072 |
return !matcher_.MatchAndExplain(x, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4073 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4074 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4075 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4076 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4077 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4078 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4079 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4080 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4081 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4082 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4083 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4084 |
const Matcher<T> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4085 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4086 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4087 |
// Implements the Not(m) matcher, which matches a value that doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4088 |
// match matcher m. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4089 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4090 |
class NotMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4091 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4092 |
explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4093 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4094 |
// This template type conversion operator allows Not(m) to be used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4095 |
// to match any type m can match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4096 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4097 |
operator Matcher<T>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4098 |
return Matcher<T>(new NotMatcherImpl<T>(SafeMatcherCast<T>(matcher_))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4099 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4100 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4101 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4102 |
InnerMatcher matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4103 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4104 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4105 |
// Implements the AllOf(m1, m2) matcher for a particular argument type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4106 |
// T. We do not nest it inside the BothOfMatcher class template, as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4107 |
// that will prevent different instantiations of BothOfMatcher from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4108 |
// sharing the same BothOfMatcherImpl<T> class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4109 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4110 |
class AllOfMatcherImpl : public MatcherInterface<const T&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4111 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4112 |
explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4113 |
: matchers_(std::move(matchers)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4114 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4115 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4116 |
*os << "("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4117 |
for (size_t i = 0; i < matchers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4118 |
if (i != 0) *os << ") and ("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4119 |
matchers_[i].DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4120 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4121 |
*os << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4122 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4123 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4124 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4125 |
*os << "("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4126 |
for (size_t i = 0; i < matchers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4127 |
if (i != 0) *os << ") or ("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4128 |
matchers_[i].DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4129 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4130 |
*os << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4131 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4132 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4133 |
bool MatchAndExplain(const T& x, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4134 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4135 |
// If either matcher1_ or matcher2_ doesn't match x, we only need |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4136 |
// to explain why one of them fails. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4137 |
std::string all_match_result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4138 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4139 |
for (size_t i = 0; i < matchers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4140 |
StringMatchResultListener slistener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4141 |
if (matchers_[i].MatchAndExplain(x, &slistener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4142 |
if (all_match_result.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4143 |
all_match_result = slistener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4144 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4145 |
std::string result = slistener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4146 |
if (!result.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4147 |
all_match_result += ", and "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4148 |
all_match_result += result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4149 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4150 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4151 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4152 |
*listener << slistener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4153 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4154 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4155 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4157 |
// Otherwise we need to explain why *both* of them match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4158 |
*listener << all_match_result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4159 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4160 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4161 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4162 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4163 |
const std::vector<Matcher<T> > matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4164 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4165 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4166 |
// VariadicMatcher is used for the variadic implementation of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4167 |
// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4168 |
// CombiningMatcher<T> is used to recursively combine the provided matchers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4169 |
// (of type Args...). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4170 |
template <template <typename T> class CombiningMatcher, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4171 |
class VariadicMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4172 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4173 |
VariadicMatcher(const Args&... matchers) // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4174 |
: matchers_(matchers...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4175 |
static_assert(sizeof...(Args) > 0, "Must have at least one matcher."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4176 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4177 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4178 |
VariadicMatcher(const VariadicMatcher&) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4179 |
VariadicMatcher& operator=(const VariadicMatcher&) = delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4180 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4181 |
// This template type conversion operator allows an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4182 |
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4183 |
// all of the provided matchers (Matcher1, Matcher2, ...) can match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4184 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4185 |
operator Matcher<T>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4186 |
std::vector<Matcher<T> > values; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4187 |
CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4188 |
return Matcher<T>(new CombiningMatcher<T>(std::move(values))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4189 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4190 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4191 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4192 |
template <typename T, size_t I> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4193 |
void CreateVariadicMatcher(std::vector<Matcher<T> >* values, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4194 |
std::integral_constant<size_t, I>) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4195 |
values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4196 |
CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4197 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4198 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4199 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4200 |
void CreateVariadicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4201 |
std::vector<Matcher<T> >*, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4202 |
std::integral_constant<size_t, sizeof...(Args)>) const {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4203 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4204 |
std::tuple<Args...> matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4205 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4206 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4207 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4208 |
using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4209 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4210 |
// Implements the AnyOf(m1, m2) matcher for a particular argument type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4211 |
// T. We do not nest it inside the AnyOfMatcher class template, as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4212 |
// that will prevent different instantiations of AnyOfMatcher from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4213 |
// sharing the same EitherOfMatcherImpl<T> class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4214 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4215 |
class AnyOfMatcherImpl : public MatcherInterface<const T&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4216 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4217 |
explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4218 |
: matchers_(std::move(matchers)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4219 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4220 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4221 |
*os << "("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4222 |
for (size_t i = 0; i < matchers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4223 |
if (i != 0) *os << ") or ("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4224 |
matchers_[i].DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4225 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4226 |
*os << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4227 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4228 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4229 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4230 |
*os << "("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4231 |
for (size_t i = 0; i < matchers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4232 |
if (i != 0) *os << ") and ("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4233 |
matchers_[i].DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4234 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4235 |
*os << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4236 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4237 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4238 |
bool MatchAndExplain(const T& x, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4239 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4240 |
std::string no_match_result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4241 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4242 |
// If either matcher1_ or matcher2_ matches x, we just need to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4243 |
// explain why *one* of them matches. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4244 |
for (size_t i = 0; i < matchers_.size(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4245 |
StringMatchResultListener slistener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4246 |
if (matchers_[i].MatchAndExplain(x, &slistener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4247 |
*listener << slistener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4248 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4249 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4250 |
if (no_match_result.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4251 |
no_match_result = slistener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4252 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4253 |
std::string result = slistener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4254 |
if (!result.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4255 |
no_match_result += ", and "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4256 |
no_match_result += result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4257 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4258 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4259 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4260 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4261 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4262 |
// Otherwise we need to explain why *both* of them fail. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4263 |
*listener << no_match_result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4264 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4265 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4266 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4267 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4268 |
const std::vector<Matcher<T> > matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4269 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4270 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4271 |
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4272 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4273 |
using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4275 |
// Wrapper for implementation of Any/AllOfArray(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4276 |
template <template <class> class MatcherImpl, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4277 |
class SomeOfArrayMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4278 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4279 |
// Constructs the matcher from a sequence of element values or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4280 |
// element matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4281 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4282 |
SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4283 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4284 |
template <typename U> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4285 |
operator Matcher<U>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4286 |
using RawU = typename std::decay<U>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4287 |
std::vector<Matcher<RawU>> matchers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4288 |
for (const auto& matcher : matchers_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4289 |
matchers.push_back(MatcherCast<RawU>(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4290 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4291 |
return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4292 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4294 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4295 |
const ::std::vector<T> matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4296 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4298 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4299 |
using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4300 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4301 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4302 |
using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4303 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4304 |
// Used for implementing Truly(pred), which turns a predicate into a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4305 |
// matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4306 |
template <typename Predicate> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4307 |
class TrulyMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4308 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4309 |
explicit TrulyMatcher(Predicate pred) : predicate_(pred) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4311 |
// This method template allows Truly(pred) to be used as a matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4312 |
// for type T where T is the argument type of predicate 'pred'. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4313 |
// argument is passed by reference as the predicate may be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4314 |
// interested in the address of the argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4315 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4316 |
bool MatchAndExplain(T& x, // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4317 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4318 |
// Without the if-statement, MSVC sometimes warns about converting |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4319 |
// a value to bool (warning 4800). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4320 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4321 |
// We cannot write 'return !!predicate_(x);' as that doesn't work |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4322 |
// when predicate_(x) returns a class convertible to bool but |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4323 |
// having no operator!(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4324 |
if (predicate_(x)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4325 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4326 |
*listener << "didn't satisfy the given predicate"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4327 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4328 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4329 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4330 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4331 |
*os << "satisfies the given predicate"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4332 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4333 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4334 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4335 |
*os << "doesn't satisfy the given predicate"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4336 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4337 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4338 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4339 |
Predicate predicate_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4340 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4342 |
// Used for implementing Matches(matcher), which turns a matcher into |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4343 |
// a predicate. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4344 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4345 |
class MatcherAsPredicate { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4346 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4347 |
explicit MatcherAsPredicate(M matcher) : matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4348 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4349 |
// This template operator() allows Matches(m) to be used as a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4350 |
// predicate on type T where m is a matcher on type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4351 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4352 |
// The argument x is passed by reference instead of by value, as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4353 |
// some matcher may be interested in its address (e.g. as in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4354 |
// Matches(Ref(n))(x)). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4355 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4356 |
bool operator()(const T& x) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4357 |
// We let matcher_ commit to a particular type here instead of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4358 |
// when the MatcherAsPredicate object was constructed. This |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4359 |
// allows us to write Matches(m) where m is a polymorphic matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4360 |
// (e.g. Eq(5)). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4361 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4362 |
// If we write Matcher<T>(matcher_).Matches(x) here, it won't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4363 |
// compile when matcher_ has type Matcher<const T&>; if we write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4364 |
// Matcher<const T&>(matcher_).Matches(x) here, it won't compile |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4365 |
// when matcher_ has type Matcher<T>; if we just write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4366 |
// matcher_.Matches(x), it won't compile when matcher_ is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4367 |
// polymorphic, e.g. Eq(5). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4368 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4369 |
// MatcherCast<const T&>() is necessary for making the code work |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4370 |
// in all of the above situations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4371 |
return MatcherCast<const T&>(matcher_).Matches(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4372 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4373 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4374 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4375 |
M matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4376 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4377 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4378 |
// For implementing ASSERT_THAT() and EXPECT_THAT(). The template |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4379 |
// argument M must be a type that can be converted to a matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4380 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4381 |
class PredicateFormatterFromMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4382 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4383 |
explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4385 |
// This template () operator allows a PredicateFormatterFromMatcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4386 |
// object to act as a predicate-formatter suitable for using with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4387 |
// Google Test's EXPECT_PRED_FORMAT1() macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4388 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4389 |
AssertionResult operator()(const char* value_text, const T& x) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4390 |
// We convert matcher_ to a Matcher<const T&> *now* instead of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4391 |
// when the PredicateFormatterFromMatcher object was constructed, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4392 |
// as matcher_ may be polymorphic (e.g. NotNull()) and we won't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4393 |
// know which type to instantiate it to until we actually see the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4394 |
// type of x here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4395 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4396 |
// We write SafeMatcherCast<const T&>(matcher_) instead of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4397 |
// Matcher<const T&>(matcher_), as the latter won't compile when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4398 |
// matcher_ has type Matcher<T> (e.g. An<int>()). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4399 |
// We don't write MatcherCast<const T&> either, as that allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4400 |
// potentially unsafe downcasting of the matcher argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4401 |
const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4403 |
// The expected path here is that the matcher should match (i.e. that most |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4404 |
// tests pass) so optimize for this case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4405 |
if (matcher.Matches(x)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4406 |
return AssertionSuccess(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4407 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4408 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4409 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4410 |
ss << "Value of: " << value_text << "\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4411 |
<< "Expected: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4412 |
matcher.DescribeTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4413 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4414 |
// Rerun the matcher to "PrintAndExplain" the failure. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4415 |
StringMatchResultListener listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4416 |
if (MatchPrintAndExplain(x, matcher, &listener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4417 |
ss << "\n The matcher failed on the initial attempt; but passed when " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4418 |
"rerun to generate the explanation."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4419 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4420 |
ss << "\n Actual: " << listener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4421 |
return AssertionFailure() << ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4422 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4423 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4424 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4425 |
const M matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4426 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4427 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4428 |
// A helper function for converting a matcher to a predicate-formatter |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4429 |
// without the user needing to explicitly write the type. This is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4430 |
// used for implementing ASSERT_THAT() and EXPECT_THAT(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4431 |
// Implementation detail: 'matcher' is received by-value to force decaying. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4432 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4433 |
inline PredicateFormatterFromMatcher<M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4434 |
MakePredicateFormatterFromMatcher(M matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4435 |
return PredicateFormatterFromMatcher<M>(std::move(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4436 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4437 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4438 |
// Implements the polymorphic IsNan() matcher, which matches any floating type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4439 |
// value that is Nan. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4440 |
class IsNanMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4441 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4442 |
template <typename FloatType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4443 |
bool MatchAndExplain(const FloatType& f, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4444 |
MatchResultListener* /* listener */) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4445 |
return (::std::isnan)(f); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4446 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4447 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4448 |
void DescribeTo(::std::ostream* os) const { *os << "is NaN"; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4449 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4450 |
*os << "isn't NaN"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4451 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4452 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4453 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4454 |
// Implements the polymorphic floating point equality matcher, which matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4455 |
// two float values using ULP-based approximation or, optionally, a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4456 |
// user-specified epsilon. The template is meant to be instantiated with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4457 |
// FloatType being either float or double. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4458 |
template <typename FloatType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4459 |
class FloatingEqMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4460 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4461 |
// Constructor for FloatingEqMatcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4462 |
// The matcher's input will be compared with expected. The matcher treats two |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4463 |
// NANs as equal if nan_eq_nan is true. Otherwise, under IEEE standards, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4464 |
// equality comparisons between NANs will always return false. We specify a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4465 |
// negative max_abs_error_ term to indicate that ULP-based approximation will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4466 |
// be used for comparison. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4467 |
FloatingEqMatcher(FloatType expected, bool nan_eq_nan) : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4468 |
expected_(expected), nan_eq_nan_(nan_eq_nan), max_abs_error_(-1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4469 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4471 |
// Constructor that supports a user-specified max_abs_error that will be used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4472 |
// for comparison instead of ULP-based approximation. The max absolute |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4473 |
// should be non-negative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4474 |
FloatingEqMatcher(FloatType expected, bool nan_eq_nan, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4475 |
FloatType max_abs_error) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4476 |
: expected_(expected), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4477 |
nan_eq_nan_(nan_eq_nan), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4478 |
max_abs_error_(max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4479 |
GTEST_CHECK_(max_abs_error >= 0) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4480 |
<< ", where max_abs_error is" << max_abs_error; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4481 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4482 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4483 |
// Implements floating point equality matcher as a Matcher<T>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4484 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4485 |
class Impl : public MatcherInterface<T> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4486 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4487 |
Impl(FloatType expected, bool nan_eq_nan, FloatType max_abs_error) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4488 |
: expected_(expected), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4489 |
nan_eq_nan_(nan_eq_nan), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4490 |
max_abs_error_(max_abs_error) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4491 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4492 |
bool MatchAndExplain(T value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4493 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4494 |
const FloatingPoint<FloatType> actual(value), expected(expected_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4495 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4496 |
// Compares NaNs first, if nan_eq_nan_ is true. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4497 |
if (actual.is_nan() || expected.is_nan()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4498 |
if (actual.is_nan() && expected.is_nan()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4499 |
return nan_eq_nan_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4500 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4501 |
// One is nan; the other is not nan. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4502 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4503 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4504 |
if (HasMaxAbsError()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4505 |
// We perform an equality check so that inf will match inf, regardless |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4506 |
// of error bounds. If the result of value - expected_ would result in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4507 |
// overflow or if either value is inf, the default result is infinity, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4508 |
// which should only match if max_abs_error_ is also infinity. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4509 |
if (value == expected_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4510 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4511 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4512 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4513 |
const FloatType diff = value - expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4514 |
if (::std::fabs(diff) <= max_abs_error_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4515 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4516 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4517 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4518 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4519 |
*listener << "which is " << diff << " from " << expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4520 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4521 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4522 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4523 |
return actual.AlmostEquals(expected); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4524 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4525 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4526 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4527 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4528 |
// os->precision() returns the previously set precision, which we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4529 |
// store to restore the ostream to its original configuration |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4530 |
// after outputting. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4531 |
const ::std::streamsize old_precision = os->precision( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4532 |
::std::numeric_limits<FloatType>::digits10 + 2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4533 |
if (FloatingPoint<FloatType>(expected_).is_nan()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4534 |
if (nan_eq_nan_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4535 |
*os << "is NaN"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4536 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4537 |
*os << "never matches"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4538 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4539 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4540 |
*os << "is approximately " << expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4541 |
if (HasMaxAbsError()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4542 |
*os << " (absolute error <= " << max_abs_error_ << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4543 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4544 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4545 |
os->precision(old_precision); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4546 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4547 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4548 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4549 |
// As before, get original precision. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4550 |
const ::std::streamsize old_precision = os->precision( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4551 |
::std::numeric_limits<FloatType>::digits10 + 2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4552 |
if (FloatingPoint<FloatType>(expected_).is_nan()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4553 |
if (nan_eq_nan_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4554 |
*os << "isn't NaN"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4555 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4556 |
*os << "is anything"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4557 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4558 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4559 |
*os << "isn't approximately " << expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4560 |
if (HasMaxAbsError()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4561 |
*os << " (absolute error > " << max_abs_error_ << ")"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4563 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4564 |
// Restore original precision. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4565 |
os->precision(old_precision); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4566 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4567 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4568 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4569 |
bool HasMaxAbsError() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4570 |
return max_abs_error_ >= 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4571 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4572 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4573 |
const FloatType expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4574 |
const bool nan_eq_nan_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4575 |
// max_abs_error will be used for value comparison when >= 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4576 |
const FloatType max_abs_error_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4577 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4578 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4579 |
// The following 3 type conversion operators allow FloatEq(expected) and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4580 |
// NanSensitiveFloatEq(expected) to be used as a Matcher<float>, a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4581 |
// Matcher<const float&>, or a Matcher<float&>, but nothing else. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4582 |
operator Matcher<FloatType>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4583 |
return MakeMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4584 |
new Impl<FloatType>(expected_, nan_eq_nan_, max_abs_error_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4585 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4586 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4587 |
operator Matcher<const FloatType&>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4588 |
return MakeMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4589 |
new Impl<const FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4590 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4591 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4592 |
operator Matcher<FloatType&>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4593 |
return MakeMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4594 |
new Impl<FloatType&>(expected_, nan_eq_nan_, max_abs_error_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4595 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4596 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4597 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4598 |
const FloatType expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4599 |
const bool nan_eq_nan_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4600 |
// max_abs_error will be used for value comparison when >= 0. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4601 |
const FloatType max_abs_error_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4602 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4603 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4604 |
// A 2-tuple ("binary") wrapper around FloatingEqMatcher: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4605 |
// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4606 |
// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4607 |
// against y. The former implements "Eq", the latter "Near". At present, there |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4608 |
// is no version that compares NaNs as equal. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4609 |
template <typename FloatType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4610 |
class FloatingEq2Matcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4611 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4612 |
FloatingEq2Matcher() { Init(-1, false); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4613 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4614 |
explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4615 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4616 |
explicit FloatingEq2Matcher(FloatType max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4617 |
Init(max_abs_error, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4618 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4619 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4620 |
FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4621 |
Init(max_abs_error, nan_eq_nan); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4622 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4623 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4624 |
template <typename T1, typename T2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4625 |
operator Matcher<::std::tuple<T1, T2>>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4626 |
return MakeMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4627 |
new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4628 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4629 |
template <typename T1, typename T2> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4630 |
operator Matcher<const ::std::tuple<T1, T2>&>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4631 |
return MakeMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4632 |
new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4633 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4634 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4635 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4636 |
static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4637 |
return os << "an almost-equal pair"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4638 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4639 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4640 |
template <typename Tuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4641 |
class Impl : public MatcherInterface<Tuple> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4642 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4643 |
Impl(FloatType max_abs_error, bool nan_eq_nan) : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4644 |
max_abs_error_(max_abs_error), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4645 |
nan_eq_nan_(nan_eq_nan) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4646 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4647 |
bool MatchAndExplain(Tuple args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4648 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4649 |
if (max_abs_error_ == -1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4650 |
FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4651 |
return static_cast<Matcher<FloatType>>(fm).MatchAndExplain( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4652 |
::std::get<1>(args), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4653 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4654 |
FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4655 |
max_abs_error_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4656 |
return static_cast<Matcher<FloatType>>(fm).MatchAndExplain( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4657 |
::std::get<1>(args), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4658 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4659 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4660 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4661 |
*os << "are " << GetDesc; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4662 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4663 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4664 |
*os << "aren't " << GetDesc; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4665 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4666 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4667 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4668 |
FloatType max_abs_error_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4669 |
const bool nan_eq_nan_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4670 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4671 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4672 |
void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4673 |
max_abs_error_ = max_abs_error_val; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4674 |
nan_eq_nan_ = nan_eq_nan_val; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4675 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4676 |
FloatType max_abs_error_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4677 |
bool nan_eq_nan_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4678 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4679 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4680 |
// Implements the Pointee(m) matcher for matching a pointer whose |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4681 |
// pointee matches matcher m. The pointer can be either raw or smart. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4682 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4683 |
class PointeeMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4684 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4685 |
explicit PointeeMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4686 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4687 |
// This type conversion operator template allows Pointee(m) to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4688 |
// used as a matcher for any pointer type whose pointee type is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4689 |
// compatible with the inner matcher, where type Pointer can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4690 |
// either a raw pointer or a smart pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4691 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4692 |
// The reason we do this instead of relying on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4693 |
// MakePolymorphicMatcher() is that the latter is not flexible |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4694 |
// enough for implementing the DescribeTo() method of Pointee(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4695 |
template <typename Pointer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4696 |
operator Matcher<Pointer>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4697 |
return Matcher<Pointer>(new Impl<const Pointer&>(matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4698 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4699 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4700 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4701 |
// The monomorphic implementation that works for a particular pointer type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4702 |
template <typename Pointer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4703 |
class Impl : public MatcherInterface<Pointer> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4704 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4705 |
using Pointee = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4706 |
typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4707 |
Pointer)>::element_type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4708 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4709 |
explicit Impl(const InnerMatcher& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4710 |
: matcher_(MatcherCast<const Pointee&>(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4711 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4712 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4713 |
*os << "points to a value that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4714 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4715 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4716 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4717 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4718 |
*os << "does not point to a value that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4719 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4720 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4721 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4722 |
bool MatchAndExplain(Pointer pointer, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4723 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4724 |
if (GetRawPointer(pointer) == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4725 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4726 |
*listener << "which points to "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4727 |
return MatchPrintAndExplain(*pointer, matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4728 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4729 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4730 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4731 |
const Matcher<const Pointee&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4732 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4734 |
const InnerMatcher matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4735 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4736 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4737 |
// Implements the Pointer(m) matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4738 |
// Implements the Pointer(m) matcher for matching a pointer that matches matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4739 |
// m. The pointer can be either raw or smart, and will match `m` against the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4740 |
// raw pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4741 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4742 |
class PointerMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4743 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4744 |
explicit PointerMatcher(const InnerMatcher& matcher) : matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4745 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4746 |
// This type conversion operator template allows Pointer(m) to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4747 |
// used as a matcher for any pointer type whose pointer type is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4748 |
// compatible with the inner matcher, where type PointerType can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4749 |
// either a raw pointer or a smart pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4750 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4751 |
// The reason we do this instead of relying on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4752 |
// MakePolymorphicMatcher() is that the latter is not flexible |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4753 |
// enough for implementing the DescribeTo() method of Pointer(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4754 |
template <typename PointerType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4755 |
operator Matcher<PointerType>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4756 |
return Matcher<PointerType>(new Impl<const PointerType&>(matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4757 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4758 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4759 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4760 |
// The monomorphic implementation that works for a particular pointer type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4761 |
template <typename PointerType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4762 |
class Impl : public MatcherInterface<PointerType> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4763 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4764 |
using Pointer = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4765 |
const typename std::pointer_traits<GTEST_REMOVE_REFERENCE_AND_CONST_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4766 |
PointerType)>::element_type*; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4767 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4768 |
explicit Impl(const InnerMatcher& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4769 |
: matcher_(MatcherCast<Pointer>(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4770 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4771 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4772 |
*os << "is a pointer that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4773 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4774 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4775 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4776 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4777 |
*os << "is not a pointer that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4778 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4779 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4781 |
bool MatchAndExplain(PointerType pointer, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4782 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4783 |
*listener << "which is a pointer that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4784 |
Pointer p = GetRawPointer(pointer); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4785 |
return MatchPrintAndExplain(p, matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4786 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4787 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4788 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4789 |
Matcher<Pointer> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4790 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4791 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4792 |
const InnerMatcher matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4793 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4794 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4795 |
#if GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4796 |
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4797 |
// reference that matches inner_matcher when dynamic_cast<T> is applied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4798 |
// The result of dynamic_cast<To> is forwarded to the inner matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4799 |
// If To is a pointer and the cast fails, the inner matcher will receive NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4800 |
// If To is a reference and the cast fails, this matcher returns false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4801 |
// immediately. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4802 |
template <typename To> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4803 |
class WhenDynamicCastToMatcherBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4804 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4805 |
explicit WhenDynamicCastToMatcherBase(const Matcher<To>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4806 |
: matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4807 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4808 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4809 |
GetCastTypeDescription(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4810 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4811 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4812 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4813 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4814 |
GetCastTypeDescription(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4815 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4816 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4817 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4818 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4819 |
const Matcher<To> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4820 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4821 |
static std::string GetToName() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4822 |
return GetTypeName<To>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4823 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4824 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4825 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4826 |
static void GetCastTypeDescription(::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4827 |
*os << "when dynamic_cast to " << GetToName() << ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4828 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4829 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4830 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4831 |
// Primary template. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4832 |
// To is a pointer. Cast and forward the result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4833 |
template <typename To> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4834 |
class WhenDynamicCastToMatcher : public WhenDynamicCastToMatcherBase<To> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4835 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4836 |
explicit WhenDynamicCastToMatcher(const Matcher<To>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4837 |
: WhenDynamicCastToMatcherBase<To>(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4838 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4839 |
template <typename From> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4840 |
bool MatchAndExplain(From from, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4841 |
To to = dynamic_cast<To>(from); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4842 |
return MatchPrintAndExplain(to, this->matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4843 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4844 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4845 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4846 |
// Specialize for references. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4847 |
// In this case we return false if the dynamic_cast fails. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4848 |
template <typename To> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4849 |
class WhenDynamicCastToMatcher<To&> : public WhenDynamicCastToMatcherBase<To&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4850 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4851 |
explicit WhenDynamicCastToMatcher(const Matcher<To&>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4852 |
: WhenDynamicCastToMatcherBase<To&>(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4853 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4854 |
template <typename From> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4855 |
bool MatchAndExplain(From& from, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4856 |
// We don't want an std::bad_cast here, so do the cast with pointers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4857 |
To* to = dynamic_cast<To*>(&from); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4858 |
if (to == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4859 |
*listener << "which cannot be dynamic_cast to " << this->GetToName(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4860 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4861 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4862 |
return MatchPrintAndExplain(*to, this->matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4863 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4864 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4865 |
#endif // GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4866 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4867 |
// Implements the Field() matcher for matching a field (i.e. member |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4868 |
// variable) of an object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4869 |
template <typename Class, typename FieldType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4870 |
class FieldMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4871 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4872 |
FieldMatcher(FieldType Class::*field, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4873 |
const Matcher<const FieldType&>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4874 |
: field_(field), matcher_(matcher), whose_field_("whose given field ") {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4875 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4876 |
FieldMatcher(const std::string& field_name, FieldType Class::*field, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4877 |
const Matcher<const FieldType&>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4878 |
: field_(field), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4879 |
matcher_(matcher), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4880 |
whose_field_("whose field `" + field_name + "` ") {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4881 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4882 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4883 |
*os << "is an object " << whose_field_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4884 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4885 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4886 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4887 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4888 |
*os << "is an object " << whose_field_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4889 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4890 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4891 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4892 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4893 |
bool MatchAndExplain(const T& value, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4894 |
// FIXME: The dispatch on std::is_pointer was introduced as a workaround for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4895 |
// a compiler bug, and can now be removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4896 |
return MatchAndExplainImpl( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4897 |
typename std::is_pointer<typename std::remove_const<T>::type>::type(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4898 |
value, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4899 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4900 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4901 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4902 |
bool MatchAndExplainImpl(std::false_type /* is_not_pointer */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4903 |
const Class& obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4904 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4905 |
*listener << whose_field_ << "is "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4906 |
return MatchPrintAndExplain(obj.*field_, matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4907 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4908 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4909 |
bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4910 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4911 |
if (p == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4912 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4913 |
*listener << "which points to an object "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4914 |
// Since *p has a field, it must be a class/struct/union type and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4915 |
// thus cannot be a pointer. Therefore we pass false_type() as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4916 |
// the first argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4917 |
return MatchAndExplainImpl(std::false_type(), *p, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4918 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4919 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4920 |
const FieldType Class::*field_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4921 |
const Matcher<const FieldType&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4922 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4923 |
// Contains either "whose given field " if the name of the field is unknown |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4924 |
// or "whose field `name_of_field` " if the name is known. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4925 |
const std::string whose_field_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4926 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4927 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4928 |
// Implements the Property() matcher for matching a property |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4929 |
// (i.e. return value of a getter method) of an object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4930 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4931 |
// Property is a const-qualified member function of Class returning |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4932 |
// PropertyType. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4933 |
template <typename Class, typename PropertyType, typename Property> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4934 |
class PropertyMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4935 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4936 |
typedef const PropertyType& RefToConstProperty; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4937 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4938 |
PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4939 |
: property_(property), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4940 |
matcher_(matcher), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4941 |
whose_property_("whose given property ") {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4942 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4943 |
PropertyMatcher(const std::string& property_name, Property property, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4944 |
const Matcher<RefToConstProperty>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4945 |
: property_(property), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4946 |
matcher_(matcher), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4947 |
whose_property_("whose property `" + property_name + "` ") {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4949 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4950 |
*os << "is an object " << whose_property_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4951 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4952 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4953 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4954 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4955 |
*os << "is an object " << whose_property_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4956 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4957 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4958 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4959 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4960 |
bool MatchAndExplain(const T&value, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4961 |
return MatchAndExplainImpl( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4962 |
typename std::is_pointer<typename std::remove_const<T>::type>::type(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4963 |
value, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4964 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4965 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4966 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4967 |
bool MatchAndExplainImpl(std::false_type /* is_not_pointer */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4968 |
const Class& obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4969 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4970 |
*listener << whose_property_ << "is "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4971 |
// Cannot pass the return value (for example, int) to MatchPrintAndExplain, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4972 |
// which takes a non-const reference as argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4973 |
RefToConstProperty result = (obj.*property_)(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4974 |
return MatchPrintAndExplain(result, matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4975 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4976 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4977 |
bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4978 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4979 |
if (p == nullptr) return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4980 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4981 |
*listener << "which points to an object "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4982 |
// Since *p has a property method, it must be a class/struct/union |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4983 |
// type and thus cannot be a pointer. Therefore we pass |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4984 |
// false_type() as the first argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4985 |
return MatchAndExplainImpl(std::false_type(), *p, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4986 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4987 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4988 |
Property property_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4989 |
const Matcher<RefToConstProperty> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4990 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4991 |
// Contains either "whose given property " if the name of the property is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4992 |
// unknown or "whose property `name_of_property` " if the name is known. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4993 |
const std::string whose_property_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4994 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4995 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4996 |
// Type traits specifying various features of different functors for ResultOf. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4997 |
// The default template specifies features for functor objects. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4998 |
template <typename Functor> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
4999 |
struct CallableTraits { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5000 |
typedef Functor StorageType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5001 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5002 |
static void CheckIsValid(Functor /* functor */) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5003 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5004 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5005 |
static auto Invoke(Functor f, const T& arg) -> decltype(f(arg)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5006 |
return f(arg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5007 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5008 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5009 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5010 |
// Specialization for function pointers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5011 |
template <typename ArgType, typename ResType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5012 |
struct CallableTraits<ResType(*)(ArgType)> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5013 |
typedef ResType ResultType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5014 |
typedef ResType(*StorageType)(ArgType); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5015 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5016 |
static void CheckIsValid(ResType(*f)(ArgType)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5017 |
GTEST_CHECK_(f != nullptr) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5018 |
<< "NULL function pointer is passed into ResultOf()."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5019 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5020 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5021 |
static ResType Invoke(ResType(*f)(ArgType), T arg) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5022 |
return (*f)(arg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5023 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5024 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5025 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5026 |
// Implements the ResultOf() matcher for matching a return value of a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5027 |
// unary function of an object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5028 |
template <typename Callable, typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5029 |
class ResultOfMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5030 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5031 |
ResultOfMatcher(Callable callable, InnerMatcher matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5032 |
: callable_(std::move(callable)), matcher_(std::move(matcher)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5033 |
CallableTraits<Callable>::CheckIsValid(callable_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5034 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5035 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5036 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5037 |
operator Matcher<T>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5038 |
return Matcher<T>(new Impl<const T&>(callable_, matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5039 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5040 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5041 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5042 |
typedef typename CallableTraits<Callable>::StorageType CallableStorageType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5043 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5044 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5045 |
class Impl : public MatcherInterface<T> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5046 |
using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5047 |
std::declval<CallableStorageType>(), std::declval<T>())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5048 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5049 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5050 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5051 |
Impl(const CallableStorageType& callable, const M& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5052 |
: callable_(callable), matcher_(MatcherCast<ResultType>(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5053 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5054 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5055 |
*os << "is mapped by the given callable to a value that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5056 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5057 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5058 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5059 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5060 |
*os << "is mapped by the given callable to a value that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5061 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5062 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5063 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5064 |
bool MatchAndExplain(T obj, MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5065 |
*listener << "which is mapped by the given callable to "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5066 |
// Cannot pass the return value directly to MatchPrintAndExplain, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5067 |
// takes a non-const reference as argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5068 |
// Also, specifying template argument explicitly is needed because T could |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5069 |
// be a non-const reference (e.g. Matcher<Uncopyable&>). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5070 |
ResultType result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5071 |
CallableTraits<Callable>::template Invoke<T>(callable_, obj); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5072 |
return MatchPrintAndExplain(result, matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5073 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5074 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5075 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5076 |
// Functors often define operator() as non-const method even though |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5077 |
// they are actually stateless. But we need to use them even when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5078 |
// 'this' is a const pointer. It's the user's responsibility not to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5079 |
// use stateful callables with ResultOf(), which doesn't guarantee |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5080 |
// how many times the callable will be invoked. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5081 |
mutable CallableStorageType callable_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5082 |
const Matcher<ResultType> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5083 |
}; // class Impl |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5084 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5085 |
const CallableStorageType callable_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5086 |
const InnerMatcher matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5087 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5088 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5089 |
// Implements a matcher that checks the size of an STL-style container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5090 |
template <typename SizeMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5091 |
class SizeIsMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5092 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5093 |
explicit SizeIsMatcher(const SizeMatcher& size_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5094 |
: size_matcher_(size_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5095 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5096 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5097 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5098 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5099 |
return Matcher<Container>(new Impl<const Container&>(size_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5100 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5102 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5103 |
class Impl : public MatcherInterface<Container> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5104 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5105 |
using SizeType = decltype(std::declval<Container>().size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5106 |
explicit Impl(const SizeMatcher& size_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5107 |
: size_matcher_(MatcherCast<SizeType>(size_matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5108 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5109 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5110 |
*os << "size "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5111 |
size_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5112 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5113 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5114 |
*os << "size "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5115 |
size_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5116 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5117 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5118 |
bool MatchAndExplain(Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5119 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5120 |
SizeType size = container.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5121 |
StringMatchResultListener size_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5122 |
const bool result = size_matcher_.MatchAndExplain(size, &size_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5123 |
*listener |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5124 |
<< "whose size " << size << (result ? " matches" : " doesn't match"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5125 |
PrintIfNotEmpty(size_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5126 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5127 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5129 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5130 |
const Matcher<SizeType> size_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5131 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5132 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5133 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5134 |
const SizeMatcher size_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5135 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5136 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5137 |
// Implements a matcher that checks the begin()..end() distance of an STL-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5138 |
// container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5139 |
template <typename DistanceMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5140 |
class BeginEndDistanceIsMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5141 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5142 |
explicit BeginEndDistanceIsMatcher(const DistanceMatcher& distance_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5143 |
: distance_matcher_(distance_matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5144 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5145 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5146 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5147 |
return Matcher<Container>(new Impl<const Container&>(distance_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5148 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5149 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5150 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5151 |
class Impl : public MatcherInterface<Container> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5152 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5153 |
typedef internal::StlContainerView< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5154 |
GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5155 |
typedef typename std::iterator_traits< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5156 |
typename ContainerView::type::const_iterator>::difference_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5157 |
DistanceType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5158 |
explicit Impl(const DistanceMatcher& distance_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5159 |
: distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5160 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5161 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5162 |
*os << "distance between begin() and end() "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5163 |
distance_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5164 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5165 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5166 |
*os << "distance between begin() and end() "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5167 |
distance_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5168 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5169 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5170 |
bool MatchAndExplain(Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5171 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5172 |
using std::begin; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5173 |
using std::end; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5174 |
DistanceType distance = std::distance(begin(container), end(container)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5175 |
StringMatchResultListener distance_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5176 |
const bool result = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5177 |
distance_matcher_.MatchAndExplain(distance, &distance_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5178 |
*listener << "whose distance between begin() and end() " << distance |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5179 |
<< (result ? " matches" : " doesn't match"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5180 |
PrintIfNotEmpty(distance_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5181 |
return result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5182 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5183 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5184 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5185 |
const Matcher<DistanceType> distance_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5186 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5187 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5188 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5189 |
const DistanceMatcher distance_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5190 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5191 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5192 |
// Implements an equality matcher for any STL-style container whose elements |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5193 |
// support ==. This matcher is like Eq(), but its failure explanations provide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5194 |
// more detailed information that is useful when the container is used as a set. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5195 |
// The failure message reports elements that are in one of the operands but not |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5196 |
// the other. The failure messages do not report duplicate or out-of-order |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5197 |
// elements in the containers (which don't properly matter to sets, but can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5198 |
// occur if the containers are vectors or lists, for example). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5199 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5200 |
// Uses the container's const_iterator, value_type, operator ==, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5201 |
// begin(), and end(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5202 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5203 |
class ContainerEqMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5204 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5205 |
typedef internal::StlContainerView<Container> View; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5206 |
typedef typename View::type StlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5207 |
typedef typename View::const_reference StlContainerReference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5208 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5209 |
static_assert(!std::is_const<Container>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5210 |
"Container type must not be const"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5211 |
static_assert(!std::is_reference<Container>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5212 |
"Container type must not be a reference"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5213 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5214 |
// We make a copy of expected in case the elements in it are modified |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5215 |
// after this matcher is created. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5216 |
explicit ContainerEqMatcher(const Container& expected) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5217 |
: expected_(View::Copy(expected)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5218 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5219 |
void DescribeTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5220 |
*os << "equals "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5221 |
UniversalPrint(expected_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5222 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5223 |
void DescribeNegationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5224 |
*os << "does not equal "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5225 |
UniversalPrint(expected_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5226 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5227 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5228 |
template <typename LhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5229 |
bool MatchAndExplain(const LhsContainer& lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5230 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5231 |
typedef internal::StlContainerView< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5232 |
typename std::remove_const<LhsContainer>::type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5233 |
LhsView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5234 |
typedef typename LhsView::type LhsStlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5235 |
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5236 |
if (lhs_stl_container == expected_) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5237 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5238 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5239 |
::std::ostream* const os = listener->stream(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5240 |
if (os != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5241 |
// Something is different. Check for extra values first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5242 |
bool printed_header = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5243 |
for (typename LhsStlContainer::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5244 |
lhs_stl_container.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5245 |
it != lhs_stl_container.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5246 |
if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) == |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5247 |
expected_.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5248 |
if (printed_header) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5249 |
*os << ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5250 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5251 |
*os << "which has these unexpected elements: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5252 |
printed_header = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5253 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5254 |
UniversalPrint(*it, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5255 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5256 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5257 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5258 |
// Now check for missing values. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5259 |
bool printed_header2 = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5260 |
for (typename StlContainer::const_iterator it = expected_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5261 |
it != expected_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5262 |
if (internal::ArrayAwareFind( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5263 |
lhs_stl_container.begin(), lhs_stl_container.end(), *it) == |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5264 |
lhs_stl_container.end()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5265 |
if (printed_header2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5266 |
*os << ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5267 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5268 |
*os << (printed_header ? ",\nand" : "which") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5269 |
<< " doesn't have these expected elements: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5270 |
printed_header2 = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5271 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5272 |
UniversalPrint(*it, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5273 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5274 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5275 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5277 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5278 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5279 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5280 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5281 |
const StlContainer expected_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5282 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5283 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5284 |
// A comparator functor that uses the < operator to compare two values. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5285 |
struct LessComparator { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5286 |
template <typename T, typename U> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5287 |
bool operator()(const T& lhs, const U& rhs) const { return lhs < rhs; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5288 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5290 |
// Implements WhenSortedBy(comparator, container_matcher). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5291 |
template <typename Comparator, typename ContainerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5292 |
class WhenSortedByMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5293 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5294 |
WhenSortedByMatcher(const Comparator& comparator, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5295 |
const ContainerMatcher& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5296 |
: comparator_(comparator), matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5297 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5298 |
template <typename LhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5299 |
operator Matcher<LhsContainer>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5300 |
return MakeMatcher(new Impl<LhsContainer>(comparator_, matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5301 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5302 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5303 |
template <typename LhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5304 |
class Impl : public MatcherInterface<LhsContainer> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5305 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5306 |
typedef internal::StlContainerView< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5307 |
GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5308 |
typedef typename LhsView::type LhsStlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5309 |
typedef typename LhsView::const_reference LhsStlContainerReference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5310 |
// Transforms std::pair<const Key, Value> into std::pair<Key, Value> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5311 |
// so that we can match associative containers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5312 |
typedef typename RemoveConstFromKey< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5313 |
typename LhsStlContainer::value_type>::type LhsValue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5314 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5315 |
Impl(const Comparator& comparator, const ContainerMatcher& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5316 |
: comparator_(comparator), matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5318 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5319 |
*os << "(when sorted) "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5320 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5321 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5322 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5323 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5324 |
*os << "(when sorted) "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5325 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5326 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5327 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5328 |
bool MatchAndExplain(LhsContainer lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5329 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5330 |
LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5331 |
::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5332 |
lhs_stl_container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5333 |
::std::sort( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5334 |
sorted_container.begin(), sorted_container.end(), comparator_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5335 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5336 |
if (!listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5337 |
// If the listener is not interested, we do not need to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5338 |
// construct the inner explanation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5339 |
return matcher_.Matches(sorted_container); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5340 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5341 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5342 |
*listener << "which is "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5343 |
UniversalPrint(sorted_container, listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5344 |
*listener << " when sorted"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5346 |
StringMatchResultListener inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5347 |
const bool match = matcher_.MatchAndExplain(sorted_container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5348 |
&inner_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5349 |
PrintIfNotEmpty(inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5350 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5351 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5352 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5353 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5354 |
const Comparator comparator_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5355 |
const Matcher<const ::std::vector<LhsValue>&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5356 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5357 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5358 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5359 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5360 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5361 |
const Comparator comparator_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5362 |
const ContainerMatcher matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5363 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5365 |
// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5366 |
// must be able to be safely cast to Matcher<std::tuple<const T1&, const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5367 |
// T2&> >, where T1 and T2 are the types of elements in the LHS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5368 |
// container and the RHS container respectively. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5369 |
template <typename TupleMatcher, typename RhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5370 |
class PointwiseMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5371 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5372 |
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5373 |
use_UnorderedPointwise_with_hash_tables); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5374 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5375 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5376 |
typedef internal::StlContainerView<RhsContainer> RhsView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5377 |
typedef typename RhsView::type RhsStlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5378 |
typedef typename RhsStlContainer::value_type RhsValue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5379 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5380 |
static_assert(!std::is_const<RhsContainer>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5381 |
"RhsContainer type must not be const"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5382 |
static_assert(!std::is_reference<RhsContainer>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5383 |
"RhsContainer type must not be a reference"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5385 |
// Like ContainerEq, we make a copy of rhs in case the elements in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5386 |
// it are modified after this matcher is created. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5387 |
PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5388 |
: tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5389 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5390 |
template <typename LhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5391 |
operator Matcher<LhsContainer>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5392 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5393 |
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5394 |
use_UnorderedPointwise_with_hash_tables); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5395 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5396 |
return Matcher<LhsContainer>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5397 |
new Impl<const LhsContainer&>(tuple_matcher_, rhs_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5398 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5399 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5400 |
template <typename LhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5401 |
class Impl : public MatcherInterface<LhsContainer> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5402 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5403 |
typedef internal::StlContainerView< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5404 |
GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)> LhsView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5405 |
typedef typename LhsView::type LhsStlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5406 |
typedef typename LhsView::const_reference LhsStlContainerReference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5407 |
typedef typename LhsStlContainer::value_type LhsValue; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5408 |
// We pass the LHS value and the RHS value to the inner matcher by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5409 |
// reference, as they may be expensive to copy. We must use tuple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5410 |
// instead of pair here, as a pair cannot hold references (C++ 98, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5411 |
// 20.2.2 [lib.pairs]). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5412 |
typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5413 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5414 |
Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5415 |
// mono_tuple_matcher_ holds a monomorphic version of the tuple matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5416 |
: mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5417 |
rhs_(rhs) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5418 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5419 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5420 |
*os << "contains " << rhs_.size() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5421 |
<< " values, where each value and its corresponding value in "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5422 |
UniversalPrinter<RhsStlContainer>::Print(rhs_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5423 |
*os << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5424 |
mono_tuple_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5425 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5426 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5427 |
*os << "doesn't contain exactly " << rhs_.size() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5428 |
<< " values, or contains a value x at some index i" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5429 |
<< " where x and the i-th value of "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5430 |
UniversalPrint(rhs_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5431 |
*os << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5432 |
mono_tuple_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5433 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5435 |
bool MatchAndExplain(LhsContainer lhs, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5436 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5437 |
LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5438 |
const size_t actual_size = lhs_stl_container.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5439 |
if (actual_size != rhs_.size()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5440 |
*listener << "which contains " << actual_size << " values"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5441 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5442 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5443 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5444 |
typename LhsStlContainer::const_iterator left = lhs_stl_container.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5445 |
typename RhsStlContainer::const_iterator right = rhs_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5446 |
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5447 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5448 |
StringMatchResultListener inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5449 |
// Create InnerMatcherArg as a temporarily object to avoid it outlives |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5450 |
// *left and *right. Dereference or the conversion to `const T&` may |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5451 |
// return temp objects, e.g for vector<bool>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5452 |
if (!mono_tuple_matcher_.MatchAndExplain( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5453 |
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5454 |
ImplicitCast_<const RhsValue&>(*right)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5455 |
&inner_listener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5456 |
*listener << "where the value pair ("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5457 |
UniversalPrint(*left, listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5458 |
*listener << ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5459 |
UniversalPrint(*right, listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5460 |
*listener << ") at index #" << i << " don't match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5461 |
PrintIfNotEmpty(inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5462 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5463 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5464 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5465 |
if (!mono_tuple_matcher_.Matches( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5466 |
InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5467 |
ImplicitCast_<const RhsValue&>(*right)))) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5468 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5469 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5470 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5471 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5472 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5473 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5474 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5475 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5476 |
const Matcher<InnerMatcherArg> mono_tuple_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5477 |
const RhsStlContainer rhs_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5478 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5480 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5481 |
const TupleMatcher tuple_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5482 |
const RhsStlContainer rhs_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5483 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5484 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5485 |
// Holds the logic common to ContainsMatcherImpl and EachMatcherImpl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5486 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5487 |
class QuantifierMatcherImpl : public MatcherInterface<Container> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5488 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5489 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5490 |
typedef StlContainerView<RawContainer> View; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5491 |
typedef typename View::type StlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5492 |
typedef typename View::const_reference StlContainerReference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5493 |
typedef typename StlContainer::value_type Element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5494 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5495 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5496 |
explicit QuantifierMatcherImpl(InnerMatcher inner_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5497 |
: inner_matcher_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5498 |
testing::SafeMatcherCast<const Element&>(inner_matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5499 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5500 |
// Checks whether: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5501 |
// * All elements in the container match, if all_elements_should_match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5502 |
// * Any element in the container matches, if !all_elements_should_match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5503 |
bool MatchAndExplainImpl(bool all_elements_should_match, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5504 |
Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5505 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5506 |
StlContainerReference stl_container = View::ConstReference(container); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5507 |
size_t i = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5508 |
for (typename StlContainer::const_iterator it = stl_container.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5509 |
it != stl_container.end(); ++it, ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5510 |
StringMatchResultListener inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5511 |
const bool matches = inner_matcher_.MatchAndExplain(*it, &inner_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5512 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5513 |
if (matches != all_elements_should_match) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5514 |
*listener << "whose element #" << i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5515 |
<< (matches ? " matches" : " doesn't match"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5516 |
PrintIfNotEmpty(inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5517 |
return !all_elements_should_match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5518 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5519 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5520 |
return all_elements_should_match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5521 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5522 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5523 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5524 |
const Matcher<const Element&> inner_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5525 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5526 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5527 |
// Implements Contains(element_matcher) for the given argument type Container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5528 |
// Symmetric to EachMatcherImpl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5529 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5530 |
class ContainsMatcherImpl : public QuantifierMatcherImpl<Container> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5531 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5532 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5533 |
explicit ContainsMatcherImpl(InnerMatcher inner_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5534 |
: QuantifierMatcherImpl<Container>(inner_matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5535 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5536 |
// Describes what this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5537 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5538 |
*os << "contains at least one element that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5539 |
this->inner_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5540 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5542 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5543 |
*os << "doesn't contain any element that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5544 |
this->inner_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5545 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5546 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5547 |
bool MatchAndExplain(Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5548 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5549 |
return this->MatchAndExplainImpl(false, container, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5550 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5551 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5553 |
// Implements Each(element_matcher) for the given argument type Container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5554 |
// Symmetric to ContainsMatcherImpl. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5555 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5556 |
class EachMatcherImpl : public QuantifierMatcherImpl<Container> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5557 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5558 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5559 |
explicit EachMatcherImpl(InnerMatcher inner_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5560 |
: QuantifierMatcherImpl<Container>(inner_matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5561 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5562 |
// Describes what this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5563 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5564 |
*os << "only contains elements that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5565 |
this->inner_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5566 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5567 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5568 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5569 |
*os << "contains some element that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5570 |
this->inner_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5571 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5572 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5573 |
bool MatchAndExplain(Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5574 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5575 |
return this->MatchAndExplainImpl(true, container, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5576 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5577 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5578 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5579 |
// Implements polymorphic Contains(element_matcher). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5580 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5581 |
class ContainsMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5582 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5583 |
explicit ContainsMatcher(M m) : inner_matcher_(m) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5584 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5585 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5586 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5587 |
return Matcher<Container>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5588 |
new ContainsMatcherImpl<const Container&>(inner_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5589 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5590 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5591 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5592 |
const M inner_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5593 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5594 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5595 |
// Implements polymorphic Each(element_matcher). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5596 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5597 |
class EachMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5598 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5599 |
explicit EachMatcher(M m) : inner_matcher_(m) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5600 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5601 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5602 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5603 |
return Matcher<Container>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5604 |
new EachMatcherImpl<const Container&>(inner_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5605 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5606 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5607 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5608 |
const M inner_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5609 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5611 |
struct Rank1 {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5612 |
struct Rank0 : Rank1 {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5613 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5614 |
namespace pair_getters { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5615 |
using std::get; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5616 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5617 |
auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5618 |
return get<0>(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5619 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5620 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5621 |
auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5622 |
return x.first; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5623 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5624 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5625 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5626 |
auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5627 |
return get<1>(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5628 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5629 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5630 |
auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5631 |
return x.second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5632 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5633 |
} // namespace pair_getters |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5634 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5635 |
// Implements Key(inner_matcher) for the given argument pair type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5636 |
// Key(inner_matcher) matches an std::pair whose 'first' field matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5637 |
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5638 |
// std::map that contains at least one element whose key is >= 5. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5639 |
template <typename PairType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5640 |
class KeyMatcherImpl : public MatcherInterface<PairType> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5641 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5642 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5643 |
typedef typename RawPairType::first_type KeyType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5644 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5645 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5646 |
explicit KeyMatcherImpl(InnerMatcher inner_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5647 |
: inner_matcher_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5648 |
testing::SafeMatcherCast<const KeyType&>(inner_matcher)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5649 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5650 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5651 |
// Returns true if and only if 'key_value.first' (the key) matches the inner |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5652 |
// matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5653 |
bool MatchAndExplain(PairType key_value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5654 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5655 |
StringMatchResultListener inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5656 |
const bool match = inner_matcher_.MatchAndExplain( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5657 |
pair_getters::First(key_value, Rank0()), &inner_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5658 |
const std::string explanation = inner_listener.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5659 |
if (explanation != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5660 |
*listener << "whose first field is a value " << explanation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5661 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5662 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5663 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5664 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5665 |
// Describes what this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5666 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5667 |
*os << "has a key that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5668 |
inner_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5669 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5670 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5671 |
// Describes what the negation of this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5672 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5673 |
*os << "doesn't have a key that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5674 |
inner_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5675 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5676 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5677 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5678 |
const Matcher<const KeyType&> inner_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5679 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5680 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5681 |
// Implements polymorphic Key(matcher_for_key). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5682 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5683 |
class KeyMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5684 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5685 |
explicit KeyMatcher(M m) : matcher_for_key_(m) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5686 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5687 |
template <typename PairType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5688 |
operator Matcher<PairType>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5689 |
return Matcher<PairType>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5690 |
new KeyMatcherImpl<const PairType&>(matcher_for_key_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5691 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5692 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5693 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5694 |
const M matcher_for_key_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5695 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5696 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5697 |
// Implements polymorphic Address(matcher_for_address). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5698 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5699 |
class AddressMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5700 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5701 |
explicit AddressMatcher(InnerMatcher m) : matcher_(m) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5702 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5703 |
template <typename Type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5704 |
operator Matcher<Type>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5705 |
return Matcher<Type>(new Impl<const Type&>(matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5706 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5707 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5708 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5709 |
// The monomorphic implementation that works for a particular object type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5710 |
template <typename Type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5711 |
class Impl : public MatcherInterface<Type> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5712 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5713 |
using Address = const GTEST_REMOVE_REFERENCE_AND_CONST_(Type) *; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5714 |
explicit Impl(const InnerMatcher& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5715 |
: matcher_(MatcherCast<Address>(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5716 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5717 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5718 |
*os << "has address that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5719 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5720 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5721 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5722 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5723 |
*os << "does not have address that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5724 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5725 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5726 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5727 |
bool MatchAndExplain(Type object, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5728 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5729 |
*listener << "which has address "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5730 |
Address address = std::addressof(object); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5731 |
return MatchPrintAndExplain(address, matcher_, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5732 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5734 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5735 |
const Matcher<Address> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5736 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5737 |
const InnerMatcher matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5738 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5739 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5740 |
// Implements Pair(first_matcher, second_matcher) for the given argument pair |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5741 |
// type with its two matchers. See Pair() function below. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5742 |
template <typename PairType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5743 |
class PairMatcherImpl : public MatcherInterface<PairType> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5744 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5745 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(PairType) RawPairType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5746 |
typedef typename RawPairType::first_type FirstType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5747 |
typedef typename RawPairType::second_type SecondType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5748 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5749 |
template <typename FirstMatcher, typename SecondMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5750 |
PairMatcherImpl(FirstMatcher first_matcher, SecondMatcher second_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5751 |
: first_matcher_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5752 |
testing::SafeMatcherCast<const FirstType&>(first_matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5753 |
second_matcher_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5754 |
testing::SafeMatcherCast<const SecondType&>(second_matcher)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5755 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5756 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5757 |
// Describes what this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5758 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5759 |
*os << "has a first field that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5760 |
first_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5761 |
*os << ", and has a second field that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5762 |
second_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5763 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5764 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5765 |
// Describes what the negation of this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5766 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5767 |
*os << "has a first field that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5768 |
first_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5769 |
*os << ", or has a second field that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5770 |
second_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5771 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5772 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5773 |
// Returns true if and only if 'a_pair.first' matches first_matcher and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5774 |
// 'a_pair.second' matches second_matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5775 |
bool MatchAndExplain(PairType a_pair, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5776 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5777 |
if (!listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5778 |
// If the listener is not interested, we don't need to construct the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5779 |
// explanation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5780 |
return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5781 |
second_matcher_.Matches(pair_getters::Second(a_pair, Rank0())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5782 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5783 |
StringMatchResultListener first_inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5784 |
if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5785 |
&first_inner_listener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5786 |
*listener << "whose first field does not match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5787 |
PrintIfNotEmpty(first_inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5788 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5789 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5790 |
StringMatchResultListener second_inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5791 |
if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5792 |
&second_inner_listener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5793 |
*listener << "whose second field does not match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5794 |
PrintIfNotEmpty(second_inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5795 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5796 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5797 |
ExplainSuccess(first_inner_listener.str(), second_inner_listener.str(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5798 |
listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5799 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5800 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5801 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5802 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5803 |
void ExplainSuccess(const std::string& first_explanation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5804 |
const std::string& second_explanation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5805 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5806 |
*listener << "whose both fields match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5807 |
if (first_explanation != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5808 |
*listener << ", where the first field is a value " << first_explanation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5809 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5810 |
if (second_explanation != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5811 |
*listener << ", "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5812 |
if (first_explanation != "") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5813 |
*listener << "and "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5814 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5815 |
*listener << "where "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5816 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5817 |
*listener << "the second field is a value " << second_explanation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5818 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5819 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5820 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5821 |
const Matcher<const FirstType&> first_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5822 |
const Matcher<const SecondType&> second_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5823 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5824 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5825 |
// Implements polymorphic Pair(first_matcher, second_matcher). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5826 |
template <typename FirstMatcher, typename SecondMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5827 |
class PairMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5828 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5829 |
PairMatcher(FirstMatcher first_matcher, SecondMatcher second_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5830 |
: first_matcher_(first_matcher), second_matcher_(second_matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5831 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5832 |
template <typename PairType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5833 |
operator Matcher<PairType> () const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5834 |
return Matcher<PairType>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5835 |
new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5836 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5837 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5838 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5839 |
const FirstMatcher first_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5840 |
const SecondMatcher second_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5841 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5842 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5843 |
template <typename T, size_t... I> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5844 |
auto UnpackStructImpl(const T& t, IndexSequence<I...>, int) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5845 |
-> decltype(std::tie(get<I>(t)...)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5846 |
static_assert(std::tuple_size<T>::value == sizeof...(I), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5847 |
"Number of arguments doesn't match the number of fields."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5848 |
return std::tie(get<I>(t)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5849 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5850 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5851 |
#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 201606 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5852 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5853 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<1>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5854 |
const auto& [a] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5855 |
return std::tie(a); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5856 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5857 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5858 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<2>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5859 |
const auto& [a, b] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5860 |
return std::tie(a, b); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5861 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5862 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5863 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<3>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5864 |
const auto& [a, b, c] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5865 |
return std::tie(a, b, c); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5866 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5867 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5868 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<4>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5869 |
const auto& [a, b, c, d] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5870 |
return std::tie(a, b, c, d); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5871 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5872 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5873 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<5>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5874 |
const auto& [a, b, c, d, e] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5875 |
return std::tie(a, b, c, d, e); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5876 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5877 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5878 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<6>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5879 |
const auto& [a, b, c, d, e, f] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5880 |
return std::tie(a, b, c, d, e, f); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5881 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5882 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5883 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<7>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5884 |
const auto& [a, b, c, d, e, f, g] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5885 |
return std::tie(a, b, c, d, e, f, g); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5886 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5887 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5888 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<8>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5889 |
const auto& [a, b, c, d, e, f, g, h] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5890 |
return std::tie(a, b, c, d, e, f, g, h); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5891 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5892 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5893 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<9>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5894 |
const auto& [a, b, c, d, e, f, g, h, i] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5895 |
return std::tie(a, b, c, d, e, f, g, h, i); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5896 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5897 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5898 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<10>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5899 |
const auto& [a, b, c, d, e, f, g, h, i, j] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5900 |
return std::tie(a, b, c, d, e, f, g, h, i, j); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5901 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5902 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5903 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<11>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5904 |
const auto& [a, b, c, d, e, f, g, h, i, j, k] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5905 |
return std::tie(a, b, c, d, e, f, g, h, i, j, k); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5906 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5907 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5908 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<12>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5909 |
const auto& [a, b, c, d, e, f, g, h, i, j, k, l] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5910 |
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5911 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5912 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5913 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<13>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5914 |
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5915 |
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5916 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5917 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5918 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<14>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5919 |
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5920 |
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5921 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5922 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5923 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<15>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5924 |
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5925 |
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5926 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5927 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5928 |
auto UnpackStructImpl(const T& t, MakeIndexSequence<16>, char) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5929 |
const auto& [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = t; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5930 |
return std::tie(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5931 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5932 |
#endif // defined(__cpp_structured_bindings) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5933 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5934 |
template <size_t I, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5935 |
auto UnpackStruct(const T& t) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5936 |
-> decltype((UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5937 |
return (UnpackStructImpl)(t, MakeIndexSequence<I>{}, 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5938 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5939 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5940 |
// Helper function to do comma folding in C++11. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5941 |
// The array ensures left-to-right order of evaluation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5942 |
// Usage: VariadicExpand({expr...}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5943 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5944 |
void VariadicExpand(const T (&)[N]) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5945 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5946 |
template <typename Struct, typename StructSize> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5947 |
class FieldsAreMatcherImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5948 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5949 |
template <typename Struct, size_t... I> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5950 |
class FieldsAreMatcherImpl<Struct, IndexSequence<I...>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5951 |
: public MatcherInterface<Struct> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5952 |
using UnpackedType = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5953 |
decltype(UnpackStruct<sizeof...(I)>(std::declval<const Struct&>())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5954 |
using MatchersType = std::tuple< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5955 |
Matcher<const typename std::tuple_element<I, UnpackedType>::type&>...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5956 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5957 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5958 |
template <typename Inner> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5959 |
explicit FieldsAreMatcherImpl(const Inner& matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5960 |
: matchers_(testing::SafeMatcherCast< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5961 |
const typename std::tuple_element<I, UnpackedType>::type&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5962 |
std::get<I>(matchers))...) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5963 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5964 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5965 |
const char* separator = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5966 |
VariadicExpand( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5967 |
{(*os << separator << "has field #" << I << " that ", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5968 |
std::get<I>(matchers_).DescribeTo(os), separator = ", and ")...}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5969 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5970 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5971 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5972 |
const char* separator = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5973 |
VariadicExpand({(*os << separator << "has field #" << I << " that ", |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5974 |
std::get<I>(matchers_).DescribeNegationTo(os), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5975 |
separator = ", or ")...}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5976 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5977 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5978 |
bool MatchAndExplain(Struct t, MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5979 |
return MatchInternal((UnpackStruct<sizeof...(I)>)(t), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5980 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5981 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5982 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5983 |
bool MatchInternal(UnpackedType tuple, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5984 |
if (!listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5985 |
// If the listener is not interested, we don't need to construct the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5986 |
// explanation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5987 |
bool good = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5988 |
VariadicExpand({good = good && std::get<I>(matchers_).Matches( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5989 |
std::get<I>(tuple))...}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5990 |
return good; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5991 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5992 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5993 |
size_t failed_pos = ~size_t{}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5994 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5995 |
std::vector<StringMatchResultListener> inner_listener(sizeof...(I)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5996 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5997 |
VariadicExpand( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5998 |
{failed_pos == ~size_t{} && !std::get<I>(matchers_).MatchAndExplain( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
5999 |
std::get<I>(tuple), &inner_listener[I]) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6000 |
? failed_pos = I |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6001 |
: 0 ...}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6002 |
if (failed_pos != ~size_t{}) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6003 |
*listener << "whose field #" << failed_pos << " does not match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6004 |
PrintIfNotEmpty(inner_listener[failed_pos].str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6005 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6006 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6007 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6008 |
*listener << "whose all elements match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6009 |
const char* separator = ", where"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6010 |
for (size_t index = 0; index < sizeof...(I); ++index) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6011 |
const std::string str = inner_listener[index].str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6012 |
if (!str.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6013 |
*listener << separator << " field #" << index << " is a value " << str; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6014 |
separator = ", and"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6015 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6016 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6017 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6018 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6019 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6020 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6021 |
MatchersType matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6022 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6023 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6024 |
template <typename... Inner> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6025 |
class FieldsAreMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6026 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6027 |
explicit FieldsAreMatcher(Inner... inner) : matchers_(std::move(inner)...) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6028 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6029 |
template <typename Struct> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6030 |
operator Matcher<Struct>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6031 |
return Matcher<Struct>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6032 |
new FieldsAreMatcherImpl<const Struct&, IndexSequenceFor<Inner...>>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6033 |
matchers_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6034 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6035 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6036 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6037 |
std::tuple<Inner...> matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6038 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6039 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6040 |
// Implements ElementsAre() and ElementsAreArray(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6041 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6042 |
class ElementsAreMatcherImpl : public MatcherInterface<Container> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6043 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6044 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6045 |
typedef internal::StlContainerView<RawContainer> View; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6046 |
typedef typename View::type StlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6047 |
typedef typename View::const_reference StlContainerReference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6048 |
typedef typename StlContainer::value_type Element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6049 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6050 |
// Constructs the matcher from a sequence of element values or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6051 |
// element matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6052 |
template <typename InputIter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6053 |
ElementsAreMatcherImpl(InputIter first, InputIter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6054 |
while (first != last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6055 |
matchers_.push_back(MatcherCast<const Element&>(*first++)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6056 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6057 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6058 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6059 |
// Describes what this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6060 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6061 |
if (count() == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6062 |
*os << "is empty"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6063 |
} else if (count() == 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6064 |
*os << "has 1 element that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6065 |
matchers_[0].DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6066 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6067 |
*os << "has " << Elements(count()) << " where\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6068 |
for (size_t i = 0; i != count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6069 |
*os << "element #" << i << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6070 |
matchers_[i].DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6071 |
if (i + 1 < count()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6072 |
*os << ",\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6073 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6074 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6075 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6076 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6077 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6078 |
// Describes what the negation of this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6079 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6080 |
if (count() == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6081 |
*os << "isn't empty"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6082 |
return; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6083 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6084 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6085 |
*os << "doesn't have " << Elements(count()) << ", or\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6086 |
for (size_t i = 0; i != count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6087 |
*os << "element #" << i << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6088 |
matchers_[i].DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6089 |
if (i + 1 < count()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6090 |
*os << ", or\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6091 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6092 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6093 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6094 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6095 |
bool MatchAndExplain(Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6096 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6097 |
// To work with stream-like "containers", we must only walk |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6098 |
// through the elements in one pass. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6099 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6100 |
const bool listener_interested = listener->IsInterested(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6101 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6102 |
// explanations[i] is the explanation of the element at index i. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6103 |
::std::vector<std::string> explanations(count()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6104 |
StlContainerReference stl_container = View::ConstReference(container); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6105 |
typename StlContainer::const_iterator it = stl_container.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6106 |
size_t exam_pos = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6107 |
bool mismatch_found = false; // Have we found a mismatched element yet? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6108 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6109 |
// Go through the elements and matchers in pairs, until we reach |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6110 |
// the end of either the elements or the matchers, or until we find a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6111 |
// mismatch. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6112 |
for (; it != stl_container.end() && exam_pos != count(); ++it, ++exam_pos) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6113 |
bool match; // Does the current element match the current matcher? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6114 |
if (listener_interested) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6115 |
StringMatchResultListener s; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6116 |
match = matchers_[exam_pos].MatchAndExplain(*it, &s); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6117 |
explanations[exam_pos] = s.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6118 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6119 |
match = matchers_[exam_pos].Matches(*it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6120 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6121 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6122 |
if (!match) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6123 |
mismatch_found = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6124 |
break; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6125 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6126 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6127 |
// If mismatch_found is true, 'exam_pos' is the index of the mismatch. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6129 |
// Find how many elements the actual container has. We avoid |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6130 |
// calling size() s.t. this code works for stream-like "containers" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6131 |
// that don't define size(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6132 |
size_t actual_count = exam_pos; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6133 |
for (; it != stl_container.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6134 |
++actual_count; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6135 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6136 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6137 |
if (actual_count != count()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6138 |
// The element count doesn't match. If the container is empty, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6139 |
// there's no need to explain anything as Google Mock already |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6140 |
// prints the empty container. Otherwise we just need to show |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6141 |
// how many elements there actually are. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6142 |
if (listener_interested && (actual_count != 0)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6143 |
*listener << "which has " << Elements(actual_count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6144 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6145 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6146 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6147 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6148 |
if (mismatch_found) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6149 |
// The element count matches, but the exam_pos-th element doesn't match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6150 |
if (listener_interested) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6151 |
*listener << "whose element #" << exam_pos << " doesn't match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6152 |
PrintIfNotEmpty(explanations[exam_pos], listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6153 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6154 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6155 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6157 |
// Every element matches its expectation. We need to explain why |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6158 |
// (the obvious ones can be skipped). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6159 |
if (listener_interested) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6160 |
bool reason_printed = false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6161 |
for (size_t i = 0; i != count(); ++i) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6162 |
const std::string& s = explanations[i]; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6163 |
if (!s.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6164 |
if (reason_printed) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6165 |
*listener << ",\nand "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6166 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6167 |
*listener << "whose element #" << i << " matches, " << s; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6168 |
reason_printed = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6169 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6170 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6171 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6172 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6173 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6175 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6176 |
static Message Elements(size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6177 |
return Message() << count << (count == 1 ? " element" : " elements"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6178 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6179 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6180 |
size_t count() const { return matchers_.size(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6181 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6182 |
::std::vector<Matcher<const Element&> > matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6183 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6184 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6185 |
// Connectivity matrix of (elements X matchers), in element-major order. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6186 |
// Initially, there are no edges. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6187 |
// Use NextGraph() to iterate over all possible edge configurations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6188 |
// Use Randomize() to generate a random edge configuration. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6189 |
class GTEST_API_ MatchMatrix { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6190 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6191 |
MatchMatrix(size_t num_elements, size_t num_matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6192 |
: num_elements_(num_elements), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6193 |
num_matchers_(num_matchers), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6194 |
matched_(num_elements_* num_matchers_, 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6195 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6196 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6197 |
size_t LhsSize() const { return num_elements_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6198 |
size_t RhsSize() const { return num_matchers_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6199 |
bool HasEdge(size_t ilhs, size_t irhs) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6200 |
return matched_[SpaceIndex(ilhs, irhs)] == 1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6201 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6202 |
void SetEdge(size_t ilhs, size_t irhs, bool b) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6203 |
matched_[SpaceIndex(ilhs, irhs)] = b ? 1 : 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6204 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6205 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6206 |
// Treating the connectivity matrix as a (LhsSize()*RhsSize())-bit number, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6207 |
// adds 1 to that number; returns false if incrementing the graph left it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6208 |
// empty. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6209 |
bool NextGraph(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6210 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6211 |
void Randomize(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6212 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6213 |
std::string DebugString() const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6214 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6215 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6216 |
size_t SpaceIndex(size_t ilhs, size_t irhs) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6217 |
return ilhs * num_matchers_ + irhs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6218 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6219 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6220 |
size_t num_elements_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6221 |
size_t num_matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6222 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6223 |
// Each element is a char interpreted as bool. They are stored as a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6224 |
// flattened array in lhs-major order, use 'SpaceIndex()' to translate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6225 |
// a (ilhs, irhs) matrix coordinate into an offset. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6226 |
::std::vector<char> matched_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6227 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6228 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6229 |
typedef ::std::pair<size_t, size_t> ElementMatcherPair; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6230 |
typedef ::std::vector<ElementMatcherPair> ElementMatcherPairs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6231 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6232 |
// Returns a maximum bipartite matching for the specified graph 'g'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6233 |
// The matching is represented as a vector of {element, matcher} pairs. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6234 |
GTEST_API_ ElementMatcherPairs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6235 |
FindMaxBipartiteMatching(const MatchMatrix& g); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6236 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6237 |
struct UnorderedMatcherRequire { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6238 |
enum Flags { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6239 |
Superset = 1 << 0, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6240 |
Subset = 1 << 1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6241 |
ExactMatch = Superset | Subset, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6242 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6243 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6244 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6245 |
// Untyped base class for implementing UnorderedElementsAre. By |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6246 |
// putting logic that's not specific to the element type here, we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6247 |
// reduce binary bloat and increase compilation speed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6248 |
class GTEST_API_ UnorderedElementsAreMatcherImplBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6249 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6250 |
explicit UnorderedElementsAreMatcherImplBase( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6251 |
UnorderedMatcherRequire::Flags matcher_flags) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6252 |
: match_flags_(matcher_flags) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6254 |
// A vector of matcher describers, one for each element matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6255 |
// Does not own the describers (and thus can be used only when the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6256 |
// element matchers are alive). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6257 |
typedef ::std::vector<const MatcherDescriberInterface*> MatcherDescriberVec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6258 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6259 |
// Describes this UnorderedElementsAre matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6260 |
void DescribeToImpl(::std::ostream* os) const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6261 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6262 |
// Describes the negation of this UnorderedElementsAre matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6263 |
void DescribeNegationToImpl(::std::ostream* os) const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6264 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6265 |
bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6266 |
const MatchMatrix& matrix, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6267 |
MatchResultListener* listener) const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6268 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6269 |
bool FindPairing(const MatchMatrix& matrix, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6270 |
MatchResultListener* listener) const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6271 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6272 |
MatcherDescriberVec& matcher_describers() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6273 |
return matcher_describers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6274 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6275 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6276 |
static Message Elements(size_t n) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6277 |
return Message() << n << " element" << (n == 1 ? "" : "s"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6278 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6279 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6280 |
UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6281 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6282 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6283 |
UnorderedMatcherRequire::Flags match_flags_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6284 |
MatcherDescriberVec matcher_describers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6285 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6286 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6287 |
// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6288 |
// IsSupersetOf. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6289 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6290 |
class UnorderedElementsAreMatcherImpl |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6291 |
: public MatcherInterface<Container>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6292 |
public UnorderedElementsAreMatcherImplBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6293 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6294 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6295 |
typedef internal::StlContainerView<RawContainer> View; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6296 |
typedef typename View::type StlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6297 |
typedef typename View::const_reference StlContainerReference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6298 |
typedef typename StlContainer::const_iterator StlContainerConstIterator; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6299 |
typedef typename StlContainer::value_type Element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6300 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6301 |
template <typename InputIter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6302 |
UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6303 |
InputIter first, InputIter last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6304 |
: UnorderedElementsAreMatcherImplBase(matcher_flags) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6305 |
for (; first != last; ++first) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6306 |
matchers_.push_back(MatcherCast<const Element&>(*first)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6307 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6308 |
for (const auto& m : matchers_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6309 |
matcher_describers().push_back(m.GetDescriber()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6310 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6311 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6312 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6313 |
// Describes what this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6314 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6315 |
return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6316 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6318 |
// Describes what the negation of this matcher does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6319 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6320 |
return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6321 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6322 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6323 |
bool MatchAndExplain(Container container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6324 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6325 |
StlContainerReference stl_container = View::ConstReference(container); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6326 |
::std::vector<std::string> element_printouts; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6327 |
MatchMatrix matrix = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6328 |
AnalyzeElements(stl_container.begin(), stl_container.end(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6329 |
&element_printouts, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6331 |
if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6332 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6333 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6334 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6335 |
if (match_flags() == UnorderedMatcherRequire::ExactMatch) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6336 |
if (matrix.LhsSize() != matrix.RhsSize()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6337 |
// The element count doesn't match. If the container is empty, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6338 |
// there's no need to explain anything as Google Mock already |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6339 |
// prints the empty container. Otherwise we just need to show |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6340 |
// how many elements there actually are. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6341 |
if (matrix.LhsSize() != 0 && listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6342 |
*listener << "which has " << Elements(matrix.LhsSize()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6343 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6344 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6345 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6346 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6347 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6348 |
return VerifyMatchMatrix(element_printouts, matrix, listener) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6349 |
FindPairing(matrix, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6350 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6351 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6352 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6353 |
template <typename ElementIter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6354 |
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6355 |
::std::vector<std::string>* element_printouts, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6356 |
MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6357 |
element_printouts->clear(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6358 |
::std::vector<char> did_match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6359 |
size_t num_elements = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6360 |
DummyMatchResultListener dummy; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6361 |
for (; elem_first != elem_last; ++num_elements, ++elem_first) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6362 |
if (listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6363 |
element_printouts->push_back(PrintToString(*elem_first)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6364 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6365 |
for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6366 |
did_match.push_back( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6367 |
matchers_[irhs].MatchAndExplain(*elem_first, &dummy)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6368 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6369 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6370 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6371 |
MatchMatrix matrix(num_elements, matchers_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6372 |
::std::vector<char>::const_iterator did_match_iter = did_match.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6373 |
for (size_t ilhs = 0; ilhs != num_elements; ++ilhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6374 |
for (size_t irhs = 0; irhs != matchers_.size(); ++irhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6375 |
matrix.SetEdge(ilhs, irhs, *did_match_iter++ != 0); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6376 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6377 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6378 |
return matrix; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6379 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6381 |
::std::vector<Matcher<const Element&> > matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6382 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6383 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6384 |
// Functor for use in TransformTuple. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6385 |
// Performs MatcherCast<Target> on an input argument of any type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6386 |
template <typename Target> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6387 |
struct CastAndAppendTransform { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6388 |
template <typename Arg> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6389 |
Matcher<Target> operator()(const Arg& a) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6390 |
return MatcherCast<Target>(a); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6391 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6392 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6393 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6394 |
// Implements UnorderedElementsAre. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6395 |
template <typename MatcherTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6396 |
class UnorderedElementsAreMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6397 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6398 |
explicit UnorderedElementsAreMatcher(const MatcherTuple& args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6399 |
: matchers_(args) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6400 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6401 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6402 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6403 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6404 |
typedef typename internal::StlContainerView<RawContainer>::type View; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6405 |
typedef typename View::value_type Element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6406 |
typedef ::std::vector<Matcher<const Element&> > MatcherVec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6407 |
MatcherVec matchers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6408 |
matchers.reserve(::std::tuple_size<MatcherTuple>::value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6409 |
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6410 |
::std::back_inserter(matchers)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6411 |
return Matcher<Container>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6412 |
new UnorderedElementsAreMatcherImpl<const Container&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6413 |
UnorderedMatcherRequire::ExactMatch, matchers.begin(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6414 |
matchers.end())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6415 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6416 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6417 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6418 |
const MatcherTuple matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6419 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6420 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6421 |
// Implements ElementsAre. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6422 |
template <typename MatcherTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6423 |
class ElementsAreMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6424 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6425 |
explicit ElementsAreMatcher(const MatcherTuple& args) : matchers_(args) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6426 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6427 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6428 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6429 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6430 |
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value || |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6431 |
::std::tuple_size<MatcherTuple>::value < 2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6432 |
use_UnorderedElementsAre_with_hash_tables); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6433 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6434 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6435 |
typedef typename internal::StlContainerView<RawContainer>::type View; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6436 |
typedef typename View::value_type Element; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6437 |
typedef ::std::vector<Matcher<const Element&> > MatcherVec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6438 |
MatcherVec matchers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6439 |
matchers.reserve(::std::tuple_size<MatcherTuple>::value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6440 |
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6441 |
::std::back_inserter(matchers)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6442 |
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6443 |
matchers.begin(), matchers.end())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6444 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6445 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6446 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6447 |
const MatcherTuple matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6448 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6449 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6450 |
// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6451 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6452 |
class UnorderedElementsAreArrayMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6453 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6454 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6455 |
UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6456 |
Iter first, Iter last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6457 |
: match_flags_(match_flags), matchers_(first, last) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6458 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6459 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6460 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6461 |
return Matcher<Container>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6462 |
new UnorderedElementsAreMatcherImpl<const Container&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6463 |
match_flags_, matchers_.begin(), matchers_.end())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6464 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6465 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6466 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6467 |
UnorderedMatcherRequire::Flags match_flags_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6468 |
::std::vector<T> matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6469 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6471 |
// Implements ElementsAreArray(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6472 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6473 |
class ElementsAreArrayMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6474 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6475 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6476 |
ElementsAreArrayMatcher(Iter first, Iter last) : matchers_(first, last) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6477 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6478 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6479 |
operator Matcher<Container>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6480 |
GTEST_COMPILE_ASSERT_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6481 |
!IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6482 |
use_UnorderedElementsAreArray_with_hash_tables); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6483 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6484 |
return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6485 |
matchers_.begin(), matchers_.end())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6486 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6487 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6488 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6489 |
const ::std::vector<T> matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6490 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6491 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6492 |
// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6493 |
// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6494 |
// second) is a polymorphic matcher that matches a value x if and only if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6495 |
// tm matches tuple (x, second). Useful for implementing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6496 |
// UnorderedPointwise() in terms of UnorderedElementsAreArray(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6497 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6498 |
// BoundSecondMatcher is copyable and assignable, as we need to put |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6499 |
// instances of this class in a vector when implementing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6500 |
// UnorderedPointwise(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6501 |
template <typename Tuple2Matcher, typename Second> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6502 |
class BoundSecondMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6503 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6504 |
BoundSecondMatcher(const Tuple2Matcher& tm, const Second& second) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6505 |
: tuple2_matcher_(tm), second_value_(second) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6506 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6507 |
BoundSecondMatcher(const BoundSecondMatcher& other) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6508 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6509 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6510 |
operator Matcher<T>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6511 |
return MakeMatcher(new Impl<T>(tuple2_matcher_, second_value_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6512 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6513 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6514 |
// We have to define this for UnorderedPointwise() to compile in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6515 |
// C++98 mode, as it puts BoundSecondMatcher instances in a vector, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6516 |
// which requires the elements to be assignable in C++98. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6517 |
// compiler cannot generate the operator= for us, as Tuple2Matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6518 |
// and Second may not be assignable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6519 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6520 |
// However, this should never be called, so the implementation just |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6521 |
// need to assert. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6522 |
void operator=(const BoundSecondMatcher& /*rhs*/) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6523 |
GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6524 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6525 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6526 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6527 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6528 |
class Impl : public MatcherInterface<T> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6529 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6530 |
typedef ::std::tuple<T, Second> ArgTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6531 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6532 |
Impl(const Tuple2Matcher& tm, const Second& second) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6533 |
: mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6534 |
second_value_(second) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6535 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6536 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6537 |
*os << "and "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6538 |
UniversalPrint(second_value_, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6539 |
*os << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6540 |
mono_tuple2_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6541 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6542 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6543 |
bool MatchAndExplain(T x, MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6544 |
return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6545 |
listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6546 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6547 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6548 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6549 |
const Matcher<const ArgTuple&> mono_tuple2_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6550 |
const Second second_value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6551 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6553 |
const Tuple2Matcher tuple2_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6554 |
const Second second_value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6555 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6556 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6557 |
// Given a 2-tuple matcher tm and a value second, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6558 |
// MatcherBindSecond(tm, second) returns a matcher that matches a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6559 |
// value x if and only if tm matches tuple (x, second). Useful for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6560 |
// implementing UnorderedPointwise() in terms of UnorderedElementsAreArray(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6561 |
template <typename Tuple2Matcher, typename Second> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6562 |
BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6563 |
const Tuple2Matcher& tm, const Second& second) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6564 |
return BoundSecondMatcher<Tuple2Matcher, Second>(tm, second); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6565 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6566 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6567 |
// Returns the description for a matcher defined using the MATCHER*() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6568 |
// macro where the user-supplied description string is "", if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6569 |
// 'negation' is false; otherwise returns the description of the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6570 |
// negation of the matcher. 'param_values' contains a list of strings |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6571 |
// that are the print-out of the matcher's parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6572 |
GTEST_API_ std::string FormatMatcherDescription(bool negation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6573 |
const char* matcher_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6574 |
const Strings& param_values); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6575 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6576 |
// Implements a matcher that checks the value of a optional<> type variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6577 |
template <typename ValueMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6578 |
class OptionalMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6579 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6580 |
explicit OptionalMatcher(const ValueMatcher& value_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6581 |
: value_matcher_(value_matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6582 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6583 |
template <typename Optional> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6584 |
operator Matcher<Optional>() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6585 |
return Matcher<Optional>(new Impl<const Optional&>(value_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6586 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6587 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6588 |
template <typename Optional> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6589 |
class Impl : public MatcherInterface<Optional> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6590 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6591 |
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6592 |
typedef typename OptionalView::value_type ValueType; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6593 |
explicit Impl(const ValueMatcher& value_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6594 |
: value_matcher_(MatcherCast<ValueType>(value_matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6595 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6596 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6597 |
*os << "value "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6598 |
value_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6599 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6600 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6601 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6602 |
*os << "value "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6603 |
value_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6604 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6605 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6606 |
bool MatchAndExplain(Optional optional, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6607 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6608 |
if (!optional) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6609 |
*listener << "which is not engaged"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6610 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6611 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6612 |
const ValueType& value = *optional; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6613 |
StringMatchResultListener value_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6614 |
const bool match = value_matcher_.MatchAndExplain(value, &value_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6615 |
*listener << "whose value " << PrintToString(value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6616 |
<< (match ? " matches" : " doesn't match"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6617 |
PrintIfNotEmpty(value_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6618 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6619 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6621 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6622 |
const Matcher<ValueType> value_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6623 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6624 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6625 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6626 |
const ValueMatcher value_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6627 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6628 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6629 |
namespace variant_matcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6630 |
// Overloads to allow VariantMatcher to do proper ADL lookup. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6631 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6632 |
void holds_alternative() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6633 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6634 |
void get() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6635 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6636 |
// Implements a matcher that checks the value of a variant<> type variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6637 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6638 |
class VariantMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6639 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6640 |
explicit VariantMatcher(::testing::Matcher<const T&> matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6641 |
: matcher_(std::move(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6642 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6643 |
template <typename Variant> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6644 |
bool MatchAndExplain(const Variant& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6645 |
::testing::MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6646 |
using std::get; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6647 |
if (!listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6648 |
return holds_alternative<T>(value) && matcher_.Matches(get<T>(value)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6649 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6650 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6651 |
if (!holds_alternative<T>(value)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6652 |
*listener << "whose value is not of type '" << GetTypeName() << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6653 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6654 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6655 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6656 |
const T& elem = get<T>(value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6657 |
StringMatchResultListener elem_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6658 |
const bool match = matcher_.MatchAndExplain(elem, &elem_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6659 |
*listener << "whose value " << PrintToString(elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6660 |
<< (match ? " matches" : " doesn't match"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6661 |
PrintIfNotEmpty(elem_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6662 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6663 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6664 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6665 |
void DescribeTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6666 |
*os << "is a variant<> with value of type '" << GetTypeName() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6667 |
<< "' and the value "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6668 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6669 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6670 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6671 |
void DescribeNegationTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6672 |
*os << "is a variant<> with value of type other than '" << GetTypeName() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6673 |
<< "' or the value "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6674 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6675 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6676 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6677 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6678 |
static std::string GetTypeName() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6679 |
#if GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6680 |
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6681 |
return internal::GetTypeName<T>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6682 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6683 |
return "the element type"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6684 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6685 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6686 |
const ::testing::Matcher<const T&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6687 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6688 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6689 |
} // namespace variant_matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6690 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6691 |
namespace any_cast_matcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6692 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6693 |
// Overloads to allow AnyCastMatcher to do proper ADL lookup. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6694 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6695 |
void any_cast() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6696 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6697 |
// Implements a matcher that any_casts the value. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6698 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6699 |
class AnyCastMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6700 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6701 |
explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6702 |
: matcher_(matcher) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6703 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6704 |
template <typename AnyType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6705 |
bool MatchAndExplain(const AnyType& value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6706 |
::testing::MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6707 |
if (!listener->IsInterested()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6708 |
const T* ptr = any_cast<T>(&value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6709 |
return ptr != nullptr && matcher_.Matches(*ptr); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6710 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6711 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6712 |
const T* elem = any_cast<T>(&value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6713 |
if (elem == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6714 |
*listener << "whose value is not of type '" << GetTypeName() << "'"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6715 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6716 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6717 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6718 |
StringMatchResultListener elem_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6719 |
const bool match = matcher_.MatchAndExplain(*elem, &elem_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6720 |
*listener << "whose value " << PrintToString(*elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6721 |
<< (match ? " matches" : " doesn't match"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6722 |
PrintIfNotEmpty(elem_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6723 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6724 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6725 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6726 |
void DescribeTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6727 |
*os << "is an 'any' type with value of type '" << GetTypeName() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6728 |
<< "' and the value "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6729 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6730 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6731 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6732 |
void DescribeNegationTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6733 |
*os << "is an 'any' type with value of type other than '" << GetTypeName() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6734 |
<< "' or the value "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6735 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6736 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6737 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6738 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6739 |
static std::string GetTypeName() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6740 |
#if GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6741 |
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6742 |
return internal::GetTypeName<T>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6743 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6744 |
return "the element type"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6745 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6746 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6747 |
const ::testing::Matcher<const T&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6748 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6749 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6750 |
} // namespace any_cast_matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6752 |
// Implements the Args() matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6753 |
template <class ArgsTuple, size_t... k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6754 |
class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6755 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6756 |
using RawArgsTuple = typename std::decay<ArgsTuple>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6757 |
using SelectedArgs = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6758 |
std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6759 |
using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6760 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6761 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6762 |
explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6763 |
: inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6764 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6765 |
bool MatchAndExplain(ArgsTuple args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6766 |
MatchResultListener* listener) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6767 |
// Workaround spurious C4100 on MSVC<=15.7 when k is empty. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6768 |
(void)args; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6769 |
const SelectedArgs& selected_args = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6770 |
std::forward_as_tuple(std::get<k>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6771 |
if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6772 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6773 |
PrintIndices(listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6774 |
*listener << "are " << PrintToString(selected_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6775 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6776 |
StringMatchResultListener inner_listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6777 |
const bool match = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6778 |
inner_matcher_.MatchAndExplain(selected_args, &inner_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6779 |
PrintIfNotEmpty(inner_listener.str(), listener->stream()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6780 |
return match; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6781 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6782 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6783 |
void DescribeTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6784 |
*os << "are a tuple "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6785 |
PrintIndices(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6786 |
inner_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6787 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6788 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6789 |
void DescribeNegationTo(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6790 |
*os << "are a tuple "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6791 |
PrintIndices(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6792 |
inner_matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6793 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6794 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6795 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6796 |
// Prints the indices of the selected fields. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6797 |
static void PrintIndices(::std::ostream* os) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6798 |
*os << "whose fields ("; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6799 |
const char* sep = ""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6800 |
// Workaround spurious C4189 on MSVC<=15.7 when k is empty. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6801 |
(void)sep; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6802 |
const char* dummy[] = {"", (*os << sep << "#" << k, sep = ", ")...}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6803 |
(void)dummy; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6804 |
*os << ") "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6805 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6806 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6807 |
MonomorphicInnerMatcher inner_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6808 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6809 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6810 |
template <class InnerMatcher, size_t... k> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6811 |
class ArgsMatcher { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6812 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6813 |
explicit ArgsMatcher(InnerMatcher inner_matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6814 |
: inner_matcher_(std::move(inner_matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6815 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6816 |
template <typename ArgsTuple> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6817 |
operator Matcher<ArgsTuple>() const { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6818 |
return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6819 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6820 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6821 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6822 |
InnerMatcher inner_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6823 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6824 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6825 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6827 |
// ElementsAreArray(iterator_first, iterator_last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6828 |
// ElementsAreArray(pointer, count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6829 |
// ElementsAreArray(array) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6830 |
// ElementsAreArray(container) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6831 |
// ElementsAreArray({ e1, e2, ..., en }) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6832 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6833 |
// The ElementsAreArray() functions are like ElementsAre(...), except |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6834 |
// that they are given a homogeneous sequence rather than taking each |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6835 |
// element as a function argument. The sequence can be specified as an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6836 |
// array, a pointer and count, a vector, an initializer list, or an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6837 |
// STL iterator range. In each of these cases, the underlying sequence |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6838 |
// can be either a sequence of values or a sequence of matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6839 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6840 |
// All forms of ElementsAreArray() make a copy of the input matcher sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6841 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6842 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6843 |
inline internal::ElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6844 |
typename ::std::iterator_traits<Iter>::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6845 |
ElementsAreArray(Iter first, Iter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6846 |
typedef typename ::std::iterator_traits<Iter>::value_type T; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6847 |
return internal::ElementsAreArrayMatcher<T>(first, last); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6848 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6849 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6850 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6851 |
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6852 |
const T* pointer, size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6853 |
return ElementsAreArray(pointer, pointer + count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6854 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6855 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6856 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6857 |
inline internal::ElementsAreArrayMatcher<T> ElementsAreArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6858 |
const T (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6859 |
return ElementsAreArray(array, N); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6860 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6861 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6862 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6863 |
inline internal::ElementsAreArrayMatcher<typename Container::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6864 |
ElementsAreArray(const Container& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6865 |
return ElementsAreArray(container.begin(), container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6866 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6867 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6868 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6869 |
inline internal::ElementsAreArrayMatcher<T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6870 |
ElementsAreArray(::std::initializer_list<T> xs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6871 |
return ElementsAreArray(xs.begin(), xs.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6872 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6873 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6874 |
// UnorderedElementsAreArray(iterator_first, iterator_last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6875 |
// UnorderedElementsAreArray(pointer, count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6876 |
// UnorderedElementsAreArray(array) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6877 |
// UnorderedElementsAreArray(container) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6878 |
// UnorderedElementsAreArray({ e1, e2, ..., en }) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6879 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6880 |
// UnorderedElementsAreArray() verifies that a bijective mapping onto a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6881 |
// collection of matchers exists. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6882 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6883 |
// The matchers can be specified as an array, a pointer and count, a container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6884 |
// an initializer list, or an STL iterator range. In each of these cases, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6885 |
// underlying matchers can be either values or matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6886 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6887 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6888 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6889 |
typename ::std::iterator_traits<Iter>::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6890 |
UnorderedElementsAreArray(Iter first, Iter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6891 |
typedef typename ::std::iterator_traits<Iter>::value_type T; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6892 |
return internal::UnorderedElementsAreArrayMatcher<T>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6893 |
internal::UnorderedMatcherRequire::ExactMatch, first, last); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6894 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6895 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6896 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6897 |
inline internal::UnorderedElementsAreArrayMatcher<T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6898 |
UnorderedElementsAreArray(const T* pointer, size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6899 |
return UnorderedElementsAreArray(pointer, pointer + count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6900 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6901 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6902 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6903 |
inline internal::UnorderedElementsAreArrayMatcher<T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6904 |
UnorderedElementsAreArray(const T (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6905 |
return UnorderedElementsAreArray(array, N); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6906 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6907 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6908 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6909 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6910 |
typename Container::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6911 |
UnorderedElementsAreArray(const Container& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6912 |
return UnorderedElementsAreArray(container.begin(), container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6913 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6914 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6915 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6916 |
inline internal::UnorderedElementsAreArrayMatcher<T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6917 |
UnorderedElementsAreArray(::std::initializer_list<T> xs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6918 |
return UnorderedElementsAreArray(xs.begin(), xs.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6919 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6920 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6921 |
// _ is a matcher that matches anything of any type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6922 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6923 |
// This definition is fine as: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6924 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6925 |
// 1. The C++ standard permits using the name _ in a namespace that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6926 |
// is not the global namespace or ::std. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6927 |
// 2. The AnythingMatcher class has no data member or constructor, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6928 |
// so it's OK to create global variables of this type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6929 |
// 3. c-style has approved of using _ in this case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6930 |
const internal::AnythingMatcher _ = {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6931 |
// Creates a matcher that matches any value of the given type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6932 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6933 |
inline Matcher<T> A() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6934 |
return _; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6935 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6936 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6937 |
// Creates a matcher that matches any value of the given type T. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6938 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6939 |
inline Matcher<T> An() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6940 |
return _; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6941 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6942 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6943 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6944 |
Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6945 |
const M& value, std::false_type /* convertible_to_matcher */, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6946 |
std::false_type /* convertible_to_T */) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6947 |
return Eq(value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6948 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6949 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6950 |
// Creates a polymorphic matcher that matches any NULL pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6951 |
inline PolymorphicMatcher<internal::IsNullMatcher > IsNull() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6952 |
return MakePolymorphicMatcher(internal::IsNullMatcher()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6953 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6954 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6955 |
// Creates a polymorphic matcher that matches any non-NULL pointer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6956 |
// This is convenient as Not(NULL) doesn't compile (the compiler |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6957 |
// thinks that that expression is comparing a pointer with an integer). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6958 |
inline PolymorphicMatcher<internal::NotNullMatcher > NotNull() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6959 |
return MakePolymorphicMatcher(internal::NotNullMatcher()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6960 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6961 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6962 |
// Creates a polymorphic matcher that matches any argument that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6963 |
// references variable x. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6964 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6965 |
inline internal::RefMatcher<T&> Ref(T& x) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6966 |
return internal::RefMatcher<T&>(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6967 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6968 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6969 |
// Creates a polymorphic matcher that matches any NaN floating point. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6970 |
inline PolymorphicMatcher<internal::IsNanMatcher> IsNan() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6971 |
return MakePolymorphicMatcher(internal::IsNanMatcher()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6972 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6973 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6974 |
// Creates a matcher that matches any double argument approximately |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6975 |
// equal to rhs, where two NANs are considered unequal. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6976 |
inline internal::FloatingEqMatcher<double> DoubleEq(double rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6977 |
return internal::FloatingEqMatcher<double>(rhs, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6978 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6979 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6980 |
// Creates a matcher that matches any double argument approximately |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6981 |
// equal to rhs, including NaN values when rhs is NaN. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6982 |
inline internal::FloatingEqMatcher<double> NanSensitiveDoubleEq(double rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6983 |
return internal::FloatingEqMatcher<double>(rhs, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6984 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6985 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6986 |
// Creates a matcher that matches any double argument approximately equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6987 |
// rhs, up to the specified max absolute error bound, where two NANs are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6988 |
// considered unequal. The max absolute error bound must be non-negative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6989 |
inline internal::FloatingEqMatcher<double> DoubleNear( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6990 |
double rhs, double max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6991 |
return internal::FloatingEqMatcher<double>(rhs, false, max_abs_error); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6992 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6993 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6994 |
// Creates a matcher that matches any double argument approximately equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6995 |
// rhs, up to the specified max absolute error bound, including NaN values when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6996 |
// rhs is NaN. The max absolute error bound must be non-negative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6997 |
inline internal::FloatingEqMatcher<double> NanSensitiveDoubleNear( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6998 |
double rhs, double max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
6999 |
return internal::FloatingEqMatcher<double>(rhs, true, max_abs_error); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7000 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7001 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7002 |
// Creates a matcher that matches any float argument approximately |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7003 |
// equal to rhs, where two NANs are considered unequal. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7004 |
inline internal::FloatingEqMatcher<float> FloatEq(float rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7005 |
return internal::FloatingEqMatcher<float>(rhs, false); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7006 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7007 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7008 |
// Creates a matcher that matches any float argument approximately |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7009 |
// equal to rhs, including NaN values when rhs is NaN. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7010 |
inline internal::FloatingEqMatcher<float> NanSensitiveFloatEq(float rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7011 |
return internal::FloatingEqMatcher<float>(rhs, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7012 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7013 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7014 |
// Creates a matcher that matches any float argument approximately equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7015 |
// rhs, up to the specified max absolute error bound, where two NANs are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7016 |
// considered unequal. The max absolute error bound must be non-negative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7017 |
inline internal::FloatingEqMatcher<float> FloatNear( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7018 |
float rhs, float max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7019 |
return internal::FloatingEqMatcher<float>(rhs, false, max_abs_error); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7020 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7021 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7022 |
// Creates a matcher that matches any float argument approximately equal to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7023 |
// rhs, up to the specified max absolute error bound, including NaN values when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7024 |
// rhs is NaN. The max absolute error bound must be non-negative. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7025 |
inline internal::FloatingEqMatcher<float> NanSensitiveFloatNear( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7026 |
float rhs, float max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7027 |
return internal::FloatingEqMatcher<float>(rhs, true, max_abs_error); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7028 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7029 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7030 |
// Creates a matcher that matches a pointer (raw or smart) that points |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7031 |
// to a value that matches inner_matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7032 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7033 |
inline internal::PointeeMatcher<InnerMatcher> Pointee( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7034 |
const InnerMatcher& inner_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7035 |
return internal::PointeeMatcher<InnerMatcher>(inner_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7036 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7037 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7038 |
#if GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7039 |
// Creates a matcher that matches a pointer or reference that matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7040 |
// inner_matcher when dynamic_cast<To> is applied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7041 |
// The result of dynamic_cast<To> is forwarded to the inner matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7042 |
// If To is a pointer and the cast fails, the inner matcher will receive NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7043 |
// If To is a reference and the cast fails, this matcher returns false |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7044 |
// immediately. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7045 |
template <typename To> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7046 |
inline PolymorphicMatcher<internal::WhenDynamicCastToMatcher<To> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7047 |
WhenDynamicCastTo(const Matcher<To>& inner_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7048 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7049 |
internal::WhenDynamicCastToMatcher<To>(inner_matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7050 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7051 |
#endif // GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7052 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7053 |
// Creates a matcher that matches an object whose given field matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7054 |
// 'matcher'. For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7055 |
// Field(&Foo::number, Ge(5)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7056 |
// matches a Foo object x if and only if x.number >= 5. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7057 |
template <typename Class, typename FieldType, typename FieldMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7058 |
inline PolymorphicMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7059 |
internal::FieldMatcher<Class, FieldType> > Field( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7060 |
FieldType Class::*field, const FieldMatcher& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7061 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7062 |
internal::FieldMatcher<Class, FieldType>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7063 |
field, MatcherCast<const FieldType&>(matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7064 |
// The call to MatcherCast() is required for supporting inner |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7065 |
// matchers of compatible types. For example, it allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7066 |
// Field(&Foo::bar, m) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7067 |
// to compile where bar is an int32 and m is a matcher for int64. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7068 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7070 |
// Same as Field() but also takes the name of the field to provide better error |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7071 |
// messages. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7072 |
template <typename Class, typename FieldType, typename FieldMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7073 |
inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7074 |
const std::string& field_name, FieldType Class::*field, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7075 |
const FieldMatcher& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7076 |
return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7077 |
field_name, field, MatcherCast<const FieldType&>(matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7078 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7079 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7080 |
// Creates a matcher that matches an object whose given property |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7081 |
// matches 'matcher'. For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7082 |
// Property(&Foo::str, StartsWith("hi")) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7083 |
// matches a Foo object x if and only if x.str() starts with "hi". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7084 |
template <typename Class, typename PropertyType, typename PropertyMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7085 |
inline PolymorphicMatcher<internal::PropertyMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7086 |
Class, PropertyType, PropertyType (Class::*)() const> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7087 |
Property(PropertyType (Class::*property)() const, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7088 |
const PropertyMatcher& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7089 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7090 |
internal::PropertyMatcher<Class, PropertyType, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7091 |
PropertyType (Class::*)() const>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7092 |
property, MatcherCast<const PropertyType&>(matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7093 |
// The call to MatcherCast() is required for supporting inner |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7094 |
// matchers of compatible types. For example, it allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7095 |
// Property(&Foo::bar, m) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7096 |
// to compile where bar() returns an int32 and m is a matcher for int64. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7097 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7098 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7099 |
// Same as Property() above, but also takes the name of the property to provide |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7100 |
// better error messages. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7101 |
template <typename Class, typename PropertyType, typename PropertyMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7102 |
inline PolymorphicMatcher<internal::PropertyMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7103 |
Class, PropertyType, PropertyType (Class::*)() const> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7104 |
Property(const std::string& property_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7105 |
PropertyType (Class::*property)() const, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7106 |
const PropertyMatcher& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7107 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7108 |
internal::PropertyMatcher<Class, PropertyType, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7109 |
PropertyType (Class::*)() const>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7110 |
property_name, property, MatcherCast<const PropertyType&>(matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7111 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7112 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7113 |
// The same as above but for reference-qualified member functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7114 |
template <typename Class, typename PropertyType, typename PropertyMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7115 |
inline PolymorphicMatcher<internal::PropertyMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7116 |
Class, PropertyType, PropertyType (Class::*)() const &> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7117 |
Property(PropertyType (Class::*property)() const &, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7118 |
const PropertyMatcher& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7119 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7120 |
internal::PropertyMatcher<Class, PropertyType, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7121 |
PropertyType (Class::*)() const&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7122 |
property, MatcherCast<const PropertyType&>(matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7123 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7124 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7125 |
// Three-argument form for reference-qualified member functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7126 |
template <typename Class, typename PropertyType, typename PropertyMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7127 |
inline PolymorphicMatcher<internal::PropertyMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7128 |
Class, PropertyType, PropertyType (Class::*)() const &> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7129 |
Property(const std::string& property_name, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7130 |
PropertyType (Class::*property)() const &, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7131 |
const PropertyMatcher& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7132 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7133 |
internal::PropertyMatcher<Class, PropertyType, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7134 |
PropertyType (Class::*)() const&>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7135 |
property_name, property, MatcherCast<const PropertyType&>(matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7136 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7137 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7138 |
// Creates a matcher that matches an object if and only if the result of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7139 |
// applying a callable to x matches 'matcher'. For example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7140 |
// ResultOf(f, StartsWith("hi")) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7141 |
// matches a Foo object x if and only if f(x) starts with "hi". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7142 |
// `callable` parameter can be a function, function pointer, or a functor. It is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7143 |
// required to keep no state affecting the results of the calls on it and make |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7144 |
// no assumptions about how many calls will be made. Any state it keeps must be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7145 |
// protected from the concurrent access. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7146 |
template <typename Callable, typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7147 |
internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7148 |
Callable callable, InnerMatcher matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7149 |
return internal::ResultOfMatcher<Callable, InnerMatcher>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7150 |
std::move(callable), std::move(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7151 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7152 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7153 |
// String matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7154 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7155 |
// Matches a string equal to str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7156 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7157 |
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7158 |
const internal::StringLike<T>& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7159 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7160 |
internal::StrEqualityMatcher<std::string>(std::string(str), true, true)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7161 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7162 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7163 |
// Matches a string not equal to str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7164 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7165 |
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7166 |
const internal::StringLike<T>& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7167 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7168 |
internal::StrEqualityMatcher<std::string>(std::string(str), false, true)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7169 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7170 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7171 |
// Matches a string equal to str, ignoring case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7172 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7173 |
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7174 |
const internal::StringLike<T>& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7175 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7176 |
internal::StrEqualityMatcher<std::string>(std::string(str), true, false)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7177 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7178 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7179 |
// Matches a string not equal to str, ignoring case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7180 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7181 |
PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7182 |
const internal::StringLike<T>& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7183 |
return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::string>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7184 |
std::string(str), false, false)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7185 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7186 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7187 |
// Creates a matcher that matches any string, std::string, or C string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7188 |
// that contains the given substring. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7189 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7190 |
PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7191 |
const internal::StringLike<T>& substring) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7192 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7193 |
internal::HasSubstrMatcher<std::string>(std::string(substring))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7194 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7195 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7196 |
// Matches a string that starts with 'prefix' (case-sensitive). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7197 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7198 |
PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7199 |
const internal::StringLike<T>& prefix) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7200 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7201 |
internal::StartsWithMatcher<std::string>(std::string(prefix))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7202 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7203 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7204 |
// Matches a string that ends with 'suffix' (case-sensitive). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7205 |
template <typename T = std::string> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7206 |
PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7207 |
const internal::StringLike<T>& suffix) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7208 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7209 |
internal::EndsWithMatcher<std::string>(std::string(suffix))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7210 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7211 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7212 |
#if GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7213 |
// Wide string matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7214 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7215 |
// Matches a string equal to str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7216 |
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7217 |
const std::wstring& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7218 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7219 |
internal::StrEqualityMatcher<std::wstring>(str, true, true)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7220 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7221 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7222 |
// Matches a string not equal to str. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7223 |
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7224 |
const std::wstring& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7225 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7226 |
internal::StrEqualityMatcher<std::wstring>(str, false, true)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7227 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7228 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7229 |
// Matches a string equal to str, ignoring case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7230 |
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7231 |
StrCaseEq(const std::wstring& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7232 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7233 |
internal::StrEqualityMatcher<std::wstring>(str, true, false)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7234 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7235 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7236 |
// Matches a string not equal to str, ignoring case. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7237 |
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7238 |
StrCaseNe(const std::wstring& str) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7239 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7240 |
internal::StrEqualityMatcher<std::wstring>(str, false, false)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7241 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7242 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7243 |
// Creates a matcher that matches any ::wstring, std::wstring, or C wide string |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7244 |
// that contains the given substring. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7245 |
inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7246 |
const std::wstring& substring) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7247 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7248 |
internal::HasSubstrMatcher<std::wstring>(substring)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7249 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7250 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7251 |
// Matches a string that starts with 'prefix' (case-sensitive). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7252 |
inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7253 |
StartsWith(const std::wstring& prefix) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7254 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7255 |
internal::StartsWithMatcher<std::wstring>(prefix)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7256 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7257 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7258 |
// Matches a string that ends with 'suffix' (case-sensitive). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7259 |
inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7260 |
const std::wstring& suffix) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7261 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7262 |
internal::EndsWithMatcher<std::wstring>(suffix)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7263 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7264 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7265 |
#endif // GTEST_HAS_STD_WSTRING |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7266 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7267 |
// Creates a polymorphic matcher that matches a 2-tuple where the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7268 |
// first field == the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7269 |
inline internal::Eq2Matcher Eq() { return internal::Eq2Matcher(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7270 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7271 |
// Creates a polymorphic matcher that matches a 2-tuple where the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7272 |
// first field >= the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7273 |
inline internal::Ge2Matcher Ge() { return internal::Ge2Matcher(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7275 |
// Creates a polymorphic matcher that matches a 2-tuple where the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7276 |
// first field > the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7277 |
inline internal::Gt2Matcher Gt() { return internal::Gt2Matcher(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7278 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7279 |
// Creates a polymorphic matcher that matches a 2-tuple where the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7280 |
// first field <= the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7281 |
inline internal::Le2Matcher Le() { return internal::Le2Matcher(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7282 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7283 |
// Creates a polymorphic matcher that matches a 2-tuple where the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7284 |
// first field < the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7285 |
inline internal::Lt2Matcher Lt() { return internal::Lt2Matcher(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7286 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7287 |
// Creates a polymorphic matcher that matches a 2-tuple where the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7288 |
// first field != the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7289 |
inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7290 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7291 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7292 |
// FloatEq(first field) matches the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7293 |
inline internal::FloatingEq2Matcher<float> FloatEq() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7294 |
return internal::FloatingEq2Matcher<float>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7295 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7296 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7297 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7298 |
// DoubleEq(first field) matches the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7299 |
inline internal::FloatingEq2Matcher<double> DoubleEq() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7300 |
return internal::FloatingEq2Matcher<double>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7301 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7302 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7303 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7304 |
// FloatEq(first field) matches the second field with NaN equality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7305 |
inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7306 |
return internal::FloatingEq2Matcher<float>(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7307 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7308 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7309 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7310 |
// DoubleEq(first field) matches the second field with NaN equality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7311 |
inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7312 |
return internal::FloatingEq2Matcher<double>(true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7313 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7314 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7315 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7316 |
// FloatNear(first field, max_abs_error) matches the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7317 |
inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7318 |
return internal::FloatingEq2Matcher<float>(max_abs_error); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7319 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7320 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7321 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7322 |
// DoubleNear(first field, max_abs_error) matches the second field. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7323 |
inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7324 |
return internal::FloatingEq2Matcher<double>(max_abs_error); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7325 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7327 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7328 |
// FloatNear(first field, max_abs_error) matches the second field with NaN |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7329 |
// equality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7330 |
inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7331 |
float max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7332 |
return internal::FloatingEq2Matcher<float>(max_abs_error, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7333 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7334 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7335 |
// Creates a polymorphic matcher that matches a 2-tuple where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7336 |
// DoubleNear(first field, max_abs_error) matches the second field with NaN |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7337 |
// equality. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7338 |
inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7339 |
double max_abs_error) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7340 |
return internal::FloatingEq2Matcher<double>(max_abs_error, true); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7341 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7342 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7343 |
// Creates a matcher that matches any value of type T that m doesn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7344 |
// match. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7345 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7346 |
inline internal::NotMatcher<InnerMatcher> Not(InnerMatcher m) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7347 |
return internal::NotMatcher<InnerMatcher>(m); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7348 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7349 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7350 |
// Returns a matcher that matches anything that satisfies the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7351 |
// predicate. The predicate can be any unary function or functor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7352 |
// whose return type can be implicitly converted to bool. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7353 |
template <typename Predicate> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7354 |
inline PolymorphicMatcher<internal::TrulyMatcher<Predicate> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7355 |
Truly(Predicate pred) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7356 |
return MakePolymorphicMatcher(internal::TrulyMatcher<Predicate>(pred)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7357 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7358 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7359 |
// Returns a matcher that matches the container size. The container must |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7360 |
// support both size() and size_type which all STL-like containers provide. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7361 |
// Note that the parameter 'size' can be a value of type size_type as well as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7362 |
// matcher. For instance: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7363 |
// EXPECT_THAT(container, SizeIs(2)); // Checks container has 2 elements. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7364 |
// EXPECT_THAT(container, SizeIs(Le(2)); // Checks container has at most 2. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7365 |
template <typename SizeMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7366 |
inline internal::SizeIsMatcher<SizeMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7367 |
SizeIs(const SizeMatcher& size_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7368 |
return internal::SizeIsMatcher<SizeMatcher>(size_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7369 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7370 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7371 |
// Returns a matcher that matches the distance between the container's begin() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7372 |
// iterator and its end() iterator, i.e. the size of the container. This matcher |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7373 |
// can be used instead of SizeIs with containers such as std::forward_list which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7374 |
// do not implement size(). The container must provide const_iterator (with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7375 |
// valid iterator_traits), begin() and end(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7376 |
template <typename DistanceMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7377 |
inline internal::BeginEndDistanceIsMatcher<DistanceMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7378 |
BeginEndDistanceIs(const DistanceMatcher& distance_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7379 |
return internal::BeginEndDistanceIsMatcher<DistanceMatcher>(distance_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7380 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7381 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7382 |
// Returns a matcher that matches an equal container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7383 |
// This matcher behaves like Eq(), but in the event of mismatch lists the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7384 |
// values that are included in one container but not the other. (Duplicate |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7385 |
// values and order differences are not explained.) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7386 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7387 |
inline PolymorphicMatcher<internal::ContainerEqMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7388 |
typename std::remove_const<Container>::type>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7389 |
ContainerEq(const Container& rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7390 |
return MakePolymorphicMatcher(internal::ContainerEqMatcher<Container>(rhs)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7391 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7392 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7393 |
// Returns a matcher that matches a container that, when sorted using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7394 |
// the given comparator, matches container_matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7395 |
template <typename Comparator, typename ContainerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7396 |
inline internal::WhenSortedByMatcher<Comparator, ContainerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7397 |
WhenSortedBy(const Comparator& comparator, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7398 |
const ContainerMatcher& container_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7399 |
return internal::WhenSortedByMatcher<Comparator, ContainerMatcher>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7400 |
comparator, container_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7401 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7403 |
// Returns a matcher that matches a container that, when sorted using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7404 |
// the < operator, matches container_matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7405 |
template <typename ContainerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7406 |
inline internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7407 |
WhenSorted(const ContainerMatcher& container_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7408 |
return |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7409 |
internal::WhenSortedByMatcher<internal::LessComparator, ContainerMatcher>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7410 |
internal::LessComparator(), container_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7411 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7412 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7413 |
// Matches an STL-style container or a native array that contains the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7414 |
// same number of elements as in rhs, where its i-th element and rhs's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7415 |
// i-th element (as a pair) satisfy the given pair matcher, for all i. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7416 |
// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7417 |
// T1&, const T2&> >, where T1 and T2 are the types of elements in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7418 |
// LHS container and the RHS container respectively. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7419 |
template <typename TupleMatcher, typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7420 |
inline internal::PointwiseMatcher<TupleMatcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7421 |
typename std::remove_const<Container>::type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7422 |
Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7423 |
return internal::PointwiseMatcher<TupleMatcher, Container>(tuple_matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7424 |
rhs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7425 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7426 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7427 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7428 |
// Supports the Pointwise(m, {a, b, c}) syntax. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7429 |
template <typename TupleMatcher, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7430 |
inline internal::PointwiseMatcher<TupleMatcher, std::vector<T> > Pointwise( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7431 |
const TupleMatcher& tuple_matcher, std::initializer_list<T> rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7432 |
return Pointwise(tuple_matcher, std::vector<T>(rhs)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7433 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7435 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7436 |
// UnorderedPointwise(pair_matcher, rhs) matches an STL-style |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7437 |
// container or a native array that contains the same number of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7438 |
// elements as in rhs, where in some permutation of the container, its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7439 |
// i-th element and rhs's i-th element (as a pair) satisfy the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7440 |
// pair matcher, for all i. Tuple2Matcher must be able to be safely |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7441 |
// cast to Matcher<std::tuple<const T1&, const T2&> >, where T1 and T2 are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7442 |
// the types of elements in the LHS container and the RHS container |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7443 |
// respectively. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7444 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7445 |
// This is like Pointwise(pair_matcher, rhs), except that the element |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7446 |
// order doesn't matter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7447 |
template <typename Tuple2Matcher, typename RhsContainer> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7448 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7449 |
typename internal::BoundSecondMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7450 |
Tuple2Matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7451 |
typename internal::StlContainerView< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7452 |
typename std::remove_const<RhsContainer>::type>::type::value_type>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7453 |
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7454 |
const RhsContainer& rhs_container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7455 |
// RhsView allows the same code to handle RhsContainer being a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7456 |
// STL-style container and it being a native C-style array. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7457 |
typedef typename internal::StlContainerView<RhsContainer> RhsView; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7458 |
typedef typename RhsView::type RhsStlContainer; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7459 |
typedef typename RhsStlContainer::value_type Second; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7460 |
const RhsStlContainer& rhs_stl_container = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7461 |
RhsView::ConstReference(rhs_container); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7462 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7463 |
// Create a matcher for each element in rhs_container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7464 |
::std::vector<internal::BoundSecondMatcher<Tuple2Matcher, Second> > matchers; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7465 |
for (typename RhsStlContainer::const_iterator it = rhs_stl_container.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7466 |
it != rhs_stl_container.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7467 |
matchers.push_back( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7468 |
internal::MatcherBindSecond(tuple2_matcher, *it)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7469 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7470 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7471 |
// Delegate the work to UnorderedElementsAreArray(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7472 |
return UnorderedElementsAreArray(matchers); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7473 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7474 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7475 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7476 |
// Supports the UnorderedPointwise(m, {a, b, c}) syntax. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7477 |
template <typename Tuple2Matcher, typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7478 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7479 |
typename internal::BoundSecondMatcher<Tuple2Matcher, T> > |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7480 |
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7481 |
std::initializer_list<T> rhs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7482 |
return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7483 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7484 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7485 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7486 |
// Matches an STL-style container or a native array that contains at |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7487 |
// least one element matching the given value or matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7488 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7489 |
// Examples: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7490 |
// ::std::set<int> page_ids; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7491 |
// page_ids.insert(3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7492 |
// page_ids.insert(1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7493 |
// EXPECT_THAT(page_ids, Contains(1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7494 |
// EXPECT_THAT(page_ids, Contains(Gt(2))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7495 |
// EXPECT_THAT(page_ids, Not(Contains(4))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7496 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7497 |
// ::std::map<int, size_t> page_lengths; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7498 |
// page_lengths[1] = 100; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7499 |
// EXPECT_THAT(page_lengths, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7500 |
// Contains(::std::pair<const int, size_t>(1, 100))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7501 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7502 |
// const char* user_ids[] = { "joe", "mike", "tom" }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7503 |
// EXPECT_THAT(user_ids, Contains(Eq(::std::string("tom")))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7504 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7505 |
inline internal::ContainsMatcher<M> Contains(M matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7506 |
return internal::ContainsMatcher<M>(matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7507 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7508 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7509 |
// IsSupersetOf(iterator_first, iterator_last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7510 |
// IsSupersetOf(pointer, count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7511 |
// IsSupersetOf(array) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7512 |
// IsSupersetOf(container) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7513 |
// IsSupersetOf({e1, e2, ..., en}) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7514 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7515 |
// IsSupersetOf() verifies that a surjective partial mapping onto a collection |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7516 |
// of matchers exists. In other words, a container matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7517 |
// IsSupersetOf({e1, ..., en}) if and only if there is a permutation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7518 |
// {y1, ..., yn} of some of the container's elements where y1 matches e1, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7519 |
// ..., and yn matches en. Obviously, the size of the container must be >= n |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7520 |
// in order to have a match. Examples: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7521 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7522 |
// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7523 |
// 1 matches Ne(0). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7524 |
// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7525 |
// both Eq(1) and Lt(2). The reason is that different matchers must be used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7526 |
// for elements in different slots of the container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7527 |
// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7528 |
// Eq(1) and (the second) 1 matches Lt(2). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7529 |
// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7530 |
// Gt(1) and 3 matches (the second) Gt(1). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7531 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7532 |
// The matchers can be specified as an array, a pointer and count, a container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7533 |
// an initializer list, or an STL iterator range. In each of these cases, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7534 |
// underlying matchers can be either values or matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7535 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7536 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7537 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7538 |
typename ::std::iterator_traits<Iter>::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7539 |
IsSupersetOf(Iter first, Iter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7540 |
typedef typename ::std::iterator_traits<Iter>::value_type T; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7541 |
return internal::UnorderedElementsAreArrayMatcher<T>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7542 |
internal::UnorderedMatcherRequire::Superset, first, last); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7543 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7544 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7545 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7546 |
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7547 |
const T* pointer, size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7548 |
return IsSupersetOf(pointer, pointer + count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7549 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7550 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7551 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7552 |
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7553 |
const T (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7554 |
return IsSupersetOf(array, N); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7555 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7556 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7557 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7558 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7559 |
typename Container::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7560 |
IsSupersetOf(const Container& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7561 |
return IsSupersetOf(container.begin(), container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7563 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7564 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7565 |
inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7566 |
::std::initializer_list<T> xs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7567 |
return IsSupersetOf(xs.begin(), xs.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7568 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7569 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7570 |
// IsSubsetOf(iterator_first, iterator_last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7571 |
// IsSubsetOf(pointer, count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7572 |
// IsSubsetOf(array) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7573 |
// IsSubsetOf(container) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7574 |
// IsSubsetOf({e1, e2, ..., en}) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7575 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7576 |
// IsSubsetOf() verifies that an injective mapping onto a collection of matchers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7577 |
// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7578 |
// only if there is a subset of matchers {m1, ..., mk} which would match the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7579 |
// container using UnorderedElementsAre. Obviously, the size of the container |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7580 |
// must be <= n in order to have a match. Examples: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7581 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7582 |
// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7583 |
// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7584 |
// matches Lt(0). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7585 |
// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7586 |
// match Gt(0). The reason is that different matchers must be used for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7587 |
// elements in different slots of the container. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7588 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7589 |
// The matchers can be specified as an array, a pointer and count, a container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7590 |
// an initializer list, or an STL iterator range. In each of these cases, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7591 |
// underlying matchers can be either values or matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7592 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7593 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7594 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7595 |
typename ::std::iterator_traits<Iter>::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7596 |
IsSubsetOf(Iter first, Iter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7597 |
typedef typename ::std::iterator_traits<Iter>::value_type T; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7598 |
return internal::UnorderedElementsAreArrayMatcher<T>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7599 |
internal::UnorderedMatcherRequire::Subset, first, last); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7600 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7601 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7602 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7603 |
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7604 |
const T* pointer, size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7605 |
return IsSubsetOf(pointer, pointer + count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7606 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7607 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7608 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7609 |
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7610 |
const T (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7611 |
return IsSubsetOf(array, N); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7612 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7613 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7614 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7615 |
inline internal::UnorderedElementsAreArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7616 |
typename Container::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7617 |
IsSubsetOf(const Container& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7618 |
return IsSubsetOf(container.begin(), container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7619 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7620 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7621 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7622 |
inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7623 |
::std::initializer_list<T> xs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7624 |
return IsSubsetOf(xs.begin(), xs.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7625 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7626 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7627 |
// Matches an STL-style container or a native array that contains only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7628 |
// elements matching the given value or matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7629 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7630 |
// Each(m) is semantically equivalent to Not(Contains(Not(m))). Only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7631 |
// the messages are different. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7632 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7633 |
// Examples: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7634 |
// ::std::set<int> page_ids; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7635 |
// // Each(m) matches an empty container, regardless of what m is. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7636 |
// EXPECT_THAT(page_ids, Each(Eq(1))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7637 |
// EXPECT_THAT(page_ids, Each(Eq(77))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7638 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7639 |
// page_ids.insert(3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7640 |
// EXPECT_THAT(page_ids, Each(Gt(0))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7641 |
// EXPECT_THAT(page_ids, Not(Each(Gt(4)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7642 |
// page_ids.insert(1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7643 |
// EXPECT_THAT(page_ids, Not(Each(Lt(2)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7644 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7645 |
// ::std::map<int, size_t> page_lengths; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7646 |
// page_lengths[1] = 100; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7647 |
// page_lengths[2] = 200; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7648 |
// page_lengths[3] = 300; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7649 |
// EXPECT_THAT(page_lengths, Not(Each(Pair(1, 100)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7650 |
// EXPECT_THAT(page_lengths, Each(Key(Le(3)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7651 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7652 |
// const char* user_ids[] = { "joe", "mike", "tom" }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7653 |
// EXPECT_THAT(user_ids, Not(Each(Eq(::std::string("tom"))))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7654 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7655 |
inline internal::EachMatcher<M> Each(M matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7656 |
return internal::EachMatcher<M>(matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7657 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7658 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7659 |
// Key(inner_matcher) matches an std::pair whose 'first' field matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7660 |
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7661 |
// std::map that contains at least one element whose key is >= 5. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7662 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7663 |
inline internal::KeyMatcher<M> Key(M inner_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7664 |
return internal::KeyMatcher<M>(inner_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7665 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7666 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7667 |
// Pair(first_matcher, second_matcher) matches a std::pair whose 'first' field |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7668 |
// matches first_matcher and whose 'second' field matches second_matcher. For |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7669 |
// example, EXPECT_THAT(map_type, ElementsAre(Pair(Ge(5), "foo"))) can be used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7670 |
// to match a std::map<int, string> that contains exactly one element whose key |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7671 |
// is >= 5 and whose value equals "foo". |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7672 |
template <typename FirstMatcher, typename SecondMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7673 |
inline internal::PairMatcher<FirstMatcher, SecondMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7674 |
Pair(FirstMatcher first_matcher, SecondMatcher second_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7675 |
return internal::PairMatcher<FirstMatcher, SecondMatcher>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7676 |
first_matcher, second_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7677 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7678 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7679 |
namespace no_adl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7680 |
// FieldsAre(matchers...) matches piecewise the fields of compatible structs. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7681 |
// These include those that support `get<I>(obj)`, and when structured bindings |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7682 |
// are enabled any class that supports them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7683 |
// In particular, `std::tuple`, `std::pair`, `std::array` and aggregate types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7684 |
template <typename... M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7685 |
internal::FieldsAreMatcher<typename std::decay<M>::type...> FieldsAre( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7686 |
M&&... matchers) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7687 |
return internal::FieldsAreMatcher<typename std::decay<M>::type...>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7688 |
std::forward<M>(matchers)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7689 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7690 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7691 |
// Creates a matcher that matches a pointer (raw or smart) that matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7692 |
// inner_matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7693 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7694 |
inline internal::PointerMatcher<InnerMatcher> Pointer( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7695 |
const InnerMatcher& inner_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7696 |
return internal::PointerMatcher<InnerMatcher>(inner_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7697 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7698 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7699 |
// Creates a matcher that matches an object that has an address that matches |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7700 |
// inner_matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7701 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7702 |
inline internal::AddressMatcher<InnerMatcher> Address( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7703 |
const InnerMatcher& inner_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7704 |
return internal::AddressMatcher<InnerMatcher>(inner_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7705 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7706 |
} // namespace no_adl |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7707 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7708 |
// Returns a predicate that is satisfied by anything that matches the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7709 |
// given matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7710 |
template <typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7711 |
inline internal::MatcherAsPredicate<M> Matches(M matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7712 |
return internal::MatcherAsPredicate<M>(matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7713 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7714 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7715 |
// Returns true if and only if the value matches the matcher. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7716 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7717 |
inline bool Value(const T& value, M matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7718 |
return testing::Matches(matcher)(value); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7719 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7720 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7721 |
// Matches the value against the given matcher and explains the match |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7722 |
// result to listener. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7723 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7724 |
inline bool ExplainMatchResult( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7725 |
M matcher, const T& value, MatchResultListener* listener) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7726 |
return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7727 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7728 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7729 |
// Returns a string representation of the given matcher. Useful for description |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7730 |
// strings of matchers defined using MATCHER_P* macros that accept matchers as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7731 |
// their arguments. For example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7732 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7733 |
// MATCHER_P(XAndYThat, matcher, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7734 |
// "X that " + DescribeMatcher<int>(matcher, negation) + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7735 |
// " and Y that " + DescribeMatcher<double>(matcher, negation)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7736 |
// return ExplainMatchResult(matcher, arg.x(), result_listener) && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7737 |
// ExplainMatchResult(matcher, arg.y(), result_listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7738 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7739 |
template <typename T, typename M> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7740 |
std::string DescribeMatcher(const M& matcher, bool negation = false) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7741 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7742 |
Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7743 |
if (negation) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7744 |
monomorphic_matcher.DescribeNegationTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7745 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7746 |
monomorphic_matcher.DescribeTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7747 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7748 |
return ss.str(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7749 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7750 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7751 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7752 |
internal::ElementsAreMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7753 |
std::tuple<typename std::decay<const Args&>::type...>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7754 |
ElementsAre(const Args&... matchers) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7755 |
return internal::ElementsAreMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7756 |
std::tuple<typename std::decay<const Args&>::type...>>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7757 |
std::make_tuple(matchers...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7758 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7759 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7760 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7761 |
internal::UnorderedElementsAreMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7762 |
std::tuple<typename std::decay<const Args&>::type...>> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7763 |
UnorderedElementsAre(const Args&... matchers) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7764 |
return internal::UnorderedElementsAreMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7765 |
std::tuple<typename std::decay<const Args&>::type...>>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7766 |
std::make_tuple(matchers...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7767 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7768 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7769 |
// Define variadic matcher versions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7770 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7771 |
internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7772 |
const Args&... matchers) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7773 |
return internal::AllOfMatcher<typename std::decay<const Args&>::type...>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7774 |
matchers...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7775 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7776 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7777 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7778 |
internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7779 |
const Args&... matchers) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7780 |
return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7781 |
matchers...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7782 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7783 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7784 |
// AnyOfArray(array) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7785 |
// AnyOfArray(pointer, count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7786 |
// AnyOfArray(container) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7787 |
// AnyOfArray({ e1, e2, ..., en }) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7788 |
// AnyOfArray(iterator_first, iterator_last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7789 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7790 |
// AnyOfArray() verifies whether a given value matches any member of a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7791 |
// collection of matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7792 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7793 |
// AllOfArray(array) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7794 |
// AllOfArray(pointer, count) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7795 |
// AllOfArray(container) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7796 |
// AllOfArray({ e1, e2, ..., en }) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7797 |
// AllOfArray(iterator_first, iterator_last) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7798 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7799 |
// AllOfArray() verifies whether a given value matches all members of a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7800 |
// collection of matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7801 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7802 |
// The matchers can be specified as an array, a pointer and count, a container, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7803 |
// an initializer list, or an STL iterator range. In each of these cases, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7804 |
// underlying matchers can be either values or matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7805 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7806 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7807 |
inline internal::AnyOfArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7808 |
typename ::std::iterator_traits<Iter>::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7809 |
AnyOfArray(Iter first, Iter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7810 |
return internal::AnyOfArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7811 |
typename ::std::iterator_traits<Iter>::value_type>(first, last); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7812 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7813 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7814 |
template <typename Iter> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7815 |
inline internal::AllOfArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7816 |
typename ::std::iterator_traits<Iter>::value_type> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7817 |
AllOfArray(Iter first, Iter last) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7818 |
return internal::AllOfArrayMatcher< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7819 |
typename ::std::iterator_traits<Iter>::value_type>(first, last); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7820 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7821 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7822 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7823 |
inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7824 |
return AnyOfArray(ptr, ptr + count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7825 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7827 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7828 |
inline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7829 |
return AllOfArray(ptr, ptr + count); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7830 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7831 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7832 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7833 |
inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7834 |
return AnyOfArray(array, N); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7835 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7836 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7837 |
template <typename T, size_t N> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7838 |
inline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7839 |
return AllOfArray(array, N); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7840 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7841 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7842 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7843 |
inline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7844 |
const Container& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7845 |
return AnyOfArray(container.begin(), container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7846 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7847 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7848 |
template <typename Container> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7849 |
inline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7850 |
const Container& container) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7851 |
return AllOfArray(container.begin(), container.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7852 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7853 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7854 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7855 |
inline internal::AnyOfArrayMatcher<T> AnyOfArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7856 |
::std::initializer_list<T> xs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7857 |
return AnyOfArray(xs.begin(), xs.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7858 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7860 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7861 |
inline internal::AllOfArrayMatcher<T> AllOfArray( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7862 |
::std::initializer_list<T> xs) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7863 |
return AllOfArray(xs.begin(), xs.end()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7864 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7865 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7866 |
// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7867 |
// fields of it matches a_matcher. C++ doesn't support default |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7868 |
// arguments for function templates, so we have to overload it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7869 |
template <size_t... k, typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7870 |
internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7871 |
InnerMatcher&& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7872 |
return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7873 |
std::forward<InnerMatcher>(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7874 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7875 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7876 |
// AllArgs(m) is a synonym of m. This is useful in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7877 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7878 |
// EXPECT_CALL(foo, Bar(_, _)).With(AllArgs(Eq())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7879 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7880 |
// which is easier to read than |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7881 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7882 |
// EXPECT_CALL(foo, Bar(_, _)).With(Eq()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7883 |
template <typename InnerMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7884 |
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7885 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7886 |
// Returns a matcher that matches the value of an optional<> type variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7887 |
// The matcher implementation only uses '!arg' and requires that the optional<> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7888 |
// type has a 'value_type' member type and that '*arg' is of type 'value_type' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7889 |
// and is printable using 'PrintToString'. It is compatible with |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7890 |
// std::optional/std::experimental::optional. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7891 |
// Note that to compare an optional type variable against nullopt you should |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7892 |
// use Eq(nullopt) and not Eq(Optional(nullopt)). The latter implies that the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7893 |
// optional value contains an optional itself. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7894 |
template <typename ValueMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7895 |
inline internal::OptionalMatcher<ValueMatcher> Optional( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7896 |
const ValueMatcher& value_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7897 |
return internal::OptionalMatcher<ValueMatcher>(value_matcher); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7898 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7899 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7900 |
// Returns a matcher that matches the value of a absl::any type variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7901 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7902 |
PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7903 |
const Matcher<const T&>& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7904 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7905 |
internal::any_cast_matcher::AnyCastMatcher<T>(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7906 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7907 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7908 |
// Returns a matcher that matches the value of a variant<> type variable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7909 |
// The matcher implementation uses ADL to find the holds_alternative and get |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7910 |
// functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7911 |
// It is compatible with std::variant. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7912 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7913 |
PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7914 |
const Matcher<const T&>& matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7915 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7916 |
internal::variant_matcher::VariantMatcher<T>(matcher)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7917 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7918 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7919 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7920 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7921 |
// Anything inside the `internal` namespace is internal to the implementation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7922 |
// and must not be used in user code! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7923 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7924 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7925 |
class WithWhatMatcherImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7926 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7927 |
WithWhatMatcherImpl(Matcher<std::string> matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7928 |
: matcher_(std::move(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7930 |
void DescribeTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7931 |
*os << "contains .what() that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7932 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7933 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7934 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7935 |
void DescribeNegationTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7936 |
*os << "contains .what() that does not "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7937 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7938 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7939 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7940 |
template <typename Err> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7941 |
bool MatchAndExplain(const Err& err, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7942 |
*listener << "which contains .what() that "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7943 |
return matcher_.MatchAndExplain(err.what(), listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7944 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7945 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7946 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7947 |
const Matcher<std::string> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7948 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7949 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7950 |
inline PolymorphicMatcher<WithWhatMatcherImpl> WithWhat( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7951 |
Matcher<std::string> m) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7952 |
return MakePolymorphicMatcher(WithWhatMatcherImpl(std::move(m))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7953 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7954 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7955 |
template <typename Err> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7956 |
class ExceptionMatcherImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7957 |
class NeverThrown { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7958 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7959 |
const char* what() const noexcept { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7960 |
return "this exception should never be thrown"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7961 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7962 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7963 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7964 |
// If the matchee raises an exception of a wrong type, we'd like to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7965 |
// catch it and print its message and type. To do that, we add an additional |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7966 |
// catch clause: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7967 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7968 |
// try { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7969 |
// catch (const Err&) { /* an expected exception */ } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7970 |
// catch (const std::exception&) { /* exception of a wrong type */ } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7971 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7972 |
// However, if the `Err` itself is `std::exception`, we'd end up with two |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7973 |
// identical `catch` clauses: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7974 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7975 |
// try { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7976 |
// catch (const std::exception&) { /* an expected exception */ } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7977 |
// catch (const std::exception&) { /* exception of a wrong type */ } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7978 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7979 |
// This can cause a warning or an error in some compilers. To resolve |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7980 |
// the issue, we use a fake error type whenever `Err` is `std::exception`: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7981 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7982 |
// try { ... } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7983 |
// catch (const std::exception&) { /* an expected exception */ } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7984 |
// catch (const NeverThrown&) { /* exception of a wrong type */ } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7985 |
using DefaultExceptionType = typename std::conditional< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7986 |
std::is_same<typename std::remove_cv< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7987 |
typename std::remove_reference<Err>::type>::type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7988 |
std::exception>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7989 |
const NeverThrown&, const std::exception&>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7990 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7991 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7992 |
ExceptionMatcherImpl(Matcher<const Err&> matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7993 |
: matcher_(std::move(matcher)) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7994 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7995 |
void DescribeTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7996 |
*os << "throws an exception which is a " << GetTypeName<Err>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7997 |
*os << " which "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7998 |
matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
7999 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8000 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8001 |
void DescribeNegationTo(std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8002 |
*os << "throws an exception which is not a " << GetTypeName<Err>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8003 |
*os << " which "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8004 |
matcher_.DescribeNegationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8005 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8006 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8007 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8008 |
bool MatchAndExplain(T&& x, MatchResultListener* listener) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8009 |
try { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8010 |
(void)(std::forward<T>(x)()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8011 |
} catch (const Err& err) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8012 |
*listener << "throws an exception which is a " << GetTypeName<Err>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8013 |
*listener << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8014 |
return matcher_.MatchAndExplain(err, listener); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8015 |
} catch (DefaultExceptionType err) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8016 |
#if GTEST_HAS_RTTI |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8017 |
*listener << "throws an exception of type " << GetTypeName(typeid(err)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8018 |
*listener << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8019 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8020 |
*listener << "throws an std::exception-derived type "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8021 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8022 |
*listener << "with description \"" << err.what() << "\""; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8023 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8024 |
} catch (...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8025 |
*listener << "throws an exception of an unknown type"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8026 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8027 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8028 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8029 |
*listener << "does not throw any exception"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8030 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8031 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8032 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8033 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8034 |
const Matcher<const Err&> matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8035 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8036 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8037 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8038 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8039 |
// Throws() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8040 |
// Throws(exceptionMatcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8041 |
// ThrowsMessage(messageMatcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8042 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8043 |
// This matcher accepts a callable and verifies that when invoked, it throws |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8044 |
// an exception with the given type and properties. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8045 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8046 |
// Examples: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8047 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8048 |
// EXPECT_THAT( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8049 |
// []() { throw std::runtime_error("message"); }, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8050 |
// Throws<std::runtime_error>()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8051 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8052 |
// EXPECT_THAT( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8053 |
// []() { throw std::runtime_error("message"); }, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8054 |
// ThrowsMessage<std::runtime_error>(HasSubstr("message"))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8055 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8056 |
// EXPECT_THAT( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8057 |
// []() { throw std::runtime_error("message"); }, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8058 |
// Throws<std::runtime_error>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8059 |
// Property(&std::runtime_error::what, HasSubstr("message")))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8060 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8061 |
template <typename Err> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8062 |
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8063 |
return MakePolymorphicMatcher( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8064 |
internal::ExceptionMatcherImpl<Err>(A<const Err&>())); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8065 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8066 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8067 |
template <typename Err, typename ExceptionMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8068 |
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> Throws( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8069 |
const ExceptionMatcher& exception_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8070 |
// Using matcher cast allows users to pass a matcher of a more broad type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8071 |
// For example user may want to pass Matcher<std::exception> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8072 |
// to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8073 |
return MakePolymorphicMatcher(internal::ExceptionMatcherImpl<Err>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8074 |
SafeMatcherCast<const Err&>(exception_matcher))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8075 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8076 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8077 |
template <typename Err, typename MessageMatcher> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8078 |
PolymorphicMatcher<internal::ExceptionMatcherImpl<Err>> ThrowsMessage( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8079 |
MessageMatcher&& message_matcher) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8080 |
static_assert(std::is_base_of<std::exception, Err>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8081 |
"expected an std::exception-derived type"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8082 |
return Throws<Err>(internal::WithWhat( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8083 |
MatcherCast<std::string>(std::forward<MessageMatcher>(message_matcher)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8084 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8085 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8086 |
#endif // GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8087 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8088 |
// These macros allow using matchers to check values in Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8089 |
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8090 |
// succeed if and only if the value matches the matcher. If the assertion |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8091 |
// fails, the value and the description of the matcher will be printed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8092 |
#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8093 |
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8094 |
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8095 |
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8096 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8097 |
// MATCHER* macroses itself are listed below. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8098 |
#define MATCHER(name, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8099 |
class name##Matcher \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8100 |
: public ::testing::internal::MatcherBaseImpl<name##Matcher> { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8101 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8102 |
template <typename arg_type> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8103 |
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8104 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8105 |
gmock_Impl() {} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8106 |
bool MatchAndExplain( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8107 |
const arg_type& arg, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8108 |
::testing::MatchResultListener* result_listener) const override; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8109 |
void DescribeTo(::std::ostream* gmock_os) const override { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8110 |
*gmock_os << FormatDescription(false); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8111 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8112 |
void DescribeNegationTo(::std::ostream* gmock_os) const override { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8113 |
*gmock_os << FormatDescription(true); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8114 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8115 |
\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8116 |
private: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8117 |
::std::string FormatDescription(bool negation) const { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8118 |
::std::string gmock_description = (description); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8119 |
if (!gmock_description.empty()) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8120 |
return gmock_description; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8121 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8122 |
return ::testing::internal::FormatMatcherDescription(negation, #name, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8123 |
{}); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8124 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8125 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8126 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8127 |
GTEST_ATTRIBUTE_UNUSED_ inline name##Matcher name() { return {}; } \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8128 |
template <typename arg_type> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8129 |
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8130 |
const arg_type& arg, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8131 |
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8132 |
const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8133 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8134 |
#define MATCHER_P(name, p0, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8135 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (p0)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8136 |
#define MATCHER_P2(name, p0, p1, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8137 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (p0, p1)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8138 |
#define MATCHER_P3(name, p0, p1, p2, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8139 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (p0, p1, p2)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8140 |
#define MATCHER_P4(name, p0, p1, p2, p3, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8141 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, (p0, p1, p2, p3)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8142 |
#define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8143 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8144 |
(p0, p1, p2, p3, p4)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8145 |
#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8146 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8147 |
(p0, p1, p2, p3, p4, p5)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8148 |
#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8149 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8150 |
(p0, p1, p2, p3, p4, p5, p6)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8151 |
#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8152 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8153 |
(p0, p1, p2, p3, p4, p5, p6, p7)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8154 |
#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8155 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8156 |
(p0, p1, p2, p3, p4, p5, p6, p7, p8)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8157 |
#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8158 |
GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8159 |
(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8160 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8161 |
#define GMOCK_INTERNAL_MATCHER(name, full_name, description, args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8162 |
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8163 |
class full_name : public ::testing::internal::MatcherBaseImpl< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8164 |
full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>> { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8165 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8166 |
using full_name::MatcherBaseImpl::MatcherBaseImpl; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8167 |
template <typename arg_type> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8168 |
class gmock_Impl : public ::testing::MatcherInterface<const arg_type&> { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8169 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8170 |
explicit gmock_Impl(GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8171 |
: GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) {} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8172 |
bool MatchAndExplain( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8173 |
const arg_type& arg, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8174 |
::testing::MatchResultListener* result_listener) const override; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8175 |
void DescribeTo(::std::ostream* gmock_os) const override { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8176 |
*gmock_os << FormatDescription(false); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8177 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8178 |
void DescribeNegationTo(::std::ostream* gmock_os) const override { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8179 |
*gmock_os << FormatDescription(true); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8180 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8181 |
GMOCK_INTERNAL_MATCHER_MEMBERS(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8182 |
\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8183 |
private: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8184 |
::std::string FormatDescription(bool negation) const { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8185 |
::std::string gmock_description = (description); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8186 |
if (!gmock_description.empty()) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8187 |
return gmock_description; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8188 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8189 |
return ::testing::internal::FormatMatcherDescription( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8190 |
negation, #name, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8191 |
::testing::internal::UniversalTersePrintTupleFieldsToStrings( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8192 |
::std::tuple<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8193 |
GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8194 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8195 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8196 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8197 |
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8198 |
inline full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)> name( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8199 |
GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args)) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8200 |
return full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8201 |
GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args)); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8202 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8203 |
template <GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8204 |
template <typename arg_type> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8205 |
bool full_name<GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args)>::gmock_Impl< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8206 |
arg_type>::MatchAndExplain(const arg_type& arg, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8207 |
::testing::MatchResultListener* \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8208 |
result_listener GTEST_ATTRIBUTE_UNUSED_) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8209 |
const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8210 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8211 |
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAMS(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8212 |
GMOCK_PP_TAIL( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8213 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM, , args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8214 |
#define GMOCK_INTERNAL_MATCHER_TEMPLATE_PARAM(i_unused, data_unused, arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8215 |
, typename arg##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8216 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8217 |
#define GMOCK_INTERNAL_MATCHER_TYPE_PARAMS(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8218 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_TYPE_PARAM, , args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8219 |
#define GMOCK_INTERNAL_MATCHER_TYPE_PARAM(i_unused, data_unused, arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8220 |
, arg##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8221 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8222 |
#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARGS(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8223 |
GMOCK_PP_TAIL(dummy_first GMOCK_PP_FOR_EACH( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8224 |
GMOCK_INTERNAL_MATCHER_FUNCTION_ARG, , args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8225 |
#define GMOCK_INTERNAL_MATCHER_FUNCTION_ARG(i, data_unused, arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8226 |
, arg##_type gmock_p##i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8227 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8228 |
#define GMOCK_INTERNAL_MATCHER_FORWARD_ARGS(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8229 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_FORWARD_ARG, , args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8230 |
#define GMOCK_INTERNAL_MATCHER_FORWARD_ARG(i, data_unused, arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8231 |
, arg(::std::forward<arg##_type>(gmock_p##i)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8232 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8233 |
#define GMOCK_INTERNAL_MATCHER_MEMBERS(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8234 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER, , args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8235 |
#define GMOCK_INTERNAL_MATCHER_MEMBER(i_unused, data_unused, arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8236 |
const arg##_type arg; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8237 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8238 |
#define GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8239 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_MEMBER_USAGE, , args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8240 |
#define GMOCK_INTERNAL_MATCHER_MEMBER_USAGE(i_unused, data_unused, arg) , arg |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8241 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8242 |
#define GMOCK_INTERNAL_MATCHER_ARGS_USAGE(args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8243 |
GMOCK_PP_TAIL(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_MATCHER_ARG_USAGE, , args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8244 |
#define GMOCK_INTERNAL_MATCHER_ARG_USAGE(i, data_unused, arg_unused) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8245 |
, gmock_p##i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8246 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8247 |
// To prevent ADL on certain functions we put them on a separate namespace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8248 |
using namespace no_adl; // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8249 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8250 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8251 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8252 |
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8254 |
// Include any custom callback matchers added by the local installation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8255 |
// We must include this header at the end to make sure it can use the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8256 |
// declarations from this file. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8257 |
// Copyright 2015, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8258 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8259 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8260 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8261 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8262 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8263 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8264 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8265 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8266 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8267 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8268 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8269 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8270 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8271 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8272 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8273 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8274 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8275 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8276 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8277 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8278 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8279 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8280 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8281 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8282 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8283 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8284 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8285 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8286 |
// Injection point for custom user configurations. See README for details |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8287 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8288 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8290 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8291 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8292 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8294 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8295 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8296 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8297 |
# include <stdexcept> // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8298 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8299 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8300 |
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8301 |
/* class A needs to have dll-interface to be used by clients of class B */) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8302 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8303 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8304 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8305 |
// An abstract handle of an expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8306 |
class Expectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8307 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8308 |
// A set of expectation handles. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8309 |
class ExpectationSet; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8311 |
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8312 |
// and MUST NOT BE USED IN USER CODE!!! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8313 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8314 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8315 |
// Implements a mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8316 |
template <typename F> class FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8317 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8318 |
// Base class for expectations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8319 |
class ExpectationBase; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8320 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8321 |
// Implements an expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8322 |
template <typename F> class TypedExpectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8323 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8324 |
// Helper class for testing the Expectation class template. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8325 |
class ExpectationTester; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8327 |
// Helper classes for implementing NiceMock, StrictMock, and NaggyMock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8328 |
template <typename MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8329 |
class NiceMockImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8330 |
template <typename MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8331 |
class StrictMockImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8332 |
template <typename MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8333 |
class NaggyMockImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8334 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8335 |
// Protects the mock object registry (in class Mock), all function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8336 |
// mockers, and all expectations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8337 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8338 |
// The reason we don't use more fine-grained protection is: when a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8339 |
// mock function Foo() is called, it needs to consult its expectations |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8340 |
// to see which one should be picked. If another thread is allowed to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8341 |
// call a mock function (either Foo() or a different one) at the same |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8342 |
// time, it could affect the "retired" attributes of Foo()'s |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8343 |
// expectations when InSequence() is used, and thus affect which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8344 |
// expectation gets picked. Therefore, we sequence all mock function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8345 |
// calls to ensure the integrity of the mock objects' states. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8346 |
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8347 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8348 |
// Untyped base class for ActionResultHolder<R>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8349 |
class UntypedActionResultHolderBase; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8350 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8351 |
// Abstract base class of FunctionMocker. This is the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8352 |
// type-agnostic part of the function mocker interface. Its pure |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8353 |
// virtual methods are implemented by FunctionMocker. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8354 |
class GTEST_API_ UntypedFunctionMockerBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8355 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8356 |
UntypedFunctionMockerBase(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8357 |
virtual ~UntypedFunctionMockerBase(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8358 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8359 |
// Verifies that all expectations on this mock function have been |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8360 |
// satisfied. Reports one or more Google Test non-fatal failures |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8361 |
// and returns false if not. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8362 |
bool VerifyAndClearExpectationsLocked() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8363 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8364 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8365 |
// Clears the ON_CALL()s set on this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8366 |
virtual void ClearDefaultActionsLocked() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8367 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8368 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8369 |
// In all of the following Untyped* functions, it's the caller's |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8370 |
// responsibility to guarantee the correctness of the arguments' |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8371 |
// types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8372 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8373 |
// Performs the default action with the given arguments and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8374 |
// the action's result. The call description string will be used in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8375 |
// the error message to describe the call in the case the default |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8376 |
// action fails. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8377 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8378 |
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8379 |
void* untyped_args, const std::string& call_description) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8381 |
// Performs the given action with the given arguments and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8382 |
// the action's result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8383 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8384 |
virtual UntypedActionResultHolderBase* UntypedPerformAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8385 |
const void* untyped_action, void* untyped_args) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8386 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8387 |
// Writes a message that the call is uninteresting (i.e. neither |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8388 |
// explicitly expected nor explicitly unexpected) to the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8389 |
// ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8390 |
virtual void UntypedDescribeUninterestingCall( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8391 |
const void* untyped_args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8392 |
::std::ostream* os) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8393 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8394 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8395 |
// Returns the expectation that matches the given function arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8396 |
// (or NULL is there's no match); when a match is found, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8397 |
// untyped_action is set to point to the action that should be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8398 |
// performed (or NULL if the action is "do default"), and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8399 |
// is_excessive is modified to indicate whether the call exceeds the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8400 |
// expected number. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8401 |
virtual const ExpectationBase* UntypedFindMatchingExpectation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8402 |
const void* untyped_args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8403 |
const void** untyped_action, bool* is_excessive, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8404 |
::std::ostream* what, ::std::ostream* why) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8405 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8406 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8407 |
// Prints the given function arguments to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8408 |
virtual void UntypedPrintArgs(const void* untyped_args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8409 |
::std::ostream* os) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8410 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8411 |
// Sets the mock object this mock method belongs to, and registers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8412 |
// this information in the global mock registry. Will be called |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8413 |
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8414 |
// method. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8415 |
void RegisterOwner(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8416 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8417 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8418 |
// Sets the mock object this mock method belongs to, and sets the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8419 |
// name of the mock function. Will be called upon each invocation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8420 |
// of this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8421 |
void SetOwnerAndName(const void* mock_obj, const char* name) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8422 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8423 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8424 |
// Returns the mock object this mock method belongs to. Must be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8425 |
// called after RegisterOwner() or SetOwnerAndName() has been |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8426 |
// called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8427 |
const void* MockObject() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8428 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8429 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8430 |
// Returns the name of this mock method. Must be called after |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8431 |
// SetOwnerAndName() has been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8432 |
const char* Name() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8433 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8435 |
// Returns the result of invoking this mock function with the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8436 |
// arguments. This function can be safely called from multiple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8437 |
// threads concurrently. The caller is responsible for deleting the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8438 |
// result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8439 |
UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8440 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8441 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8442 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8443 |
typedef std::vector<const void*> UntypedOnCallSpecs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8445 |
using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8446 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8447 |
// Returns an Expectation object that references and co-owns exp, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8448 |
// which must be an expectation on this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8449 |
Expectation GetHandleOf(ExpectationBase* exp); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8450 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8451 |
// Address of the mock object this mock method belongs to. Only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8452 |
// valid after this mock method has been called or |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8453 |
// ON_CALL/EXPECT_CALL has been invoked on it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8454 |
const void* mock_obj_; // Protected by g_gmock_mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8455 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8456 |
// Name of the function being mocked. Only valid after this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8457 |
// method has been called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8458 |
const char* name_; // Protected by g_gmock_mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8459 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8460 |
// All default action specs for this function mocker. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8461 |
UntypedOnCallSpecs untyped_on_call_specs_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8462 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8463 |
// All expectations for this function mocker. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8464 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8465 |
// It's undefined behavior to interleave expectations (EXPECT_CALLs |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8466 |
// or ON_CALLs) and mock function calls. Also, the order of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8467 |
// expectations is important. Therefore it's a logic race condition |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8468 |
// to read/write untyped_expectations_ concurrently. In order for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8469 |
// tools like tsan to catch concurrent read/write accesses to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8470 |
// untyped_expectations, we deliberately leave accesses to it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8471 |
// unprotected. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8472 |
UntypedExpectations untyped_expectations_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8473 |
}; // class UntypedFunctionMockerBase |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8474 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8475 |
// Untyped base class for OnCallSpec<F>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8476 |
class UntypedOnCallSpecBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8477 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8478 |
// The arguments are the location of the ON_CALL() statement. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8479 |
UntypedOnCallSpecBase(const char* a_file, int a_line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8480 |
: file_(a_file), line_(a_line), last_clause_(kNone) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8481 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8482 |
// Where in the source file was the default action spec defined? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8483 |
const char* file() const { return file_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8484 |
int line() const { return line_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8485 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8486 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8487 |
// Gives each clause in the ON_CALL() statement a name. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8488 |
enum Clause { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8489 |
// Do not change the order of the enum members! The run-time |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8490 |
// syntax checking relies on it. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8491 |
kNone, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8492 |
kWith, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8493 |
kWillByDefault |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8494 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8495 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8496 |
// Asserts that the ON_CALL() statement has a certain property. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8497 |
void AssertSpecProperty(bool property, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8498 |
const std::string& failure_message) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8499 |
Assert(property, file_, line_, failure_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8500 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8501 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8502 |
// Expects that the ON_CALL() statement has a certain property. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8503 |
void ExpectSpecProperty(bool property, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8504 |
const std::string& failure_message) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8505 |
Expect(property, file_, line_, failure_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8506 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8507 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8508 |
const char* file_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8509 |
int line_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8510 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8511 |
// The last clause in the ON_CALL() statement as seen so far. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8512 |
// Initially kNone and changes as the statement is parsed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8513 |
Clause last_clause_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8514 |
}; // class UntypedOnCallSpecBase |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8515 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8516 |
// This template class implements an ON_CALL spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8517 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8518 |
class OnCallSpec : public UntypedOnCallSpecBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8519 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8520 |
typedef typename Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8521 |
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8522 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8523 |
// Constructs an OnCallSpec object from the information inside |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8524 |
// the parenthesis of an ON_CALL() statement. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8525 |
OnCallSpec(const char* a_file, int a_line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8526 |
const ArgumentMatcherTuple& matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8527 |
: UntypedOnCallSpecBase(a_file, a_line), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8528 |
matchers_(matchers), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8529 |
// By default, extra_matcher_ should match anything. However, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8530 |
// we cannot initialize it with _ as that causes ambiguity between |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8531 |
// Matcher's copy and move constructor for some argument types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8532 |
extra_matcher_(A<const ArgumentTuple&>()) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8533 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8534 |
// Implements the .With() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8535 |
OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8536 |
// Makes sure this is called at most once. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8537 |
ExpectSpecProperty(last_clause_ < kWith, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8538 |
".With() cannot appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8539 |
"more than once in an ON_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8540 |
last_clause_ = kWith; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8541 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8542 |
extra_matcher_ = m; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8543 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8544 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8545 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8546 |
// Implements the .WillByDefault() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8547 |
OnCallSpec& WillByDefault(const Action<F>& action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8548 |
ExpectSpecProperty(last_clause_ < kWillByDefault, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8549 |
".WillByDefault() must appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8550 |
"exactly once in an ON_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8551 |
last_clause_ = kWillByDefault; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8553 |
ExpectSpecProperty(!action.IsDoDefault(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8554 |
"DoDefault() cannot be used in ON_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8555 |
action_ = action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8556 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8557 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8558 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8559 |
// Returns true if and only if the given arguments match the matchers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8560 |
bool Matches(const ArgumentTuple& args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8561 |
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8563 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8564 |
// Returns the action specified by the user. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8565 |
const Action<F>& GetAction() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8566 |
AssertSpecProperty(last_clause_ == kWillByDefault, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8567 |
".WillByDefault() must appear exactly " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8568 |
"once in an ON_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8569 |
return action_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8570 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8571 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8572 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8573 |
// The information in statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8574 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8575 |
// ON_CALL(mock_object, Method(matchers)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8576 |
// .With(multi-argument-matcher) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8577 |
// .WillByDefault(action); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8578 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8579 |
// is recorded in the data members like this: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8580 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8581 |
// source file that contains the statement => file_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8582 |
// line number of the statement => line_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8583 |
// matchers => matchers_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8584 |
// multi-argument-matcher => extra_matcher_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8585 |
// action => action_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8586 |
ArgumentMatcherTuple matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8587 |
Matcher<const ArgumentTuple&> extra_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8588 |
Action<F> action_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8589 |
}; // class OnCallSpec |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8590 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8591 |
// Possible reactions on uninteresting calls. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8592 |
enum CallReaction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8593 |
kAllow, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8594 |
kWarn, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8595 |
kFail, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8596 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8597 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8598 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8599 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8600 |
// Utilities for manipulating mock objects. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8601 |
class GTEST_API_ Mock { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8602 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8603 |
// The following public methods can be called concurrently. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8604 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8605 |
// Tells Google Mock to ignore mock_obj when checking for leaked |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8606 |
// mock objects. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8607 |
static void AllowLeak(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8608 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8609 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8610 |
// Verifies and clears all expectations on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8611 |
// If the expectations aren't satisfied, generates one or more |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8612 |
// Google Test non-fatal failures and returns false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8613 |
static bool VerifyAndClearExpectations(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8614 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8615 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8616 |
// Verifies all expectations on the given mock object and clears its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8617 |
// default actions and expectations. Returns true if and only if the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8618 |
// verification was successful. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8619 |
static bool VerifyAndClear(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8620 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8621 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8622 |
// Returns whether the mock was created as a naggy mock (default) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8623 |
static bool IsNaggy(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8624 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8625 |
// Returns whether the mock was created as a nice mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8626 |
static bool IsNice(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8627 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8628 |
// Returns whether the mock was created as a strict mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8629 |
static bool IsStrict(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8630 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8631 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8632 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8633 |
friend class internal::UntypedFunctionMockerBase; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8634 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8635 |
// Needed for a function mocker to register itself (so that we know |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8636 |
// how to clear a mock object). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8637 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8638 |
friend class internal::FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8639 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8640 |
template <typename MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8641 |
friend class internal::NiceMockImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8642 |
template <typename MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8643 |
friend class internal::NaggyMockImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8644 |
template <typename MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8645 |
friend class internal::StrictMockImpl; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8646 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8647 |
// Tells Google Mock to allow uninteresting calls on the given mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8648 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8649 |
static void AllowUninterestingCalls(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8650 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8651 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8652 |
// Tells Google Mock to warn the user about uninteresting calls on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8653 |
// the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8654 |
static void WarnUninterestingCalls(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8655 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8656 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8657 |
// Tells Google Mock to fail uninteresting calls on the given mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8658 |
// object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8659 |
static void FailUninterestingCalls(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8660 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8661 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8662 |
// Tells Google Mock the given mock object is being destroyed and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8663 |
// its entry in the call-reaction table should be removed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8664 |
static void UnregisterCallReaction(const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8665 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8666 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8667 |
// Returns the reaction Google Mock will have on uninteresting calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8668 |
// made on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8669 |
static internal::CallReaction GetReactionOnUninterestingCalls( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8670 |
const void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8671 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8672 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8673 |
// Verifies that all expectations on the given mock object have been |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8674 |
// satisfied. Reports one or more Google Test non-fatal failures |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8675 |
// and returns false if not. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8676 |
static bool VerifyAndClearExpectationsLocked(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8677 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8678 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8679 |
// Clears all ON_CALL()s set on the given mock object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8680 |
static void ClearDefaultActionsLocked(void* mock_obj) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8681 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8682 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8683 |
// Registers a mock object and a mock method it owns. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8684 |
static void Register( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8685 |
const void* mock_obj, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8686 |
internal::UntypedFunctionMockerBase* mocker) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8687 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8688 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8689 |
// Tells Google Mock where in the source code mock_obj is used in an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8690 |
// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8691 |
// information helps the user identify which object it is. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8692 |
static void RegisterUseByOnCallOrExpectCall( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8693 |
const void* mock_obj, const char* file, int line) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8694 |
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8695 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8696 |
// Unregisters a mock method; removes the owning mock object from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8697 |
// the registry when the last mock method associated with it has |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8698 |
// been unregistered. This is called only in the destructor of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8699 |
// FunctionMocker. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8700 |
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8701 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8702 |
}; // class Mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8703 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8704 |
// An abstract handle of an expectation. Useful in the .After() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8705 |
// clause of EXPECT_CALL() for setting the (partial) order of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8706 |
// expectations. The syntax: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8707 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8708 |
// Expectation e1 = EXPECT_CALL(...)...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8709 |
// EXPECT_CALL(...).After(e1)...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8710 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8711 |
// sets two expectations where the latter can only be matched after |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8712 |
// the former has been satisfied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8713 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8714 |
// Notes: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8715 |
// - This class is copyable and has value semantics. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8716 |
// - Constness is shallow: a const Expectation object itself cannot |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8717 |
// be modified, but the mutable methods of the ExpectationBase |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8718 |
// object it references can be called via expectation_base(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8719 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8720 |
class GTEST_API_ Expectation { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8721 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8722 |
// Constructs a null object that doesn't reference any expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8723 |
Expectation(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8724 |
Expectation(Expectation&&) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8725 |
Expectation(const Expectation&) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8726 |
Expectation& operator=(Expectation&&) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8727 |
Expectation& operator=(const Expectation&) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8728 |
~Expectation(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8729 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8730 |
// This single-argument ctor must not be explicit, in order to support the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8731 |
// Expectation e = EXPECT_CALL(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8732 |
// syntax. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8733 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8734 |
// A TypedExpectation object stores its pre-requisites as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8735 |
// Expectation objects, and needs to call the non-const Retire() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8736 |
// method on the ExpectationBase objects they reference. Therefore |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8737 |
// Expectation must receive a *non-const* reference to the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8738 |
// ExpectationBase object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8739 |
Expectation(internal::ExpectationBase& exp); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8740 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8741 |
// The compiler-generated copy ctor and operator= work exactly as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8742 |
// intended, so we don't need to define our own. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8743 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8744 |
// Returns true if and only if rhs references the same expectation as this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8745 |
// object does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8746 |
bool operator==(const Expectation& rhs) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8747 |
return expectation_base_ == rhs.expectation_base_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8748 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8749 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8750 |
bool operator!=(const Expectation& rhs) const { return !(*this == rhs); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8751 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8752 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8753 |
friend class ExpectationSet; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8754 |
friend class Sequence; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8755 |
friend class ::testing::internal::ExpectationBase; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8756 |
friend class ::testing::internal::UntypedFunctionMockerBase; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8757 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8758 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8759 |
friend class ::testing::internal::FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8760 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8761 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8762 |
friend class ::testing::internal::TypedExpectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8763 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8764 |
// This comparator is needed for putting Expectation objects into a set. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8765 |
class Less { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8766 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8767 |
bool operator()(const Expectation& lhs, const Expectation& rhs) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8768 |
return lhs.expectation_base_.get() < rhs.expectation_base_.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8769 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8770 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8771 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8772 |
typedef ::std::set<Expectation, Less> Set; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8773 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8774 |
Expectation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8775 |
const std::shared_ptr<internal::ExpectationBase>& expectation_base); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8776 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8777 |
// Returns the expectation this object references. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8778 |
const std::shared_ptr<internal::ExpectationBase>& expectation_base() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8779 |
return expectation_base_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8780 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8781 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8782 |
// A shared_ptr that co-owns the expectation this handle references. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8783 |
std::shared_ptr<internal::ExpectationBase> expectation_base_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8784 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8785 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8786 |
// A set of expectation handles. Useful in the .After() clause of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8787 |
// EXPECT_CALL() for setting the (partial) order of expectations. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8788 |
// syntax: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8789 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8790 |
// ExpectationSet es; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8791 |
// es += EXPECT_CALL(...)...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8792 |
// es += EXPECT_CALL(...)...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8793 |
// EXPECT_CALL(...).After(es)...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8794 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8795 |
// sets three expectations where the last one can only be matched |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8796 |
// after the first two have both been satisfied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8797 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8798 |
// This class is copyable and has value semantics. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8799 |
class ExpectationSet { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8800 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8801 |
// A bidirectional iterator that can read a const element in the set. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8802 |
typedef Expectation::Set::const_iterator const_iterator; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8803 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8804 |
// An object stored in the set. This is an alias of Expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8805 |
typedef Expectation::Set::value_type value_type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8806 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8807 |
// Constructs an empty set. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8808 |
ExpectationSet() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8809 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8810 |
// This single-argument ctor must not be explicit, in order to support the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8811 |
// ExpectationSet es = EXPECT_CALL(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8812 |
// syntax. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8813 |
ExpectationSet(internal::ExpectationBase& exp) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8814 |
*this += Expectation(exp); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8815 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8816 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8817 |
// This single-argument ctor implements implicit conversion from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8818 |
// Expectation and thus must not be explicit. This allows either an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8819 |
// Expectation or an ExpectationSet to be used in .After(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8820 |
ExpectationSet(const Expectation& e) { // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8821 |
*this += e; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8822 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8823 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8824 |
// The compiler-generator ctor and operator= works exactly as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8825 |
// intended, so we don't need to define our own. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8827 |
// Returns true if and only if rhs contains the same set of Expectation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8828 |
// objects as this does. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8829 |
bool operator==(const ExpectationSet& rhs) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8830 |
return expectations_ == rhs.expectations_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8831 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8832 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8833 |
bool operator!=(const ExpectationSet& rhs) const { return !(*this == rhs); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8834 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8835 |
// Implements the syntax |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8836 |
// expectation_set += EXPECT_CALL(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8837 |
ExpectationSet& operator+=(const Expectation& e) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8838 |
expectations_.insert(e); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8839 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8840 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8841 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8842 |
int size() const { return static_cast<int>(expectations_.size()); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8843 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8844 |
const_iterator begin() const { return expectations_.begin(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8845 |
const_iterator end() const { return expectations_.end(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8846 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8847 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8848 |
Expectation::Set expectations_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8849 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8850 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8851 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8852 |
// Sequence objects are used by a user to specify the relative order |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8853 |
// in which the expectations should match. They are copyable (we rely |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8854 |
// on the compiler-defined copy constructor and assignment operator). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8855 |
class GTEST_API_ Sequence { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8856 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8857 |
// Constructs an empty sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8858 |
Sequence() : last_expectation_(new Expectation) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8859 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8860 |
// Adds an expectation to this sequence. The caller must ensure |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8861 |
// that no other thread is accessing this Sequence object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8862 |
void AddExpectation(const Expectation& expectation) const; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8863 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8864 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8865 |
// The last expectation in this sequence. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8866 |
std::shared_ptr<Expectation> last_expectation_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8867 |
}; // class Sequence |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8868 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8869 |
// An object of this type causes all EXPECT_CALL() statements |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8870 |
// encountered in its scope to be put in an anonymous sequence. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8871 |
// work is done in the constructor and destructor. You should only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8872 |
// create an InSequence object on the stack. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8873 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8874 |
// The sole purpose for this class is to support easy definition of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8875 |
// sequential expectations, e.g. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8876 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8877 |
// { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8878 |
// InSequence dummy; // The name of the object doesn't matter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8879 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8880 |
// // The following expectations must match in the order they appear. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8881 |
// EXPECT_CALL(a, Bar())...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8882 |
// EXPECT_CALL(a, Baz())...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8883 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8884 |
// EXPECT_CALL(b, Xyz())...; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8885 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8886 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8887 |
// You can create InSequence objects in multiple threads, as long as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8888 |
// they are used to affect different mock objects. The idea is that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8889 |
// each thread can create and set up its own mocks as if it's the only |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8890 |
// thread. However, for clarity of your tests we recommend you to set |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8891 |
// up mocks in the main thread unless you have a good reason not to do |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8892 |
// so. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8893 |
class GTEST_API_ InSequence { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8894 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8895 |
InSequence(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8896 |
~InSequence(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8897 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8898 |
bool sequence_created_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8899 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8900 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(InSequence); // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8901 |
} GTEST_ATTRIBUTE_UNUSED_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8902 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8903 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8904 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8905 |
// Points to the implicit sequence introduced by a living InSequence |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8906 |
// object (if any) in the current thread or NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8907 |
GTEST_API_ extern ThreadLocal<Sequence*> g_gmock_implicit_sequence; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8908 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8909 |
// Base class for implementing expectations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8910 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8911 |
// There are two reasons for having a type-agnostic base class for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8912 |
// Expectation: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8913 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8914 |
// 1. We need to store collections of expectations of different |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8915 |
// types (e.g. all pre-requisites of a particular expectation, all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8916 |
// expectations in a sequence). Therefore these expectation objects |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8917 |
// must share a common base class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8918 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8919 |
// 2. We can avoid binary code bloat by moving methods not depending |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8920 |
// on the template argument of Expectation to the base class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8921 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8922 |
// This class is internal and mustn't be used by user code directly. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8923 |
class GTEST_API_ ExpectationBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8924 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8925 |
// source_text is the EXPECT_CALL(...) source that created this Expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8926 |
ExpectationBase(const char* file, int line, const std::string& source_text); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8927 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8928 |
virtual ~ExpectationBase(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8929 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8930 |
// Where in the source file was the expectation spec defined? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8931 |
const char* file() const { return file_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8932 |
int line() const { return line_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8933 |
const char* source_text() const { return source_text_.c_str(); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8934 |
// Returns the cardinality specified in the expectation spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8935 |
const Cardinality& cardinality() const { return cardinality_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8936 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8937 |
// Describes the source file location of this expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8938 |
void DescribeLocationTo(::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8939 |
*os << FormatFileLocation(file(), line()) << " "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8940 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8941 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8942 |
// Describes how many times a function call matching this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8943 |
// expectation has occurred. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8944 |
void DescribeCallCountTo(::std::ostream* os) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8945 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8946 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8947 |
// If this mock method has an extra matcher (i.e. .With(matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8948 |
// describes it to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8949 |
virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8950 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8951 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8952 |
friend class ::testing::Expectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8953 |
friend class UntypedFunctionMockerBase; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8954 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8955 |
enum Clause { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8956 |
// Don't change the order of the enum members! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8957 |
kNone, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8958 |
kWith, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8959 |
kTimes, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8960 |
kInSequence, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8961 |
kAfter, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8962 |
kWillOnce, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8963 |
kWillRepeatedly, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8964 |
kRetiresOnSaturation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8965 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8966 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8967 |
typedef std::vector<const void*> UntypedActions; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8968 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8969 |
// Returns an Expectation object that references and co-owns this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8970 |
// expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8971 |
virtual Expectation GetHandle() = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8972 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8973 |
// Asserts that the EXPECT_CALL() statement has the given property. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8974 |
void AssertSpecProperty(bool property, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8975 |
const std::string& failure_message) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8976 |
Assert(property, file_, line_, failure_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8977 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8978 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8979 |
// Expects that the EXPECT_CALL() statement has the given property. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8980 |
void ExpectSpecProperty(bool property, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8981 |
const std::string& failure_message) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8982 |
Expect(property, file_, line_, failure_message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8983 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8984 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8985 |
// Explicitly specifies the cardinality of this expectation. Used |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8986 |
// by the subclasses to implement the .Times() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8987 |
void SpecifyCardinality(const Cardinality& cardinality); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8988 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8989 |
// Returns true if and only if the user specified the cardinality |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8990 |
// explicitly using a .Times(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8991 |
bool cardinality_specified() const { return cardinality_specified_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8992 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8993 |
// Sets the cardinality of this expectation spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8994 |
void set_cardinality(const Cardinality& a_cardinality) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8995 |
cardinality_ = a_cardinality; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8996 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8997 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8998 |
// The following group of methods should only be called after the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
8999 |
// EXPECT_CALL() statement, and only when g_gmock_mutex is held by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9000 |
// the current thread. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9001 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9002 |
// Retires all pre-requisites of this expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9003 |
void RetireAllPreRequisites() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9004 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9005 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9006 |
// Returns true if and only if this expectation is retired. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9007 |
bool is_retired() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9008 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9009 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9010 |
return retired_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9011 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9012 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9013 |
// Retires this expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9014 |
void Retire() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9015 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9016 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9017 |
retired_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9018 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9019 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9020 |
// Returns true if and only if this expectation is satisfied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9021 |
bool IsSatisfied() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9022 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9023 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9024 |
return cardinality().IsSatisfiedByCallCount(call_count_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9025 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9026 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9027 |
// Returns true if and only if this expectation is saturated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9028 |
bool IsSaturated() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9029 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9030 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9031 |
return cardinality().IsSaturatedByCallCount(call_count_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9032 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9033 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9034 |
// Returns true if and only if this expectation is over-saturated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9035 |
bool IsOverSaturated() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9036 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9037 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9038 |
return cardinality().IsOverSaturatedByCallCount(call_count_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9039 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9040 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9041 |
// Returns true if and only if all pre-requisites of this expectation are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9042 |
// satisfied. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9043 |
bool AllPrerequisitesAreSatisfied() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9044 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9045 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9046 |
// Adds unsatisfied pre-requisites of this expectation to 'result'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9047 |
void FindUnsatisfiedPrerequisites(ExpectationSet* result) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9048 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9049 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9050 |
// Returns the number this expectation has been invoked. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9051 |
int call_count() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9052 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9053 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9054 |
return call_count_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9055 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9056 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9057 |
// Increments the number this expectation has been invoked. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9058 |
void IncrementCallCount() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9059 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9060 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9061 |
call_count_++; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9062 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9063 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9064 |
// Checks the action count (i.e. the number of WillOnce() and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9065 |
// WillRepeatedly() clauses) against the cardinality if this hasn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9066 |
// been done before. Prints a warning if there are too many or too |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9067 |
// few actions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9068 |
void CheckActionCountIfNotDone() const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9069 |
GTEST_LOCK_EXCLUDED_(mutex_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9070 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9071 |
friend class ::testing::Sequence; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9072 |
friend class ::testing::internal::ExpectationTester; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9073 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9074 |
template <typename Function> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9075 |
friend class TypedExpectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9076 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9077 |
// Implements the .Times() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9078 |
void UntypedTimes(const Cardinality& a_cardinality); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9079 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9080 |
// This group of fields are part of the spec and won't change after |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9081 |
// an EXPECT_CALL() statement finishes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9082 |
const char* file_; // The file that contains the expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9083 |
int line_; // The line number of the expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9084 |
const std::string source_text_; // The EXPECT_CALL(...) source text. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9085 |
// True if and only if the cardinality is specified explicitly. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9086 |
bool cardinality_specified_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9087 |
Cardinality cardinality_; // The cardinality of the expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9088 |
// The immediate pre-requisites (i.e. expectations that must be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9089 |
// satisfied before this expectation can be matched) of this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9090 |
// expectation. We use std::shared_ptr in the set because we want an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9091 |
// Expectation object to be co-owned by its FunctionMocker and its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9092 |
// successors. This allows multiple mock objects to be deleted at |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9093 |
// different times. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9094 |
ExpectationSet immediate_prerequisites_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9095 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9096 |
// This group of fields are the current state of the expectation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9097 |
// and can change as the mock function is called. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9098 |
int call_count_; // How many times this expectation has been invoked. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9099 |
bool retired_; // True if and only if this expectation has retired. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9100 |
UntypedActions untyped_actions_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9101 |
bool extra_matcher_specified_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9102 |
bool repeated_action_specified_; // True if a WillRepeatedly() was specified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9103 |
bool retires_on_saturation_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9104 |
Clause last_clause_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9105 |
mutable bool action_count_checked_; // Under mutex_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9106 |
mutable Mutex mutex_; // Protects action_count_checked_. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9107 |
}; // class ExpectationBase |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9108 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9109 |
// Impements an expectation for the given function type. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9110 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9111 |
class TypedExpectation : public ExpectationBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9112 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9113 |
typedef typename Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9114 |
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9115 |
typedef typename Function<F>::Result Result; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9116 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9117 |
TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9118 |
const std::string& a_source_text, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9119 |
const ArgumentMatcherTuple& m) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9120 |
: ExpectationBase(a_file, a_line, a_source_text), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9121 |
owner_(owner), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9122 |
matchers_(m), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9123 |
// By default, extra_matcher_ should match anything. However, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9124 |
// we cannot initialize it with _ as that causes ambiguity between |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9125 |
// Matcher's copy and move constructor for some argument types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9126 |
extra_matcher_(A<const ArgumentTuple&>()), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9127 |
repeated_action_(DoDefault()) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9128 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9129 |
~TypedExpectation() override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9130 |
// Check the validity of the action count if it hasn't been done |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9131 |
// yet (for example, if the expectation was never used). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9132 |
CheckActionCountIfNotDone(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9133 |
for (UntypedActions::const_iterator it = untyped_actions_.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9134 |
it != untyped_actions_.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9135 |
delete static_cast<const Action<F>*>(*it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9136 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9137 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9138 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9139 |
// Implements the .With() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9140 |
TypedExpectation& With(const Matcher<const ArgumentTuple&>& m) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9141 |
if (last_clause_ == kWith) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9142 |
ExpectSpecProperty(false, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9143 |
".With() cannot appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9144 |
"more than once in an EXPECT_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9145 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9146 |
ExpectSpecProperty(last_clause_ < kWith, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9147 |
".With() must be the first " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9148 |
"clause in an EXPECT_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9149 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9150 |
last_clause_ = kWith; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9151 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9152 |
extra_matcher_ = m; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9153 |
extra_matcher_specified_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9154 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9155 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9156 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9157 |
// Implements the .Times() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9158 |
TypedExpectation& Times(const Cardinality& a_cardinality) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9159 |
ExpectationBase::UntypedTimes(a_cardinality); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9160 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9161 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9162 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9163 |
// Implements the .Times() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9164 |
TypedExpectation& Times(int n) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9165 |
return Times(Exactly(n)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9166 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9167 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9168 |
// Implements the .InSequence() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9169 |
TypedExpectation& InSequence(const Sequence& s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9170 |
ExpectSpecProperty(last_clause_ <= kInSequence, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9171 |
".InSequence() cannot appear after .After()," |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9172 |
" .WillOnce(), .WillRepeatedly(), or " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9173 |
".RetiresOnSaturation()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9174 |
last_clause_ = kInSequence; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9175 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9176 |
s.AddExpectation(GetHandle()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9177 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9178 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9179 |
TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9180 |
return InSequence(s1).InSequence(s2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9181 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9182 |
TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9183 |
const Sequence& s3) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9184 |
return InSequence(s1, s2).InSequence(s3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9185 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9186 |
TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9187 |
const Sequence& s3, const Sequence& s4) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9188 |
return InSequence(s1, s2, s3).InSequence(s4); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9189 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9190 |
TypedExpectation& InSequence(const Sequence& s1, const Sequence& s2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9191 |
const Sequence& s3, const Sequence& s4, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9192 |
const Sequence& s5) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9193 |
return InSequence(s1, s2, s3, s4).InSequence(s5); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9194 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9195 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9196 |
// Implements that .After() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9197 |
TypedExpectation& After(const ExpectationSet& s) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9198 |
ExpectSpecProperty(last_clause_ <= kAfter, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9199 |
".After() cannot appear after .WillOnce()," |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9200 |
" .WillRepeatedly(), or " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9201 |
".RetiresOnSaturation()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9202 |
last_clause_ = kAfter; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9203 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9204 |
for (ExpectationSet::const_iterator it = s.begin(); it != s.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9205 |
immediate_prerequisites_ += *it; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9206 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9207 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9208 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9209 |
TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9210 |
return After(s1).After(s2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9211 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9212 |
TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9213 |
const ExpectationSet& s3) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9214 |
return After(s1, s2).After(s3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9215 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9216 |
TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9217 |
const ExpectationSet& s3, const ExpectationSet& s4) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9218 |
return After(s1, s2, s3).After(s4); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9219 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9220 |
TypedExpectation& After(const ExpectationSet& s1, const ExpectationSet& s2, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9221 |
const ExpectationSet& s3, const ExpectationSet& s4, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9222 |
const ExpectationSet& s5) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9223 |
return After(s1, s2, s3, s4).After(s5); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9224 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9225 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9226 |
// Implements the .WillOnce() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9227 |
TypedExpectation& WillOnce(const Action<F>& action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9228 |
ExpectSpecProperty(last_clause_ <= kWillOnce, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9229 |
".WillOnce() cannot appear after " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9230 |
".WillRepeatedly() or .RetiresOnSaturation()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9231 |
last_clause_ = kWillOnce; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9232 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9233 |
untyped_actions_.push_back(new Action<F>(action)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9234 |
if (!cardinality_specified()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9235 |
set_cardinality(Exactly(static_cast<int>(untyped_actions_.size()))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9236 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9237 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9238 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9239 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9240 |
// Implements the .WillRepeatedly() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9241 |
TypedExpectation& WillRepeatedly(const Action<F>& action) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9242 |
if (last_clause_ == kWillRepeatedly) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9243 |
ExpectSpecProperty(false, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9244 |
".WillRepeatedly() cannot appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9245 |
"more than once in an EXPECT_CALL()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9246 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9247 |
ExpectSpecProperty(last_clause_ < kWillRepeatedly, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9248 |
".WillRepeatedly() cannot appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9249 |
"after .RetiresOnSaturation()."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9250 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9251 |
last_clause_ = kWillRepeatedly; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9252 |
repeated_action_specified_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9254 |
repeated_action_ = action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9255 |
if (!cardinality_specified()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9256 |
set_cardinality(AtLeast(static_cast<int>(untyped_actions_.size()))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9257 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9258 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9259 |
// Now that no more action clauses can be specified, we check |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9260 |
// whether their count makes sense. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9261 |
CheckActionCountIfNotDone(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9262 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9263 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9264 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9265 |
// Implements the .RetiresOnSaturation() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9266 |
TypedExpectation& RetiresOnSaturation() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9267 |
ExpectSpecProperty(last_clause_ < kRetiresOnSaturation, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9268 |
".RetiresOnSaturation() cannot appear " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9269 |
"more than once."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9270 |
last_clause_ = kRetiresOnSaturation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9271 |
retires_on_saturation_ = true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9272 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9273 |
// Now that no more action clauses can be specified, we check |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9274 |
// whether their count makes sense. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9275 |
CheckActionCountIfNotDone(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9276 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9277 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9278 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9279 |
// Returns the matchers for the arguments as specified inside the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9280 |
// EXPECT_CALL() macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9281 |
const ArgumentMatcherTuple& matchers() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9282 |
return matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9283 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9285 |
// Returns the matcher specified by the .With() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9286 |
const Matcher<const ArgumentTuple&>& extra_matcher() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9287 |
return extra_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9288 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9289 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9290 |
// Returns the action specified by the .WillRepeatedly() clause. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9291 |
const Action<F>& repeated_action() const { return repeated_action_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9292 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9293 |
// If this mock method has an extra matcher (i.e. .With(matcher)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9294 |
// describes it to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9295 |
void MaybeDescribeExtraMatcherTo(::std::ostream* os) override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9296 |
if (extra_matcher_specified_) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9297 |
*os << " Expected args: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9298 |
extra_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9299 |
*os << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9300 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9301 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9302 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9303 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9304 |
template <typename Function> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9305 |
friend class FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9306 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9307 |
// Returns an Expectation object that references and co-owns this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9308 |
// expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9309 |
Expectation GetHandle() override { return owner_->GetHandleOf(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9310 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9311 |
// The following methods will be called only after the EXPECT_CALL() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9312 |
// statement finishes and when the current thread holds |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9313 |
// g_gmock_mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9314 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9315 |
// Returns true if and only if this expectation matches the given arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9316 |
bool Matches(const ArgumentTuple& args) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9317 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9318 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9319 |
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9320 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9321 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9322 |
// Returns true if and only if this expectation should handle the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9323 |
// arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9324 |
bool ShouldHandleArguments(const ArgumentTuple& args) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9325 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9326 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9327 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9328 |
// In case the action count wasn't checked when the expectation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9329 |
// was defined (e.g. if this expectation has no WillRepeatedly() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9330 |
// or RetiresOnSaturation() clause), we check it when the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9331 |
// expectation is used for the first time. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9332 |
CheckActionCountIfNotDone(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9333 |
return !is_retired() && AllPrerequisitesAreSatisfied() && Matches(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9334 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9335 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9336 |
// Describes the result of matching the arguments against this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9337 |
// expectation to the given ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9338 |
void ExplainMatchResultTo( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9339 |
const ArgumentTuple& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9340 |
::std::ostream* os) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9341 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9342 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9343 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9344 |
if (is_retired()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9345 |
*os << " Expected: the expectation is active\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9346 |
<< " Actual: it is retired\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9347 |
} else if (!Matches(args)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9348 |
if (!TupleMatches(matchers_, args)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9349 |
ExplainMatchFailureTupleTo(matchers_, args, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9350 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9351 |
StringMatchResultListener listener; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9352 |
if (!extra_matcher_.MatchAndExplain(args, &listener)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9353 |
*os << " Expected args: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9354 |
extra_matcher_.DescribeTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9355 |
*os << "\n Actual: don't match"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9356 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9357 |
internal::PrintIfNotEmpty(listener.str(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9358 |
*os << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9359 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9360 |
} else if (!AllPrerequisitesAreSatisfied()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9361 |
*os << " Expected: all pre-requisites are satisfied\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9362 |
<< " Actual: the following immediate pre-requisites " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9363 |
<< "are not satisfied:\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9364 |
ExpectationSet unsatisfied_prereqs; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9365 |
FindUnsatisfiedPrerequisites(&unsatisfied_prereqs); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9366 |
int i = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9367 |
for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9368 |
it != unsatisfied_prereqs.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9369 |
it->expectation_base()->DescribeLocationTo(os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9370 |
*os << "pre-requisite #" << i++ << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9371 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9372 |
*os << " (end of pre-requisites)\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9373 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9374 |
// This line is here just for completeness' sake. It will never |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9375 |
// be executed as currently the ExplainMatchResultTo() function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9376 |
// is called only when the mock function call does NOT match the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9377 |
// expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9378 |
*os << "The call matches the expectation.\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9379 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9380 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9381 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9382 |
// Returns the action that should be taken for the current invocation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9383 |
const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9384 |
const ArgumentTuple& args) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9385 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9386 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9387 |
const int count = call_count(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9388 |
Assert(count >= 1, __FILE__, __LINE__, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9389 |
"call_count() is <= 0 when GetCurrentAction() is " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9390 |
"called - this should never happen."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9391 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9392 |
const int action_count = static_cast<int>(untyped_actions_.size()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9393 |
if (action_count > 0 && !repeated_action_specified_ && |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9394 |
count > action_count) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9395 |
// If there is at least one WillOnce() and no WillRepeatedly(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9396 |
// we warn the user when the WillOnce() clauses ran out. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9397 |
::std::stringstream ss; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9398 |
DescribeLocationTo(&ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9399 |
ss << "Actions ran out in " << source_text() << "...\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9400 |
<< "Called " << count << " times, but only " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9401 |
<< action_count << " WillOnce()" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9402 |
<< (action_count == 1 ? " is" : "s are") << " specified - "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9403 |
mocker->DescribeDefaultActionTo(args, &ss); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9404 |
Log(kWarning, ss.str(), 1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9405 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9406 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9407 |
return count <= action_count |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9408 |
? *static_cast<const Action<F>*>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9409 |
untyped_actions_[static_cast<size_t>(count - 1)]) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9410 |
: repeated_action(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9411 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9412 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9413 |
// Given the arguments of a mock function call, if the call will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9414 |
// over-saturate this expectation, returns the default action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9415 |
// otherwise, returns the next action in this expectation. Also |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9416 |
// describes *what* happened to 'what', and explains *why* Google |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9417 |
// Mock does it to 'why'. This method is not const as it calls |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9418 |
// IncrementCallCount(). A return value of NULL means the default |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9419 |
// action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9420 |
const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9421 |
const ArgumentTuple& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9422 |
::std::ostream* what, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9423 |
::std::ostream* why) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9424 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9425 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9426 |
if (IsSaturated()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9427 |
// We have an excessive call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9428 |
IncrementCallCount(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9429 |
*what << "Mock function called more times than expected - "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9430 |
mocker->DescribeDefaultActionTo(args, what); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9431 |
DescribeCallCountTo(why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9432 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9433 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9434 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9435 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9436 |
IncrementCallCount(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9437 |
RetireAllPreRequisites(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9438 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9439 |
if (retires_on_saturation_ && IsSaturated()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9440 |
Retire(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9441 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9442 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9443 |
// Must be done after IncrementCount()! |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9444 |
*what << "Mock function call matches " << source_text() <<"...\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9445 |
return &(GetCurrentAction(mocker, args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9446 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9447 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9448 |
// All the fields below won't change once the EXPECT_CALL() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9449 |
// statement finishes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9450 |
FunctionMocker<F>* const owner_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9451 |
ArgumentMatcherTuple matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9452 |
Matcher<const ArgumentTuple&> extra_matcher_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9453 |
Action<F> repeated_action_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9454 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9455 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(TypedExpectation); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9456 |
}; // class TypedExpectation |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9457 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9458 |
// A MockSpec object is used by ON_CALL() or EXPECT_CALL() for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9459 |
// specifying the default behavior of, or expectation on, a mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9460 |
// function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9462 |
// Note: class MockSpec really belongs to the ::testing namespace. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9463 |
// However if we define it in ::testing, MSVC will complain when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9464 |
// classes in ::testing::internal declare it as a friend class |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9465 |
// template. To workaround this compiler bug, we define MockSpec in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9466 |
// ::testing::internal and import it into ::testing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9467 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9468 |
// Logs a message including file and line number information. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9469 |
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9470 |
const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9471 |
const std::string& message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9472 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9473 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9474 |
class MockSpec { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9475 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9476 |
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9477 |
typedef typename internal::Function<F>::ArgumentMatcherTuple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9478 |
ArgumentMatcherTuple; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9479 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9480 |
// Constructs a MockSpec object, given the function mocker object |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9481 |
// that the spec is associated with. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9482 |
MockSpec(internal::FunctionMocker<F>* function_mocker, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9483 |
const ArgumentMatcherTuple& matchers) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9484 |
: function_mocker_(function_mocker), matchers_(matchers) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9485 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9486 |
// Adds a new default action spec to the function mocker and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9487 |
// the newly created spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9488 |
internal::OnCallSpec<F>& InternalDefaultActionSetAt( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9489 |
const char* file, int line, const char* obj, const char* call) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9490 |
LogWithLocation(internal::kInfo, file, line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9491 |
std::string("ON_CALL(") + obj + ", " + call + ") invoked"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9492 |
return function_mocker_->AddNewOnCallSpec(file, line, matchers_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9493 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9494 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9495 |
// Adds a new expectation spec to the function mocker and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9496 |
// the newly created spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9497 |
internal::TypedExpectation<F>& InternalExpectedAt( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9498 |
const char* file, int line, const char* obj, const char* call) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9499 |
const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9500 |
call + ")"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9501 |
LogWithLocation(internal::kInfo, file, line, source_text + " invoked"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9502 |
return function_mocker_->AddNewExpectation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9503 |
file, line, source_text, matchers_); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9504 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9505 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9506 |
// This operator overload is used to swallow the superfluous parameter list |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9507 |
// introduced by the ON/EXPECT_CALL macros. See the macro comments for more |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9508 |
// explanation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9509 |
MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9510 |
return *this; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9511 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9512 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9513 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9514 |
template <typename Function> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9515 |
friend class internal::FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9516 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9517 |
// The function mocker that owns this spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9518 |
internal::FunctionMocker<F>* const function_mocker_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9519 |
// The argument matchers specified in the spec. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9520 |
ArgumentMatcherTuple matchers_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9521 |
}; // class MockSpec |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9522 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9523 |
// Wrapper type for generically holding an ordinary value or lvalue reference. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9524 |
// If T is not a reference type, it must be copyable or movable. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9525 |
// ReferenceOrValueWrapper<T> is movable, and will also be copyable unless |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9526 |
// T is a move-only value type (which means that it will always be copyable |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9527 |
// if the current platform does not support move semantics). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9528 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9529 |
// The primary template defines handling for values, but function header |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9530 |
// comments describe the contract for the whole template (including |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9531 |
// specializations). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9532 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9533 |
class ReferenceOrValueWrapper { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9534 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9535 |
// Constructs a wrapper from the given value/reference. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9536 |
explicit ReferenceOrValueWrapper(T value) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9537 |
: value_(std::move(value)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9538 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9539 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9540 |
// Unwraps and returns the underlying value/reference, exactly as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9541 |
// originally passed. The behavior of calling this more than once on |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9542 |
// the same object is unspecified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9543 |
T Unwrap() { return std::move(value_); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9544 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9545 |
// Provides nondestructive access to the underlying value/reference. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9546 |
// Always returns a const reference (more precisely, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9547 |
// const std::add_lvalue_reference<T>::type). The behavior of calling this |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9548 |
// after calling Unwrap on the same object is unspecified. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9549 |
const T& Peek() const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9550 |
return value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9551 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9552 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9553 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9554 |
T value_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9555 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9556 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9557 |
// Specialization for lvalue reference types. See primary template |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9558 |
// for documentation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9559 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9560 |
class ReferenceOrValueWrapper<T&> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9561 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9562 |
// Workaround for debatable pass-by-reference lint warning (c-library-team |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9563 |
// policy precludes NOLINT in this context) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9564 |
typedef T& reference; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9565 |
explicit ReferenceOrValueWrapper(reference ref) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9566 |
: value_ptr_(&ref) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9567 |
T& Unwrap() { return *value_ptr_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9568 |
const T& Peek() const { return *value_ptr_; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9569 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9570 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9571 |
T* value_ptr_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9572 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9573 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9574 |
// C++ treats the void type specially. For example, you cannot define |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9575 |
// a void-typed variable or pass a void value to a function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9576 |
// ActionResultHolder<T> holds a value of type T, where T must be a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9577 |
// copyable type or void (T doesn't need to be default-constructable). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9578 |
// It hides the syntactic difference between void and other types, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9579 |
// is used to unify the code for invoking both void-returning and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9580 |
// non-void-returning mock functions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9581 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9582 |
// Untyped base class for ActionResultHolder<T>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9583 |
class UntypedActionResultHolderBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9584 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9585 |
virtual ~UntypedActionResultHolderBase() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9586 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9587 |
// Prints the held value as an action's result to os. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9588 |
virtual void PrintAsActionResult(::std::ostream* os) const = 0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9589 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9590 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9591 |
// This generic definition is used when T is not void. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9592 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9593 |
class ActionResultHolder : public UntypedActionResultHolderBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9594 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9595 |
// Returns the held value. Must not be called more than once. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9596 |
T Unwrap() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9597 |
return result_.Unwrap(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9598 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9599 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9600 |
// Prints the held value as an action's result to os. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9601 |
void PrintAsActionResult(::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9602 |
*os << "\n Returns: "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9603 |
// T may be a reference type, so we don't use UniversalPrint(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9604 |
UniversalPrinter<T>::Print(result_.Peek(), os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9605 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9606 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9607 |
// Performs the given mock function's default action and returns the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9608 |
// result in a new-ed ActionResultHolder. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9609 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9610 |
static ActionResultHolder* PerformDefaultAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9611 |
const FunctionMocker<F>* func_mocker, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9612 |
typename Function<F>::ArgumentTuple&& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9613 |
const std::string& call_description) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9614 |
return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9615 |
std::move(args), call_description))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9616 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9617 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9618 |
// Performs the given action and returns the result in a new-ed |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9619 |
// ActionResultHolder. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9620 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9621 |
static ActionResultHolder* PerformAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9622 |
const Action<F>& action, typename Function<F>::ArgumentTuple&& args) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9623 |
return new ActionResultHolder( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9624 |
Wrapper(action.Perform(std::move(args)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9625 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9626 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9627 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9628 |
typedef ReferenceOrValueWrapper<T> Wrapper; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9629 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9630 |
explicit ActionResultHolder(Wrapper result) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9631 |
: result_(std::move(result)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9632 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9633 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9634 |
Wrapper result_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9635 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9636 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9637 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9638 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9639 |
// Specialization for T = void. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9640 |
template <> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9641 |
class ActionResultHolder<void> : public UntypedActionResultHolderBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9642 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9643 |
void Unwrap() { } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9644 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9645 |
void PrintAsActionResult(::std::ostream* /* os */) const override {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9646 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9647 |
// Performs the given mock function's default action and returns ownership |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9648 |
// of an empty ActionResultHolder*. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9649 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9650 |
static ActionResultHolder* PerformDefaultAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9651 |
const FunctionMocker<F>* func_mocker, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9652 |
typename Function<F>::ArgumentTuple&& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9653 |
const std::string& call_description) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9654 |
func_mocker->PerformDefaultAction(std::move(args), call_description); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9655 |
return new ActionResultHolder; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9656 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9657 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9658 |
// Performs the given action and returns ownership of an empty |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9659 |
// ActionResultHolder*. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9660 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9661 |
static ActionResultHolder* PerformAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9662 |
const Action<F>& action, typename Function<F>::ArgumentTuple&& args) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9663 |
action.Perform(std::move(args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9664 |
return new ActionResultHolder; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9665 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9666 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9667 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9668 |
ActionResultHolder() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9669 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9670 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9671 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9672 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9673 |
class FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9674 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9675 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9676 |
class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9677 |
using F = R(Args...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9678 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9679 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9680 |
using Result = R; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9681 |
using ArgumentTuple = std::tuple<Args...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9682 |
using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9683 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9684 |
FunctionMocker() {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9685 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9686 |
// There is no generally useful and implementable semantics of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9687 |
// copying a mock object, so copying a mock is usually a user error. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9688 |
// Thus we disallow copying function mockers. If the user really |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9689 |
// wants to copy a mock object, they should implement their own copy |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9690 |
// operation, for example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9691 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9692 |
// class MockFoo : public Foo { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9693 |
// public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9694 |
// // Defines a copy constructor explicitly. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9695 |
// MockFoo(const MockFoo& src) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9696 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9697 |
// }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9698 |
FunctionMocker(const FunctionMocker&) = delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9699 |
FunctionMocker& operator=(const FunctionMocker&) = delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9700 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9701 |
// The destructor verifies that all expectations on this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9702 |
// function have been satisfied. If not, it will report Google Test |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9703 |
// non-fatal failures for the violations. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9704 |
~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9705 |
MutexLock l(&g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9706 |
VerifyAndClearExpectationsLocked(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9707 |
Mock::UnregisterLocked(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9708 |
ClearDefaultActionsLocked(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9709 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9710 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9711 |
// Returns the ON_CALL spec that matches this mock function with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9712 |
// given arguments; returns NULL if no matching ON_CALL is found. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9713 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9714 |
const OnCallSpec<F>* FindOnCallSpec( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9715 |
const ArgumentTuple& args) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9716 |
for (UntypedOnCallSpecs::const_reverse_iterator it |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9717 |
= untyped_on_call_specs_.rbegin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9718 |
it != untyped_on_call_specs_.rend(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9719 |
const OnCallSpec<F>* spec = static_cast<const OnCallSpec<F>*>(*it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9720 |
if (spec->Matches(args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9721 |
return spec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9722 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9723 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9724 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9725 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9726 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9727 |
// Performs the default action of this mock function on the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9728 |
// arguments and returns the result. Asserts (or throws if |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9729 |
// exceptions are enabled) with a helpful call descrption if there |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9730 |
// is no valid return value. This method doesn't depend on the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9731 |
// mutable state of this object, and thus can be called concurrently |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9732 |
// without locking. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9733 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9734 |
Result PerformDefaultAction(ArgumentTuple&& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9735 |
const std::string& call_description) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9736 |
const OnCallSpec<F>* const spec = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9737 |
this->FindOnCallSpec(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9738 |
if (spec != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9739 |
return spec->GetAction().Perform(std::move(args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9740 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9741 |
const std::string message = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9742 |
call_description + |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9743 |
"\n The mock function has no default action " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9744 |
"set, and its return type has no default value set."; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9745 |
#if GTEST_HAS_EXCEPTIONS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9746 |
if (!DefaultValue<Result>::Exists()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9747 |
throw std::runtime_error(message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9748 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9749 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9750 |
Assert(DefaultValue<Result>::Exists(), "", -1, message); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9751 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9752 |
return DefaultValue<Result>::Get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9753 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9754 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9755 |
// Performs the default action with the given arguments and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9756 |
// the action's result. The call description string will be used in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9757 |
// the error message to describe the call in the case the default |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9758 |
// action fails. The caller is responsible for deleting the result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9759 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9760 |
UntypedActionResultHolderBase* UntypedPerformDefaultAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9761 |
void* untyped_args, // must point to an ArgumentTuple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9762 |
const std::string& call_description) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9763 |
ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9764 |
return ResultHolder::PerformDefaultAction(this, std::move(*args), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9765 |
call_description); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9766 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9767 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9768 |
// Performs the given action with the given arguments and returns |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9769 |
// the action's result. The caller is responsible for deleting the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9770 |
// result. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9771 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9772 |
UntypedActionResultHolderBase* UntypedPerformAction( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9773 |
const void* untyped_action, void* untyped_args) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9774 |
// Make a copy of the action before performing it, in case the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9775 |
// action deletes the mock object (and thus deletes itself). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9776 |
const Action<F> action = *static_cast<const Action<F>*>(untyped_action); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9777 |
ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9778 |
return ResultHolder::PerformAction(action, std::move(*args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9779 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9780 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9781 |
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked(): |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9782 |
// clears the ON_CALL()s set on this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9783 |
void ClearDefaultActionsLocked() override |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9784 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9785 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9786 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9787 |
// Deleting our default actions may trigger other mock objects to be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9788 |
// deleted, for example if an action contains a reference counted smart |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9789 |
// pointer to that mock object, and that is the last reference. So if we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9790 |
// delete our actions within the context of the global mutex we may deadlock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9791 |
// when this method is called again. Instead, make a copy of the set of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9792 |
// actions to delete, clear our set within the mutex, and then delete the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9793 |
// actions outside of the mutex. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9794 |
UntypedOnCallSpecs specs_to_delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9795 |
untyped_on_call_specs_.swap(specs_to_delete); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9796 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9797 |
g_gmock_mutex.Unlock(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9798 |
for (UntypedOnCallSpecs::const_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9799 |
specs_to_delete.begin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9800 |
it != specs_to_delete.end(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9801 |
delete static_cast<const OnCallSpec<F>*>(*it); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9802 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9803 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9804 |
// Lock the mutex again, since the caller expects it to be locked when we |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9805 |
// return. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9806 |
g_gmock_mutex.Lock(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9807 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9808 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9809 |
// Returns the result of invoking this mock function with the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9810 |
// arguments. This function can be safely called from multiple |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9811 |
// threads concurrently. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9812 |
Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9813 |
ArgumentTuple tuple(std::forward<Args>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9814 |
std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9815 |
this->UntypedInvokeWith(static_cast<void*>(&tuple)))); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9816 |
return holder->Unwrap(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9817 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9818 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9819 |
MockSpec<F> With(Matcher<Args>... m) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9820 |
return MockSpec<F>(this, ::std::make_tuple(std::move(m)...)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9821 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9822 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9823 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9824 |
template <typename Function> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9825 |
friend class MockSpec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9826 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9827 |
typedef ActionResultHolder<Result> ResultHolder; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9828 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9829 |
// Adds and returns a default action spec for this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9830 |
OnCallSpec<F>& AddNewOnCallSpec( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9831 |
const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9832 |
const ArgumentMatcherTuple& m) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9833 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9834 |
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9835 |
OnCallSpec<F>* const on_call_spec = new OnCallSpec<F>(file, line, m); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9836 |
untyped_on_call_specs_.push_back(on_call_spec); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9837 |
return *on_call_spec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9838 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9839 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9840 |
// Adds and returns an expectation spec for this mock function. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9841 |
TypedExpectation<F>& AddNewExpectation(const char* file, int line, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9842 |
const std::string& source_text, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9843 |
const ArgumentMatcherTuple& m) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9844 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9845 |
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9846 |
TypedExpectation<F>* const expectation = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9847 |
new TypedExpectation<F>(this, file, line, source_text, m); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9848 |
const std::shared_ptr<ExpectationBase> untyped_expectation(expectation); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9849 |
// See the definition of untyped_expectations_ for why access to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9850 |
// it is unprotected here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9851 |
untyped_expectations_.push_back(untyped_expectation); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9852 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9853 |
// Adds this expectation into the implicit sequence if there is one. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9854 |
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9855 |
if (implicit_sequence != nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9856 |
implicit_sequence->AddExpectation(Expectation(untyped_expectation)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9857 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9858 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9859 |
return *expectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9860 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9861 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9862 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9863 |
template <typename Func> friend class TypedExpectation; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9864 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9865 |
// Some utilities needed for implementing UntypedInvokeWith(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9866 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9867 |
// Describes what default action will be performed for the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9868 |
// arguments. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9869 |
// L = * |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9870 |
void DescribeDefaultActionTo(const ArgumentTuple& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9871 |
::std::ostream* os) const { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9872 |
const OnCallSpec<F>* const spec = FindOnCallSpec(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9873 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9874 |
if (spec == nullptr) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9875 |
*os << (std::is_void<Result>::value ? "returning directly.\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9876 |
: "returning default value.\n"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9877 |
} else { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9878 |
*os << "taking default action specified at:\n" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9879 |
<< FormatFileLocation(spec->file(), spec->line()) << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9880 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9881 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9882 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9883 |
// Writes a message that the call is uninteresting (i.e. neither |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9884 |
// explicitly expected nor explicitly unexpected) to the given |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9885 |
// ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9886 |
void UntypedDescribeUninterestingCall(const void* untyped_args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9887 |
::std::ostream* os) const override |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9888 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9889 |
const ArgumentTuple& args = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9890 |
*static_cast<const ArgumentTuple*>(untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9891 |
*os << "Uninteresting mock function call - "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9892 |
DescribeDefaultActionTo(args, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9893 |
*os << " Function call: " << Name(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9894 |
UniversalPrint(args, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9895 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9896 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9897 |
// Returns the expectation that matches the given function arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9898 |
// (or NULL is there's no match); when a match is found, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9899 |
// untyped_action is set to point to the action that should be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9900 |
// performed (or NULL if the action is "do default"), and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9901 |
// is_excessive is modified to indicate whether the call exceeds the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9902 |
// expected number. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9903 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9904 |
// Critical section: We must find the matching expectation and the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9905 |
// corresponding action that needs to be taken in an ATOMIC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9906 |
// transaction. Otherwise another thread may call this mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9907 |
// method in the middle and mess up the state. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9908 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9909 |
// However, performing the action has to be left out of the critical |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9910 |
// section. The reason is that we have no control on what the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9911 |
// action does (it can invoke an arbitrary user function or even a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9912 |
// mock function) and excessive locking could cause a dead lock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9913 |
const ExpectationBase* UntypedFindMatchingExpectation( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9914 |
const void* untyped_args, const void** untyped_action, bool* is_excessive, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9915 |
::std::ostream* what, ::std::ostream* why) override |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9916 |
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9917 |
const ArgumentTuple& args = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9918 |
*static_cast<const ArgumentTuple*>(untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9919 |
MutexLock l(&g_gmock_mutex); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9920 |
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9921 |
if (exp == nullptr) { // A match wasn't found. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9922 |
this->FormatUnexpectedCallMessageLocked(args, what, why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9923 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9924 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9925 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9926 |
// This line must be done before calling GetActionForArguments(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9927 |
// which will increment the call count for *exp and thus affect |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9928 |
// its saturation status. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9929 |
*is_excessive = exp->IsSaturated(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9930 |
const Action<F>* action = exp->GetActionForArguments(this, args, what, why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9931 |
if (action != nullptr && action->IsDoDefault()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9932 |
action = nullptr; // Normalize "do default" to NULL. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9933 |
*untyped_action = action; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9934 |
return exp; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9935 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9936 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9937 |
// Prints the given function arguments to the ostream. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9938 |
void UntypedPrintArgs(const void* untyped_args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9939 |
::std::ostream* os) const override { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9940 |
const ArgumentTuple& args = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9941 |
*static_cast<const ArgumentTuple*>(untyped_args); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9942 |
UniversalPrint(args, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9943 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9944 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9945 |
// Returns the expectation that matches the arguments, or NULL if no |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9946 |
// expectation matches them. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9947 |
TypedExpectation<F>* FindMatchingExpectationLocked( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9948 |
const ArgumentTuple& args) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9949 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9950 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9951 |
// See the definition of untyped_expectations_ for why access to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9952 |
// it is unprotected here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9953 |
for (typename UntypedExpectations::const_reverse_iterator it = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9954 |
untyped_expectations_.rbegin(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9955 |
it != untyped_expectations_.rend(); ++it) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9956 |
TypedExpectation<F>* const exp = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9957 |
static_cast<TypedExpectation<F>*>(it->get()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9958 |
if (exp->ShouldHandleArguments(args)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9959 |
return exp; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9960 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9961 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9962 |
return nullptr; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9963 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9964 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9965 |
// Returns a message that the arguments don't match any expectation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9966 |
void FormatUnexpectedCallMessageLocked( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9967 |
const ArgumentTuple& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9968 |
::std::ostream* os, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9969 |
::std::ostream* why) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9970 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9971 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9972 |
*os << "\nUnexpected mock function call - "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9973 |
DescribeDefaultActionTo(args, os); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9974 |
PrintTriedExpectationsLocked(args, why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9975 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9976 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9977 |
// Prints a list of expectations that have been tried against the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9978 |
// current mock function call. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9979 |
void PrintTriedExpectationsLocked( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9980 |
const ArgumentTuple& args, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9981 |
::std::ostream* why) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9982 |
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9983 |
g_gmock_mutex.AssertHeld(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9984 |
const size_t count = untyped_expectations_.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9985 |
*why << "Google Mock tried the following " << count << " " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9986 |
<< (count == 1 ? "expectation, but it didn't match" : |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9987 |
"expectations, but none matched") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9988 |
<< ":\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9989 |
for (size_t i = 0; i < count; i++) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9990 |
TypedExpectation<F>* const expectation = |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9991 |
static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9992 |
*why << "\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9993 |
expectation->DescribeLocationTo(why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9994 |
if (count > 1) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9995 |
*why << "tried expectation #" << i << ": "; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9996 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9997 |
*why << expectation->source_text() << "...\n"; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9998 |
expectation->ExplainMatchResultTo(args, why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
9999 |
expectation->DescribeCallCountTo(why); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10000 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10001 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10002 |
}; // class FunctionMocker |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10003 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10004 |
// Reports an uninteresting call (whose description is in msg) in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10005 |
// manner specified by 'reaction'. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10006 |
void ReportUninterestingCall(CallReaction reaction, const std::string& msg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10007 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10008 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10009 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10010 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10011 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10012 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10013 |
class MockFunction; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10014 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10015 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10016 |
class MockFunction<R(Args...)> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10017 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10018 |
MockFunction(const MockFunction&) = delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10019 |
MockFunction& operator=(const MockFunction&) = delete; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10020 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10021 |
std::function<R(Args...)> AsStdFunction() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10022 |
return [this](Args... args) -> R { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10023 |
return this->Call(std::forward<Args>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10024 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10025 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10026 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10027 |
// Implementation detail: the expansion of the MOCK_METHOD macro. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10028 |
R Call(Args... args) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10029 |
mock_.SetOwnerAndName(this, "Call"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10030 |
return mock_.Invoke(std::forward<Args>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10031 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10032 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10033 |
MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10034 |
mock_.RegisterOwner(this); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10035 |
return mock_.With(std::move(m)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10036 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10037 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10038 |
MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10039 |
return this->gmock_Call(::testing::A<Args>()...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10040 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10041 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10042 |
protected: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10043 |
MockFunction() = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10044 |
~MockFunction() = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10045 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10046 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10047 |
FunctionMocker<R(Args...)> mock_; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10048 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10049 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10050 |
/* |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10051 |
The SignatureOf<F> struct is a meta-function returning function signature |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10052 |
corresponding to the provided F argument. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10053 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10054 |
It makes use of MockFunction easier by allowing it to accept more F arguments |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10055 |
than just function signatures. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10056 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10057 |
Specializations provided here cover only a signature type itself and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10058 |
std::function. However, if need be it can be easily extended to cover also other |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10059 |
types (like for example boost::function). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10060 |
*/ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10061 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10062 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10063 |
struct SignatureOf; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10064 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10065 |
template <typename R, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10066 |
struct SignatureOf<R(Args...)> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10067 |
using type = R(Args...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10068 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10070 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10071 |
struct SignatureOf<std::function<F>> : SignatureOf<F> {}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10072 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10073 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10074 |
using SignatureOfT = typename SignatureOf<F>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10075 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10076 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10077 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10078 |
// A MockFunction<F> type has one mock method whose type is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10079 |
// internal::SignatureOfT<F>. It is useful when you just want your |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10080 |
// test code to emit some messages and have Google Mock verify the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10081 |
// right messages are sent (and perhaps at the right times). For |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10082 |
// example, if you are exercising code: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10083 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10084 |
// Foo(1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10085 |
// Foo(2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10086 |
// Foo(3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10087 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10088 |
// and want to verify that Foo(1) and Foo(3) both invoke |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10089 |
// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10090 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10091 |
// TEST(FooTest, InvokesBarCorrectly) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10092 |
// MyMock mock; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10093 |
// MockFunction<void(string check_point_name)> check; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10094 |
// { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10095 |
// InSequence s; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10096 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10097 |
// EXPECT_CALL(mock, Bar("a")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10098 |
// EXPECT_CALL(check, Call("1")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10099 |
// EXPECT_CALL(check, Call("2")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10100 |
// EXPECT_CALL(mock, Bar("a")); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10101 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10102 |
// Foo(1); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10103 |
// check.Call("1"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10104 |
// Foo(2); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10105 |
// check.Call("2"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10106 |
// Foo(3); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10107 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10108 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10109 |
// The expectation spec says that the first Bar("a") must happen |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10110 |
// before check point "1", the second Bar("a") must happen after check |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10111 |
// point "2", and nothing should happen between the two check |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10112 |
// points. The explicit check points make it easy to tell which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10113 |
// Bar("a") is called by which call to Foo(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10114 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10115 |
// MockFunction<F> can also be used to exercise code that accepts |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10116 |
// std::function<internal::SignatureOfT<F>> callbacks. To do so, use |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10117 |
// AsStdFunction() method to create std::function proxy forwarding to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10118 |
// original object's Call. Example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10119 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10120 |
// TEST(FooTest, RunsCallbackWithBarArgument) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10121 |
// MockFunction<int(string)> callback; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10122 |
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10123 |
// Foo(callback.AsStdFunction()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10124 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10125 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10126 |
// The internal::SignatureOfT<F> indirection allows to use other types |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10127 |
// than just function signature type. This is typically useful when |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10128 |
// providing a mock for a predefined std::function type. Example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10129 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10130 |
// using FilterPredicate = std::function<bool(string)>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10131 |
// void MyFilterAlgorithm(FilterPredicate predicate); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10132 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10133 |
// TEST(FooTest, FilterPredicateAlwaysAccepts) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10134 |
// MockFunction<FilterPredicate> predicateMock; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10135 |
// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10136 |
// MyFilterAlgorithm(predicateMock.AsStdFunction()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10137 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10138 |
template <typename F> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10139 |
class MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10140 |
using Base = internal::MockFunction<internal::SignatureOfT<F>>; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10141 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10142 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10143 |
using Base::Base; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10144 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10145 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10146 |
// The style guide prohibits "using" statements in a namespace scope |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10147 |
// inside a header file. However, the MockSpec class template is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10148 |
// meant to be defined in the ::testing namespace. The following line |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10149 |
// is just a trick for working around a bug in MSVC 8.0, which cannot |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10150 |
// handle it if we define MockSpec in ::testing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10151 |
using internal::MockSpec; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10152 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10153 |
// Const(x) is a convenient function for obtaining a const reference |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10154 |
// to x. This is useful for setting expectations on an overloaded |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10155 |
// const mock method, e.g. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10156 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10157 |
// class MockFoo : public FooInterface { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10158 |
// public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10159 |
// MOCK_METHOD0(Bar, int()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10160 |
// MOCK_CONST_METHOD0(Bar, int&()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10161 |
// }; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10162 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10163 |
// MockFoo foo; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10164 |
// // Expects a call to non-const MockFoo::Bar(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10165 |
// EXPECT_CALL(foo, Bar()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10166 |
// // Expects a call to const MockFoo::Bar(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10167 |
// EXPECT_CALL(Const(foo), Bar()); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10168 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10169 |
inline const T& Const(const T& x) { return x; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10170 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10171 |
// Constructs an Expectation object that references and co-owns exp. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10172 |
inline Expectation::Expectation(internal::ExpectationBase& exp) // NOLINT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10173 |
: expectation_base_(exp.GetHandle().expectation_base()) {} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10174 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10175 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10176 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10177 |
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10178 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10179 |
// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10180 |
// required to avoid compile errors when the name of the method used in call is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10181 |
// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10182 |
// tests in internal/gmock-spec-builders_test.cc for more details. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10183 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10184 |
// This macro supports statements both with and without parameter matchers. If |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10185 |
// the parameter list is omitted, gMock will accept any parameters, which allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10186 |
// tests to be written that don't need to encode the number of method |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10187 |
// parameter. This technique may only be used for non-overloaded methods. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10188 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10189 |
// // These are the same: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10190 |
// ON_CALL(mock, NoArgsMethod()).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10191 |
// ON_CALL(mock, NoArgsMethod).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10192 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10193 |
// // As are these: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10194 |
// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10195 |
// ON_CALL(mock, TwoArgsMethod).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10196 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10197 |
// // Can also specify args if you want, of course: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10198 |
// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10199 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10200 |
// // Overloads work as long as you specify parameters: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10201 |
// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10202 |
// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10203 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10204 |
// // Oops! Which overload did you want? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10205 |
// ON_CALL(mock, OverloadedMethod).WillByDefault(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10206 |
// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10207 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10208 |
// How this works: The mock class uses two overloads of the gmock_Method |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10209 |
// expectation setter method plus an operator() overload on the MockSpec object. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10210 |
// In the matcher list form, the macro expands to: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10211 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10212 |
// // This statement: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10213 |
// ON_CALL(mock, TwoArgsMethod(_, 45))... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10214 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10215 |
// // ...expands to: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10216 |
// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10217 |
// |-------------v---------------||------------v-------------| |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10218 |
// invokes first overload swallowed by operator() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10219 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10220 |
// // ...which is essentially: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10221 |
// mock.gmock_TwoArgsMethod(_, 45)... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10222 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10223 |
// Whereas the form without a matcher list: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10224 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10225 |
// // This statement: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10226 |
// ON_CALL(mock, TwoArgsMethod)... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10227 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10228 |
// // ...expands to: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10229 |
// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10230 |
// |-----------------------v--------------------------| |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10231 |
// invokes second overload |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10232 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10233 |
// // ...which is essentially: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10234 |
// mock.gmock_TwoArgsMethod(_, _)... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10235 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10236 |
// The WithoutMatchers() argument is used to disambiguate overloads and to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10237 |
// block the caller from accidentally invoking the second overload directly. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10238 |
// second argument is an internal type derived from the method signature. The |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10239 |
// failure to disambiguate two overloads of this method in the ON_CALL statement |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10240 |
// is how we block callers from setting expectations on overloaded methods. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10241 |
#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10242 |
((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10243 |
nullptr) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10244 |
.Setter(__FILE__, __LINE__, #mock_expr, #call) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10245 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10246 |
#define ON_CALL(obj, call) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10247 |
GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10248 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10249 |
#define EXPECT_CALL(obj, call) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10250 |
GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10251 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10252 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10253 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10254 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10255 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10256 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10257 |
using identity_t = T; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10258 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10259 |
template <typename Pattern> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10260 |
struct ThisRefAdjuster { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10261 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10262 |
using AdjustT = typename std::conditional< |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10263 |
std::is_const<typename std::remove_reference<Pattern>::type>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10264 |
typename std::conditional<std::is_lvalue_reference<Pattern>::value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10265 |
const T&, const T&&>::type, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10266 |
typename std::conditional<std::is_lvalue_reference<Pattern>::value, T&, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10267 |
T&&>::type>::type; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10268 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10269 |
template <typename MockType> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10270 |
static AdjustT<MockType> Adjust(const MockType& mock) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10271 |
return static_cast<AdjustT<MockType>>(const_cast<MockType&>(mock)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10272 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10273 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10274 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10275 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10276 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10277 |
// The style guide prohibits "using" statements in a namespace scope |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10278 |
// inside a header file. However, the FunctionMocker class template |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10279 |
// is meant to be defined in the ::testing namespace. The following |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10280 |
// line is just a trick for working around a bug in MSVC 8.0, which |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10281 |
// cannot handle it if we define FunctionMocker in ::testing. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10282 |
using internal::FunctionMocker; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10283 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10284 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10285 |
#define MOCK_METHOD(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10286 |
GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10287 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10288 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10289 |
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10290 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10291 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10292 |
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10294 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10295 |
GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ()) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10296 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10297 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10298 |
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10299 |
GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10300 |
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10301 |
GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10302 |
GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10303 |
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10304 |
GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10305 |
GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10306 |
GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Spec), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10307 |
GMOCK_INTERNAL_GET_CALLTYPE(_Spec), GMOCK_INTERNAL_GET_REF_SPEC(_Spec), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10308 |
(GMOCK_INTERNAL_SIGNATURE(_Ret, _Args))) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10309 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10310 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10311 |
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10312 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10313 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10314 |
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10315 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10316 |
#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10317 |
GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10318 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10319 |
#define GMOCK_INTERNAL_WRONG_ARITY(...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10320 |
static_assert( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10321 |
false, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10322 |
"MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10323 |
"_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10324 |
"enclosed in parentheses. If _Ret is a type with unprotected commas, " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10325 |
"it must also be enclosed in parentheses.") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10326 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10327 |
#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10328 |
static_assert( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10329 |
GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10330 |
GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10331 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10332 |
#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10333 |
static_assert( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10334 |
std::is_function<__VA_ARGS__>::value, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10335 |
"Signature must be a function type, maybe return type contains " \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10336 |
"unprotected comma."); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10337 |
static_assert( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10338 |
::testing::tuple_size<typename ::testing::internal::Function< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10339 |
__VA_ARGS__>::ArgumentTuple>::value == _N, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10340 |
"This method does not take " GMOCK_PP_STRINGIZE( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10341 |
_N) " arguments. Parenthesize all types with unprotected commas.") |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10342 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10343 |
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10344 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10345 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10346 |
#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10347 |
_Override, _Final, _NoexceptSpec, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10348 |
_CallType, _RefSpec, _Signature) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10349 |
typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10350 |
_Signature)>::Result \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10351 |
GMOCK_INTERNAL_EXPAND(_CallType) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10352 |
_MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10353 |
GMOCK_PP_IF(_Constness, const, ) _RefSpec _NoexceptSpec \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10354 |
GMOCK_PP_IF(_Override, override, ) GMOCK_PP_IF(_Final, final, ) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10355 |
GMOCK_MOCKER_(_N, _Constness, _MethodName) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10356 |
.SetOwnerAndName(this, #_MethodName); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10357 |
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10358 |
.Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10359 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10360 |
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10361 |
GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10362 |
GMOCK_PP_IF(_Constness, const, ) _RefSpec { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10363 |
GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10364 |
return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10365 |
.With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10366 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10367 |
::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10368 |
const ::testing::internal::WithoutMatchers&, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10369 |
GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10370 |
GMOCK_PP_REMOVE_PARENS(_Signature)>*) const _RefSpec _NoexceptSpec { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10371 |
return ::testing::internal::ThisRefAdjuster<GMOCK_PP_IF( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10372 |
_Constness, const, ) int _RefSpec>::Adjust(*this) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10373 |
.gmock_##_MethodName(GMOCK_PP_REPEAT( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10374 |
GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10375 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10376 |
mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10377 |
GMOCK_MOCKER_(_N, _Constness, _MethodName) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10378 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10379 |
#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10380 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10381 |
// Five Valid modifiers. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10382 |
#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10383 |
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10385 |
#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10386 |
GMOCK_PP_HAS_COMMA( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10387 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10388 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10389 |
#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10390 |
GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10391 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10392 |
#define GMOCK_INTERNAL_GET_NOEXCEPT_SPEC(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10393 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT, ~, _Tuple) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10394 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10395 |
#define GMOCK_INTERNAL_NOEXCEPT_SPEC_IF_NOEXCEPT(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10396 |
GMOCK_PP_IF( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10397 |
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10398 |
_elem, ) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10399 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10400 |
#define GMOCK_INTERNAL_GET_REF_SPEC(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10401 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_REF_SPEC_IF_REF, ~, _Tuple) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10402 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10403 |
#define GMOCK_INTERNAL_REF_SPEC_IF_REF(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10404 |
GMOCK_PP_IF(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10405 |
GMOCK_PP_CAT(GMOCK_INTERNAL_UNPACK_, _elem), ) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10406 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10407 |
#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10408 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10409 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10410 |
#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10411 |
static_assert( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10412 |
(GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10413 |
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10414 |
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10415 |
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10416 |
GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_REF(_i, _, _elem)) + \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10417 |
GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10418 |
GMOCK_PP_STRINGIZE( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10419 |
_elem) " cannot be recognized as a valid specification modifier."); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10420 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10421 |
// Modifiers implementation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10422 |
#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10423 |
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10424 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10425 |
#define GMOCK_INTERNAL_DETECT_CONST_I_const , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10426 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10427 |
#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10428 |
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10429 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10430 |
#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10431 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10432 |
#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10433 |
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10434 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10435 |
#define GMOCK_INTERNAL_DETECT_FINAL_I_final , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10436 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10437 |
#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10438 |
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10439 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10440 |
#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10441 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10442 |
#define GMOCK_INTERNAL_DETECT_REF(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10443 |
GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_REF_I_, _elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10445 |
#define GMOCK_INTERNAL_DETECT_REF_I_ref , |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10446 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10447 |
#define GMOCK_INTERNAL_UNPACK_ref(x) x |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10448 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10449 |
#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10450 |
GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10451 |
GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10452 |
(_elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10453 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10454 |
// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10455 |
// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10456 |
// maybe they can be simplified somehow. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10457 |
#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10458 |
GMOCK_INTERNAL_IS_CALLTYPE_I( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10459 |
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10460 |
#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10461 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10462 |
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10463 |
GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10464 |
GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10465 |
#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10466 |
GMOCK_PP_IDENTITY _arg |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10467 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10468 |
#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10469 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10470 |
// Note: The use of `identity_t` here allows _Ret to represent return types that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10471 |
// would normally need to be specified in a different way. For example, a method |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10472 |
// returning a function pointer must be written as |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10473 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10474 |
// fn_ptr_return_t (*method(method_args_t...))(fn_ptr_args_t...) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10475 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10476 |
// But we only support placing the return type at the beginning. To handle this, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10477 |
// we wrap all calls in identity_t, so that a declaration will be expanded to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10478 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10479 |
// identity_t<fn_ptr_return_t (*)(fn_ptr_args_t...)> method(method_args_t...) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10480 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10481 |
// This allows us to work around the syntactic oddities of function/method |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10482 |
// types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10483 |
#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10484 |
::testing::internal::identity_t<GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10485 |
GMOCK_PP_REMOVE_PARENS, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10486 |
GMOCK_PP_IDENTITY)(_Ret)>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10487 |
GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10488 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10489 |
#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10490 |
GMOCK_PP_COMMA_IF(_i) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10491 |
GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10492 |
GMOCK_PP_IDENTITY) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10493 |
(_elem) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10494 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10495 |
#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10496 |
GMOCK_PP_COMMA_IF(_i) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10497 |
GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10498 |
gmock_a##_i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10499 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10500 |
#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10501 |
GMOCK_PP_COMMA_IF(_i) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10502 |
::std::forward<GMOCK_INTERNAL_ARG_O( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10503 |
_i, GMOCK_PP_REMOVE_PARENS(_Signature))>(gmock_a##_i) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10504 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10505 |
#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10506 |
GMOCK_PP_COMMA_IF(_i) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10507 |
GMOCK_INTERNAL_MATCHER_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature)) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10508 |
gmock_a##_i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10509 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10510 |
#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10511 |
GMOCK_PP_COMMA_IF(_i) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10512 |
gmock_a##_i |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10513 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10514 |
#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10515 |
GMOCK_PP_COMMA_IF(_i) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10516 |
::testing::A<GMOCK_INTERNAL_ARG_O(_i, GMOCK_PP_REMOVE_PARENS(_Signature))>() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10517 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10518 |
#define GMOCK_INTERNAL_ARG_O(_i, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10519 |
typename ::testing::internal::Function<__VA_ARGS__>::template Arg<_i>::type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10520 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10521 |
#define GMOCK_INTERNAL_MATCHER_O(_i, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10522 |
const ::testing::Matcher<typename ::testing::internal::Function< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10523 |
__VA_ARGS__>::template Arg<_i>::type>& |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10524 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10525 |
#define MOCK_METHOD0(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 0, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10526 |
#define MOCK_METHOD1(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 1, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10527 |
#define MOCK_METHOD2(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 2, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10528 |
#define MOCK_METHOD3(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 3, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10529 |
#define MOCK_METHOD4(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 4, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10530 |
#define MOCK_METHOD5(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 5, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10531 |
#define MOCK_METHOD6(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 6, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10532 |
#define MOCK_METHOD7(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 7, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10533 |
#define MOCK_METHOD8(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 8, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10534 |
#define MOCK_METHOD9(m, ...) GMOCK_INTERNAL_MOCK_METHODN(, , m, 9, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10535 |
#define MOCK_METHOD10(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10536 |
GMOCK_INTERNAL_MOCK_METHODN(, , m, 10, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10537 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10538 |
#define MOCK_CONST_METHOD0(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10539 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 0, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10540 |
#define MOCK_CONST_METHOD1(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10541 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 1, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10542 |
#define MOCK_CONST_METHOD2(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10543 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 2, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10544 |
#define MOCK_CONST_METHOD3(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10545 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 3, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10546 |
#define MOCK_CONST_METHOD4(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10547 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 4, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10548 |
#define MOCK_CONST_METHOD5(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10549 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 5, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10550 |
#define MOCK_CONST_METHOD6(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10551 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 6, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10552 |
#define MOCK_CONST_METHOD7(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10553 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 7, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10554 |
#define MOCK_CONST_METHOD8(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10555 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 8, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10556 |
#define MOCK_CONST_METHOD9(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10557 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 9, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10558 |
#define MOCK_CONST_METHOD10(m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10559 |
GMOCK_INTERNAL_MOCK_METHODN(const, , m, 10, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10560 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10561 |
#define MOCK_METHOD0_T(m, ...) MOCK_METHOD0(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10562 |
#define MOCK_METHOD1_T(m, ...) MOCK_METHOD1(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10563 |
#define MOCK_METHOD2_T(m, ...) MOCK_METHOD2(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10564 |
#define MOCK_METHOD3_T(m, ...) MOCK_METHOD3(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10565 |
#define MOCK_METHOD4_T(m, ...) MOCK_METHOD4(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10566 |
#define MOCK_METHOD5_T(m, ...) MOCK_METHOD5(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10567 |
#define MOCK_METHOD6_T(m, ...) MOCK_METHOD6(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10568 |
#define MOCK_METHOD7_T(m, ...) MOCK_METHOD7(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10569 |
#define MOCK_METHOD8_T(m, ...) MOCK_METHOD8(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10570 |
#define MOCK_METHOD9_T(m, ...) MOCK_METHOD9(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10571 |
#define MOCK_METHOD10_T(m, ...) MOCK_METHOD10(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10572 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10573 |
#define MOCK_CONST_METHOD0_T(m, ...) MOCK_CONST_METHOD0(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10574 |
#define MOCK_CONST_METHOD1_T(m, ...) MOCK_CONST_METHOD1(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10575 |
#define MOCK_CONST_METHOD2_T(m, ...) MOCK_CONST_METHOD2(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10576 |
#define MOCK_CONST_METHOD3_T(m, ...) MOCK_CONST_METHOD3(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10577 |
#define MOCK_CONST_METHOD4_T(m, ...) MOCK_CONST_METHOD4(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10578 |
#define MOCK_CONST_METHOD5_T(m, ...) MOCK_CONST_METHOD5(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10579 |
#define MOCK_CONST_METHOD6_T(m, ...) MOCK_CONST_METHOD6(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10580 |
#define MOCK_CONST_METHOD7_T(m, ...) MOCK_CONST_METHOD7(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10581 |
#define MOCK_CONST_METHOD8_T(m, ...) MOCK_CONST_METHOD8(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10582 |
#define MOCK_CONST_METHOD9_T(m, ...) MOCK_CONST_METHOD9(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10583 |
#define MOCK_CONST_METHOD10_T(m, ...) MOCK_CONST_METHOD10(m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10584 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10585 |
#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10586 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 0, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10587 |
#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10588 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 1, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10589 |
#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10590 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 2, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10591 |
#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10592 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 3, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10593 |
#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10594 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 4, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10595 |
#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10596 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 5, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10597 |
#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10598 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 6, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10599 |
#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10600 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 7, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10601 |
#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10602 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 8, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10603 |
#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10604 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 9, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10605 |
#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10606 |
GMOCK_INTERNAL_MOCK_METHODN(, ct, m, 10, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10607 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10608 |
#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10609 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 0, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10610 |
#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10611 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 1, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10612 |
#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10613 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 2, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10614 |
#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10615 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 3, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10616 |
#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10617 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 4, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10618 |
#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10619 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 5, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10620 |
#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10621 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 6, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10622 |
#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10623 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 7, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10624 |
#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10625 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 8, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10626 |
#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10627 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 9, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10628 |
#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10629 |
GMOCK_INTERNAL_MOCK_METHODN(const, ct, m, 10, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10630 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10631 |
#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10632 |
MOCK_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10633 |
#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10634 |
MOCK_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10635 |
#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10636 |
MOCK_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10637 |
#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10638 |
MOCK_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10639 |
#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10640 |
MOCK_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10641 |
#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10642 |
MOCK_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10643 |
#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10644 |
MOCK_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10645 |
#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10646 |
MOCK_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10647 |
#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10648 |
MOCK_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10649 |
#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10650 |
MOCK_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10651 |
#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10652 |
MOCK_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10653 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10654 |
#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10655 |
MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10656 |
#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10657 |
MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10658 |
#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10659 |
MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10660 |
#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10661 |
MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10662 |
#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10663 |
MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10664 |
#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10665 |
MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10666 |
#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10667 |
MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10668 |
#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10669 |
MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10670 |
#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10671 |
MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10672 |
#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10673 |
MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10674 |
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10675 |
MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, __VA_ARGS__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10676 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10677 |
#define GMOCK_INTERNAL_MOCK_METHODN(constness, ct, Method, args_num, ...) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10678 |
GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10679 |
args_num, ::testing::internal::identity_t<__VA_ARGS__>); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10680 |
GMOCK_INTERNAL_MOCK_METHOD_IMPL( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10681 |
args_num, Method, GMOCK_PP_NARG0(constness), 0, 0, , ct, , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10682 |
(::testing::internal::identity_t<__VA_ARGS__>)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10683 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10684 |
#define GMOCK_MOCKER_(arity, constness, Method) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10685 |
GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10686 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10687 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10688 |
// Copyright 2007, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10689 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10690 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10691 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10692 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10693 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10694 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10695 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10696 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10697 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10698 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10699 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10700 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10701 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10702 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10703 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10704 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10705 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10706 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10707 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10708 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10709 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10710 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10711 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10712 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10713 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10714 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10715 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10716 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10717 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10718 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10719 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10720 |
// This file implements some commonly used variadic actions. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10721 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10722 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10723 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10724 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10725 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10726 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10727 |
#include <memory> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10728 |
#include <utility> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10729 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10730 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10731 |
// Include any custom callback actions added by the local installation. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10732 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10733 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10734 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10735 |
#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10736 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10737 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10738 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10739 |
// Sometimes you want to give an action explicit template parameters |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10740 |
// that cannot be inferred from its value parameters. ACTION() and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10741 |
// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10742 |
// and can be viewed as an extension to ACTION() and ACTION_P*(). |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10743 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10744 |
// The syntax: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10745 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10746 |
// ACTION_TEMPLATE(ActionName, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10747 |
// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10748 |
// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10749 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10750 |
// defines an action template that takes m explicit template |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10751 |
// parameters and n value parameters. name_i is the name of the i-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10752 |
// template parameter, and kind_i specifies whether it's a typename, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10753 |
// an integral constant, or a template. p_i is the name of the i-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10754 |
// value parameter. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10755 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10756 |
// Example: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10757 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10758 |
// // DuplicateArg<k, T>(output) converts the k-th argument of the mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10759 |
// // function to type T and copies it to *output. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10760 |
// ACTION_TEMPLATE(DuplicateArg, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10761 |
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10762 |
// AND_1_VALUE_PARAMS(output)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10763 |
// *output = T(::std::get<k>(args)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10764 |
// } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10765 |
// ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10766 |
// int n; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10767 |
// EXPECT_CALL(mock, Foo(_, _)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10768 |
// .WillOnce(DuplicateArg<1, unsigned char>(&n)); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10769 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10770 |
// To create an instance of an action template, write: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10771 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10772 |
// ActionName<t1, ..., t_m>(v1, ..., v_n) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10773 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10774 |
// where the ts are the template arguments and the vs are the value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10775 |
// arguments. The value argument types are inferred by the compiler. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10776 |
// If you want to explicitly specify the value argument types, you can |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10777 |
// provide additional template arguments: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10778 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10779 |
// ActionName<t1, ..., t_m, u1, ..., u_k>(v1, ..., v_n) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10780 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10781 |
// where u_i is the desired type of v_i. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10782 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10783 |
// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10784 |
// number of value parameters, but not on the number of template |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10785 |
// parameters. Without the restriction, the meaning of the following |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10786 |
// is unclear: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10787 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10788 |
// OverloadedAction<int, bool>(x); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10789 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10790 |
// Are we using a single-template-parameter action where 'bool' refers |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10791 |
// to the type of x, or are we using a two-template-parameter action |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10792 |
// where the compiler is asked to infer the type of x? |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10793 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10794 |
// Implementation notes: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10795 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10796 |
// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10797 |
// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10798 |
// implementing ACTION_TEMPLATE. The main trick we use is to create |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10799 |
// new macro invocations when expanding a macro. For example, we have |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10800 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10801 |
// #define ACTION_TEMPLATE(name, template_params, value_params) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10802 |
// ... GMOCK_INTERNAL_DECL_##template_params ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10803 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10804 |
// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10805 |
// to expand to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10806 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10807 |
// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10808 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10809 |
// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10810 |
// preprocessor will continue to expand it to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10811 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10812 |
// ... typename T ... |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10813 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10814 |
// This technique conforms to the C++ standard and is portable. It |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10815 |
// allows us to implement action templates using O(N) code, where N is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10816 |
// the maximum number of template/value parameters supported. Without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10817 |
// using it, we'd have to devote O(N^2) amount of code to implement all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10818 |
// combinations of m and n. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10819 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10820 |
// Declares the template parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10821 |
#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10822 |
#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10823 |
name1) kind0 name0, kind1 name1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10824 |
#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10825 |
kind2, name2) kind0 name0, kind1 name1, kind2 name2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10826 |
#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10827 |
kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10828 |
kind3 name3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10829 |
#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10830 |
kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10831 |
kind2 name2, kind3 name3, kind4 name4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10832 |
#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10833 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10834 |
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10835 |
#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10836 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10837 |
name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10838 |
kind5 name5, kind6 name6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10839 |
#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10840 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10841 |
kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10842 |
kind4 name4, kind5 name5, kind6 name6, kind7 name7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10843 |
#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10844 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10845 |
kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10846 |
kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10847 |
kind8 name8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10848 |
#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10849 |
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10850 |
name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10851 |
kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10852 |
kind6 name6, kind7 name7, kind8 name8, kind9 name9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10853 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10854 |
// Lists the template parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10855 |
#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10856 |
#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10857 |
name1) name0, name1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10858 |
#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10859 |
kind2, name2) name0, name1, name2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10860 |
#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10861 |
kind2, name2, kind3, name3) name0, name1, name2, name3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10862 |
#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10863 |
kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10864 |
name4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10865 |
#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10866 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10867 |
name2, name3, name4, name5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10868 |
#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10869 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10870 |
name6) name0, name1, name2, name3, name4, name5, name6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10871 |
#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10872 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10873 |
kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10874 |
#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10875 |
kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10876 |
kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10877 |
name6, name7, name8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10878 |
#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10879 |
name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10880 |
name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10881 |
name3, name4, name5, name6, name7, name8, name9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10882 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10883 |
// Declares the types of value parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10884 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10885 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10886 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10887 |
typename p0##_type, typename p1##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10888 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10889 |
typename p0##_type, typename p1##_type, typename p2##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10890 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10891 |
typename p0##_type, typename p1##_type, typename p2##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10892 |
typename p3##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10893 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10894 |
typename p0##_type, typename p1##_type, typename p2##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10895 |
typename p3##_type, typename p4##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10896 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10897 |
typename p0##_type, typename p1##_type, typename p2##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10898 |
typename p3##_type, typename p4##_type, typename p5##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10899 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10900 |
p6) , typename p0##_type, typename p1##_type, typename p2##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10901 |
typename p3##_type, typename p4##_type, typename p5##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10902 |
typename p6##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10903 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10904 |
p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10905 |
typename p3##_type, typename p4##_type, typename p5##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10906 |
typename p6##_type, typename p7##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10907 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10908 |
p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10909 |
typename p3##_type, typename p4##_type, typename p5##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10910 |
typename p6##_type, typename p7##_type, typename p8##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10911 |
#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10912 |
p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10913 |
typename p2##_type, typename p3##_type, typename p4##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10914 |
typename p5##_type, typename p6##_type, typename p7##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10915 |
typename p8##_type, typename p9##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10916 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10917 |
// Initializes the value parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10918 |
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10919 |
() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10920 |
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10921 |
(p0##_type gmock_p0) : p0(::std::move(gmock_p0)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10922 |
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10923 |
(p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10924 |
p1(::std::move(gmock_p1)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10925 |
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10926 |
(p0##_type gmock_p0, p1##_type gmock_p1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10927 |
p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10928 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10929 |
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10930 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10931 |
p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10932 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10933 |
p3(::std::move(gmock_p3)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10934 |
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10935 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10936 |
p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10937 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10938 |
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10939 |
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10940 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10941 |
p3##_type gmock_p3, p4##_type gmock_p4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10942 |
p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10943 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10944 |
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10945 |
p5(::std::move(gmock_p5)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10946 |
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10947 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10948 |
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10949 |
p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10950 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10951 |
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10952 |
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10953 |
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10954 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10955 |
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10956 |
p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10957 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10958 |
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10959 |
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10960 |
p7(::std::move(gmock_p7)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10961 |
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10962 |
p7, p8)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10963 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10964 |
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10965 |
p6##_type gmock_p6, p7##_type gmock_p7, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10966 |
p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10967 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10968 |
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10969 |
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10970 |
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10971 |
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10972 |
p7, p8, p9)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10973 |
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10974 |
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10975 |
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10976 |
p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10977 |
p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10978 |
p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10979 |
p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10980 |
p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10981 |
p9(::std::move(gmock_p9)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10982 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10983 |
// Defines the copy constructor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10984 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_0_VALUE_PARAMS() \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10985 |
{} // Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82134 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10986 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_1_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10987 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_2_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10988 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_3_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10989 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_4_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10990 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_5_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10991 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_6_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10992 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_7_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10993 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_8_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10994 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_9_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10995 |
#define GMOCK_INTERNAL_DEFN_COPY_AND_10_VALUE_PARAMS(...) = default; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10996 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10997 |
// Declares the fields for storing the value parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10998 |
#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
10999 |
#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11000 |
#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11001 |
p1##_type p1; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11002 |
#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11003 |
p1##_type p1; p2##_type p2; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11004 |
#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11005 |
p1##_type p1; p2##_type p2; p3##_type p3; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11006 |
#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11007 |
p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11008 |
#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11009 |
p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11010 |
p5##_type p5; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11011 |
#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11012 |
p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11013 |
p5##_type p5; p6##_type p6; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11014 |
#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11015 |
p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11016 |
p5##_type p5; p6##_type p6; p7##_type p7; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11017 |
#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11018 |
p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11019 |
p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11020 |
#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11021 |
p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11022 |
p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11023 |
p9##_type p9; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11024 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11025 |
// Lists the value parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11026 |
#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11027 |
#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11028 |
#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11029 |
#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11030 |
#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11031 |
#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11032 |
p2, p3, p4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11033 |
#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11034 |
p1, p2, p3, p4, p5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11035 |
#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11036 |
p6) p0, p1, p2, p3, p4, p5, p6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11037 |
#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11038 |
p7) p0, p1, p2, p3, p4, p5, p6, p7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11039 |
#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11040 |
p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11041 |
#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11042 |
p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11043 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11044 |
// Lists the value parameter types. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11045 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11046 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11047 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11048 |
p1##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11049 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11050 |
p1##_type, p2##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11051 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11052 |
p0##_type, p1##_type, p2##_type, p3##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11053 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11054 |
p0##_type, p1##_type, p2##_type, p3##_type, p4##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11055 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11056 |
p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11057 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11058 |
p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11059 |
p6##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11060 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11061 |
p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11062 |
p5##_type, p6##_type, p7##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11063 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11064 |
p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11065 |
p5##_type, p6##_type, p7##_type, p8##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11066 |
#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11067 |
p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11068 |
p5##_type, p6##_type, p7##_type, p8##_type, p9##_type |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11069 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11070 |
// Declares the value parameters. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11071 |
#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11072 |
#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11073 |
#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11074 |
p1##_type p1 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11075 |
#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11076 |
p1##_type p1, p2##_type p2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11077 |
#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11078 |
p1##_type p1, p2##_type p2, p3##_type p3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11079 |
#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11080 |
p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11081 |
#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11082 |
p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11083 |
p5##_type p5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11084 |
#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11085 |
p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11086 |
p5##_type p5, p6##_type p6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11087 |
#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11088 |
p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11089 |
p5##_type p5, p6##_type p6, p7##_type p7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11090 |
#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11091 |
p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11092 |
p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11093 |
#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11094 |
p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11095 |
p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11096 |
p9##_type p9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11097 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11098 |
// The suffix of the class template implementing the action template. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11099 |
#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS() |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11100 |
#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11101 |
#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11102 |
#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11103 |
#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11104 |
#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11105 |
#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11106 |
#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11107 |
#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11108 |
p7) P8 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11109 |
#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11110 |
p7, p8) P9 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11111 |
#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11112 |
p7, p8, p9) P10 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11113 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11114 |
// The name of the class template implementing the action template. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11115 |
#define GMOCK_ACTION_CLASS_(name, value_params)\ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11116 |
GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11117 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11118 |
#define ACTION_TEMPLATE(name, template_params, value_params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11119 |
template <GMOCK_INTERNAL_DECL_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11120 |
GMOCK_INTERNAL_DECL_TYPE_##value_params> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11121 |
class GMOCK_ACTION_CLASS_(name, value_params) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11122 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11123 |
explicit GMOCK_ACTION_CLASS_(name, value_params)( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11124 |
GMOCK_INTERNAL_DECL_##value_params) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11125 |
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11126 |
= default; , \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11127 |
: impl_(std::make_shared<gmock_Impl>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11128 |
GMOCK_INTERNAL_LIST_##value_params)) { }) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11129 |
GMOCK_ACTION_CLASS_(name, value_params)( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11130 |
const GMOCK_ACTION_CLASS_(name, value_params)&) noexcept \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11131 |
GMOCK_INTERNAL_DEFN_COPY_##value_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11132 |
GMOCK_ACTION_CLASS_(name, value_params)( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11133 |
GMOCK_ACTION_CLASS_(name, value_params)&&) noexcept \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11134 |
GMOCK_INTERNAL_DEFN_COPY_##value_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11135 |
template <typename F> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11136 |
operator ::testing::Action<F>() const { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11137 |
return GMOCK_PP_IF( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11138 |
GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11139 |
(::testing::internal::MakeAction<F, gmock_Impl>()), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11140 |
(::testing::internal::MakeAction<F>(impl_))); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11141 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11142 |
private: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11143 |
class gmock_Impl { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11144 |
public: \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11145 |
explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11146 |
template <typename function_type, typename return_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11147 |
typename args_type, GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11148 |
return_type gmock_PerformImpl(GMOCK_ACTION_ARG_TYPES_AND_NAMES_) const; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11149 |
GMOCK_INTERNAL_DEFN_##value_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11150 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11151 |
GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(GMOCK_INTERNAL_COUNT_##value_params), \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11152 |
, std::shared_ptr<const gmock_Impl> impl_;) \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11153 |
}; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11154 |
template <GMOCK_INTERNAL_DECL_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11155 |
GMOCK_INTERNAL_DECL_TYPE_##value_params> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11156 |
GMOCK_ACTION_CLASS_(name, value_params)< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11157 |
GMOCK_INTERNAL_LIST_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11158 |
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11159 |
GMOCK_INTERNAL_DECL_##value_params) GTEST_MUST_USE_RESULT_; \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11160 |
template <GMOCK_INTERNAL_DECL_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11161 |
GMOCK_INTERNAL_DECL_TYPE_##value_params> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11162 |
inline GMOCK_ACTION_CLASS_(name, value_params)< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11163 |
GMOCK_INTERNAL_LIST_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11164 |
GMOCK_INTERNAL_LIST_TYPE_##value_params> name( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11165 |
GMOCK_INTERNAL_DECL_##value_params) { \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11166 |
return GMOCK_ACTION_CLASS_(name, value_params)< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11167 |
GMOCK_INTERNAL_LIST_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11168 |
GMOCK_INTERNAL_LIST_TYPE_##value_params>( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11169 |
GMOCK_INTERNAL_LIST_##value_params); \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11170 |
} \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11171 |
template <GMOCK_INTERNAL_DECL_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11172 |
GMOCK_INTERNAL_DECL_TYPE_##value_params> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11173 |
template <typename function_type, typename return_type, typename args_type, \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11174 |
GMOCK_ACTION_TEMPLATE_ARGS_NAMES_> \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11175 |
return_type GMOCK_ACTION_CLASS_(name, value_params)< \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11176 |
GMOCK_INTERNAL_LIST_##template_params \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11177 |
GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::gmock_PerformImpl( \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11178 |
GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11179 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11180 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11181 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11182 |
// The ACTION*() macros trigger warning C4100 (unreferenced formal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11183 |
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11184 |
// the macro definition, as the warnings are generated when the macro |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11185 |
// is expanded and macro expansion cannot contain #pragma. Therefore |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11186 |
// we suppress them here. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11187 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11188 |
# pragma warning(push) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11189 |
# pragma warning(disable:4100) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11190 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11191 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11192 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11193 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11194 |
// internal::InvokeArgument - a helper for InvokeArgument action. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11195 |
// The basic overloads are provided here for generic functors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11196 |
// Overloads for other custom-callables are provided in the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11197 |
// internal/custom/gmock-generated-actions.h header. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11198 |
template <typename F, typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11199 |
auto InvokeArgument(F f, Args... args) -> decltype(f(args...)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11200 |
return f(args...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11201 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11202 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11203 |
template <std::size_t index, typename... Params> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11204 |
struct InvokeArgumentAction { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11205 |
template <typename... Args> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11206 |
auto operator()(Args&&... args) const -> decltype(internal::InvokeArgument( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11207 |
std::get<index>(std::forward_as_tuple(std::forward<Args>(args)...)), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11208 |
std::declval<const Params&>()...)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11209 |
internal::FlatTuple<Args&&...> args_tuple(FlatTupleConstructTag{}, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11210 |
std::forward<Args>(args)...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11211 |
return params.Apply([&](const Params&... unpacked_params) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11212 |
auto&& callable = args_tuple.template Get<index>(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11213 |
return internal::InvokeArgument( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11214 |
std::forward<decltype(callable)>(callable), unpacked_params...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11215 |
}); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11216 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11217 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11218 |
internal::FlatTuple<Params...> params; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11219 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11220 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11221 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11222 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11223 |
// The InvokeArgument<N>(a1, a2, ..., a_k) action invokes the N-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11224 |
// (0-based) argument, which must be a k-ary callable, of the mock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11225 |
// function, with arguments a1, a2, ..., a_k. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11226 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11227 |
// Notes: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11228 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11229 |
// 1. The arguments are passed by value by default. If you need to |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11230 |
// pass an argument by reference, wrap it inside std::ref(). For |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11231 |
// example, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11232 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11233 |
// InvokeArgument<1>(5, string("Hello"), std::ref(foo)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11234 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11235 |
// passes 5 and string("Hello") by value, and passes foo by |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11236 |
// reference. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11237 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11238 |
// 2. If the callable takes an argument by reference but std::ref() is |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11239 |
// not used, it will receive the reference to a copy of the value, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11240 |
// instead of the original value. For example, when the 0-th |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11241 |
// argument of the mock function takes a const string&, the action |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11242 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11243 |
// InvokeArgument<0>(string("Hello")) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11244 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11245 |
// makes a copy of the temporary string("Hello") object and passes a |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11246 |
// reference of the copy, instead of the original temporary object, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11247 |
// to the callable. This makes it easy for a user to define an |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11248 |
// InvokeArgument action from temporary values and have it performed |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11249 |
// later. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11250 |
template <std::size_t index, typename... Params> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11251 |
internal::InvokeArgumentAction<index, typename std::decay<Params>::type...> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11252 |
InvokeArgument(Params&&... params) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11253 |
return {internal::FlatTuple<typename std::decay<Params>::type...>( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11254 |
internal::FlatTupleConstructTag{}, std::forward<Params>(params)...)}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11255 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11256 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11257 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11258 |
# pragma warning(pop) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11259 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11260 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11261 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11262 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11263 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11264 |
// Copyright 2013, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11265 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11266 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11267 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11268 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11269 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11270 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11271 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11272 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11273 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11274 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11275 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11276 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11277 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11278 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11279 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11280 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11281 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11282 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11283 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11284 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11285 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11286 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11287 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11288 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11289 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11290 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11291 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11292 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11293 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11294 |
// Google Mock - a framework for writing C++ mock classes. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11295 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11296 |
// This file implements some matchers that depend on gmock-matchers.h. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11297 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11298 |
// Note that tests are implemented in gmock-matchers_test.cc rather than |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11299 |
// gmock-more-matchers-test.cc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11300 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11301 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11302 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11303 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11304 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11305 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11306 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11307 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11308 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11309 |
// Silence C4100 (unreferenced formal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11310 |
// parameter) for MSVC |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11311 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11312 |
# pragma warning(push) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11313 |
# pragma warning(disable:4100) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11314 |
#if (_MSC_VER == 1900) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11315 |
// and silence C4800 (C4800: 'int *const ': forcing value |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11316 |
// to bool 'true' or 'false') for MSVC 14 |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11317 |
# pragma warning(disable:4800) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11318 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11319 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11320 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11321 |
// Defines a matcher that matches an empty container. The container must |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11322 |
// support both size() and empty(), which all STL-like containers provide. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11323 |
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11324 |
if (arg.empty()) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11325 |
return true; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11326 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11327 |
*result_listener << "whose size is " << arg.size(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11328 |
return false; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11329 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11330 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11331 |
// Define a matcher that matches a value that evaluates in boolean |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11332 |
// context to true. Useful for types that define "explicit operator |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11333 |
// bool" operators and so can't be compared for equality with true |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11334 |
// and false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11335 |
MATCHER(IsTrue, negation ? "is false" : "is true") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11336 |
return static_cast<bool>(arg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11337 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11338 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11339 |
// Define a matcher that matches a value that evaluates in boolean |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11340 |
// context to false. Useful for types that define "explicit operator |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11341 |
// bool" operators and so can't be compared for equality with true |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11342 |
// and false. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11343 |
MATCHER(IsFalse, negation ? "is true" : "is false") { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11344 |
return !static_cast<bool>(arg); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11345 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11346 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11347 |
#ifdef _MSC_VER |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11348 |
# pragma warning(pop) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11349 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11350 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11351 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11352 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11353 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11354 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11355 |
// Copyright 2008, Google Inc. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11356 |
// All rights reserved. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11357 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11358 |
// Redistribution and use in source and binary forms, with or without |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11359 |
// modification, are permitted provided that the following conditions are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11360 |
// met: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11361 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11362 |
// * Redistributions of source code must retain the above copyright |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11363 |
// notice, this list of conditions and the following disclaimer. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11364 |
// * Redistributions in binary form must reproduce the above |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11365 |
// copyright notice, this list of conditions and the following disclaimer |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11366 |
// in the documentation and/or other materials provided with the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11367 |
// distribution. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11368 |
// * Neither the name of Google Inc. nor the names of its |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11369 |
// contributors may be used to endorse or promote products derived from |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11370 |
// this software without specific prior written permission. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11371 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11372 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11373 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11374 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11375 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11376 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11377 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11378 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11379 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11380 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11381 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11382 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11383 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11384 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11385 |
// Implements class templates NiceMock, NaggyMock, and StrictMock. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11386 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11387 |
// Given a mock class MockFoo that is created using Google Mock, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11388 |
// NiceMock<MockFoo> is a subclass of MockFoo that allows |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11389 |
// uninteresting calls (i.e. calls to mock methods that have no |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11390 |
// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11391 |
// that prints a warning when an uninteresting call occurs, and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11392 |
// StrictMock<MockFoo> is a subclass of MockFoo that treats all |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11393 |
// uninteresting calls as errors. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11394 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11395 |
// Currently a mock is naggy by default, so MockFoo and |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11396 |
// NaggyMock<MockFoo> behave like the same. However, we will soon |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11397 |
// switch the default behavior of mocks to be nice, as that in general |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11398 |
// leads to more maintainable tests. When that happens, MockFoo will |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11399 |
// stop behaving like NaggyMock<MockFoo> and start behaving like |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11400 |
// NiceMock<MockFoo>. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11401 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11402 |
// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11403 |
// their respective base class. Therefore you can write |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11404 |
// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11405 |
// has a constructor that accepts (int, const char*), for example. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11406 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11407 |
// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11408 |
// and StrictMock<MockFoo> only works for mock methods defined using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11409 |
// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11410 |
// If a mock method is defined in a base class of MockFoo, the "nice" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11411 |
// or "strict" modifier may not affect it, depending on the compiler. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11412 |
// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11413 |
// supported. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11414 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11415 |
// GOOGLETEST_CM0002 DO NOT DELETE |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11416 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11417 |
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11418 |
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11419 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11420 |
#include <type_traits> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11421 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11422 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11423 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11424 |
template <class MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11425 |
class NiceMock; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11426 |
template <class MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11427 |
class NaggyMock; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11428 |
template <class MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11429 |
class StrictMock; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11430 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11431 |
namespace internal { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11432 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11433 |
std::true_type StrictnessModifierProbe(const NiceMock<T>&); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11434 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11435 |
std::true_type StrictnessModifierProbe(const NaggyMock<T>&); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11436 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11437 |
std::true_type StrictnessModifierProbe(const StrictMock<T>&); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11438 |
std::false_type StrictnessModifierProbe(...); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11439 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11440 |
template <typename T> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11441 |
constexpr bool HasStrictnessModifier() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11442 |
return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11443 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11444 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11445 |
// Base classes that register and deregister with testing::Mock to alter the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11446 |
// default behavior around uninteresting calls. Inheriting from one of these |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11447 |
// classes first and then MockClass ensures the MockClass constructor is run |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11448 |
// after registration, and that the MockClass destructor runs before |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11449 |
// deregistration. This guarantees that MockClass's constructor and destructor |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11450 |
// run with the same level of strictness as its instance methods. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11451 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11452 |
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW && \ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11453 |
(defined(_MSC_VER) || defined(__clang__)) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11454 |
// We need to mark these classes with this declspec to ensure that |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11455 |
// the empty base class optimization is performed. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11456 |
#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11457 |
#else |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11458 |
#define GTEST_INTERNAL_EMPTY_BASE_CLASS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11459 |
#endif |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11460 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11461 |
template <typename Base> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11462 |
class NiceMockImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11463 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11464 |
NiceMockImpl() { ::testing::Mock::AllowUninterestingCalls(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11465 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11466 |
~NiceMockImpl() { ::testing::Mock::UnregisterCallReaction(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11467 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11468 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11469 |
template <typename Base> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11470 |
class NaggyMockImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11471 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11472 |
NaggyMockImpl() { ::testing::Mock::WarnUninterestingCalls(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11473 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11474 |
~NaggyMockImpl() { ::testing::Mock::UnregisterCallReaction(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11475 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11476 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11477 |
template <typename Base> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11478 |
class StrictMockImpl { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11479 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11480 |
StrictMockImpl() { ::testing::Mock::FailUninterestingCalls(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11481 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11482 |
~StrictMockImpl() { ::testing::Mock::UnregisterCallReaction(this); } |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11483 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11484 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11485 |
} // namespace internal |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11486 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11487 |
template <class MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11488 |
class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11489 |
: private internal::NiceMockImpl<MockClass>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11490 |
public MockClass { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11491 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11492 |
static_assert(!internal::HasStrictnessModifier<MockClass>(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11493 |
"Can't apply NiceMock to a class hierarchy that already has a " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11494 |
"strictness modifier. See " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11495 |
"https://google.github.io/googletest/" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11496 |
"gmock_cook_book.html#NiceStrictNaggy"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11497 |
NiceMock() : MockClass() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11498 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11499 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11500 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11501 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11502 |
// Ideally, we would inherit base class's constructors through a using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11503 |
// declaration, which would preserve their visibility. However, many existing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11504 |
// tests rely on the fact that current implementation reexports protected |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11505 |
// constructors as public. These tests would need to be cleaned up first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11506 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11507 |
// Single argument constructor is special-cased so that it can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11508 |
// made explicit. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11509 |
template <typename A> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11510 |
explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11511 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11512 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11513 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11514 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11515 |
template <typename TArg1, typename TArg2, typename... An> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11516 |
NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11517 |
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11518 |
std::forward<An>(args)...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11519 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11520 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11521 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11522 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11523 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11524 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11525 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11526 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11527 |
template <class MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11528 |
class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11529 |
: private internal::NaggyMockImpl<MockClass>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11530 |
public MockClass { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11531 |
static_assert(!internal::HasStrictnessModifier<MockClass>(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11532 |
"Can't apply NaggyMock to a class hierarchy that already has a " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11533 |
"strictness modifier. See " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11534 |
"https://google.github.io/googletest/" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11535 |
"gmock_cook_book.html#NiceStrictNaggy"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11536 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11537 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11538 |
NaggyMock() : MockClass() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11539 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11540 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11541 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11542 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11543 |
// Ideally, we would inherit base class's constructors through a using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11544 |
// declaration, which would preserve their visibility. However, many existing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11545 |
// tests rely on the fact that current implementation reexports protected |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11546 |
// constructors as public. These tests would need to be cleaned up first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11547 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11548 |
// Single argument constructor is special-cased so that it can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11549 |
// made explicit. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11550 |
template <typename A> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11551 |
explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11552 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11553 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11554 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11555 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11556 |
template <typename TArg1, typename TArg2, typename... An> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11557 |
NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11558 |
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11559 |
std::forward<An>(args)...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11560 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11561 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11562 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11563 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11564 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11565 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11566 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11567 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11568 |
template <class MockClass> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11569 |
class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11570 |
: private internal::StrictMockImpl<MockClass>, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11571 |
public MockClass { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11572 |
public: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11573 |
static_assert( |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11574 |
!internal::HasStrictnessModifier<MockClass>(), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11575 |
"Can't apply StrictMock to a class hierarchy that already has a " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11576 |
"strictness modifier. See " |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11577 |
"https://google.github.io/googletest/" |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11578 |
"gmock_cook_book.html#NiceStrictNaggy"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11579 |
StrictMock() : MockClass() { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11580 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11581 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11582 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11583 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11584 |
// Ideally, we would inherit base class's constructors through a using |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11585 |
// declaration, which would preserve their visibility. However, many existing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11586 |
// tests rely on the fact that current implementation reexports protected |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11587 |
// constructors as public. These tests would need to be cleaned up first. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11588 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11589 |
// Single argument constructor is special-cased so that it can be |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11590 |
// made explicit. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11591 |
template <typename A> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11592 |
explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11593 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11594 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11595 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11596 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11597 |
template <typename TArg1, typename TArg2, typename... An> |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11598 |
StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args) |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11599 |
: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11600 |
std::forward<An>(args)...) { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11601 |
static_assert(sizeof(*this) == sizeof(MockClass), |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11602 |
"The impl subclass shouldn't introduce any padding"); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11603 |
} |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11604 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11605 |
private: |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11606 |
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11607 |
}; |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11608 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11609 |
#undef GTEST_INTERNAL_EMPTY_BASE_CLASS |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11610 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11611 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11612 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11613 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11614 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11615 |
namespace testing { |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11616 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11617 |
// Declares Google Mock flags that we want a user to use programmatically. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11618 |
GMOCK_DECLARE_bool_(catch_leaked_mocks); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11619 |
GMOCK_DECLARE_string_(verbose); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11620 |
GMOCK_DECLARE_int32_(default_mock_behavior); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11621 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11622 |
// Initializes Google Mock. This must be called before running the |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11623 |
// tests. In particular, it parses the command line for the flags |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11624 |
// that Google Mock recognizes. Whenever a Google Mock flag is seen, |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11625 |
// it is removed from argv, and *argc is decremented. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11626 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11627 |
// No value is returned. Instead, the Google Mock flag variables are |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11628 |
// updated. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11629 |
// |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11630 |
// Since Google Test is needed for Google Mock to work, this function |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11631 |
// also initializes Google Test and parses its flags, if that hasn't |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11632 |
// been done. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11633 |
GTEST_API_ void InitGoogleMock(int* argc, char** argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11634 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11635 |
// This overloaded version can be used in Windows programs compiled in |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11636 |
// UNICODE mode. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11637 |
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11638 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11639 |
// This overloaded version can be used on Arduino/embedded platforms where |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11640 |
// there is no argc/argv. |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11641 |
GTEST_API_ void InitGoogleMock(); |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11642 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11643 |
} // namespace testing |
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11644 |
|
| f8deb5b9 |
Poul Sander |
2022-01-15 13:55 |
11645 |
#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ |
|
|
1970-01-01 00:00 |
11646 |
|