diff --git a/include/gmock/gmock-actions.h b/include/gmock/gmock-actions.h index 1d5509ce..215af4f9 100644 --- a/include/gmock/gmock-actions.h +++ b/include/gmock/gmock-actions.h @@ -1020,6 +1020,14 @@ SetArgPointee(const T& x) { return MakePolymorphicAction(internal::SetArgumentPointeeAction< N, T, internal::IsAProtocolMessage::value>(x)); } +// This overload allows SetArgPointee() to accept a string literal. +template +PolymorphicAction< + internal::SetArgumentPointeeAction > +SetArgPointee(const char* p) { + return MakePolymorphicAction(internal::SetArgumentPointeeAction< + N, const char*, false>(p)); +} // The following version is DEPRECATED. template PolymorphicAction< diff --git a/scripts/gmock_doctor.py b/scripts/gmock_doctor.py index 18c117fb..15e2433c 100755 --- a/scripts/gmock_doctor.py +++ b/scripts/gmock_doctor.py @@ -459,6 +459,20 @@ def _TypeInTemplatedBaseDiagnoser(msg): r'error: \'(?P.+)\' was not declared in this scope\n' r'.*error: template argument 1 is invalid\n' r'.*error: \'.+\' was not declared in this scope') + clang_regex_type_of_retval_or_sole_param = ( + _CLANG_FILE_LINE_RE + + r'error: use of undeclared identifier \'(?P.*)\'\n' + r'(.*\n)*?' + r'(?P=file):(?P=line):(?P=column): error: ' + r'non-friend class member \'Result\' cannot have a qualified name' + ) + clang_regex_type_of_a_param = ( + _CLANG_FILE_LINE_RE + + r'error: C\+\+ requires a type specifier for all declarations\n' + r'(.*\n)*?' + r'(?P=file):(?P=line):(?P=column): error: ' + r'C\+\+ requires a type specifier for all declarations' + ) diagnosis = """ In a mock class template, types or typedefs defined in the base class @@ -473,7 +487,9 @@ need to make it visible. One way to do it is: [(gcc_4_3_1_regex_type_in_retval, diagnosis % {'type': 'Foo'}), (gcc_4_4_0_regex_type_in_retval, diagnosis % {'type': 'Foo'}), (gcc_regex_type_of_sole_param, diagnosis), - (gcc_regex_type_of_a_param, diagnosis)], + (gcc_regex_type_of_a_param, diagnosis), + (clang_regex_type_of_retval_or_sole_param, diagnosis), + (clang_regex_type_of_a_param, diagnosis % {'type': 'Foo'})], msg) diff --git a/test/gmock-actions_test.cc b/test/gmock-actions_test.cc index 7200fa1a..e12402b9 100644 --- a/test/gmock-actions_test.cc +++ b/test/gmock-actions_test.cc @@ -715,6 +715,43 @@ TEST(SetArgPointeeTest, SetsTheNthPointee) { EXPECT_EQ('a', ch); } +// Tests that SetArgPointee() accepts a string literal. +TEST(SetArgPointeeTest, AcceptsStringLiteral) { + typedef void MyFunction(bool, std::string*, const char**); + Action a = SetArgPointee<1>("hi"); + std::string str; + const char* ptr = NULL; + a.Perform(make_tuple(true, &str, &ptr)); + EXPECT_EQ("hi", str); + EXPECT_TRUE(ptr == NULL); + + a = SetArgPointee<2>("world"); + str = ""; + a.Perform(make_tuple(true, &str, &ptr)); + EXPECT_EQ("", str); + EXPECT_STREQ("world", ptr); +} + +// Tests that SetArgPointee() accepts a char pointer. +TEST(SetArgPointeeTest, AcceptsCharPointer) { + typedef void MyFunction(bool, std::string*, const char**); + const char* const hi = "hi"; + Action a = SetArgPointee<1>(hi); + std::string str; + const char* ptr = NULL; + a.Perform(make_tuple(true, &str, &ptr)); + EXPECT_EQ("hi", str); + EXPECT_TRUE(ptr == NULL); + + char world_array[] = "world"; + char* const world = world_array; + a = SetArgPointee<2>(world); + str = ""; + a.Perform(make_tuple(true, &str, &ptr)); + EXPECT_EQ("", str); + EXPECT_EQ(world, ptr); +} + #if GTEST_HAS_PROTOBUF_ // Tests that SetArgPointee(proto_buffer) sets the v1 protobuf diff --git a/test/gmock_test.cc b/test/gmock_test.cc index ba137dd3..0b891137 100644 --- a/test/gmock_test.cc +++ b/test/gmock_test.cc @@ -251,5 +251,5 @@ TEST(WideInitGoogleMockTest, CallsInitGoogleTest) { TEST(FlagTest, IsAccessibleInCode) { bool dummy = testing::GMOCK_FLAG(catch_leaked_mocks) && testing::GMOCK_FLAG(verbose) == ""; - dummy = dummy; // Avoids the "unused local variable" warning. + (void)dummy; // Avoids the "unused local variable" warning. }