187 lines
5.6 KiB
C++
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
|