From 6e1970e2376c14bf658eb88f655a054030353f9f Mon Sep 17 00:00:00 2001
From: Alyssa Wilk <alyssar@chromium.org>
Date: Thu, 10 Aug 2017 09:41:09 -0400
Subject: [PATCH 1/3] Adding a flag option to change the default mock type

---
 .../include/gmock/gmock-spec-builders.h       |  1 -
 googlemock/include/gmock/gmock.h              |  1 +
 googlemock/src/gmock-spec-builders.cc         |  3 +-
 googlemock/src/gmock.cc                       | 24 ++++++++++-
 googlemock/test/gmock-spec-builders_test.cc   | 35 ++++++++++++++++
 googlemock/test/gmock_test.cc                 | 41 +++++++++++++++++++
 6 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h
index 39f72129..96802444 100644
--- a/googlemock/include/gmock/gmock-spec-builders.h
+++ b/googlemock/include/gmock/gmock-spec-builders.h
@@ -363,7 +363,6 @@ enum CallReaction {
   kAllow,
   kWarn,
   kFail,
-  kDefault = kWarn  // By default, warn about uninteresting calls.
 };
 
 }  // namespace internal
diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h
index 6735c71b..5764bc85 100644
--- a/googlemock/include/gmock/gmock.h
+++ b/googlemock/include/gmock/gmock.h
@@ -71,6 +71,7 @@ namespace testing {
 // Declares Google Mock flags that we want a user to use programmatically.
 GMOCK_DECLARE_bool_(catch_leaked_mocks);
 GMOCK_DECLARE_string_(verbose);
+GMOCK_DECLARE_int32_(default_mock_behavior);
 
 // Initializes Google Mock.  This must be called before running the
 // tests.  In particular, it parses the command line for the flags
diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc
index 2fa1ee4b..1fc8d988 100644
--- a/googlemock/src/gmock-spec-builders.cc
+++ b/googlemock/src/gmock-spec-builders.cc
@@ -648,7 +648,8 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
         GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
   internal::MutexLock l(&internal::g_gmock_mutex);
   return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
-      internal::kDefault : g_uninteresting_call_reaction[mock_obj];
+      static_cast<internal::CallReaction>(GMOCK_FLAG(default_mock_behavior)) :
+      g_uninteresting_call_reaction[mock_obj];
 }
 
 // Tells Google Mock to ignore mock_obj when checking for leaked mock
diff --git a/googlemock/src/gmock.cc b/googlemock/src/gmock.cc
index eac3d842..3c370510 100644
--- a/googlemock/src/gmock.cc
+++ b/googlemock/src/gmock.cc
@@ -48,6 +48,13 @@ GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
                      "  warning - prints warnings and errors.\n"
                      "  error   - prints errors only.");
 
+GMOCK_DEFINE_int32_(default_mock_behavior, 1,
+                    "Controls the default behavior of mocks."
+                    "  Valid values:\n"
+                    "  0 - by default, mocks act as NiceMocks.\n"
+                    "  1 - by default, mocks act as NaggyMocks.\n"
+                    "  2 - by default, mocks act as StrictMocks.");
+
 namespace internal {
 
 // Parses a string as a command line flag.  The string should have the
@@ -120,6 +127,19 @@ static bool ParseGoogleMockStringFlag(const char* str, const char* flag,
   return true;
 }
 
+static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
+                                   int* value) {
+  // Gets the value of the flag as a string.
+  const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
+
+  // Aborts if the parsing failed.
+  if (value_str == NULL) return false;
+
+  // Sets *value to the value of the flag.
+  *value = atoi(value_str);
+  return true;
+}
+
 // The internal implementation of InitGoogleMock().
 //
 // The type parameter CharType can be instantiated to either char or
@@ -138,7 +158,9 @@ void InitGoogleMockImpl(int* argc, CharType** argv) {
     // Do we see a Google Mock flag?
     if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
                                 &GMOCK_FLAG(catch_leaked_mocks)) ||
