Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: testing/gmock/test/gmock-generated-actions_test.cc

Issue 521012: Update gmock and gtest. (Closed)
Patch Set: update readme Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2007, Google Inc. 1 // Copyright 2007, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 using testing::ByRef; 56 using testing::ByRef;
57 using testing::DoAll; 57 using testing::DoAll;
58 using testing::Invoke; 58 using testing::Invoke;
59 using testing::Return; 59 using testing::Return;
60 using testing::ReturnNew; 60 using testing::ReturnNew;
61 using testing::SetArgumentPointee; 61 using testing::SetArgumentPointee;
62 using testing::StaticAssertTypeEq; 62 using testing::StaticAssertTypeEq;
63 using testing::Unused; 63 using testing::Unused;
64 using testing::WithArgs; 64 using testing::WithArgs;
65 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
66 // Sample functions and functors for testing various actions. 70 // Sample functions and functors for testing various actions.
67 int Nullary() { return 1; } 71 int Nullary() { return 1; }
68 72
69 class NullaryFunctor { 73 class NullaryFunctor {
70 public: 74 public:
71 int operator()() { return 2; } 75 int operator()() { return 2; }
72 }; 76 };
73 77
74 bool g_done = false; 78 bool g_done = false;
75 79
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 const char*, const char*, const char*, 239 const char*, const char*, const char*,
236 const char*, const char*, const char*, 240 const char*, const char*, const char*,
237 const char*))> a = 241 const char*))> a =
238 InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0"); 242 InvokeArgument<0>("1", "2", "3", "4", "5", "6", "7", "8", "9", "0");
239 EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10))); 243 EXPECT_EQ("1234567890", a.Perform(make_tuple(&Concat10)));
240 } 244 }
241 245
242 // Tests using InvokeArgument with a function that takes a pointer argument. 246 // Tests using InvokeArgument with a function that takes a pointer argument.
243 TEST(InvokeArgumentTest, ByPointerFunction) { 247 TEST(InvokeArgumentTest, ByPointerFunction) {
244 Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT 248 Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
245 InvokeArgument<0>(static_cast<const char*>("Hi"), 1); 249 InvokeArgument<0>(static_cast<const char*>("Hi"), Short(1));
246 EXPECT_STREQ("i", a.Perform(make_tuple(&Binary))); 250 EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
247 } 251 }
248 252
249 // Tests using InvokeArgument with a function that takes a const char* 253 // Tests using InvokeArgument with a function that takes a const char*
250 // by passing it a C-string literal. 254 // by passing it a C-string literal.
251 TEST(InvokeArgumentTest, FunctionWithCStringLiteral) { 255 TEST(InvokeArgumentTest, FunctionWithCStringLiteral) {
252 Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT 256 Action<const char*(const char*(*)(const char* input, short n))> a = // NOLINT
253 InvokeArgument<0>("Hi", 1); 257 InvokeArgument<0>("Hi", Short(1));
254 EXPECT_STREQ("i", a.Perform(make_tuple(&Binary))); 258 EXPECT_STREQ("i", a.Perform(make_tuple(&Binary)));
255 } 259 }
256 260
257 // Tests using InvokeArgument with a function that takes a const reference. 261 // Tests using InvokeArgument with a function that takes a const reference.
258 TEST(InvokeArgumentTest, ByConstReferenceFunction) { 262 TEST(InvokeArgumentTest, ByConstReferenceFunction) {
259 Action<bool(bool(*function)(const string& s))> a = // NOLINT 263 Action<bool(bool(*function)(const string& s))> a = // NOLINT
260 InvokeArgument<0>(string("Hi")); 264 InvokeArgument<0>(string("Hi"));
261 // When action 'a' is constructed, it makes a copy of the temporary 265 // When action 'a' is constructed, it makes a copy of the temporary
262 // string object passed to it, so it's OK to use 'a' later, when the 266 // string object passed to it, so it's OK to use 'a' later, when the
263 // temporary object has already died. 267 // temporary object has already died.
(...skipping 15 matching lines...) Expand all
279 283
280 // Tests using WithArgs and with an action that takes 1 argument. 284 // Tests using WithArgs and with an action that takes 1 argument.
281 TEST(WithArgsTest, OneArg) { 285 TEST(WithArgsTest, OneArg) {
282 Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT 286 Action<bool(double x, int n)> a = WithArgs<1>(Invoke(Unary)); // NOLINT
283 EXPECT_TRUE(a.Perform(make_tuple(1.5, -1))); 287 EXPECT_TRUE(a.Perform(make_tuple(1.5, -1)));
284 EXPECT_FALSE(a.Perform(make_tuple(1.5, 1))); 288 EXPECT_FALSE(a.Perform(make_tuple(1.5, 1)));
285 } 289 }
286 290
287 // Tests using WithArgs with an action that takes 2 arguments. 291 // Tests using WithArgs with an action that takes 2 arguments.
288 TEST(WithArgsTest, TwoArgs) { 292 TEST(WithArgsTest, TwoArgs) {
289 Action<const char*(const char* s, double x, int n)> a = 293 Action<const char*(const char* s, double x, short n)> a =
290 WithArgs<0, 2>(Invoke(Binary)); 294 WithArgs<0, 2>(Invoke(Binary));
291 const char s[] = "Hello"; 295 const char s[] = "Hello";
292 EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, 2))); 296 EXPECT_EQ(s + 2, a.Perform(make_tuple(CharPtr(s), 0.5, Short(2))));
293 } 297 }
294 298
295 // Tests using WithArgs with an action that takes 3 arguments. 299 // Tests using WithArgs with an action that takes 3 arguments.
296 TEST(WithArgsTest, ThreeArgs) { 300 TEST(WithArgsTest, ThreeArgs) {
297 Action<int(int, double, char, short)> a = // NOLINT 301 Action<int(int, double, char, short)> a = // NOLINT
298 WithArgs<0, 2, 3>(Invoke(Ternary)); 302 WithArgs<0, 2, 3>(Invoke(Ternary));
299 EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, 20, 3))); 303 EXPECT_EQ(123, a.Perform(make_tuple(100, 6.5, Char(20), Short(3))));
300 } 304 }
301 305
302 // Tests using WithArgs with an action that takes 4 arguments. 306 // Tests using WithArgs with an action that takes 4 arguments.
303 TEST(WithArgsTest, FourArgs) { 307 TEST(WithArgsTest, FourArgs) {
304 Action<string(const char*, const char*, double, const char*, const char*)> a = 308 Action<string(const char*, const char*, double, const char*, const char*)> a =
305 WithArgs<4, 3, 1, 0>(Invoke(Concat4)); 309 WithArgs<4, 3, 1, 0>(Invoke(Concat4));
306 EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5, 310 EXPECT_EQ("4310", a.Perform(make_tuple(CharPtr("0"), CharPtr("1"), 2.5,
307 CharPtr("3"), CharPtr("4")))); 311 CharPtr("3"), CharPtr("4"))));
308 } 312 }
309 313
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 TEST(WithArgsTest, NonInvokeAction) { 376 TEST(WithArgsTest, NonInvokeAction) {
373 Action<int(const string&, int, int)> a = // NOLINT 377 Action<int(const string&, int, int)> a = // NOLINT
374 WithArgs<2, 1>(MakeAction(new SubstractAction)); 378 WithArgs<2, 1>(MakeAction(new SubstractAction));
375 EXPECT_EQ(8, a.Perform(make_tuple(CharPtr("hi"), 2, 10))); 379 EXPECT_EQ(8, a.Perform(make_tuple(CharPtr("hi"), 2, 10)));
376 } 380 }
377 381
378 // Tests using WithArgs to pass all original arguments in the original order. 382 // Tests using WithArgs to pass all original arguments in the original order.
379 TEST(WithArgsTest, Identity) { 383 TEST(WithArgsTest, Identity) {
380 Action<int(int x, char y, short z)> a = // NOLINT 384 Action<int(int x, char y, short z)> a = // NOLINT
381 WithArgs<0, 1, 2>(Invoke(Ternary)); 385 WithArgs<0, 1, 2>(Invoke(Ternary));
382 EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 3))); 386 EXPECT_EQ(123, a.Perform(make_tuple(100, Char(20), Short(3))));
383 } 387 }
384 388
385 // Tests using WithArgs with repeated arguments. 389 // Tests using WithArgs with repeated arguments.
386 TEST(WithArgsTest, RepeatedArguments) { 390 TEST(WithArgsTest, RepeatedArguments) {
387 Action<int(bool, int m, int n)> a = // NOLINT 391 Action<int(bool, int m, int n)> a = // NOLINT
388 WithArgs<1, 1, 1, 1>(Invoke(SumOf4)); 392 WithArgs<1, 1, 1, 1>(Invoke(SumOf4));
389 EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10))); 393 EXPECT_EQ(4, a.Perform(make_tuple(false, 1, 10)));
390 } 394 }
391 395
392 // Tests using WithArgs with reversed argument order. 396 // Tests using WithArgs with reversed argument order.
393 TEST(WithArgsTest, ReversedArgumentOrder) { 397 TEST(WithArgsTest, ReversedArgumentOrder) {
394 Action<const char*(short n, const char* input)> a = // NOLINT 398 Action<const char*(short n, const char* input)> a = // NOLINT
395 WithArgs<1, 0>(Invoke(Binary)); 399 WithArgs<1, 0>(Invoke(Binary));
396 const char s[] = "Hello"; 400 const char s[] = "Hello";
397 EXPECT_EQ(s + 2, a.Perform(make_tuple(2, CharPtr(s)))); 401 EXPECT_EQ(s + 2, a.Perform(make_tuple(Short(2), CharPtr(s))));
398 } 402 }
399 403
400 // Tests using WithArgs with compatible, but not identical, argument types. 404 // Tests using WithArgs with compatible, but not identical, argument types.
401 TEST(WithArgsTest, ArgsOfCompatibleTypes) { 405 TEST(WithArgsTest, ArgsOfCompatibleTypes) {
402 Action<long(short x, int y, double z, char c)> a = // NOLINT 406 Action<long(short x, char y, double z, char c)> a = // NOLINT
403 WithArgs<0, 1, 3>(Invoke(Ternary)); 407 WithArgs<0, 1, 3>(Invoke(Ternary));
404 EXPECT_EQ(123, a.Perform(make_tuple(100, 20, 5.6, 3))); 408 EXPECT_EQ(123, a.Perform(make_tuple(Short(100), Char(20), 5.6, Char(3))));
405 } 409 }
406 410
407 // Tests using WithArgs with an action that returns void. 411 // Tests using WithArgs with an action that returns void.
408 TEST(WithArgsTest, VoidAction) { 412 TEST(WithArgsTest, VoidAction) {
409 Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary)); 413 Action<void(double x, char c, int n)> a = WithArgs<2, 1>(Invoke(VoidBinary));
410 g_done = false; 414 g_done = false;
411 a.Perform(make_tuple(1.5, 'a', 3)); 415 a.Perform(make_tuple(1.5, 'a', 3));
412 EXPECT_TRUE(g_done); 416 EXPECT_TRUE(g_done);
413 } 417 }
414 418
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 EXPECT_EQ(2, n); 580 EXPECT_EQ(2, n);
577 EXPECT_EQ('a', a); 581 EXPECT_EQ('a', a);
578 EXPECT_EQ('b', b); 582 EXPECT_EQ('b', b);
579 EXPECT_EQ('c', c); 583 EXPECT_EQ('c', c);
580 EXPECT_EQ('d', d); 584 EXPECT_EQ('d', d);
581 EXPECT_EQ('e', e); 585 EXPECT_EQ('e', e);
582 EXPECT_EQ('f', f); 586 EXPECT_EQ('f', f);
583 EXPECT_EQ('g', g); 587 EXPECT_EQ('g', g);
584 } 588 }
585 589
590 // The ACTION*() macros trigger warning C4100 (unreferenced formal
591 // parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
592 // the macro definition, as the warnings are generated when the macro
593 // is expanded and macro expansion cannot contain #pragma. Therefore
594 // we suppress them here.
595 #ifdef _MSC_VER
596 #pragma warning(push)
597 #pragma warning(disable:4100)
598 #endif
599
586 // Tests the ACTION*() macro family. 600 // Tests the ACTION*() macro family.
587 601
588 // Tests that ACTION() can define an action that doesn't reference the 602 // Tests that ACTION() can define an action that doesn't reference the
589 // mock function arguments. 603 // mock function arguments.
590 ACTION(Return5) { return 5; } 604 ACTION(Return5) { return 5; }
591 605
592 TEST(ActionMacroTest, WorksWhenNotReferencingArguments) { 606 TEST(ActionMacroTest, WorksWhenNotReferencingArguments) {
593 Action<double()> a1 = Return5(); 607 Action<double()> a1 = Return5();
594 EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple())); 608 EXPECT_DOUBLE_EQ(5, a1.Perform(make_tuple()));
595 609
(...skipping 30 matching lines...) Expand all
626 // via args_type and args. 640 // via args_type and args.
627 ACTION(Sum2) { 641 ACTION(Sum2) {
628 StaticAssertTypeEq< ::std::tr1::tuple<int, char, int*>, args_type>(); 642 StaticAssertTypeEq< ::std::tr1::tuple<int, char, int*>, args_type>();
629 args_type args_copy = args; 643 args_type args_copy = args;
630 return get<0>(args_copy) + get<1>(args_copy); 644 return get<0>(args_copy) + get<1>(args_copy);
631 } 645 }
632 646
633 TEST(ActionMacroTest, CanReferenceArgumentTuple) { 647 TEST(ActionMacroTest, CanReferenceArgumentTuple) {
634 Action<int(int, char, int*)> a1 = Sum2(); 648 Action<int(int, char, int*)> a1 = Sum2();
635 int dummy = 0; 649 int dummy = 0;
636 EXPECT_EQ(11, a1.Perform(make_tuple(5, static_cast<char>(6), &dummy))); 650 EXPECT_EQ(11, a1.Perform(make_tuple(5, Char(6), &dummy)));
637 } 651 }
638 652
639 // Tests that the body of ACTION() can reference the mock function 653 // Tests that the body of ACTION() can reference the mock function
640 // type. 654 // type.
641 int Dummy(bool flag) { return flag? 1 : 0; } 655 int Dummy(bool flag) { return flag? 1 : 0; }
642 656
643 ACTION(InvokeDummy) { 657 ACTION(InvokeDummy) {
644 StaticAssertTypeEq<int(bool), function_type>(); 658 StaticAssertTypeEq<int(bool), function_type>();
645 function_type* fp = &Dummy; 659 function_type* fp = &Dummy;
646 return (*fp)(true); 660 return (*fp)(true);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
724 // Tests that the body of ACTION_P can reference the argument types 738 // Tests that the body of ACTION_P can reference the argument types
725 // and the parameter type. 739 // and the parameter type.
726 ACTION_P(TypedPlus, n) { 740 ACTION_P(TypedPlus, n) {
727 arg0_type t1 = arg0; 741 arg0_type t1 = arg0;
728 n_type t2 = n; 742 n_type t2 = n;
729 return t1 + t2; 743 return t1 + t2;
730 } 744 }
731 745
732 TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) { 746 TEST(ActionPMacroTest, CanReferenceArgumentAndParameterTypes) {
733 Action<int(char m, bool t)> a1 = TypedPlus(9); 747 Action<int(char m, bool t)> a1 = TypedPlus(9);
734 EXPECT_EQ(10, a1.Perform(make_tuple(static_cast<char>(1), true))); 748 EXPECT_EQ(10, a1.Perform(make_tuple(Char(1), true)));
735 } 749 }
736 750
737 // Tests that a parameterized action can be used in any mock function 751 // Tests that a parameterized action can be used in any mock function
738 // whose type is compatible. 752 // whose type is compatible.
739 TEST(ActionPMacroTest, WorksInCompatibleMockFunction) { 753 TEST(ActionPMacroTest, WorksInCompatibleMockFunction) {
740 Action<std::string(const std::string& s)> a1 = Plus("tail"); 754 Action<std::string(const std::string& s)> a1 = Plus("tail");
741 const std::string re = "re"; 755 const std::string re = "re";
742 EXPECT_EQ("retail", a1.Perform(make_tuple(re))); 756 EXPECT_EQ("retail", a1.Perform(make_tuple(re)));
743 } 757 }
744 758
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); 858 Action<int(int)> a1 = Plus(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
845 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, 859 EXPECT_EQ(10 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10,
846 a1.Perform(make_tuple(10))); 860 a1.Perform(make_tuple(10)));
847 } 861 }
848 862
849 // Tests that the action body can promote the parameter types. 863 // Tests that the action body can promote the parameter types.
850 864
851 ACTION_P2(PadArgument, prefix, suffix) { 865 ACTION_P2(PadArgument, prefix, suffix) {
852 // The following lines promote the two parameters to desired types. 866 // The following lines promote the two parameters to desired types.
853 std::string prefix_str(prefix); 867 std::string prefix_str(prefix);
854 char suffix_char(suffix); 868 char suffix_char = static_cast<char>(suffix);
855 return prefix_str + arg0 + suffix_char; 869 return prefix_str + arg0 + suffix_char;
856 } 870 }
857 871
858 TEST(ActionPnMacroTest, SimpleTypePromotion) { 872 TEST(ActionPnMacroTest, SimpleTypePromotion) {
859 Action<std::string(const char*)> no_promo = 873 Action<std::string(const char*)> no_promo =
860 PadArgument(std::string("foo"), 'r'); 874 PadArgument(std::string("foo"), 'r');
861 Action<std::string(const char*)> promo = 875 Action<std::string(const char*)> promo =
862 PadArgument("foo", static_cast<int>('r')); 876 PadArgument("foo", static_cast<int>('r'));
863 EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba")))); 877 EXPECT_EQ("foobar", no_promo.Perform(make_tuple(CharPtr("ba"))));
864 EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba")))); 878 EXPECT_EQ("foobar", promo.Perform(make_tuple(CharPtr("ba"))));
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 AND_0_VALUE_PARAMS()) { 1085 AND_0_VALUE_PARAMS()) {
1072 delete std::tr1::get<k>(args); 1086 delete std::tr1::get<k>(args);
1073 } 1087 }
1074 1088
1075 // Resets a bool variable in the destructor. 1089 // Resets a bool variable in the destructor.
1076 class BoolResetter { 1090 class BoolResetter {
1077 public: 1091 public:
1078 explicit BoolResetter(bool* value) : value_(value) {} 1092 explicit BoolResetter(bool* value) : value_(value) {}
1079 ~BoolResetter() { *value_ = false; } 1093 ~BoolResetter() { *value_ = false; }
1080 private: 1094 private:
1081 bool* const value_; 1095 bool* value_;
1082 }; 1096 };
1083 1097
1084 TEST(ActionTemplateTest, WorksForIntegralTemplateParams) { 1098 TEST(ActionTemplateTest, WorksForIntegralTemplateParams) {
1085 const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>(); 1099 const Action<void(int*, BoolResetter*)> a = MyDeleteArg<1>();
1086 int n = 0; 1100 int n = 0;
1087 bool b = true; 1101 bool b = true;
1088 BoolResetter* resetter = new BoolResetter(&b); 1102 BoolResetter* resetter = new BoolResetter(&b);
1089 a.Perform(make_tuple(&n, resetter)); 1103 a.Perform(make_tuple(&n, resetter));
1090 EXPECT_FALSE(b); // Verifies that resetter is deleted. 1104 EXPECT_FALSE(b); // Verifies that resetter is deleted.
1091 } 1105 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 const Action<int()> a2 = ReturnSum<int>(1, 2); 1197 const Action<int()> a2 = ReturnSum<int>(1, 2);
1184 const Action<int()> a3 = ReturnSum<int>(1, 2, 3); 1198 const Action<int()> a3 = ReturnSum<int>(1, 2, 3);
1185 const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5); 1199 const Action<int()> a4 = ReturnSum<int, 10000>(2000, 300, 40, 5);
1186 EXPECT_EQ(0, a0.Perform(make_tuple())); 1200 EXPECT_EQ(0, a0.Perform(make_tuple()));
1187 EXPECT_EQ(1, a1.Perform(make_tuple())); 1201 EXPECT_EQ(1, a1.Perform(make_tuple()));
1188 EXPECT_EQ(3, a2.Perform(make_tuple())); 1202 EXPECT_EQ(3, a2.Perform(make_tuple()));
1189 EXPECT_EQ(6, a3.Perform(make_tuple())); 1203 EXPECT_EQ(6, a3.Perform(make_tuple()));
1190 EXPECT_EQ(12345, a4.Perform(make_tuple())); 1204 EXPECT_EQ(12345, a4.Perform(make_tuple()));
1191 } 1205 }
1192 1206
1207 #ifdef _MSC_VER
1208 #pragma warning(pop)
1209 #endif
1210
1193 } // namespace gmock_generated_actions_test 1211 } // namespace gmock_generated_actions_test
1194 } // namespace testing 1212 } // namespace testing
OLDNEW
« no previous file with comments | « testing/gmock/test/gmock-cardinalities_test.cc ('k') | testing/gmock/test/gmock-generated-function-mockers_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698