eedb/tests/utils/UniquePtrMockWrapper.hpp
2017-03-18 13:46:06 +01:00

187 lines
5.6 KiB
C++

#pragma once
#include <gmock/gmock.h>
#include <memory>
struct UnderlyingUniquePtrAlreadyMoved : public std::runtime_error {
UnderlyingUniquePtrAlreadyMoved() : std::runtime_error("unique_ptr already moved") {
}
};
template <typename Mock, typename Ptr = std::unique_ptr<Mock>>
class UniquePtrMockWrapper {
public:
using MockType = Mock;
using PtrType = Ptr;
explicit UniquePtrMockWrapper(Mock* p_ptr = new Mock()) : m_uniquePtr(p_ptr), m_rawPtr(p_ptr) {
}
explicit UniquePtrMockWrapper(std::nullptr_t)
: UniquePtrMockWrapper(static_cast<Mock*>(nullptr)) {
}
template <typename MockDerived, typename EnableIf = typename std::enable_if<std::is_convertible<MockDerived*, Mock*>::value>::type>
explicit UniquePtrMockWrapper(MockDerived* p_ptr)
: UniquePtrMockWrapper(static_cast<Mock*>(p_ptr)) {
}
template <typename NotMockPtr, typename EnableIf = typename std::enable_if<not std::is_convertible<NotMockPtr, Mock*>::value>::type, typename... Args>
explicit UniquePtrMockWrapper(NotMockPtr&& p_firstArg, Args&&... p_args)
: UniquePtrMockWrapper(new Mock(std::forward<NotMockPtr>(p_firstArg), std::forward<Args>(p_args)...)) {
}
template <typename MockDerived, typename EnableIf = typename std::enable_if<std::is_convertible<MockDerived*, Mock*>::value>::type>
explicit UniquePtrMockWrapper(std::unique_ptr<MockDerived> p_ptr)
: UniquePtrMockWrapper(static_cast<Mock*>(p_ptr.release())) {
}
Ptr getPtr() {
if (!m_uniquePtr) {
throw UnderlyingUniquePtrAlreadyMoved();
}
return std::move(m_uniquePtr);
}
Mock* get() const {
return m_rawPtr;
}
Mock& operator*() const {
return *m_rawPtr;
}
Mock* operator->() const {
return m_rawPtr;
}
template <typename MockBase,
typename EnableIf = typename std::enable_if<std::is_convertible<Mock*, MockBase*>::value &&
std::is_same<Ptr, std::unique_ptr<Mock>>::value>::type>
/*implicit*/ operator std::unique_ptr<MockBase>() {
return getPtr();
}
void reset(Mock* p_ptr) {
m_uniquePtr.reset(p_ptr);
m_rawPtr = p_ptr;
}
private:
Ptr m_uniquePtr;
Mock* m_rawPtr;
};
//namespace testing {
//struct UniquePtrReturnedMoreThanOnce : public std::logic_error {
// UniquePtrReturnedMoreThanOnce() : std::logic_error("std::unique_ptr returned more than once") {
// }
//};
//namespace internal {
//template <typename T>
//class ActionResultHolder<std::unique_ptr<T>> : public UntypedActionResultHolderBase {
// using UP = std::unique_ptr<T>;
// public:
// explicit ActionResultHolder(UP p_value) : m_value(std::move(p_value)) {
// }
// UP GetValueAndDelete() const {
// UP l_retval(std::move(m_value));
// delete this;
// return std::move(l_retval);
// }
// virtual void PrintAsActionResult(::std::ostream* p_os) const override {
// *p_os << "\n Returns: ";
// UniversalPrinter<UP>::Print(m_value, p_os);
// }
// template <typename F>
// static ActionResultHolder* PerformDefaultAction(const FunctionMockerBase<F>* p_func_mocker,
// const typename Function<F>::ArgumentTuple& p_args,
// const string& p_call_description) {
// return new ActionResultHolder(p_func_mocker->PerformDefaultAction(p_args, p_call_description));
// }
// template <typename F>
// static ActionResultHolder* PerformAction(const Action<F>& p_action,
// const typename Function<F>::ArgumentTuple& p_args) {
// return new ActionResultHolder(p_action.Perform(p_args));
// }
// private:
// mutable UP m_value;
// GTEST_DISALLOW_ASSIGN_(ActionResultHolder);
//};
//template <typename T>
//class ReturnUniquePtrAction {
// public:
// using UniquePtr = std::unique_ptr<T>;
// using SharedUniquePtr = std::shared_ptr<UniquePtr>;
// explicit ReturnUniquePtrAction(UniquePtr p_ref) : m_ref(new UniquePtr(std::move(p_ref))) {
// }
// template <typename F>
// operator Action<F>() const {
// return Action<F>(new Impl<F>(m_ref));
// }
// private:
// template <typename F>
// class Impl : public ActionInterface<F> {
// public:
// typedef typename Function<F>::Result Result;
// typedef typename Function<F>::ArgumentTuple ArgumentTuple;
// explicit Impl(SharedUniquePtr p_ref) : m_ref(p_ref) {
// }
// virtual Result Perform(const ArgumentTuple&) {
// if (m_performed) {
// throw UniquePtrReturnedMoreThanOnce{};
// }
// m_performed = true;
// return std::move(*m_ref);
// }
// private:
// bool m_performed = false;
// SharedUniquePtr mutable m_ref;
// GTEST_DISALLOW_ASSIGN_(Impl);
// };
// SharedUniquePtr mutable m_ref;
// GTEST_DISALLOW_ASSIGN_(ReturnUniquePtrAction);
//};
//} // namespace internal
//template <typename T>
//internal::ReturnUniquePtrAction<T> ReturnUniquePtr(std::unique_ptr<T> p_ptr) {
// return internal::ReturnUniquePtrAction<T>(std::move(p_ptr));
//}
//template <typename T>
//class DefaultValue<std::unique_ptr<T>> {
// public:
// static void Clear() {
// }
// static bool IsSet() {
// return false;
// }
// static bool Exists() {
// return true;
// }
// static std::unique_ptr<T> Get() {
// return std::unique_ptr<T>();
// }
//};
//} // namespace testing