]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | // Copyright 2007, Google Inc. |
2 | // All rights reserved. | |
3 | // | |
4 | // Redistribution and use in source and binary forms, with or without | |
5 | // modification, are permitted provided that the following conditions are | |
6 | // met: | |
7 | // | |
8 | // * Redistributions of source code must retain the above copyright | |
9 | // notice, this list of conditions and the following disclaimer. | |
10 | // * Redistributions in binary form must reproduce the above | |
11 | // copyright notice, this list of conditions and the following disclaimer | |
12 | // in the documentation and/or other materials provided with the | |
13 | // distribution. | |
14 | // * Neither the name of Google Inc. nor the names of its | |
15 | // contributors may be used to endorse or promote products derived from | |
16 | // this software without specific prior written permission. | |
17 | // | |
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 | // | |
30 | // Author: wan@google.com (Zhanyong Wan) | |
31 | ||
32 | // Google Mock - a framework for writing C++ mock classes. | |
33 | // | |
34 | // This file tests the built-in actions generated by a script. | |
35 | ||
36 | #include "gmock/gmock-generated-actions.h" | |
37 | ||
38 | #include <functional> | |
39 | #include <sstream> | |
40 | #include <string> | |
41 | #include "gmock/gmock.h" | |
42 | #include "gtest/gtest.h" | |
43 | ||
44 | namespace testing { | |
45 | namespace gmock_generated_actions_test { | |
46 | ||
47 | using ::std::plus; | |
48 | using ::std::string; | |
49 | using testing::get; | |
50 | using testing::make_tuple; | |
51 | using testing::tuple; | |
52 | using testing::tuple_element; | |
53 | using testing::_; | |
54 | using testing::Action; | |
55 | using testing::ActionInterface; | |
56 | using testing::ByRef; | |
57 | using testing::DoAll; | |
58 | using testing::Invoke; | |
59 | using testing::Return; | |
60 | using testing::ReturnNew; | |
61 | using testing::SetArgPointee; | |
62 | using testing::StaticAssertTypeEq; | |
63 | using testing::Unused; | |
64 | using testing::WithArgs; | |
65 | ||
66 | // For suppressing compiler warnings on conversion possibly losing precision. | |
67 | inline short Short(short n) { return n; } // NOLINT | |
68 | inline char Char(char ch) { return ch; } | |
69 | ||
70 | // Sample functions and functors for testing various actions. | |
71 | int Nullary() { return 1; } | |
72 | ||
73 | class NullaryFunctor { | |
74 | public: | |
75 | int operator()() { return 2; } | |
76 | }; | |
77 | ||
78 | bool g_done = false; | |
79 | ||
80 | bool Unary(int x) { return x < 0; } | |
81 | ||
82 | const char* Plus1(const char* s) { return s + 1; } | |
83 | ||
84 | bool ByConstRef(const string& s) { return s == "Hi"; } | |
85 | ||
86 | const double g_double = 0; | |
87 | bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; } | |
88 | ||
89 | string ByNonConstRef(string& s) { return s += "+"; } // NOLINT | |
90 | ||
91 | struct UnaryFunctor { | |
92 | int operator()(bool x) { return x ? 1 : -1; } | |
93 | }; | |
94 | ||
95 | const char* Binary(const char* input, short n) { return input + n; } // NOLINT | |
96 | ||
97 | void VoidBinary(int, char) { g_done = true; } | |
98 | ||
99 | int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT | |
100 | ||
101 | void VoidTernary(int, char, bool) { g_done = true; } | |
102 | ||
103 | int SumOf4(int a, int b, int c, int d) { return a + b + c + d; } | |
104 | ||
105 | string Concat4(const char* s1, const char* s2, const char* s3, | |
106 | const char* s4) { | |
107 | return string(s1) + s2 + s3 + s4; | |
108 | } | |
109 | ||
110 | int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; } | |
111 | ||
112 | struct SumOf5Functor { | |
113 | int operator()(int a, int b, int c, int d, int e) { | |
114 | return a + b + c + d + e; | |
115 | } | |
116 | }; | |
117 | ||
118 | string Concat5(const char* s1, const char* s2, const char* s3, | |
119 | const char* s4, const char* s5) { | |
120 | return string(s1) + s2 + s3 + s4 + s5; | |
121 | } | |
122 | ||
123 | int SumOf6(int a, int b, int c, int d, int e, int f) { | |
124 | return a + b + c + d + e + f; | |
125 | } | |
126 | ||
127 | struct SumOf6Functor { | |
128 | int operator()(int a, int b, int c, int d, int e, int f) { | |
129 | return a + b + c + d + e + f; | |
130 | } | |
131 | }; | |
132 | ||
133 | string Concat6(const char* s1, const char* s2, const char* s3, | |
134 | const char* s4, const char* s5, const char* s6) { | |
135 | return string(s1) + s2 + s3 + s4 + s5 + s6; | |
136 | } | |
137 | ||
138 | string Concat7(const char* s1, const char* s2, const char* s3, | |
139 | const char* s4, const char* s5, const char* s6, | |
140 | const char* s7) { | |
141 | return string(s1) + s2 + s3 + s4 + s5 + s6 + s7; | |
142 | } | |
143 | ||
144 | string Concat8(const char* s1, const char* s2, const char* s3, | |
145 | const char* s4, const char* s5, const char* s6, | |
146 | const char* s7, const char* s8) { | |
147 | return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8; | |
148 | } | |
149 | ||
150 | string Concat9(const char* s1, const char* s2, const char* s3, | |
151 | const char* s4, const char* s5, const char* s6, | |
152 | const char* s7, const char* s8, const char* s9) { | |
153 | return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9; | |
154 | } | |
155 | ||
156 | string Concat10(const char* s1, const char* s2, const char* s3, | |
157 | const char* s4, const char* s5, const char* s6, | |
158 | const char* s7, const char* s8, const char* s9, | |
159 | const char* s10) { | |
160 | return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10; | |
161 | } | |
162 | ||
163 | // A helper that turns the type of a C-string literal from const | |
164 | // char[N] to const char*. | |
165 | inline const char* CharPtr(const char* s) { return s; } | |
166 | ||
167 | // Tests InvokeArgument<N>(...). | |
168 | ||
169 | // Tests using InvokeArgument with a nullary function. | |
170 | TEST(InvokeArgumentTest, Function0) { | |
171 | Action<int(int, int(*)())> a = InvokeArgument<1>(); // NOLINT | |
172 | EXPECT_EQ(1, a.Perform(make_tuple(2, &Nullary))); | |
173 | } | |
174 | ||
175 | // Tests using InvokeArgument with a unary function. | |
176 | TEST(InvokeArgumentTest, Functor1) { | |
177 | Action<int(UnaryFunctor)> a = InvokeArgument<0>(true); // NOLINT | |
178 | EXPECT_EQ(1, a.Perform(make_tuple(UnaryFunctor()))); | |
179 | } | |
180 | ||
181 | // Tests using InvokeArgument with a 5-ary function. | |
182 | TEST(InvokeArgumentTest, Function5) { | |
183 | Action<int(int(*)(int, int, int, int, int))> a = // NOLINT | |
184 | InvokeArgument<0>(10000, 2000, 300, 40, 5); | |
185 | EXPECT_EQ(12345, a.Perform(make_tuple(&SumOf5))); | |
186 | } | |
187 | ||
188 | // Tests using InvokeArgument with a 5-ary functor. | |
189 | TEST(InvokeArgumentTest, Functor5) { | |
190 | Action<int(SumOf5Functor)> a = // NOLINT | |
191 | InvokeArgument<0>(10000, 2000, 300, 40, 5); | |
192 | EXPECT_EQ(12345, a.Perform(make_tuple(SumOf5Functor()))); | |
193 | } | |
194 | ||
195 | // Tests using InvokeArgument with a 6-ary function. | |
196 | TEST(InvokeArgumentTest, Function6) { | |
197 | Action<int(int(*)(int, int, int, int, int, int))> a = // NOLINT | |
198 | InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6); | |
199 | EXPECT_EQ(123456, a.Perform(make_tuple(&SumOf6))); | |
200 | } | |
201 | ||
202 | // Tests using InvokeArgument with a 6-ary functor. | |
203 | TEST(InvokeArgumentTest, Functor6) { | |
204 | Action<int(SumOf6Functor)> a = // NOLINT | |
205 | InvokeArgument<0>(100000, 20000, 3000, 400, 50, 6); | |
206 | EXPECT_EQ(123456, a.Perform(make_tuple(SumOf6Functor()))); | |
207 | } | |
208 | ||
209 | // Tests using InvokeArgument with a 7-ary function. | |
210 | TEST(InvokeArgumentTest, Function7) { | |
211 | Action<string(string(*)(const char*, const char*, const char*, | |
212 | const char*, const char*, const char*, | |
213 | const char*))> a = | |
214 | InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7"); | |
215 | EXPECT_EQ("1234567", a.Perform(make_tuple(&Concat7))); | |
216 | } | |
217 | ||
218 | // Tests using InvokeArgument with a 8-ary function. | |
219 | TEST(InvokeArgumentTest, Function8) { | |
220 | Action<string(string(*)(const char*, const char*, const char*, | |
221 | const char*, const char*, const char*, | |
222 | const char*, const char*))> a = | |
223 | InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8"); | |
224 | EXPECT_EQ("12345678", a.Perform(make_tuple(&Concat8))); | |
225 | } | |
226 | ||
227 | // Tests using InvokeArgument with a 9-ary function. | |
228 | TEST(InvokeArgumentTest, Function9) { | |
229 | Action<string(string(*)(const char*, const char*, const char*, | |
230 | const char*, const char*, const char*, | |
231 | const char*, const char*, const char*))> a = | |
232 | InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9"); | |
233 | EXPECT_EQ("123456789", a.Perform(make_tuple(&Concat9))); | |
234 | } | |
235 | ||
236 | // Tests using InvokeArgument with a 10-ary function. | |
237 | TEST(InvokeArgumentTest, Function10) { | |
238 | Action<string(string(*)(const char*, const char*, const char*, | |
239 | const char*, const char*, const char*, | |
240 | const char*, const char*, const char*, | |
241 | const char*))> a = | |
242 | InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0"); | |
243 | EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10))); | |
244 | } | |
245 | ||
246 | // Tests using InvokeArgument with a function that takes a pointer argument. | |
247 | TEST(InvokeArgumentTest, ByPointerFunction) { | |
248 | Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT | |
249 | InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1)); | |
250 | EXPECT_STREQ("i", a.Perform(make_tuple(&Binary))); | |
251 | } | |
252 | ||
253 | // Tests using InvokeArgument with a function that takes a const char* | |
254 | // by passing it a C-string literal. | |
255 | TEST(InvokeArgumentTest, FunctionWithCStringLiteral) { | |
256 | Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT | |
257 | InvokeArgument<0>("Hi", Short(1)); | |
258 | EXPECT_STREQ("i", a.Perform(make_tuple(&Binary))); | |
259 | } | |
260 | ||
261 | // Tests using InvokeArgument with a function that takes a const reference. | |
262 | TEST(InvokeArgumentTest, ByConstReferenceFunction) { | |
263 | Action<bool(bool(*function)(const string& s))> a = // NOLINT | |
264 | InvokeArgument<0>(string("Hi")); | |
265 | // When action 'a' is constructed, it makes a copy of the temporary | |
266 | // string object passed to it, so it's OK to use 'a' later, when the | |
267 | // temporary object has already died. | |
268 | EXPECT_TRUE(a.Perform(make_tuple(&ByConstRef))); | |
269 | } | |
270 | ||
271 | // Tests using InvokeArgument with ByRef() and a function that takes a | |
272 | // const reference. | |
273 | TEST(InvokeArgumentTest, ByExplicitConstReferenceFunction) { | |
274 | Action<bool(bool(*)(const double& x))> a = // NOLINT | |
275 | InvokeArgument<0>(ByRef(g_double)); | |
276 | // The above line calls ByRef() on a const value. | |
277 | EXPECT_TRUE(a.Perform(make_tuple(&ReferencesGlobalDouble))); | |
278 | ||
279 | double x = 0; | |
280 | a = InvokeArgument<0>(ByRef(x)); // This calls ByRef() on a non-const. | |
281 | EXPECT_FALSE(a.Perform(make_tuple(&ReferencesGlobalDouble))); | |
282 | } | |
283 | ||
284 | // Tests using WithArgs and with an action that takes 1 argument. | |
285 | TEST(WithArgsTest, OneArg) { | |
286 | Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT | |
287 | EXPECT_TRUE(a.Perform(make_tuple(1.5, -1))); | |
288 | EXPECT_FALSE(a.Perform(make_tuple(1.5, 1))); | |
289 | } | |
290 | ||
291 | // Tests using WithArgs with an action that takes 2 arguments. | |
292 | TEST(WithArgsTest, TwoArgs) { | |
293 | Action<const char*(const char* s, double x, short n)> a = | |
294 | WithArgs<0, 2>(Invoke(Binary)); | |
295 | const char s[] = "Hello"; | |
296 | EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2)))); | |
297 | } | |
298 | ||
299 | // Tests using WithArgs with an action that takes 3 arguments. | |
300 | TEST(WithArgsTest, ThreeArgs) { | |
301 | Action<int(int, double, char, short)> a = // NOLINT | |
302 | WithArgs<0, 2, 3>(Invoke(Ternary)); | |
303 | EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3)))); | |
304 | } | |
305 | ||
306 | // Tests using WithArgs with an action that takes 4 arguments. | |
307 | TEST(WithArgsTest, FourArgs) { | |
308 | Action<string(const char*, const char*, double, const char*, const char*)> a = | |
309 | WithArgs<4, 3, 1, 0>(Invoke(Concat4)); | |
310 | EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5, | |
311 | CharPtr("3"), CharPtr("4")))); | |
312 | } | |
313 | ||
314 | // Tests using WithArgs with an action that takes 5 arguments. | |
315 | TEST(WithArgsTest, FiveArgs) { | |
316 | Action<string(const char*, const char*, const char*, | |
317 | const char*, const char*)> a = | |
318 | WithArgs<4, 3, 2, 1, 0>(Invoke(Concat5)); | |
319 | EXPECT_EQ("43210", | |
320 | a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), | |
321 | CharPtr("3"), CharPtr("4")))); | |
322 | } | |
323 | ||
324 | // Tests using WithArgs with an action that takes 6 arguments. | |
325 | TEST(WithArgsTest, SixArgs) { | |
326 | Action<string(const char*, const char*, const char*)> a = | |
327 | WithArgs<0, 1, 2, 2, 1, 0>(Invoke(Concat6)); | |
328 | EXPECT_EQ("012210", | |
329 | a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2")))); | |
330 | } | |
331 | ||
332 | // Tests using WithArgs with an action that takes 7 arguments. | |
333 | TEST(WithArgsTest, SevenArgs) { | |
334 | Action<string(const char*, const char*, const char*, const char*)> a = | |
335 | WithArgs<0, 1, 2, 3, 2, 1, 0>(Invoke(Concat7)); | |
336 | EXPECT_EQ("0123210", | |
337 | a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), | |
338 | CharPtr("3")))); | |
339 | } | |
340 | ||
341 | // Tests using WithArgs with an action that takes 8 arguments. | |
342 | TEST(WithArgsTest, EightArgs) { | |
343 | Action<string(const char*, const char*, const char*, const char*)> a = | |
344 | WithArgs<0, 1, 2, 3, 0, 1, 2, 3>(Invoke(Concat8)); | |
345 | EXPECT_EQ("01230123", | |
346 | a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), | |
347 | CharPtr("3")))); | |
348 | } | |
349 | ||
350 | // Tests using WithArgs with an action that takes 9 arguments. | |
351 | TEST(WithArgsTest, NineArgs) { | |
352 | Action<string(const char*, const char*, const char*, const char*)> a = | |
353 | WithArgs<0, 1, 2, 3, 1, 2, 3, 2, 3>(Invoke(Concat9)); | |
354 | EXPECT_EQ("012312323", | |
355 | a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), | |
356 | CharPtr("3")))); | |
357 | } | |
358 | ||
359 | // Tests using WithArgs with an action that takes 10 arguments. | |
360 | TEST(WithArgsTest, TenArgs) { | |
361 | Action<string(const char*, const char*, const char*, const char*)> a = | |
362 | WithArgs<0, 1, 2, 3, 2, 1, 0, 1, 2, 3>(Invoke(Concat10)); | |
363 | EXPECT_EQ("0123210123", | |
364 | a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), CharPtr("2"), | |
365 | CharPtr("3")))); | |
366 | } | |
367 | ||
368 | // Tests using WithArgs with an action that is not Invoke(). | |
369 | class SubstractAction : public ActionInterface<int(int, int)> { // NOLINT | |
370 | public: | |
371 | virtual int Perform(const tuple<int, int>& args) { | |
372 | return get<0>(args) - get<1>(args); | |
373 | } | |
374 | }; | |
375 | ||
376 | TEST(WithArgsTest, NonInvokeAction) { | |
377 | Action<int(const string&, int, int)> a = // NOLINT | |
378 | WithArgs<2, 1>(MakeAction(new SubstractAction)); | |
379 | string s("hello"); | |
380 | EXPECT_EQ(8, a.Perform(tuple<const string&, int, int>(s, 2, 10))); | |
381 | } | |
382 | ||
383 | // Tests using WithArgs to pass all original arguments in the original order. | |
384 | TEST(WithArgsTest, Identity) { | |
385 | Action<int(int x, char y, short z)> a = // NOLINT | |
386 | WithArgs<0, 1, 2>(Invoke(Ternary)); | |
387 | EXPECT_EQ(123, a.Perform(make_tuple(100, Char(20), Short(3)))); | |
388 | } | |
389 | ||
390 | // Tests using WithArgs with repeated arguments. | |
391 | TEST(WithArgsTest, RepeatedArguments) { | |
392 | Action<int(bool, int m, int n)> a = // NOLINT | |
393 | WithArgs<1, 1, 1, 1>(Invoke(SumOf4)); | |
394 | EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10))); | |
395 | } | |
396 | ||
397 | // Tests using WithArgs with reversed argument order. | |
398 | TEST(WithArgsTest, ReversedArgumentOrder) { | |
399 | Action<const char*(short n, const char* input)> a = // NOLINT | |
400 | WithArgs<1, 0>(Invoke(Binary)); | |
401 | const char s[] = "Hello"; | |
402 | EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s)))); | |
403 | } | |
404 | ||
405 | // Tests using WithArgs with compatible, but not identical, argument types. | |
406 | TEST(WithArgsTest, ArgsOfCompatibleTypes) { | |
407 | Action<long(short x, char y, double z, char c)> a = // NOLINT | |
408 | WithArgs<0, 1, 3>(Invoke(Ternary)); | |
409 | EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3)))); | |
410 | } | |
411 | ||
412 | // Tests using WithArgs with an action that returns void. | |
413 | TEST(WithArgsTest, VoidAction) { | |
414 | Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary)); | |
415 | g_done = false; | |
416 | a.Perform(make_tuple(1.5, 'a', 3)); | |
417 | EXPECT_TRUE(g_done); | |
418 | } | |
419 | ||
420 | // Tests DoAll(a1, a2). | |
421 | TEST(DoAllTest, TwoActions) { | |
422 | int n = 0; | |
423 | Action<int(int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT | |
424 | Return(2)); | |
425 | EXPECT_EQ(2, a.Perform(make_tuple(&n))); | |
426 | EXPECT_EQ(1, n); | |
427 | } | |
428 | ||
429 | // Tests DoAll(a1, a2, a3). | |
430 | TEST(DoAllTest, ThreeActions) { | |
431 | int m = 0, n = 0; | |
432 | Action<int(int*, int*)> a = DoAll(SetArgPointee<0>(1), // NOLINT | |
433 | SetArgPointee<1>(2), | |
434 | Return(3)); | |
435 | EXPECT_EQ(3, a.Perform(make_tuple(&m, &n))); | |
436 | EXPECT_EQ(1, m); | |
437 | EXPECT_EQ(2, n); | |
438 | } | |
439 | ||
440 | // Tests DoAll(a1, a2, a3, a4). | |
441 | TEST(DoAllTest, FourActions) { | |
442 | int m = 0, n = 0; | |
443 | char ch = '\0'; | |
444 | Action<int(int*, int*, char*)> a = // NOLINT | |
445 | DoAll(SetArgPointee<0>(1), | |
446 | SetArgPointee<1>(2), | |
447 | SetArgPointee<2>('a'), | |
448 | Return(3)); | |
449 | EXPECT_EQ(3, a.Perform(make_tuple(&m, &n, &ch))); | |
450 | EXPECT_EQ(1, m); | |
451 | EXPECT_EQ(2, n); | |
452 | EXPECT_EQ('a', ch); | |
453 | } | |
454 | ||
455 | // Tests DoAll(a1, a2, a3, a4, a5). | |
456 | TEST(DoAllTest, FiveActions) { | |
457 | int m = 0, n = 0; | |
458 | char a = '\0', b = '\0'; | |
459 | Action<int(int*, int*, char*, char*)> action = // NOLINT | |
460 | DoAll(SetArgPointee<0>(1), | |
461 | SetArgPointee<1>(2), | |
462 | SetArgPointee<2>('a'), | |
463 | SetArgPointee<3>('b'), | |
464 | Return(3)); | |
465 | EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b))); | |
466 | EXPECT_EQ(1, m); | |
467 | EXPECT_EQ(2, n); | |
468 | EXPECT_EQ('a', a); | |
469 | EXPECT_EQ('b', b); | |
470 | } | |
471 | ||
472 | // Tests DoAll(a1, a2, ..., a6). | |
473 | TEST(DoAllTest, SixActions) { | |
474 | int m = 0, n = 0; | |
475 | char a = '\0', b = '\0', c = '\0'; | |
476 | Action<int(int*, int*, char*, char*, char*)> action = // NOLINT | |
477 | DoAll(SetArgPointee<0>(1), | |
478 | SetArgPointee<1>(2), | |
479 | SetArgPointee<2>('a'), | |
480 | SetArgPointee<3>('b'), | |
481 | SetArgPointee<4>('c'), | |
482 | Return(3)); | |
483 | EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c))); | |
484 | EXPECT_EQ(1, m); | |
485 | EXPECT_EQ(2, n); | |
486 | EXPECT_EQ('a', a); | |
487 | EXPECT_EQ('b', b); | |
488 | EXPECT_EQ('c', c); | |
489 | } | |
490 | ||
491 | // Tests DoAll(a1, a2, ..., a7). | |
492 | TEST(DoAllTest, SevenActions) { | |
493 | int m = 0, n = 0; | |
494 | char a = '\0', b = '\0', c = '\0', d = '\0'; | |
495 | Action<int(int*, int*, char*, char*, char*, char*)> action = // NOLINT | |
496 | DoAll(SetArgPointee<0>(1), | |
497 | SetArgPointee<1>(2), | |
498 | SetArgPointee<2>('a'), | |
499 | SetArgPointee<3>('b'), | |
500 | SetArgPointee<4>('c'), | |
501 | SetArgPointee<5>('d'), | |
502 | Return(3)); | |
503 | EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d))); | |
504 | EXPECT_EQ(1, m); | |
505 | EXPECT_EQ(2, n); | |
506 | EXPECT_EQ('a', a); | |
507 | EXPECT_EQ('b', b); | |
508 | EXPECT_EQ('c', c); | |
509 | EXPECT_EQ('d', d); | |
510 | } | |
511 | ||
512 | // Tests DoAll(a1, a2, ..., a8). | |
513 | TEST(DoAllTest, EightActions) { | |
514 | int m = 0, n = 0; | |
515 | char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0'; | |
516 | Action<int(int*, int*, char*, char*, char*, char*, // NOLINT | |
517 | char*)> action = | |
518 | DoAll(SetArgPointee<0>(1), | |
519 | SetArgPointee<1>(2), | |
520 | SetArgPointee<2>('a'), | |
521 | SetArgPointee<3>('b'), | |
522 | SetArgPointee<4>('c'), | |
523 | SetArgPointee<5>('d'), | |
524 | SetArgPointee<6>('e'), | |
525 | Return(3)); | |
526 | EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e))); | |
527 | EXPECT_EQ(1, m); | |
528 | EXPECT_EQ(2, n); | |
529 | EXPECT_EQ('a', a); | |
530 | EXPECT_EQ('b', b); | |
531 | EXPECT_EQ('c', c); | |
532 | EXPECT_EQ('d', d); | |
533 | EXPECT_EQ('e', e); | |
534 | } | |
535 | ||
536 | // Tests DoAll(a1, a2, ..., a9). | |
537 | TEST(DoAllTest, NineActions) { | |
538 | int m = 0, n = 0; | |
539 | char a = '\0', b = '\0', c = '\0', d = '\0', e = '\0', f = '\0'; | |
540 | Action<int(int*, int*, char*, char*, char*, char*, // NOLINT | |
541 | char*, char*)> action = | |
542 | DoAll(SetArgPointee<0>(1), | |
543 | SetArgPointee<1>(2), | |
544 | SetArgPointee<2>('a'), | |
545 | SetArgPointee<3>('b'), | |
546 | SetArgPointee<4>('c'), | |
547 | SetArgPointee<5>('d'), | |
548 | SetArgPointee<6>('e'), | |
549 | SetArgPointee<7>('f'), | |
550 | Return(3)); | |
551 | EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f))); | |
552 | EXPECT_EQ(1, m); | |
553 | EXPECT_EQ(2, n); | |
554 | EXPECT_EQ('a', a); | |
555 | EXPECT_EQ('b', b); | |
556 | EXPECT_EQ('c', c); | |
557 | EXPECT_EQ('d', d); | |
558 | EXPECT_EQ('e', e); | |
559 | EXPECT_EQ('f', f); | |
560 | } | |
561 | ||
562 | // Tests DoAll(a1, a2, ..., a10). | |
563 | TEST(DoAllTest, TenActions) { | |
564 | int m = 0, n = 0; | |
565 | char a = '\0', b = '\0', c = '\0', d = '\0'; | |
566 | char e = '\0', f = '\0', g = '\0'; | |
567 | Action<int(int*, int*, char*, char*, char*, char*, // NOLINT | |
568 | char*, char*, char*)> action = | |
569 | DoAll(SetArgPointee<0>(1), | |
570 | SetArgPointee<1>(2), | |
571 | SetArgPointee<2>('a'), | |
572 | SetArgPointee<3>('b'), | |
573 | SetArgPointee<4>('c'), | |
574 | SetArgPointee<5>('d'), | |
575 | SetArgPointee<6>('e'), | |
576 | SetArgPointee<7>('f'), | |
577 | SetArgPointee<8>('g'), | |
578 | Return(3)); | |
579 | EXPECT_EQ(3, action.Perform(make_tuple(&m, &n, &a, &b, &c, &d, &e, &f, &g))); | |
580 | EXPECT_EQ(1, m); | |
581 | EXPECT_EQ(2, n); | |
582 | EXPECT_EQ('a', a); | |
583 | EXPECT_EQ('b', b); | |
584 | EXPECT_EQ('c', c); | |
585 | EXPECT_EQ('d', d); | |
586 | EXPECT_EQ('e', e); | |
587 | EXPECT_EQ('f', f); | |
588 | EXPECT_EQ('g', g); | |
589 | } | |
590 | ||
591 | // The ACTION*() macros trigger warning C4100 (unreferenced formal | |
592 | // parameter) in MSVC with -W4. Unfortunately they cannot be fixed in | |
593 | // the macro definition, as the warnings are generated when the macro | |
594 | // is expanded and macro expansion cannot contain #pragma. Therefore | |
595 | // we suppress them here. | |
596 | #ifdef _MSC_VER | |
597 | # pragma warning(push) | |
598 | # pragma warning(disable:4100) | |
599 | #endif | |
600 | ||
601 | // Tests the ACTION*() macro family. | |
602 | ||
603 | // Tests that ACTION() can define an action that doesn't reference the | |
604 | // mock function arguments. | |
605 | ACTION(Return5) { return 5; } | |
606 | ||
607 | TEST(ActionMacroTest, WorksWhenNotReferencingArguments) { | |
608 | Action<double()> a1 = Return5(); | |
609 | EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple())); | |
610 | ||
611 | Action<int(double, bool)> a2 = Return5(); | |
612 | EXPECT_EQ(5, a2.Perform(make_tuple(1, true))); | |
613 | } | |
614 | ||
615 | // Tests that ACTION() can define an action that returns void. | |
616 | ACTION(IncrementArg1) { (*arg1)++; } | |
617 | ||
618 | TEST(ActionMacroTest, WorksWhenReturningVoid) { | |
619 | Action<void(int, int*)> a1 = IncrementArg1(); | |
620 | int n = 0; | |
621 | a1.Perform(make_tuple(5, &n)); | |
622 | EXPECT_EQ(1, n); | |
623 | } | |
624 | ||
625 | // Tests that the body of ACTION() can reference the type of the | |
626 | // argument. | |
627 | ACTION(IncrementArg2) { | |
628 | StaticAssertTypeEq<int*, arg2_type>(); | |
629 | arg2_type temp = arg2; | |
630 | (*temp)++; | |
631 | } | |
632 | ||
633 | TEST(ActionMacroTest, CanReferenceArgumentType) { | |
634 | Action<void(int, bool, int*)> a1 = IncrementArg2(); | |
635 | int n = 0; | |
636 | a1.Perform(make_tuple(5, false, &n)); | |
637 | EXPECT_EQ(1, n); | |
638 | } | |
639 | ||
640 | // Tests that the body of ACTION() can reference the argument tuple | |
641 | // via args_type and args. | |
642 | ACTION(Sum2) { | |
643 | StaticAssertTypeEq<tuple<int, char, int*>, args_type>(); | |
644 | args_type args_copy = args; | |
645 | return get<0>(args_copy) + get<1>(args_copy); | |
646 | } | |
647 | ||
648 | TEST(ActionMacroTest, CanReferenceArgumentTuple) { | |
649 | Action<int(int, char, int*)> a1 = Sum2(); | |
650 | int dummy = 0; | |
651 | EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy))); | |
652 | } | |
653 | ||
654 | // Tests that the body of ACTION() can reference the mock function | |
655 | // type. | |
656 | int Dummy(bool flag) { return flag? 1 : 0; } | |
657 | ||
658 | ACTION(InvokeDummy) { | |
659 | StaticAssertTypeEq<int(bool), function_type>(); | |
660 | function_type* fp = &Dummy; | |
661 | return (*fp)(true); | |
662 | } | |
663 | ||
664 | TEST(ActionMacroTest, CanReferenceMockFunctionType) { | |
665 | Action<int(bool)> a1 = InvokeDummy(); | |
666 | EXPECT_EQ(1, a1.Perform(make_tuple(true))); | |
667 | EXPECT_EQ(1, a1.Perform(make_tuple(false))); | |
668 | } | |
669 | ||
670 | // Tests that the body of ACTION() can reference the mock function's | |
671 | // return type. | |
672 | ACTION(InvokeDummy2) { | |
673 | StaticAssertTypeEq<int, return_type>(); | |
674 | return_type result = Dummy(true); | |
675 | return result; | |
676 | } | |
677 | ||
678 | TEST(ActionMacroTest, CanReferenceMockFunctionReturnType) { | |
679 | Action<int(bool)> a1 = InvokeDummy2(); | |
680 | EXPECT_EQ(1, a1.Perform(make_tuple(true))); | |
681 | EXPECT_EQ(1, a1.Perform(make_tuple(false))); | |
682 | } | |
683 | ||
684 | // Tests that ACTION() works for arguments passed by const reference. | |
685 | ACTION(ReturnAddrOfConstBoolReferenceArg) { | |
686 | StaticAssertTypeEq<const bool&, arg1_type>(); | |
687 | return &arg1; | |
688 | } | |
689 | ||
690 | TEST(ActionMacroTest, WorksForConstReferenceArg) { | |
691 | Action<const bool*(int, const bool&)> a = ReturnAddrOfConstBoolReferenceArg(); | |
692 | const bool b = false; | |
693 | EXPECT_EQ(&b, a.Perform(tuple<int, const bool&>(0, b))); | |
694 | } | |
695 | ||
696 | // Tests that ACTION() works for arguments passed by non-const reference. | |
697 | ACTION(ReturnAddrOfIntReferenceArg) { | |
698 | StaticAssertTypeEq<int&, arg0_type>(); | |
699 | return &arg0; | |
700 | } | |
701 | ||
702 | TEST(ActionMacroTest, WorksForNonConstReferenceArg) { | |
703 | Action<int*(int&, bool, int)> a = ReturnAddrOfIntReferenceArg(); | |
704 | int n = 0; | |
705 | EXPECT_EQ(&n, a.Perform(tuple<int&, bool, int>(n, true, 1))); | |
706 | } | |
707 | ||
708 | // Tests that ACTION() can be used in a namespace. | |
709 | namespace action_test { | |
710 | ACTION(Sum) { return arg0 + arg1; } | |
711 | } // namespace action_test | |
712 | ||
713 | TEST(ActionMacroTest, WorksInNamespace) { | |
714 | Action<int(int, int)> a1 = action_test::Sum(); | |
715 | EXPECT_EQ(3, a1.Perform(make_tuple(1, 2))); | |
716 | } | |
717 | ||
718 | // Tests that the same ACTION definition works for mock functions with | |
719 | // different argument numbers. | |
720 | ACTION(PlusTwo) { return arg0 + 2; } | |
721 | ||
722 | TEST(ActionMacroTest, WorksForDifferentArgumentNumbers) { | |
723 | Action<int(int)> a1 = PlusTwo(); | |
724 | EXPECT_EQ(4, a1.Perform(make_tuple(2))); | |
725 | ||
726 | Action<double(float, void*)> a2 = PlusTwo(); | |
727 | int dummy; | |
728 | EXPECT_DOUBLE_EQ(6, a2.Perform(make_tuple(4.0f, &dummy))); | |
729 | } | |
730 | ||
731 | // Tests that ACTION_P can define a parameterized action. | |
732 | ACTION_P(Plus, n) { return arg0 + n; } | |
733 | ||
734 | TEST(ActionPMacroTest, DefinesParameterizedAction) { | |
735 | Action<int(int m, bool t)> a1 = Plus(9); | |
736 | EXPECT_EQ(10, a1.Perform(make_tuple(1, true))); | |
737 | } | |
738 | ||
739 | // Tests that the body of ACTION_P can reference the argument types | |
740 | // and the parameter type. | |
741 | ACTION_P(TypedPlus, n) { | |
742 | arg0_type t1 = arg0; | |
743 | n_type t2 = n; | |
744 | return t1 + t2; | |
745 | } | |
746 | ||
747 | TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) { | |
748 | Action<int(char m, bool t)> a1 = TypedPlus(9); | |
749 | EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true))); | |
750 | } | |
751 | ||
752 | // Tests that a parameterized action can be used in any mock function | |
753 | // whose type is compatible. | |
754 | TEST(ActionPMacroTest, WorksInCompatibleMockFunction) { | |
755 | Action<std::string(const std::string& s)> a1 = Plus("tail"); | |
756 | const std::string re = "re"; | |
757 | EXPECT_EQ("retail", a1.Perform(tuple<const std::string&>(re))); | |
758 | } | |
759 | ||
760 | // Tests that we can use ACTION*() to define actions overloaded on the | |
761 | // number of parameters. | |
762 | ||
763 | ACTION(OverloadedAction) { return arg0 ? arg1 : "hello"; } | |
764 | ||
765 | ACTION_P(OverloadedAction, default_value) { | |
766 | return arg0 ? arg1 : default_value; | |
767 | } | |
768 | ||
769 | ACTION_P2(OverloadedAction, true_value, false_value) { | |
770 | return arg0 ? true_value : false_value; | |
771 | } | |
772 | ||
773 | TEST(ActionMacroTest, CanDefineOverloadedActions) { | |
774 | typedef Action<const char*(bool, const char*)> MyAction; | |
775 | ||
776 | const MyAction a1 = OverloadedAction(); | |
777 | EXPECT_STREQ("hello", a1.Perform(make_tuple(false, CharPtr("world")))); | |
778 | EXPECT_STREQ("world", a1.Perform(make_tuple(true, CharPtr("world")))); | |
779 | ||
780 | const MyAction a2 = OverloadedAction("hi"); | |
781 | EXPECT_STREQ("hi", a2.Perform(make_tuple(false, CharPtr("world")))); | |
782 | EXPECT_STREQ("world", a2.Perform(make_tuple(true, CharPtr("world")))); | |
783 | ||
784 | const MyAction a3 = OverloadedAction("hi", "you"); | |
785 | EXPECT_STREQ("hi", a3.Perform(make_tuple(true, CharPtr("world")))); | |
786 | EXPECT_STREQ("you", a3.Perform(make_tuple(false, CharPtr("world")))); | |
787 | } | |
788 | ||
789 | // Tests ACTION_Pn where n >= 3. | |
790 | ||
791 | ACTION_P3(Plus, m, n, k) { return arg0 + m + n + k; } | |
792 | ||
793 | TEST(ActionPnMacroTest, WorksFor3Parameters) { | |
794 | Action<double(int m, bool t)> a1 = Plus(100, 20, 3.4); | |
795 | EXPECT_DOUBLE_EQ(3123.4, a1.Perform(make_tuple(3000, true))); | |
796 | ||
797 | Action<std::string(const std::string& s)> a2 = Plus("tail", "-", ">"); | |
798 | const std::string re = "re"; | |
799 | EXPECT_EQ("retail->", a2.Perform(tuple<const std::string&>(re))); | |
800 | } | |
801 | ||
802 | ACTION_P4(Plus, p0, p1, p2, p3) { return arg0 + p0 + p1 + p2 + p3; } | |
803 | ||
804 | TEST(ActionPnMacroTest, WorksFor4Parameters) { | |
805 | Action<int(int)> a1 = Plus(1, 2, 3, 4); | |
806 | EXPECT_EQ(10 + 1 + 2 + 3 + 4, a1.Perform(make_tuple(10))); | |
807 | } | |
808 | ||
809 | ACTION_P5(Plus, p0, p1, p2, p3, p4) { return arg0 + p0 + p1 + p2 + p3 + p4; } | |
810 | ||
811 | TEST(ActionPnMacroTest, WorksFor5Parameters) { | |
812 | Action<int(int)> a1 = Plus(1, 2, 3, 4, 5); | |
813 | EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5, a1.Perform(make_tuple(10))); | |
814 | } | |
815 | ||
816 | ACTION_P6(Plus, p0, p1, p2, p3, p4, p5) { | |
817 | return arg0 + p0 + p1 + p2 + p3 + p4 + p5; | |
818 | } | |
819 | ||
820 | TEST(ActionPnMacroTest, WorksFor6Parameters) { | |
821 | Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6); | |
822 | EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6, a1.Perform(make_tuple(10))); | |
823 | } | |
824 | ||
825 | ACTION_P7(Plus, p0, p1, p2, p3, p4, p5, p6) { | |
826 | return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6; | |
827 | } | |
828 | ||
829 | TEST(ActionPnMacroTest, WorksFor7Parameters) { | |
830 | Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7); | |
831 | EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7, a1.Perform(make_tuple(10))); | |
832 | } | |
833 | ||
834 | ACTION_P8(Plus, p0, p1, p2, p3, p4, p5, p6, p7) { | |
835 | return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7; | |
836 | } | |
837 | ||
838 | TEST(ActionPnMacroTest, WorksFor8Parameters) { | |
839 | Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8); | |
840 | EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8, a1.Perform(make_tuple(10))); | |
841 | } | |
842 | ||
843 | ACTION_P9(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8) { | |
844 | return arg0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8; | |
845 | } | |
846 | ||
847 | TEST(ActionPnMacroTest, WorksFor9Parameters) { | |
848 | Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9); | |
849 | EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9, a1.Perform(make_tuple(10))); | |
850 | } | |
851 | ||
852 | ACTION_P10(Plus, p0, p1, p2, p3, p4, p5, p6, p7, p8, last_param) { | |
853 | arg0_type t0 = arg0; | |
854 | last_param_type t9 = last_param; | |
855 | return t0 + p0 + p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + t9; | |
856 | } | |
857 | ||
858 | TEST(ActionPnMacroTest, WorksFor10Parameters) { | |
859 | Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); | |
860 | EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, | |
861 | a1.Perform(make_tuple(10))); | |
862 | } | |
863 | ||
864 | // Tests that the action body can promote the parameter types. | |
865 | ||
866 | ACTION_P2(PadArgument, prefix, suffix) { | |
867 | // The following lines promote the two parameters to desired types. | |
868 | std::string prefix_str(prefix); | |
869 | char suffix_char = static_cast<char>(suffix); | |
870 | return prefix_str + arg0 + suffix_char; | |
871 | } | |
872 | ||
873 | TEST(ActionPnMacroTest, SimpleTypePromotion) { | |
874 | Action<std::string(const char*)> no_promo = | |
875 | PadArgument(std::string("foo"), 'r'); | |
876 | Action<std::string(const char*)> promo = | |
877 | PadArgument("foo", static_cast<int>('r')); | |
878 | EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba")))); | |
879 | EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba")))); | |
880 | } | |
881 | ||
882 | // Tests that we can partially restrict parameter types using a | |
883 | // straight-forward pattern. | |
884 | ||
885 | // Defines a generic action that doesn't restrict the types of its | |
886 | // parameters. | |
887 | ACTION_P3(ConcatImpl, a, b, c) { | |
888 | std::stringstream ss; | |
889 | ss << a << b << c; | |
890 | return ss.str(); | |
891 | } | |
892 | ||
893 | // Next, we try to restrict that either the first parameter is a | |
894 | // string, or the second parameter is an int. | |
895 | ||
896 | // Defines a partially specialized wrapper that restricts the first | |
897 | // parameter to std::string. | |
898 | template <typename T1, typename T2> | |
899 | // ConcatImplActionP3 is the class template ACTION_P3 uses to | |
900 | // implement ConcatImpl. We shouldn't change the name as this | |
901 | // pattern requires the user to use it directly. | |
902 | ConcatImplActionP3<std::string, T1, T2> | |
903 | Concat(const std::string& a, T1 b, T2 c) { | |
904 | GTEST_INTENTIONAL_CONST_COND_PUSH_() | |
905 | if (true) { | |
906 | GTEST_INTENTIONAL_CONST_COND_POP_() | |
907 | // This branch verifies that ConcatImpl() can be invoked without | |
908 | // explicit template arguments. | |
909 | return ConcatImpl(a, b, c); | |
910 | } else { | |
911 | // This branch verifies that ConcatImpl() can also be invoked with | |
912 | // explicit template arguments. It doesn't really need to be | |
913 | // executed as this is a compile-time verification. | |
914 | return ConcatImpl<std::string, T1, T2>(a, b, c); | |
915 | } | |
916 | } | |
917 | ||
918 | // Defines another partially specialized wrapper that restricts the | |
919 | // second parameter to int. | |
920 | template <typename T1, typename T2> | |
921 | ConcatImplActionP3<T1, int, T2> | |
922 | Concat(T1 a, int b, T2 c) { | |
923 | return ConcatImpl(a, b, c); | |
924 | } | |
925 | ||
926 | TEST(ActionPnMacroTest, CanPartiallyRestrictParameterTypes) { | |
927 | Action<const std::string()> a1 = Concat("Hello", "1", 2); | |
928 | EXPECT_EQ("Hello12", a1.Perform(make_tuple())); | |
929 | ||
930 | a1 = Concat(1, 2, 3); | |
931 | EXPECT_EQ("123", a1.Perform(make_tuple())); | |
932 | } | |
933 | ||
934 | // Verifies the type of an ACTION*. | |
935 | ||
936 | ACTION(DoFoo) {} | |
937 | ACTION_P(DoFoo, p) {} | |
938 | ACTION_P2(DoFoo, p0, p1) {} | |
939 | ||
940 | TEST(ActionPnMacroTest, TypesAreCorrect) { | |
941 | // DoFoo() must be assignable to a DoFooAction variable. | |
942 | DoFooAction a0 = DoFoo(); | |
943 | ||
944 | // DoFoo(1) must be assignable to a DoFooActionP variable. | |
945 | DoFooActionP<int> a1 = DoFoo(1); | |
946 | ||
947 | // DoFoo(p1, ..., pk) must be assignable to a DoFooActionPk | |
948 | // variable, and so on. | |
949 | DoFooActionP2<int, char> a2 = DoFoo(1, '2'); | |
950 | PlusActionP3<int, int, char> a3 = Plus(1, 2, '3'); | |
951 | PlusActionP4<int, int, int, char> a4 = Plus(1, 2, 3, '4'); | |
952 | PlusActionP5<int, int, int, int, char> a5 = Plus(1, 2, 3, 4, '5'); | |
953 | PlusActionP6<int, int, int, int, int, char> a6 = Plus(1, 2, 3, 4, 5, '6'); | |
954 | PlusActionP7<int, int, int, int, int, int, char> a7 = | |
955 | Plus(1, 2, 3, 4, 5, 6, '7'); | |
956 | PlusActionP8<int, int, int, int, int, int, int, char> a8 = | |
957 | Plus(1, 2, 3, 4, 5, 6, 7, '8'); | |
958 | PlusActionP9<int, int, int, int, int, int, int, int, char> a9 = | |
959 | Plus(1, 2, 3, 4, 5, 6, 7, 8, '9'); | |
960 | PlusActionP10<int, int, int, int, int, int, int, int, int, char> a10 = | |
961 | Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, '0'); | |
962 | ||
963 | // Avoid "unused variable" warnings. | |
964 | (void)a0; | |
965 | (void)a1; | |
966 | (void)a2; | |
967 | (void)a3; | |
968 | (void)a4; | |
969 | (void)a5; | |
970 | (void)a6; | |
971 | (void)a7; | |
972 | (void)a8; | |
973 | (void)a9; | |
974 | (void)a10; | |
975 | } | |
976 | ||
977 | // Tests that an ACTION_P*() action can be explicitly instantiated | |
978 | // with reference-typed parameters. | |
979 | ||
980 | ACTION_P(Plus1, x) { return x; } | |
981 | ACTION_P2(Plus2, x, y) { return x + y; } | |
982 | ACTION_P3(Plus3, x, y, z) { return x + y + z; } | |
983 | ACTION_P10(Plus10, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) { | |
984 | return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9; | |
985 | } | |
986 | ||
987 | TEST(ActionPnMacroTest, CanExplicitlyInstantiateWithReferenceTypes) { | |
988 | int x = 1, y = 2, z = 3; | |
989 | const tuple<> empty = make_tuple(); | |
990 | ||
991 | Action<int()> a = Plus1<int&>(x); | |
992 | EXPECT_EQ(1, a.Perform(empty)); | |
993 | ||
994 | a = Plus2<const int&, int&>(x, y); | |
995 | EXPECT_EQ(3, a.Perform(empty)); | |
996 | ||
997 | a = Plus3<int&, const int&, int&>(x, y, z); | |
998 | EXPECT_EQ(6, a.Perform(empty)); | |
999 | ||
1000 | int n[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; | |
1001 | a = Plus10<const int&, int&, const int&, int&, const int&, int&, const int&, | |
1002 | int&, const int&, int&>(n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7], | |
1003 | n[8], n[9]); | |
1004 | EXPECT_EQ(55, a.Perform(empty)); | |
1005 | } | |
1006 | ||
1007 | class NullaryConstructorClass { | |
1008 | public: | |
1009 | NullaryConstructorClass() : value_(123) {} | |
1010 | int value_; | |
1011 | }; | |
1012 | ||
1013 | // Tests using ReturnNew() with a nullary constructor. | |
1014 | TEST(ReturnNewTest, NoArgs) { | |
1015 | Action<NullaryConstructorClass*()> a = ReturnNew<NullaryConstructorClass>(); | |
1016 | NullaryConstructorClass* c = a.Perform(make_tuple()); | |
1017 | EXPECT_EQ(123, c->value_); | |
1018 | delete c; | |
1019 | } | |
1020 | ||
1021 | class UnaryConstructorClass { | |
1022 | public: | |
1023 | explicit UnaryConstructorClass(int value) : value_(value) {} | |
1024 | int value_; | |
1025 | }; | |
1026 | ||
1027 | // Tests using ReturnNew() with a unary constructor. | |
1028 | TEST(ReturnNewTest, Unary) { | |
1029 | Action<UnaryConstructorClass*()> a = ReturnNew<UnaryConstructorClass>(4000); | |
1030 | UnaryConstructorClass* c = a.Perform(make_tuple()); | |
1031 | EXPECT_EQ(4000, c->value_); | |
1032 | delete c; | |
1033 | } | |
1034 | ||
1035 | TEST(ReturnNewTest, UnaryWorksWhenMockMethodHasArgs) { | |
1036 | Action<UnaryConstructorClass*(bool, int)> a = | |
1037 | ReturnNew<UnaryConstructorClass>(4000); | |
1038 | UnaryConstructorClass* c = a.Perform(make_tuple(false, 5)); | |
1039 | EXPECT_EQ(4000, c->value_); | |
1040 | delete c; | |
1041 | } | |
1042 | ||
1043 | TEST(ReturnNewTest, UnaryWorksWhenMockMethodReturnsPointerToConst) { | |
1044 | Action<const UnaryConstructorClass*()> a = | |
1045 | ReturnNew<UnaryConstructorClass>(4000); | |
1046 | const UnaryConstructorClass* c = a.Perform(make_tuple()); | |
1047 | EXPECT_EQ(4000, c->value_); | |
1048 | delete c; | |
1049 | } | |
1050 | ||
1051 | class TenArgConstructorClass { | |
1052 | public: | |
1053 | TenArgConstructorClass(int a1, int a2, int a3, int a4, int a5, | |
1054 | int a6, int a7, int a8, int a9, int a10) | |
1055 | : value_(a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10) { | |
1056 | } | |
1057 | int value_; | |
1058 | }; | |
1059 | ||
1060 | // Tests using ReturnNew() with a 10-argument constructor. | |
1061 | TEST(ReturnNewTest, ConstructorThatTakes10Arguments) { | |
1062 | Action<TenArgConstructorClass*()> a = | |
1063 | ReturnNew<TenArgConstructorClass>(1000000000, 200000000, 30000000, | |
1064 | 4000000, 500000, 60000, | |
1065 | 7000, 800, 90, 0); | |
1066 | TenArgConstructorClass* c = a.Perform(make_tuple()); | |
1067 | EXPECT_EQ(1234567890, c->value_); | |
1068 | delete c; | |
1069 | } | |
1070 | ||
1071 | // Tests that ACTION_TEMPLATE works when there is no value parameter. | |
1072 | ACTION_TEMPLATE(CreateNew, | |
1073 | HAS_1_TEMPLATE_PARAMS(typename, T), | |
1074 | AND_0_VALUE_PARAMS()) { | |
1075 | return new T; | |
1076 | } | |
1077 | ||
1078 | TEST(ActionTemplateTest, WorksWithoutValueParam) { | |
1079 | const Action<int*()> a = CreateNew<int>(); | |
1080 | int* p = a.Perform(make_tuple()); | |
1081 | delete p; | |
1082 | } | |
1083 | ||
1084 | // Tests that ACTION_TEMPLATE works when there are value parameters. | |
1085 | ACTION_TEMPLATE(CreateNew, | |
1086 | HAS_1_TEMPLATE_PARAMS(typename, T), | |
1087 | AND_1_VALUE_PARAMS(a0)) { | |
1088 | return new T(a0); | |
1089 | } | |
1090 | ||
1091 | TEST(ActionTemplateTest, WorksWithValueParams) { | |
1092 | const Action<int*()> a = CreateNew<int>(42); | |
1093 | int* p = a.Perform(make_tuple()); | |
1094 | EXPECT_EQ(42, *p); | |
1095 | delete p; | |
1096 | } | |
1097 | ||
1098 | // Tests that ACTION_TEMPLATE works for integral template parameters. | |
1099 | ACTION_TEMPLATE(MyDeleteArg, | |
1100 | HAS_1_TEMPLATE_PARAMS(int, k), | |
1101 | AND_0_VALUE_PARAMS()) { | |
1102 | delete get<k>(args); | |
1103 | } | |
1104 | ||
1105 | // Resets a bool variable in the destructor. | |
1106 | class BoolResetter { | |
1107 | public: | |
1108 | explicit BoolResetter(bool* value) : value_(value) {} | |
1109 | ~BoolResetter() { *value_ = false; } | |
1110 | private: | |
1111 | bool* value_; | |
1112 | }; | |
1113 | ||
1114 | TEST(ActionTemplateTest, WorksForIntegralTemplateParams) { | |
1115 | const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>(); | |
1116 | int n = 0; | |
1117 | bool b = true; | |
1118 | BoolResetter* resetter = new BoolResetter(&b); | |
1119 | a.Perform(make_tuple(&n, resetter)); | |
1120 | EXPECT_FALSE(b); // Verifies that resetter is deleted. | |
1121 | } | |
1122 | ||
1123 | // Tests that ACTION_TEMPLATES works for template template parameters. | |
1124 | ACTION_TEMPLATE(ReturnSmartPointer, | |
1125 | HAS_1_TEMPLATE_PARAMS(template <typename Pointee> class, | |
1126 | Pointer), | |
1127 | AND_1_VALUE_PARAMS(pointee)) { | |
1128 | return Pointer<pointee_type>(new pointee_type(pointee)); | |
1129 | } | |
1130 | ||
1131 | TEST(ActionTemplateTest, WorksForTemplateTemplateParameters) { | |
1132 | using ::testing::internal::linked_ptr; | |
1133 | const Action<linked_ptr<int>()> a = ReturnSmartPointer<linked_ptr>(42); | |
1134 | linked_ptr<int> p = a.Perform(make_tuple()); | |
1135 | EXPECT_EQ(42, *p); | |
1136 | } | |
1137 | ||
1138 | // Tests that ACTION_TEMPLATE works for 10 template parameters. | |
1139 | template <typename T1, typename T2, typename T3, int k4, bool k5, | |
1140 | unsigned int k6, typename T7, typename T8, typename T9> | |
1141 | struct GiantTemplate { | |
1142 | public: | |
1143 | explicit GiantTemplate(int a_value) : value(a_value) {} | |
1144 | int value; | |
1145 | }; | |
1146 | ||
1147 | ACTION_TEMPLATE(ReturnGiant, | |
1148 | HAS_10_TEMPLATE_PARAMS( | |
1149 | typename, T1, | |
1150 | typename, T2, | |
1151 | typename, T3, | |
1152 | int, k4, | |
1153 | bool, k5, | |
1154 | unsigned int, k6, | |
1155 | class, T7, | |
1156 | class, T8, | |
1157 | class, T9, | |
1158 | template <typename T> class, T10), | |
1159 | AND_1_VALUE_PARAMS(value)) { | |
1160 | return GiantTemplate<T10<T1>, T2, T3, k4, k5, k6, T7, T8, T9>(value); | |
1161 | } | |
1162 | ||
1163 | TEST(ActionTemplateTest, WorksFor10TemplateParameters) { | |
1164 | using ::testing::internal::linked_ptr; | |
1165 | typedef GiantTemplate<linked_ptr<int>, bool, double, 5, | |
1166 | true, 6, char, unsigned, int> Giant; | |
1167 | const Action<Giant()> a = ReturnGiant< | |
1168 | int, bool, double, 5, true, 6, char, unsigned, int, linked_ptr>(42); | |
1169 | Giant giant = a.Perform(make_tuple()); | |
1170 | EXPECT_EQ(42, giant.value); | |
1171 | } | |
1172 | ||
1173 | // Tests that ACTION_TEMPLATE works for 10 value parameters. | |
1174 | ACTION_TEMPLATE(ReturnSum, | |
1175 | HAS_1_TEMPLATE_PARAMS(typename, Number), | |
1176 | AND_10_VALUE_PARAMS(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)) { | |
1177 | return static_cast<Number>(v1) + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10; | |
1178 | } | |
1179 | ||
1180 | TEST(ActionTemplateTest, WorksFor10ValueParameters) { | |
1181 | const Action<int()> a = ReturnSum<int>(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); | |
1182 | EXPECT_EQ(55, a.Perform(make_tuple())); | |
1183 | } | |
1184 | ||
1185 | // Tests that ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded | |
1186 | // on the number of value parameters. | |
1187 | ||
1188 | ACTION(ReturnSum) { return 0; } | |
1189 | ||
1190 | ACTION_P(ReturnSum, x) { return x; } | |
1191 | ||
1192 | ACTION_TEMPLATE(ReturnSum, | |
1193 | HAS_1_TEMPLATE_PARAMS(typename, Number), | |
1194 | AND_2_VALUE_PARAMS(v1, v2)) { | |
1195 | return static_cast<Number>(v1) + v2; | |
1196 | } | |
1197 | ||
1198 | ACTION_TEMPLATE(ReturnSum, | |
1199 | HAS_1_TEMPLATE_PARAMS(typename, Number), | |
1200 | AND_3_VALUE_PARAMS(v1, v2, v3)) { | |
1201 | return static_cast<Number>(v1) + v2 + v3; | |
1202 | } | |
1203 | ||
1204 | ACTION_TEMPLATE(ReturnSum, | |
1205 | HAS_2_TEMPLATE_PARAMS(typename, Number, int, k), | |
1206 | AND_4_VALUE_PARAMS(v1, v2, v3, v4)) { | |
1207 | return static_cast<Number>(v1) + v2 + v3 + v4 + k; | |
1208 | } | |
1209 | ||
1210 | TEST(ActionTemplateTest, CanBeOverloadedOnNumberOfValueParameters) { | |
1211 | const Action<int()> a0 = ReturnSum(); | |
1212 | const Action<int()> a1 = ReturnSum(1); | |
1213 | const Action<int()> a2 = ReturnSum<int>(1, 2); | |
1214 | const Action<int()> a3 = ReturnSum<int>(1, 2, 3); | |
1215 | const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5); | |
1216 | EXPECT_EQ(0, a0.Perform(make_tuple())); | |
1217 | EXPECT_EQ(1, a1.Perform(make_tuple())); | |
1218 | EXPECT_EQ(3, a2.Perform(make_tuple())); | |
1219 | EXPECT_EQ(6, a3.Perform(make_tuple())); | |
1220 | EXPECT_EQ(12345, a4.Perform(make_tuple())); | |
1221 | } | |
1222 | ||
1223 | #ifdef _MSC_VER | |
1224 | # pragma warning(pop) | |
1225 | #endif | |
1226 | ||
1227 | } // namespace gmock_generated_actions_test | |
1228 | } // namespace testing |