-        ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
+        ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
+        ParseGoogleMockIntFlag(arg, "default_mock_behavior",
+                               &GMOCK_FLAG(default_mock_behavior))) {
       // Yes.  Shift the remainder of the argv list left by one.  Note
       // that argv has (*argc + 1) elements, the last one always being
       // NULL.  The following loop moves the trailing NULL element as
diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc
index 389e0709..00cb1198 100644
--- a/googlemock/test/gmock-spec-builders_test.cc
+++ b/googlemock/test/gmock-spec-builders_test.cc
@@ -93,8 +93,11 @@ using testing::Sequence;
 using testing::SetArgPointee;
 using testing::internal::ExpectationTester;
 using testing::internal::FormatFileLocation;
+using testing::internal::kAllow;
 using testing::internal::kErrorVerbosity;
+using testing::internal::kFail;
 using testing::internal::kInfoVerbosity;
+using testing::internal::kWarn;
 using testing::internal::kWarningVerbosity;
 using testing::internal::linked_ptr;
 
@@ -691,6 +694,38 @@ TEST(ExpectCallSyntaxTest, WarnsOnTooFewActions) {
   b.DoB();
 }
 
+TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
+  int original_behavior = testing::GMOCK_FLAG(default_mock_behavior);
+
+  testing::GMOCK_FLAG(default_mock_behavior) = kAllow;
+  CaptureStdout();
+  {
+    MockA a;
+    a.DoA(0);
+  }
+  std::string output = GetCapturedStdout();
+  EXPECT_TRUE(output.empty()) << output;
+
+  testing::GMOCK_FLAG(default_mock_behavior) = kWarn;
+  CaptureStdout();
+  {
+    MockA a;
+    a.DoA(0);
+  }
+  std::string warning_output = GetCapturedStdout();
+  EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
+  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output);
+
+  testing::GMOCK_FLAG(default_mock_behavior) = kFail;
+  EXPECT_NONFATAL_FAILURE({
+    MockA a;
+    a.DoA(0);
+  },"Uninteresting mock function call");
+
+  testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
+}
+
+
 #endif  // GTEST_HAS_STREAM_REDIRECTION
 
 // Tests the semantics of ON_CALL().
diff --git a/googlemock/test/gmock_test.cc b/googlemock/test/gmock_test.cc
index d8d0c57b..28995345 100644
--- a/googlemock/test/gmock_test.cc
+++ b/googlemock/test/gmock_test.cc
@@ -40,6 +40,7 @@
 
 #if !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
 
+using testing::GMOCK_FLAG(default_mock_behavior);
 using testing::GMOCK_FLAG(verbose);
 using testing::InitGoogleMock;
 
@@ -103,6 +104,26 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
   TestInitGoogleMock(argv, new_argv, "info");
 }
 
+TEST(InitGoogleMockTest, ParsesMultipleFlags) {
+  int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
+  const wchar_t* argv[] = {
+    L"foo.exe",
+    L"--gmock_verbose=info",
+    L"--gmock_default_mock_behavior=2",
+    NULL
+  };
+
+  const wchar_t* new_argv[] = {
+    L"foo.exe",
+    NULL
+  };
+
+  TestInitGoogleMock(argv, new_argv, "info");
+  EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
+  EXPECT_NE(2, old_default_behavior);
+  GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
+}
+
 TEST(InitGoogleMockTest, ParsesUnrecognizedFlag) {
   const char* argv[] = {
     "foo.exe",
@@ -177,6 +198,26 @@ TEST(WideInitGoogleMockTest, ParsesSingleFlag) {
   TestInitGoogleMock(argv, new_argv, "info");
 }
 
+TEST(WideInitGoogleMockTest, ParsesMultipleFlags) {
+  int old_default_behavior = GMOCK_FLAG(default_mock_behavior);
+  const wchar_t* argv[] = {
+    L"foo.exe",
+    L"--gmock_verbose=info",
+    L"--gmock_default_mock_behavior=2",
+    NULL
+  };
+
+  const wchar_t* new_argv[] = {
+    L"foo.exe",
+    NULL
+  };
+
+  TestInitGoogleMock(argv, new_argv, "info");
+  EXPECT_EQ(2, GMOCK_FLAG(default_mock_behavior));
+  EXPECT_NE(2, old_default_behavior);
+  GMOCK_FLAG(default_mock_behavior) = old_default_behavior;
+}
+
 TEST(WideInitGoogleMockTest, ParsesUnrecognizedFlag) {
   const wchar_t* argv[] = {
     L"foo.exe",

From a2803bc37dafdaad05b335e64a83aff03096a4ba Mon Sep 17 00:00:00 2001
From: Alyssa Wilk <alyssar@chromium.org>
Date: Wed, 16 Aug 2017 12:43:26 -0400
Subject: [PATCH 2/3] Handling invalid flag values

---
 googlemock/src/gmock-spec-builders.cc       |  9 ++++++++-
 googlemock/test/gmock-spec-builders_test.cc | 20 ++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/googlemock/src/gmock-spec-builders.cc b/googlemock/src/gmock-spec-builders.cc
index 1fc8d988..a725d185 100644
--- a/googlemock/src/gmock-spec-builders.cc
+++ b/googlemock/src/gmock-spec-builders.cc
@@ -508,6 +508,13 @@ bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked()
   return expectations_met;
 }
 
+CallReaction intToCallReaction(int mock_behavior) {
+  if (mock_behavior >= kAllow && mock_behavior <= kFail) {
+    return static_cast<internal::CallReaction>(mock_behavior);
+  }
+  return kWarn;
+}
+
 }  // namespace internal
 
 // Class Mock.
@@ -648,7 +655,7 @@ internal::CallReaction Mock::GetReactionOnUninterestingCalls(
         GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
   internal::MutexLock l(&internal::g_gmock_mutex);
   return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
-      static_cast<internal::CallReaction>(GMOCK_FLAG(default_mock_behavior)) :
+      internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
       g_uninteresting_call_reaction[mock_obj];
 }
 
diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc
index 00cb1198..34088de1 100644
--- a/googlemock/test/gmock-spec-builders_test.cc
+++ b/googlemock/test/gmock-spec-builders_test.cc
@@ -722,6 +722,26 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
     a.DoA(0);
   },"Uninteresting mock function call");
 
