Skip to content

Commit

Permalink
Cleaned the code a little bit.
Browse files Browse the repository at this point in the history
  • Loading branch information
FranckRJ committed May 12, 2024
1 parent fe86008 commit 788fa23
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 97 deletions.
32 changes: 16 additions & 16 deletions include/fakeit/Mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,67 +71,67 @@ namespace fakeit {
}

// const
template<typename MethodType, MethodType Method, typename R, typename T, typename ... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename ... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R (T::*vMethod)(arglist...) const) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R> (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// volatile
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// const volatile
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// no qualifier
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...)) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// ref
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) &) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// const ref
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) const&) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// rval ref
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) &&) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

// const rval ref
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<MethodIdType id, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) const&&) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
}

DtorMockingContext dtor() {
Expand Down
12 changes: 6 additions & 6 deletions include/fakeit/MockImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ namespace fakeit {
return DataMemberStubbingRoot<T, DataType>();
}

template<typename MethodType, MethodType Method, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
template<MethodIdType id, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stubMethod(R(T::*vMethod)(arglist...)) {
return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl < MethodType, Method, R, arglist... >
return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl < id, R, arglist... >
(*this, vMethod));
}

Expand Down Expand Up @@ -226,12 +226,12 @@ namespace fakeit {
};


template<typename MethodType, MethodType Method, typename R, typename ... arglist>
template<MethodIdType id, typename R, typename ... arglist>
class UniqueMethodMockingContextImpl : public MethodMockingContextImpl<R, arglist...> {
protected:

RecordedMethodBody<R, arglist...> &getRecordedMethodBody() override {
return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<MethodType, Method>(
return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<id>(
MethodMockingContextBase<R, arglist...>::_mock._proxy,
MethodMockingContextImpl<R, arglist...>::_vMethod);
}
Expand Down Expand Up @@ -323,11 +323,11 @@ namespace fakeit {
return origMethodPtr;
}

template<typename MethodType, MethodType Method, typename R, typename ... arglist>
template<MethodIdType id, typename R, typename ... arglist>
RecordedMethodBody<R, arglist...> &stubMethodIfNotStubbed(DynamicProxy<C, baseclasses...> &proxy,
R (C::*vMethod)(arglist...)) {
if (!proxy.isMethodStubbed(vMethod)) {
proxy.template stubMethod<MethodType, Method>(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod));
proxy.template stubMethod<id>(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod));
}
Destructible *d = proxy.getMethodMock(vMethod);
RecordedMethodBody<R, arglist...> *methodMock = dynamic_cast<RecordedMethodBody<R, arglist...> *>(d);
Expand Down
24 changes: 8 additions & 16 deletions include/fakeit/api_macros.hpp
Original file line number Diff line number Diff line change
@@ -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<decltype((mock).get())>::type

Expand All @@ -39,25 +31,25 @@
(mock).dtor().setMethodDetails(#mock,"destructor")

#define Method(mock, method) \
(mock).template stub<decltype(&MOCK_TYPE(mock)::method), &MOCK_TYPE(mock)::method>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(&MOCK_TYPE(mock)::method), &MOCK_TYPE(mock)::method>>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method)

#define OverloadedMethod(mock, method, prototype) \
(mock).template stub<decltype(OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstOverloadedMethod(mock, method, prototype) \
(mock).template stub<decltype(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define RefOverloadedMethod(mock, method, prototype) \
(mock).template stub<decltype(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>>(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstRefOverloadedMethod(mock, method, prototype) \
(mock).template stub<decltype(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>>(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define RValRefOverloadedMethod(mock, method, prototype) \
(mock).template stub<decltype(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>>(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstRValRefOverloadedMethod(mock, method, prototype) \
(mock).template stub<decltype(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<&fakeit::funcIdMethod<decltype(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>>(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define Verify(...) \
Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__)
Expand Down
69 changes: 29 additions & 40 deletions include/mockutils/DynamicProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
#include <vector>
#include <array>
#include <new>
#include <limits>

#include "mockutils/VirtualTable.hpp"
#include "mockutils/union_cast.hpp"
#include "mockutils/MethodInvocationHandler.hpp"
#include "mockutils/VTUtils.hpp"
#include "mockutils/FakeObject.hpp"
Expand All @@ -26,52 +24,43 @@

namespace fakeit {

namespace details {
template<typename MethodType, MethodType Method>
void funcId() {}
class InvocationHandlers : public InvocationHandlerCollection {
std::vector<std::shared_ptr<Destructible>> &_methodMocks;
std::vector<MethodIdType> &_offsets;

inline void funcIdDestructor() {}

inline void funcIdNotStubbed() {}
}

template<typename C, typename ... baseclasses>
struct DynamicProxy {

class InvocationHandlers : public InvocationHandlerCollection {
std::vector<std::shared_ptr<Destructible>> &_methodMocks;
std::vector<MethodIdType> &_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<std::shared_ptr<Destructible>> &methodMocks, std::vector<MethodIdType> &offsets)
: _methodMocks(methodMocks), _offsets(offsets) {
}
public:
InvocationHandlers(std::vector<std::shared_ptr<Destructible>> &methodMocks, std::vector<MethodIdType> &offsets)
: _methodMocks(methodMocks), _offsets(offsets) {
}

Destructible *getInvocatoinHandlerPtrById(MethodIdType id) override {
unsigned int offset = getOffset(id);
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}
Destructible *getInvocatoinHandlerPtrById(MethodIdType id) override {
unsigned int offset = getOffset(id);
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}

};
};

template<typename C, typename ... baseclasses>
struct DynamicProxy {

static_assert(std::is_polymorphic<C>::value, "DynamicProxy requires a polymorphic type");

DynamicProxy(C &inst) :
_instancePtr(&inst),
_methodMocks(VTUtils::getVTSize<C>()),
_offsets(VTUtils::getVTSize<C>(), &details::funcIdNotStubbed),
_offsets(VTUtils::getVTSize<C>(), &funcIdNotStubbed),
_invocationHandlers(_methodMocks, _offsets) {
_originalVt.copyFrom(VirtualTable<C, baseclasses...>::getVTable(*_instancePtr));
_originalVt.setCookie(InvocationHandlerCollection::VtCookieIndex, &_invocationHandlers);
Expand Down Expand Up @@ -117,11 +106,11 @@ namespace fakeit {
{
}

template<typename MethodType, MethodType Method, typename R, typename ... arglist>
template<MethodIdType id, typename R, typename ... arglist>
void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler<R, arglist...> *methodInvocationHandler) {
auto offset = VTUtils::getOffset(vMethod);
MethodProxyCreator<R, arglist...> creator;
bind(creator.template createMethodProxy<&details::funcId<MethodType, Method>>(offset), methodInvocationHandler);
bind(creator.template createMethodProxy<id>(offset), methodInvocationHandler);
}

void stubDtor(MethodInvocationHandler<void> *methodInvocationHandler) {
Expand All @@ -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
}

Expand Down
9 changes: 9 additions & 0 deletions include/mockutils/MethodProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename MethodPtrType, MethodPtrType MethodPtr>
void funcIdMethod() {}

inline void funcIdDestructor() {}

inline void funcIdNotStubbed() {}

using MethodIdType = void(*)();

struct MethodProxy {
Expand Down
17 changes: 0 additions & 17 deletions include/mockutils/constexpr_hash.hpp

This file was deleted.

3 changes: 1 addition & 2 deletions tests/multiple_translation_units_stub_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<SomeInterface> mock;
Expand Down

0 comments on commit 788fa23

Please sign in to comment.