blob: f5dab5bf5342f4346c8b960f8718f386eeae3630 [file] [log] [blame]
zhanyong.wana18423e2009-07-22 23:58:19 +00001// 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 in gmock-more-actions.h.
35
36#include <gmock/gmock-more-actions.h>
37
38#include <functional>
39#include <sstream>
40#include <string>
41#include <gmock/gmock.h>
42#include <gtest/gtest.h>
43
44namespace testing {
45namespace gmock_more_actions_test {
46
47using ::std::plus;
48using ::std::string;
49using ::std::tr1::get;
50using ::std::tr1::make_tuple;
51using ::std::tr1::tuple;
52using ::std::tr1::tuple_element;
53using testing::_;
54using testing::Action;
55using testing::ActionInterface;
56using testing::DeleteArg;
57using testing::Invoke;
58using testing::Return;
59using testing::ReturnArg;
60using testing::SaveArg;
61using testing::SetArgReferee;
62using testing::SetArgumentPointee;
63using testing::StaticAssertTypeEq;
64using testing::Unused;
65using testing::WithArg;
66using testing::WithoutArgs;
67
68// Sample functions and functors for testing Invoke() and etc.
69int Nullary() { return 1; }
70
71class NullaryFunctor {
72 public:
73 int operator()() { return 2; }
74};
75
76bool g_done = false;
77void VoidNullary() { g_done = true; }
78
79class VoidNullaryFunctor {
80 public:
81 void operator()() { g_done = true; }
82};
83
84bool Unary(int x) { return x < 0; }
85
86const char* Plus1(const char* s) { return s + 1; }
87
88void VoidUnary(int n) { g_done = true; }
89
90bool ByConstRef(const string& s) { return s == "Hi"; }
91
92const double g_double = 0;
93bool ReferencesGlobalDouble(const double& x) { return &x == &g_double; }
94
95string ByNonConstRef(string& s) { return s += "+"; } // NOLINT
96
97struct UnaryFunctor {
98 int operator()(bool x) { return x ? 1 : -1; }
99};
100
101const char* Binary(const char* input, short n) { return input + n; } // NOLINT
102
103void VoidBinary(int, char) { g_done = true; }
104
105int Ternary(int x, char y, short z) { return x + y + z; } // NOLINT
106
107void VoidTernary(int, char, bool) { g_done = true; }
108
109int SumOf4(int a, int b, int c, int d) { return a + b + c + d; }
110
111int SumOfFirst2(int a, int b, Unused, Unused) { return a + b; }
112
113void VoidFunctionWithFourArguments(char, int, float, double) { g_done = true; }
114
115string Concat4(const char* s1, const char* s2, const char* s3,
116 const char* s4) {
117 return string(s1) + s2 + s3 + s4;
118}
119
120int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
121
122struct SumOf5Functor {
123 int operator()(int a, int b, int c, int d, int e) {
124 return a + b + c + d + e;
125 }
126};
127
128string Concat5(const char* s1, const char* s2, const char* s3,
129 const char* s4, const char* s5) {
130 return string(s1) + s2 + s3 + s4 + s5;
131}
132
133int SumOf6(int a, int b, int c, int d, int e, int f) {
134 return a + b + c + d + e + f;
135}
136
137struct SumOf6Functor {
138 int operator()(int a, int b, int c, int d, int e, int f) {
139 return a + b + c + d + e + f;
140 }
141};
142
143string Concat6(const char* s1, const char* s2, const char* s3,
144 const char* s4, const char* s5, const char* s6) {
145 return string(s1) + s2 + s3 + s4 + s5 + s6;
146}
147
148string Concat7(const char* s1, const char* s2, const char* s3,
149 const char* s4, const char* s5, const char* s6,
150 const char* s7) {
151 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
152}
153
154string Concat8(const char* s1, const char* s2, const char* s3,
155 const char* s4, const char* s5, const char* s6,
156 const char* s7, const char* s8) {
157 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
158}
159
160string Concat9(const char* s1, const char* s2, const char* s3,
161 const char* s4, const char* s5, const char* s6,
162 const char* s7, const char* s8, const char* s9) {
163 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
164}
165
166string Concat10(const char* s1, const char* s2, const char* s3,
167 const char* s4, const char* s5, const char* s6,
168 const char* s7, const char* s8, const char* s9,
169 const char* s10) {
170 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
171}
172
173class Foo {
174 public:
175 Foo() : value_(123) {}
176
177 int Nullary() const { return value_; }
178
179 short Unary(long x) { return static_cast<short>(value_ + x); } // NOLINT
180
181 string Binary(const string& str, char c) const { return str + c; }
182
183 int Ternary(int x, bool y, char z) { return value_ + x + y*z; }
184
185 int SumOf4(int a, int b, int c, int d) const {
186 return a + b + c + d + value_;
187 }
188
189 int SumOfLast2(Unused, Unused, int a, int b) const { return a + b; }
190
191 int SumOf5(int a, int b, int c, int d, int e) { return a + b + c + d + e; }
192
193 int SumOf6(int a, int b, int c, int d, int e, int f) {
194 return a + b + c + d + e + f;
195 }
196
197 string Concat7(const char* s1, const char* s2, const char* s3,
198 const char* s4, const char* s5, const char* s6,
199 const char* s7) {
200 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7;
201 }
202
203 string Concat8(const char* s1, const char* s2, const char* s3,
204 const char* s4, const char* s5, const char* s6,
205 const char* s7, const char* s8) {
206 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8;
207 }
208
209 string Concat9(const char* s1, const char* s2, const char* s3,
210 const char* s4, const char* s5, const char* s6,
211 const char* s7, const char* s8, const char* s9) {
212 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9;
213 }
214
215 string Concat10(const char* s1, const char* s2, const char* s3,
216 const char* s4, const char* s5, const char* s6,
217 const char* s7, const char* s8, const char* s9,
218 const char* s10) {
219 return string(s1) + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10;
220 }
221 private:
222 int value_;
223};
224
225// Tests using Invoke() with a nullary function.
226TEST(InvokeTest, Nullary) {
227 Action<int()> a = Invoke(Nullary); // NOLINT
228 EXPECT_EQ(1, a.Perform(make_tuple()));
229}
230
231// Tests using Invoke() with a unary function.
232TEST(InvokeTest, Unary) {
233 Action<bool(int)> a = Invoke(Unary); // NOLINT
234 EXPECT_FALSE(a.Perform(make_tuple(1)));
235 EXPECT_TRUE(a.Perform(make_tuple(-1)));
236}
237
238// Tests using Invoke() with a binary function.
239TEST(InvokeTest, Binary) {
240 Action<const char*(const char*, short)> a = Invoke(Binary); // NOLINT
241 const char* p = "Hello";
242 EXPECT_EQ(p + 2, a.Perform(make_tuple(p, 2)));
243}
244
245// Tests using Invoke() with a ternary function.
246TEST(InvokeTest, Ternary) {
247 Action<int(int, char, short)> a = Invoke(Ternary); // NOLINT
248 EXPECT_EQ(6, a.Perform(make_tuple(1, '\2', 3)));
249}
250
251// Tests using Invoke() with a 4-argument function.
252TEST(InvokeTest, FunctionThatTakes4Arguments) {
253 Action<int(int, int, int, int)> a = Invoke(SumOf4); // NOLINT
254 EXPECT_EQ(1234, a.Perform(make_tuple(1000, 200, 30, 4)));
255}
256
257// Tests using Invoke() with a 5-argument function.
258TEST(InvokeTest, FunctionThatTakes5Arguments) {
259 Action<int(int, int, int, int, int)> a = Invoke(SumOf5); // NOLINT
260 EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
261}
262
263// Tests using Invoke() with a 6-argument function.
264TEST(InvokeTest, FunctionThatTakes6Arguments) {
265 Action<int(int, int, int, int, int, int)> a = Invoke(SumOf6); // NOLINT
266 EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
267}
268
269// A helper that turns the type of a C-string literal from const
270// char[N] to const char*.
271inline const char* CharPtr(const char* s) { return s; }
272
273// Tests using Invoke() with a 7-argument function.
274TEST(InvokeTest, FunctionThatTakes7Arguments) {
275 Action<string(const char*, const char*, const char*, const char*,
276 const char*, const char*, const char*)> a =
277 Invoke(Concat7);
278 EXPECT_EQ("1234567",
279 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
280 CharPtr("4"), CharPtr("5"), CharPtr("6"),
281 CharPtr("7"))));
282}
283
284// Tests using Invoke() with a 8-argument function.
285TEST(InvokeTest, FunctionThatTakes8Arguments) {
286 Action<string(const char*, const char*, const char*, const char*,
287 const char*, const char*, const char*, const char*)> a =
288 Invoke(Concat8);
289 EXPECT_EQ("12345678",
290 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
291 CharPtr("4"), CharPtr("5"), CharPtr("6"),
292 CharPtr("7"), CharPtr("8"))));
293}
294
295// Tests using Invoke() with a 9-argument function.
296TEST(InvokeTest, FunctionThatTakes9Arguments) {
297 Action<string(const char*, const char*, const char*, const char*,
298 const char*, const char*, const char*, const char*,
299 const char*)> a = Invoke(Concat9);
300 EXPECT_EQ("123456789",
301 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
302 CharPtr("4"), CharPtr("5"), CharPtr("6"),
303 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
304}
305
306// Tests using Invoke() with a 10-argument function.
307TEST(InvokeTest, FunctionThatTakes10Arguments) {
308 Action<string(const char*, const char*, const char*, const char*,
309 const char*, const char*, const char*, const char*,
310 const char*, const char*)> a = Invoke(Concat10);
311 EXPECT_EQ("1234567890",
312 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
313 CharPtr("4"), CharPtr("5"), CharPtr("6"),
314 CharPtr("7"), CharPtr("8"), CharPtr("9"),
315 CharPtr("0"))));
316}
317
318// Tests using Invoke() with functions with parameters declared as Unused.
319TEST(InvokeTest, FunctionWithUnusedParameters) {
320 Action<int(int, int, double, const string&)> a1 =
321 Invoke(SumOfFirst2);
322 EXPECT_EQ(12, a1.Perform(make_tuple(10, 2, 5.6, CharPtr("hi"))));
323
324 Action<int(int, int, bool, int*)> a2 =
325 Invoke(SumOfFirst2);
326 EXPECT_EQ(23, a2.Perform(make_tuple(20, 3, true, static_cast<int*>(NULL))));
327}
328
329// Tests using Invoke() with methods with parameters declared as Unused.
330TEST(InvokeTest, MethodWithUnusedParameters) {
331 Foo foo;
332 Action<int(string, bool, int, int)> a1 =
333 Invoke(&foo, &Foo::SumOfLast2);
334 EXPECT_EQ(12, a1.Perform(make_tuple(CharPtr("hi"), true, 10, 2)));
335
336 Action<int(char, double, int, int)> a2 =
337 Invoke(&foo, &Foo::SumOfLast2);
338 EXPECT_EQ(23, a2.Perform(make_tuple('a', 2.5, 20, 3)));
339}
340
341// Tests using Invoke() with a functor.
342TEST(InvokeTest, Functor) {
343 Action<int(short, char)> a = Invoke(plus<short>()); // NOLINT
344 EXPECT_EQ(3, a.Perform(make_tuple(1, 2)));
345}
346
347// Tests using Invoke(f) as an action of a compatible type.
348TEST(InvokeTest, FunctionWithCompatibleType) {
349 Action<long(int, short, char, bool)> a = Invoke(SumOf4); // NOLINT
350 EXPECT_EQ(4321, a.Perform(make_tuple(4000, 300, 20, true)));
351}
352
zhanyong.wana18423e2009-07-22 23:58:19 +0000353// Tests using Invoke() with an object pointer and a method pointer.
354
355// Tests using Invoke() with a nullary method.
356TEST(InvokeMethodTest, Nullary) {
357 Foo foo;
358 Action<int()> a = Invoke(&foo, &Foo::Nullary); // NOLINT
359 EXPECT_EQ(123, a.Perform(make_tuple()));
360}
361
362// Tests using Invoke() with a unary method.
363TEST(InvokeMethodTest, Unary) {
364 Foo foo;
365 Action<short(long)> a = Invoke(&foo, &Foo::Unary); // NOLINT
366 EXPECT_EQ(4123, a.Perform(make_tuple(4000)));
367}
368
369// Tests using Invoke() with a binary method.
370TEST(InvokeMethodTest, Binary) {
371 Foo foo;
372 Action<string(const string&, char)> a = Invoke(&foo, &Foo::Binary);
373 string s("Hell");
374 EXPECT_EQ("Hello", a.Perform(make_tuple(s, 'o')));
375}
376
377// Tests using Invoke() with a ternary method.
378TEST(InvokeMethodTest, Ternary) {
379 Foo foo;
380 Action<int(int, bool, char)> a = Invoke(&foo, &Foo::Ternary); // NOLINT
381 EXPECT_EQ(1124, a.Perform(make_tuple(1000, true, 1)));
382}
383
384// Tests using Invoke() with a 4-argument method.
385TEST(InvokeMethodTest, MethodThatTakes4Arguments) {
386 Foo foo;
387 Action<int(int, int, int, int)> a = Invoke(&foo, &Foo::SumOf4); // NOLINT
388 EXPECT_EQ(1357, a.Perform(make_tuple(1000, 200, 30, 4)));
389}
390
391// Tests using Invoke() with a 5-argument method.
392TEST(InvokeMethodTest, MethodThatTakes5Arguments) {
393 Foo foo;
394 Action<int(int, int, int, int, int)> a = Invoke(&foo, &Foo::SumOf5); // NOLINT
395 EXPECT_EQ(12345, a.Perform(make_tuple(10000, 2000, 300, 40, 5)));
396}
397
398// Tests using Invoke() with a 6-argument method.
399TEST(InvokeMethodTest, MethodThatTakes6Arguments) {
400 Foo foo;
401 Action<int(int, int, int, int, int, int)> a = // NOLINT
402 Invoke(&foo, &Foo::SumOf6);
403 EXPECT_EQ(123456, a.Perform(make_tuple(100000, 20000, 3000, 400, 50, 6)));
404}
405
406// Tests using Invoke() with a 7-argument method.
407TEST(InvokeMethodTest, MethodThatTakes7Arguments) {
408 Foo foo;
409 Action<string(const char*, const char*, const char*, const char*,
410 const char*, const char*, const char*)> a =
411 Invoke(&foo, &Foo::Concat7);
412 EXPECT_EQ("1234567",
413 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
414 CharPtr("4"), CharPtr("5"), CharPtr("6"),
415 CharPtr("7"))));
416}
417
418// Tests using Invoke() with a 8-argument method.
419TEST(InvokeMethodTest, MethodThatTakes8Arguments) {
420 Foo foo;
421 Action<string(const char*, const char*, const char*, const char*,
422 const char*, const char*, const char*, const char*)> a =
423 Invoke(&foo, &Foo::Concat8);
424 EXPECT_EQ("12345678",
425 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
426 CharPtr("4"), CharPtr("5"), CharPtr("6"),
427 CharPtr("7"), CharPtr("8"))));
428}
429
430// Tests using Invoke() with a 9-argument method.
431TEST(InvokeMethodTest, MethodThatTakes9Arguments) {
432 Foo foo;
433 Action<string(const char*, const char*, const char*, const char*,
434 const char*, const char*, const char*, const char*,
435 const char*)> a = Invoke(&foo, &Foo::Concat9);
436 EXPECT_EQ("123456789",
437 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
438 CharPtr("4"), CharPtr("5"), CharPtr("6"),
439 CharPtr("7"), CharPtr("8"), CharPtr("9"))));
440}
441
442// Tests using Invoke() with a 10-argument method.
443TEST(InvokeMethodTest, MethodThatTakes10Arguments) {
444 Foo foo;
445 Action<string(const char*, const char*, const char*, const char*,
446 const char*, const char*, const char*, const char*,
447 const char*, const char*)> a = Invoke(&foo, &Foo::Concat10);
448 EXPECT_EQ("1234567890",
449 a.Perform(make_tuple(CharPtr("1"), CharPtr("2"), CharPtr("3"),
450 CharPtr("4"), CharPtr("5"), CharPtr("6"),
451 CharPtr("7"), CharPtr("8"), CharPtr("9"),
452 CharPtr("0"))));
453}
454
455// Tests using Invoke(f) as an action of a compatible type.
456TEST(InvokeMethodTest, MethodWithCompatibleType) {
457 Foo foo;
458 Action<long(int, short, char, bool)> a = // NOLINT
459 Invoke(&foo, &Foo::SumOf4);
460 EXPECT_EQ(4444, a.Perform(make_tuple(4000, 300, 20, true)));
461}
462
zhanyong.wana18423e2009-07-22 23:58:19 +0000463// Tests using WithoutArgs with an action that takes no argument.
464TEST(WithoutArgsTest, NoArg) {
465 Action<int(int n)> a = WithoutArgs(Invoke(Nullary)); // NOLINT
466 EXPECT_EQ(1, a.Perform(make_tuple(2)));
467}
468
469// Tests using WithArg with an action that takes 1 argument.
470TEST(WithArgTest, OneArg) {
471 Action<bool(double x, int n)> b = WithArg<1>(Invoke(Unary)); // NOLINT
472 EXPECT_TRUE(b.Perform(make_tuple(1.5, -1)));
473 EXPECT_FALSE(b.Perform(make_tuple(1.5, 1)));
474}
475
476TEST(ReturnArgActionTest, WorksForOneArgIntArg0) {
477 const Action<int(int)> a = ReturnArg<0>();
478 EXPECT_EQ(5, a.Perform(make_tuple(5)));
479}
480
481TEST(ReturnArgActionTest, WorksForMultiArgBoolArg0) {
482 const Action<bool(bool, bool, bool)> a = ReturnArg<0>();
483 EXPECT_TRUE(a.Perform(make_tuple(true, false, false)));
484}
485
486TEST(ReturnArgActionTest, WorksForMultiArgStringArg2) {
487 const Action<string(int, int, string, int)> a = ReturnArg<2>();
488 EXPECT_EQ("seven", a.Perform(make_tuple(5, 6, string("seven"), 8)));
489}
490
491TEST(SaveArgActionTest, WorksForSameType) {
492 int result = 0;
493 const Action<void(int n)> a1 = SaveArg<0>(&result);
494 a1.Perform(make_tuple(5));
495 EXPECT_EQ(5, result);
496}
497
498TEST(SaveArgActionTest, WorksForCompatibleType) {
499 int result = 0;
500 const Action<void(bool, char)> a1 = SaveArg<1>(&result);
501 a1.Perform(make_tuple(true, 'a'));
502 EXPECT_EQ('a', result);
503}
504
505TEST(SetArgRefereeActionTest, WorksForSameType) {
506 int value = 0;
507 const Action<void(int&)> a1 = SetArgReferee<0>(1);
508 a1.Perform(tuple<int&>(value));
509 EXPECT_EQ(1, value);
510}
511
512TEST(SetArgRefereeActionTest, WorksForCompatibleType) {
513 int value = 0;
514 const Action<void(int, int&)> a1 = SetArgReferee<1>('a');
515 a1.Perform(tuple<int, int&>(0, value));
516 EXPECT_EQ('a', value);
517}
518
519TEST(SetArgRefereeActionTest, WorksWithExtraArguments) {
520 int value = 0;
521 const Action<void(bool, int, int&, const char*)> a1 = SetArgReferee<2>('a');
522 a1.Perform(tuple<bool, int, int&, const char*>(true, 0, value, "hi"));
523 EXPECT_EQ('a', value);
524}
525
526// A class that can be used to verify that its destructor is called: it will set
527// the bool provided to the constructor to true when destroyed.
528class DeletionTester {
529 public:
530 explicit DeletionTester(bool* is_deleted)
531 : is_deleted_(is_deleted) {
532 // Make sure the bit is set to false.
533 *is_deleted_ = false;
534 }
535
536 ~DeletionTester() {
537 *is_deleted_ = true;
538 }
539
540 private:
541 bool* is_deleted_;
542};
543
544TEST(DeleteArgActionTest, OneArg) {
545 bool is_deleted = false;
546 DeletionTester* t = new DeletionTester(&is_deleted);
547 const Action<void(DeletionTester*)> a1 = DeleteArg<0>(); // NOLINT
548 EXPECT_FALSE(is_deleted);
549 a1.Perform(make_tuple(t));
550 EXPECT_TRUE(is_deleted);
551}
552
553TEST(DeleteArgActionTest, TenArgs) {
554 bool is_deleted = false;
555 DeletionTester* t = new DeletionTester(&is_deleted);
556 const Action<void(bool, int, int, const char*, bool,
557 int, int, int, int, DeletionTester*)> a1 = DeleteArg<9>();
558 EXPECT_FALSE(is_deleted);
559 a1.Perform(make_tuple(true, 5, 6, CharPtr("hi"), false, 7, 8, 9, 10, t));
560 EXPECT_TRUE(is_deleted);
561}
562
563#if GTEST_HAS_EXCEPTIONS
564
565TEST(ThrowActionTest, ThrowsGivenExceptionInVoidFunction) {
566 const Action<void(int n)> a = Throw('a');
567 EXPECT_THROW(a.Perform(make_tuple(0)), char);
568}
569
570class MyException {};
571
572TEST(ThrowActionTest, ThrowsGivenExceptionInNonVoidFunction) {
573 const Action<double(char ch)> a = Throw(MyException());
574 EXPECT_THROW(a.Perform(make_tuple('0')), MyException);
575}
576
577TEST(ThrowActionTest, ThrowsGivenExceptionInNullaryFunction) {
578 const Action<double()> a = Throw(MyException());
579 EXPECT_THROW(a.Perform(make_tuple()), MyException);
580}
581
582#endif // GTEST_HAS_EXCEPTIONS
583
584// Tests that SetArrayArgument<N>(first, last) sets the elements of the array
585// pointed to by the N-th (0-based) argument to values in range [first, last).
586TEST(SetArrayArgumentTest, SetsTheNthArray) {
587 typedef void MyFunction(bool, int*, char*);
588 int numbers[] = { 1, 2, 3 };
589 Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers + 3);
590
591 int n[4] = {};
592 int* pn = n;
593 char ch[4] = {};
594 char* pch = ch;
595 a.Perform(make_tuple(true, pn, pch));
596 EXPECT_EQ(1, n[0]);
597 EXPECT_EQ(2, n[1]);
598 EXPECT_EQ(3, n[2]);
599 EXPECT_EQ(0, n[3]);
600 EXPECT_EQ('\0', ch[0]);
601 EXPECT_EQ('\0', ch[1]);
602 EXPECT_EQ('\0', ch[2]);
603 EXPECT_EQ('\0', ch[3]);
604
605 // Tests first and last are iterators.
606 std::string letters = "abc";
607 a = SetArrayArgument<2>(letters.begin(), letters.end());
608 std::fill_n(n, 4, 0);
609 std::fill_n(ch, 4, '\0');
610 a.Perform(make_tuple(true, pn, pch));
611 EXPECT_EQ(0, n[0]);
612 EXPECT_EQ(0, n[1]);
613 EXPECT_EQ(0, n[2]);
614 EXPECT_EQ(0, n[3]);
615 EXPECT_EQ('a', ch[0]);
616 EXPECT_EQ('b', ch[1]);
617 EXPECT_EQ('c', ch[2]);
618 EXPECT_EQ('\0', ch[3]);
619}
620
621// Tests SetArrayArgument<N>(first, last) where first == last.
622TEST(SetArrayArgumentTest, SetsTheNthArrayWithEmptyRange) {
623 typedef void MyFunction(bool, int*);
624 int numbers[] = { 1, 2, 3 };
625 Action<MyFunction> a = SetArrayArgument<1>(numbers, numbers);
626
627 int n[4] = {};
628 int* pn = n;
629 a.Perform(make_tuple(true, pn));
630 EXPECT_EQ(0, n[0]);
631 EXPECT_EQ(0, n[1]);
632 EXPECT_EQ(0, n[2]);
633 EXPECT_EQ(0, n[3]);
634}
635
636// Tests SetArrayArgument<N>(first, last) where *first is convertible
637// (but not equal) to the argument type.
638TEST(SetArrayArgumentTest, SetsTheNthArrayWithConvertibleType) {
639 typedef void MyFunction(bool, char*);
640 int codes[] = { 97, 98, 99 };
641 Action<MyFunction> a = SetArrayArgument<1>(codes, codes + 3);
642
643 char ch[4] = {};
644 char* pch = ch;
645 a.Perform(make_tuple(true, pch));
646 EXPECT_EQ('a', ch[0]);
647 EXPECT_EQ('b', ch[1]);
648 EXPECT_EQ('c', ch[2]);
649 EXPECT_EQ('\0', ch[3]);
650}
651
652// Test SetArrayArgument<N>(first, last) with iterator as argument.
653TEST(SetArrayArgumentTest, SetsTheNthArrayWithIteratorArgument) {
654 typedef void MyFunction(bool, std::back_insert_iterator<std::string>);
655 std::string letters = "abc";
656 Action<MyFunction> a = SetArrayArgument<1>(letters.begin(), letters.end());
657
658 std::string s;
659 a.Perform(make_tuple(true, back_inserter(s)));
660 EXPECT_EQ(letters, s);
661}
662
663} // namespace gmock_generated_actions_test
664} // namespace testing