+  // Out of bounds values are converted to kWarn
+  testing::GMOCK_FLAG(default_mock_behavior) = -1;
+  CaptureStdout();
+  {
+    MockA a;
+    a.DoA(0);
+  }
+  warning_output = GetCapturedStdout();
+  EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
+  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output);
+  testing::GMOCK_FLAG(default_mock_behavior) = 3;
+  CaptureStdout();
+  {
+    MockA a;
+    a.DoA(0);
+  }
+  warning_output = GetCapturedStdout();
+  EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
+  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output);
+
   testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
 }
 

From fa5d3b3845aa4cc38eef41c2e7ba0e98bfe15b39 Mon Sep 17 00:00:00 2001
From: Alyssa Wilk <alyssar@chromium.org>
Date: Mon, 28 Aug 2017 16:13:41 -0400
Subject: [PATCH 3/3] Applying lint checks from upstream google3

---
 googlemock/test/gmock-spec-builders_test.cc | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/googlemock/test/gmock-spec-builders_test.cc b/googlemock/test/gmock-spec-builders_test.cc
index 34088de1..c649bfd9 100644
--- a/googlemock/test/gmock-spec-builders_test.cc
+++ b/googlemock/test/gmock-spec-builders_test.cc
@@ -714,13 +714,14 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
   }
   std::string warning_output = GetCapturedStdout();
   EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
-  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output);
+  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
+                      warning_output);
 
   testing::GMOCK_FLAG(default_mock_behavior) = kFail;
   EXPECT_NONFATAL_FAILURE({
     MockA a;
     a.DoA(0);
-  },"Uninteresting mock function call");
+  }, "Uninteresting mock function call");
 
   // Out of bounds values are converted to kWarn
   testing::GMOCK_FLAG(default_mock_behavior) = -1;
@@ -731,7 +732,8 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
   }
   warning_output = GetCapturedStdout();
   EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
-  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output);
+  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
+                      warning_output);
   testing::GMOCK_FLAG(default_mock_behavior) = 3;
   CaptureStdout();
   {
@@ -740,7 +742,8 @@ TEST(ExpectCallSyntaxTest, WarningIsErrorWithFlag) {
   }
   warning_output = GetCapturedStdout();
   EXPECT_PRED_FORMAT2(IsSubstring, "GMOCK WARNING", warning_output);
-  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call", warning_output);
+  EXPECT_PRED_FORMAT2(IsSubstring, "Uninteresting mock function call",
+                      warning_output);
 
   testing::GMOCK_FLAG(default_mock_behavior) = original_behavior;
 }