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 + #include "gmock/gmock-spec-builders.h" #include "gmock/internal/gmock-port.h" namespace testing { +template +class NiceMock; +template +class NaggyMock; +template +class StrictMock; + +namespace internal { +template +std::true_type StrictnessModifierProbe(const NiceMock&); +template +std::true_type StrictnessModifierProbe(const NaggyMock&); +template +std::true_type StrictnessModifierProbe(const StrictMock&); +std::false_type StrictnessModifierProbe(...); + +template +constexpr bool HasStrictnessModifier() { + return decltype(StrictnessModifierProbe(std::declval()))::value; +} + +} // namespace internal template class NiceMock : public MockClass { public: + static_assert( + !internal::HasStrictnessModifier(), + "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_(this)); @@ -108,6 +138,13 @@ class NiceMock : public MockClass { template class NaggyMock : public MockClass { + static_assert( + !internal::HasStrictnessModifier(), + "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 StrictMock : public MockClass { public: + static_assert( + !internal::HasStrictnessModifier(), + "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_(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 -class NiceMock >; -template -class NiceMock >; -template -class NiceMock >; - -template -class NaggyMock >; -template -class NaggyMock >; -template -class NaggyMock >; - -template -class StrictMock >; -template -class StrictMock >; -template -class StrictMock >; - } // namespace testing #endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_