summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbseil Team <absl-team@google.com>2020-12-11 14:20:17 -0500
committerAndy Getz <durandal@google.com>2020-12-11 19:57:59 -0500
commit0217b5576a8df97553faf6e2f815a24aec3d457d (patch)
treec3e7cca278f9b4ad1182471b9ffcacbc59de3384
parent5a509dbd2e5a6c694116e329c5a20dc190653724 (diff)
downloadgoogletest-git-77A9B20B4C1E02FAC90D1D942E1D4C18.tar.gz
Export Test - Do Not Merge77A9B20B4C1E02FAC90D1D942E1D4C18
Add static_asserts that verify that no class hierarchy contains more than one of {NiceMock, NaggyMock, StrictMock}. This sort of nesting has always been disallowed, but this CL adds a compile-time check to prevent it. PiperOrigin-RevId: 347037822
-rw-r--r--googlemock/include/gmock/gmock-nice-strict.h71
1 files changed, 43 insertions, 28 deletions
diff --git a/googlemock/include/gmock/gmock-nice-strict.h b/googlemock/include/gmock/gmock-nice-strict.h
index a5579afc..69afa1ba 100644
--- a/googlemock/include/gmock/gmock-nice-strict.h
+++ b/googlemock/include/gmock/gmock-nice-strict.h
@@ -63,14 +63,44 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
+#include <type_traits>
+
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
+template <class MockClass>
+class NiceMock;
+template <class MockClass>
+class NaggyMock;
+template <class MockClass>
+class StrictMock;
+
+namespace internal {
+template <typename T>
+std::true_type StrictnessModifierProbe(const NiceMock<T>&);
+template <typename T>
+std::true_type StrictnessModifierProbe(const NaggyMock<T>&);
+template <typename T>
+std::true_type StrictnessModifierProbe(const StrictMock<T>&);
+std::false_type StrictnessModifierProbe(...);
+
+template <typename T>
+constexpr bool HasStrictnessModifier() {
+ return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;
+}
+
+} // namespace internal
template <class MockClass>
class NiceMock : public MockClass {
public:
+ static_assert(
+ !internal::HasStrictnessModifier<MockClass>(),
+ "Can't apply NiceMock to a class hierarchy that already has a "
+ "strictness modifier. See "
+ "https://github.com/google/googletest/blob/master/googlemock/docs/"
+ "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy");
NiceMock() : MockClass() {
::testing::Mock::AllowUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
@@ -108,6 +138,13 @@ class NiceMock : public MockClass {
template <class MockClass>
class NaggyMock : public MockClass {
+ static_assert(
+ !internal::HasStrictnessModifier<MockClass>(),
+ "Can't apply NaggyMock to a class hierarchy that already has a "
+ "strictness modifier. See "
+ "https://github.com/google/googletest/blob/master/googlemock/docs/"
+ "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy");
+
public:
NaggyMock() : MockClass() {
::testing::Mock::WarnUninterestingCalls(
@@ -147,6 +184,12 @@ class NaggyMock : public MockClass {
template <class MockClass>
class StrictMock : public MockClass {
public:
+ static_assert(
+ !internal::HasStrictnessModifier<MockClass>(),
+ "Can't apply StrictMock to a class hierarchy that already has a "
+ "strictness modifier. See "
+ "https://github.com/google/googletest/blob/master/googlemock/docs/"
+ "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy");
StrictMock() : MockClass() {
::testing::Mock::FailUninterestingCalls(
internal::ImplicitCast_<MockClass*>(this));
@@ -182,34 +225,6 @@ class StrictMock : public MockClass {
GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
};
-// The following specializations catch some (relatively more common)
-// user errors of nesting nice and strict mocks. They do NOT catch
-// all possible errors.
-
-// These specializations are declared but not defined, as NiceMock,
-// NaggyMock, and StrictMock cannot be nested.
-
-template <typename MockClass>
-class NiceMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class NiceMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class NiceMock<StrictMock<MockClass> >;
-
-template <typename MockClass>
-class NaggyMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class NaggyMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class NaggyMock<StrictMock<MockClass> >;
-
-template <typename MockClass>
-class StrictMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class StrictMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class StrictMock<StrictMock<MockClass> >;
-
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_