From 788fa23fa6209aeba429a9af71a2c04c01a963f4 Mon Sep 17 00:00:00 2001 From: FranckRJ Date: Sun, 12 May 2024 18:52:31 +0200 Subject: [PATCH] Cleaned the code a little bit. --- include/fakeit/Mock.hpp | 32 ++++----- include/fakeit/MockImpl.hpp | 12 ++-- include/fakeit/api_macros.hpp | 24 +++---- include/mockutils/DynamicProxy.hpp | 69 ++++++++----------- include/mockutils/MethodProxy.hpp | 9 +++ include/mockutils/constexpr_hash.hpp | 17 ----- .../multiple_translation_units_stub_test.cpp | 3 +- 7 files changed, 69 insertions(+), 97 deletions(-) delete mode 100644 include/mockutils/constexpr_hash.hpp diff --git a/include/fakeit/Mock.hpp b/include/fakeit/Mock.hpp index dc6f7ec4..0368ee1e 100644 --- a/include/fakeit/Mock.hpp +++ b/include/fakeit/Mock.hpp @@ -71,67 +71,67 @@ namespace fakeit { } // const - template::value>::type> MockingContext, arglist...> stub(R (T::*vMethod)(arglist...) const) { auto methodWithoutConstVolatile = reinterpret_cast (T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // volatile - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) volatile) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // const volatile - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // no qualifier - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...)) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // ref - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) &) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // const ref - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) const&) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // rval ref - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) &&) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } // const rval ref - template::value>::type> MockingContext, arglist...> stub(R(T::*vMethod)(arglist...) const&&) { auto methodWithoutConstVolatile = reinterpret_cast(T::*)(arglist...)>(vMethod); - return impl.template stubMethod(methodWithoutConstVolatile); + return impl.template stubMethod(methodWithoutConstVolatile); } DtorMockingContext dtor() { diff --git a/include/fakeit/MockImpl.hpp b/include/fakeit/MockImpl.hpp index 289b7062..ee4ce5b6 100644 --- a/include/fakeit/MockImpl.hpp +++ b/include/fakeit/MockImpl.hpp @@ -101,9 +101,9 @@ namespace fakeit { return DataMemberStubbingRoot(); } - template::value>::type> + template::value>::type> MockingContext stubMethod(R(T::*vMethod)(arglist...)) { - return MockingContext(new UniqueMethodMockingContextImpl < MethodType, Method, R, arglist... > + return MockingContext(new UniqueMethodMockingContextImpl < id, R, arglist... > (*this, vMethod)); } @@ -226,12 +226,12 @@ namespace fakeit { }; - template + template class UniqueMethodMockingContextImpl : public MethodMockingContextImpl { protected: RecordedMethodBody &getRecordedMethodBody() override { - return MethodMockingContextBase::_mock.template stubMethodIfNotStubbed( + return MethodMockingContextBase::_mock.template stubMethodIfNotStubbed( MethodMockingContextBase::_mock._proxy, MethodMockingContextImpl::_vMethod); } @@ -323,11 +323,11 @@ namespace fakeit { return origMethodPtr; } - template + template RecordedMethodBody &stubMethodIfNotStubbed(DynamicProxy &proxy, R (C::*vMethod)(arglist...)) { if (!proxy.isMethodStubbed(vMethod)) { - proxy.template stubMethod(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod)); + proxy.template stubMethod(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod)); } Destructible *d = proxy.getMethodMock(vMethod); RecordedMethodBody *methodMock = dynamic_cast *>(d); diff --git a/include/fakeit/api_macros.hpp b/include/fakeit/api_macros.hpp index a81ad315..74e18a5d 100644 --- a/include/fakeit/api_macros.hpp +++ b/include/fakeit/api_macros.hpp @@ -1,19 +1,11 @@ #pragma once -#include "mockutils/constexpr_hash.hpp" +#include "mockutils/MethodProxy.hpp" #ifdef _MSC_VER #define __func__ __FUNCTION__ #endif -#define COUNTER_STRINGIFY( counter ) #counter - -#define STUB_ID_STR( counter ) \ - __FILE__ COUNTER_STRINGIFY(counter) - -#define STUB_ID(counter) \ - fakeit::constExprHash(STUB_ID_STR(counter)) - #define MOCK_TYPE(mock) \ std::remove_reference::type @@ -39,25 +31,25 @@ (mock).dtor().setMethodDetails(#mock,"destructor") #define Method(mock, method) \ - (mock).template stub(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method) #define OverloadedMethod(mock, method, prototype) \ - (mock).template stub(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define ConstOverloadedMethod(mock, method, prototype) \ - (mock).template stub(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define RefOverloadedMethod(mock, method, prototype) \ - (mock).template stub(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define ConstRefOverloadedMethod(mock, method, prototype) \ - (mock).template stub(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define RValRefOverloadedMethod(mock, method, prototype) \ - (mock).template stub(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define ConstRValRefOverloadedMethod(mock, method, prototype) \ - (mock).template stub(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) + (mock).template stub<&fakeit::funcIdMethod>(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method) #define Verify(...) \ Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__) diff --git a/include/mockutils/DynamicProxy.hpp b/include/mockutils/DynamicProxy.hpp index 0fa607f1..f103b226 100644 --- a/include/mockutils/DynamicProxy.hpp +++ b/include/mockutils/DynamicProxy.hpp @@ -13,10 +13,8 @@ #include #include #include -#include #include "mockutils/VirtualTable.hpp" -#include "mockutils/union_cast.hpp" #include "mockutils/MethodInvocationHandler.hpp" #include "mockutils/VTUtils.hpp" #include "mockutils/FakeObject.hpp" @@ -26,52 +24,43 @@ namespace fakeit { - namespace details { - template - void funcId() {} + class InvocationHandlers : public InvocationHandlerCollection { + std::vector> &_methodMocks; + std::vector &_offsets; - inline void funcIdDestructor() {} - - inline void funcIdNotStubbed() {} - } - - template - struct DynamicProxy { - - class InvocationHandlers : public InvocationHandlerCollection { - std::vector> &_methodMocks; - std::vector &_offsets; - - unsigned int getOffset(MethodIdType id) const - { - unsigned int offset = 0; - for (; offset < _offsets.size(); offset++) { - if (_offsets[offset] == id) { - break; - } + unsigned int getOffset(MethodIdType id) const + { + unsigned int offset = 0; + for (; offset < _offsets.size(); offset++) { + if (_offsets[offset] == id) { + break; } - return offset; } + return offset; + } - public: - InvocationHandlers(std::vector> &methodMocks, std::vector &offsets) - : _methodMocks(methodMocks), _offsets(offsets) { - } + public: + InvocationHandlers(std::vector> &methodMocks, std::vector &offsets) + : _methodMocks(methodMocks), _offsets(offsets) { + } - Destructible *getInvocatoinHandlerPtrById(MethodIdType id) override { - unsigned int offset = getOffset(id); - std::shared_ptr ptr = _methodMocks[offset]; - return ptr.get(); - } + Destructible *getInvocatoinHandlerPtrById(MethodIdType id) override { + unsigned int offset = getOffset(id); + std::shared_ptr ptr = _methodMocks[offset]; + return ptr.get(); + } - }; + }; + + template + struct DynamicProxy { static_assert(std::is_polymorphic::value, "DynamicProxy requires a polymorphic type"); DynamicProxy(C &inst) : _instancePtr(&inst), _methodMocks(VTUtils::getVTSize()), - _offsets(VTUtils::getVTSize(), &details::funcIdNotStubbed), + _offsets(VTUtils::getVTSize(), &funcIdNotStubbed), _invocationHandlers(_methodMocks, _offsets) { _originalVt.copyFrom(VirtualTable::getVTable(*_instancePtr)); _originalVt.setCookie(InvocationHandlerCollection::VtCookieIndex, &_invocationHandlers); @@ -117,11 +106,11 @@ namespace fakeit { { } - template + template void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler *methodInvocationHandler) { auto offset = VTUtils::getOffset(vMethod); MethodProxyCreator creator; - bind(creator.template createMethodProxy<&details::funcId>(offset), methodInvocationHandler); + bind(creator.template createMethodProxy(offset), methodInvocationHandler); } void stubDtor(MethodInvocationHandler *methodInvocationHandler) { @@ -134,9 +123,9 @@ namespace fakeit { // For GCC / Clang, the destructor is directly called, like normal methods, so we use the member-function // version. #ifdef _MSC_VER - bindDtor(creator.createMethodProxyStatic<&details::funcIdDestructor>(offset), methodInvocationHandler); + bindDtor(creator.createMethodProxyStatic<&funcIdDestructor>(offset), methodInvocationHandler); #else - bindDtor(creator.createMethodProxy<&details::funcIdDestructor>(offset), methodInvocationHandler); + bindDtor(creator.createMethodProxy<&funcIdDestructor>(offset), methodInvocationHandler); #endif } diff --git a/include/mockutils/MethodProxy.hpp b/include/mockutils/MethodProxy.hpp index 15294256..14a06bef 100644 --- a/include/mockutils/MethodProxy.hpp +++ b/include/mockutils/MethodProxy.hpp @@ -4,6 +4,15 @@ namespace fakeit { + // A bunch of functions used by the method id mechanism. Their pointer will represent the ID of an unique mockable + // method. + template + void funcIdMethod() {} + + inline void funcIdDestructor() {} + + inline void funcIdNotStubbed() {} + using MethodIdType = void(*)(); struct MethodProxy { diff --git a/include/mockutils/constexpr_hash.hpp b/include/mockutils/constexpr_hash.hpp deleted file mode 100644 index 0a3822c6..00000000 --- a/include/mockutils/constexpr_hash.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -namespace fakeit { - - constexpr size_t _FNV_prime = sizeof(size_t) == 4 ? 16777619ULL : 1099511628211ULL; - constexpr size_t _FNV_offset_basis = sizeof(size_t) == 4 ? 2166136261ULL : 14695981039346656037ULL; - - constexpr size_t _constExprHashImpl(const char* str, size_t count) { - return count ? (_constExprHashImpl(str, count - 1) ^ str[count - 1]) * _FNV_prime : _FNV_offset_basis; - } - - template - constexpr size_t constExprHash(const char(&str)[N]) { - return _constExprHashImpl(str, N); - } - -} \ No newline at end of file diff --git a/tests/multiple_translation_units_stub_test.cpp b/tests/multiple_translation_units_stub_test.cpp index 2e4b2297..89a19d42 100644 --- a/tests/multiple_translation_units_stub_test.cpp +++ b/tests/multiple_translation_units_stub_test.cpp @@ -14,8 +14,7 @@ struct MultipleTranslationUnitsStub : tpunit::TestFixture { { } - // TODO: more tests to be sure I didn't broke something by changing stuff. - // TODO: add option to revert to old ID generation and test that tests crash. + // TODO: more tests to be sure I didn't broke something by changing stuff (alterning mocked func with when and func). void NoCollidingIds() { Mock mock;