qa: Add Turtle 1.3.2 mocking framework

This commit is contained in:
Sylwester Kocjan 2021-01-25 22:16:58 +01:00 committed by Seth Hillbrand
parent dc39703d0e
commit a65999b063
55 changed files with 4435 additions and 0 deletions

View File

@ -24,7 +24,10 @@
#ifndef UNIT_TEST_UTILS__H #ifndef UNIT_TEST_UTILS__H
#define UNIT_TEST_UTILS__H #define UNIT_TEST_UTILS__H
#define BOOST_NO_AUTO_PTR
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <turtle/mock.hpp>
#include <qa_utils/wx_utils/wx_assert.h> #include <qa_utils/wx_utils/wx_assert.h>

View File

@ -41,3 +41,4 @@ add_subdirectory( picosha2 )
add_subdirectory( json_schema_validator ) add_subdirectory( json_schema_validator )
add_subdirectory( pegtl ) add_subdirectory( pegtl )
add_subdirectory( 3dxware_sdk ) add_subdirectory( 3dxware_sdk )
add_subdirectory( turtle )

23
thirdparty/turtle/BOOST.LICENSE_1_0.txt vendored Normal file
View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

3
thirdparty/turtle/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,3 @@
add_library( turtle INTERFACE )
target_include_directories( turtle INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} )

6
thirdparty/turtle/README.txt vendored Normal file
View File

@ -0,0 +1,6 @@
This directory contains the Turtle Mocking Framework version 1.3.2 (0dd0dfa15fbc2774213523fb3a65bc1acb2857b3)
from https://github.com/mat007/turtle
Turtle is a C++ mock object library based on Boost with a focus on usability, simplicity and flexibility.
Distributed under the Boost Software License, Version 1.0, with license text in this directory.

46
thirdparty/turtle/turtle/catch.hpp vendored Normal file
View File

@ -0,0 +1,46 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon and Ovanes Markarian 2017
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_CATCH_HPP_INCLUDED
#define MOCK_CATCH_HPP_INCLUDED
#include <catch.hpp>
template<typename Result>
struct catch_mock_error_policy
{
static Result abort()
{
FAIL("Aborted");
throw std::runtime_error("unreachable");
}
template<typename Context>
static void fail(const char* message,
const Context& context,
const char* file = "file://unknown-location",
int line = 0)
{
CAPTURE(context);
FAIL_CHECK(message << " in: " << file << ":" << line);
}
template<typename Context>
static void call(const Context& context, const char* file, int line)
{
CAPTURE(context);
INFO(file << ":" << line);
}
static void pass(const char* file, int line) { INFO(file << ":" << line); }
};
#define MOCK_ERROR_POLICY catch_mock_error_policy
#include "mock.hpp"
#endif // MOCK_CATCH_HPP_INCLUDED

34
thirdparty/turtle/turtle/cleanup.hpp vendored Normal file
View File

@ -0,0 +1,34 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_CLEANUP_HPP_INCLUDED
#define MOCK_CLEANUP_HPP_INCLUDED
#include "config.hpp"
#include "reset.hpp"
#include "verify.hpp"
#ifdef MOCK_USE_BOOST_TEST
# include <boost/test/unit_test_suite.hpp>
#endif
namespace mock {
struct cleanup
{
~cleanup() { mock::reset(); }
};
#ifdef MOCK_USE_BOOST_TEST
BOOST_GLOBAL_FIXTURE(cleanup)
# if BOOST_VERSION >= 105900
;
# endif
#endif
} // namespace mock
#endif // MOCK_CLEANUP_HPP_INCLUDED

33
thirdparty/turtle/turtle/config.hpp vendored Normal file
View File

@ -0,0 +1,33 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// boost-no-inspect
#ifndef MOCK_CONFIG_HPP_INCLUDED
#define MOCK_CONFIG_HPP_INCLUDED
#include <boost/config.hpp>
#ifndef MOCK_ERROR_POLICY
# define MOCK_ERROR_POLICY mock::error
# define MOCK_USE_BOOST_TEST
#endif
#if !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX)
# ifndef MOCK_NO_HDR_MUTEX
# define MOCK_HDR_MUTEX
# endif
#endif
#if defined(__cpp_lib_uncaught_exceptions) || defined(_MSC_VER) && (_MSC_VER >= 1900)
# ifndef MOCK_NO_UNCAUGHT_EXCEPTIONS
# define MOCK_UNCAUGHT_EXCEPTIONS
# endif
#endif
#endif // MOCK_CONFIG_HPP_INCLUDED

188
thirdparty/turtle/turtle/constraint.hpp vendored Normal file
View File

@ -0,0 +1,188 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_CONSTRAINT_HPP_INCLUDED
#define MOCK_CONSTRAINT_HPP_INCLUDED
#include "config.hpp"
#include "log.hpp"
#include "unwrap_reference.hpp"
#include <boost/preprocessor/array.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <functional>
#include <type_traits>
namespace mock {
template<typename Constraint>
struct constraint
{
constraint() {}
constraint(const Constraint& c) : c_(c) {}
Constraint c_;
};
namespace detail {
template<typename Lhs, typename Rhs>
class and_
{
public:
and_(const Lhs& lhs, const Rhs& rhs) : lhs_(lhs), rhs_(rhs) {}
template<typename Actual>
bool operator()(const Actual& actual) const
{
return lhs_(actual) && rhs_(actual);
}
friend std::ostream& operator<<(std::ostream& s, const and_& a)
{
return s << "( " << mock::format(a.lhs_) << " && " << mock::format(a.rhs_) << " )";
}
private:
Lhs lhs_;
Rhs rhs_;
};
template<typename Lhs, typename Rhs>
class or_
{
public:
or_(const Lhs& lhs, const Rhs& rhs) : lhs_(lhs), rhs_(rhs) {}
template<typename Actual>
bool operator()(const Actual& actual) const
{
return lhs_(actual) || rhs_(actual);
}
friend std::ostream& operator<<(std::ostream& s, const or_& o)
{
return s << "( " << mock::format(o.lhs_) << " || " << mock::format(o.rhs_) << " )";
}
private:
Lhs lhs_;
Rhs rhs_;
};
template<typename Constraint>
class not_
{
public:
explicit not_(const Constraint& c) : c_(c) {}
template<typename Actual>
bool operator()(const Actual& actual) const
{
return !c_(actual);
}
friend std::ostream& operator<<(std::ostream& s, const not_& n) { return s << "! " << mock::format(n.c_); }
private:
Constraint c_;
};
} // namespace detail
template<typename Lhs, typename Rhs>
const constraint<detail::or_<Lhs, Rhs>> operator||(const constraint<Lhs>& lhs, const constraint<Rhs>& rhs)
{
return detail::or_<Lhs, Rhs>(lhs.c_, rhs.c_);
}
template<typename Lhs, typename Rhs>
const constraint<detail::and_<Lhs, Rhs>> operator&&(const constraint<Lhs>& lhs, const constraint<Rhs>& rhs)
{
return detail::and_<Lhs, Rhs>(lhs.c_, rhs.c_);
}
template<typename Constraint>
const constraint<detail::not_<Constraint>> operator!(const constraint<Constraint>& c)
{
return detail::not_<Constraint>(c.c_);
}
} // namespace mock
#define MOCK_UNARY_CONSTRAINT(Name, n, Args, Expr) \
namespace detail { \
struct Name \
{ \
template<typename Actual> \
bool operator()(const Actual& actual) const \
{ \
(void)actual; \
return Expr; \
} \
friend std::ostream& operator<<(std::ostream& s, const Name&) { return s << BOOST_STRINGIZE(Name); } \
}; \
} \
const mock::constraint<detail::Name> Name;
#define MOCK_CONSTRAINT_ASSIGN(z, n, d) expected##n(std::forward<T##n>(e##n))
#define MOCK_CONSTRAINT_UNWRAP_REF(z, n, d) mock::unwrap_ref(expected##n)
#define MOCK_CONSTRAINT_FORMAT(z, n, d) BOOST_PP_IF(n, << ", " <<, ) mock::format(c.expected##n)
#define MOCK_CONSTRAINT_MEMBER(z, n, d) Expected_##n expected##n;
#define MOCK_CONSTRAINT_TPL_TYPE(z, n, d) std::decay_t<const T##n>
#define MOCK_CONSTRAINT_CREF_PARAM(z, n, Args) \
const mock::unwrap_reference_t<Expected_##n>& BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARG(z, n, Args) T##n&& BOOST_PP_ARRAY_ELEM(n, Args)
#define MOCK_CONSTRAINT_ARGS(z, n, Args) T##n&& e##n
#define MOCK_CONSTRAINT_PARAM(z, n, Args) std::forward<T##n>(BOOST_PP_ARRAY_ELEM(n, Args))
#define MOCK_NARY_CONSTRAINT(Name, n, Args, Expr) \
namespace detail { \
template<BOOST_PP_ENUM_PARAMS(n, typename Expected_)> \
struct Name \
{ \
template<BOOST_PP_ENUM_PARAMS(n, typename T)> \
explicit Name(BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARGS, _)) : BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ASSIGN, _) \
{} \
template<typename Actual> \
bool operator()(const Actual& actual) const \
{ \
return test(actual, BOOST_PP_ENUM(n, MOCK_CONSTRAINT_UNWRAP_REF, _)); \
} \
template<typename Actual> \
bool test(const Actual& actual, BOOST_PP_ENUM(n, MOCK_CONSTRAINT_CREF_PARAM, (n, Args))) const \
{ \
return Expr; \
} \
friend std::ostream& operator<<(std::ostream& s, const Name& c) \
{ \
return s << BOOST_STRINGIZE(Name) << "( " << BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_FORMAT, _) << " )"; \
} \
BOOST_PP_REPEAT(n, MOCK_CONSTRAINT_MEMBER, _) \
}; \
} \
template<BOOST_PP_ENUM_PARAMS(n, typename T)> \
mock::constraint<detail::Name<BOOST_PP_ENUM(n, MOCK_CONSTRAINT_TPL_TYPE, _)>> Name( \
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_ARG, (n, Args))) \
{ \
return detail::Name<BOOST_PP_ENUM(n, MOCK_CONSTRAINT_TPL_TYPE, _)>( \
BOOST_PP_ENUM(n, MOCK_CONSTRAINT_PARAM, (n, Args))); \
}
#define MOCK_CONSTRAINT_EXT(Name, n, Args, Expr) \
BOOST_PP_IF(n, MOCK_NARY_CONSTRAINT, MOCK_UNARY_CONSTRAINT)(Name, n, Args, Expr)
#define MOCK_CONSTRAINT_AUX_AUX(Name, n, Array) \
MOCK_CONSTRAINT_EXT(Name, n, BOOST_PP_ARRAY_TO_TUPLE(BOOST_PP_ARRAY_POP_BACK(Array)), BOOST_PP_ARRAY_ELEM(n, Array))
#define MOCK_CONSTRAINT_AUX(Name, Size, Tuple) MOCK_CONSTRAINT_AUX_AUX(Name, BOOST_PP_DEC(Size), (Size, Tuple))
#define MOCK_CONSTRAINT(Name, ...) MOCK_CONSTRAINT_AUX(Name, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
#endif // MOCK_CONSTRAINT_HPP_INCLUDED

253
thirdparty/turtle/turtle/constraints.hpp vendored Normal file
View File

@ -0,0 +1,253 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_CONSTRAINTS_HPP_INCLUDED
#define MOCK_CONSTRAINTS_HPP_INCLUDED
#include "config.hpp"
#include "constraint.hpp"
#include "detail/void_t.hpp"
#include "unwrap_reference.hpp"
#include <boost/version.hpp>
#if BOOST_VERSION >= 107000
# include <boost/test/tools/floating_point_comparison.hpp>
#else
# include <boost/test/floating_point_comparison.hpp>
#endif
#include <functional>
#include <memory>
#include <type_traits>
namespace mock {
MOCK_UNARY_CONSTRAINT(any, 0, , ((void)actual, true))
MOCK_UNARY_CONSTRAINT(affirm, 0, , !!actual)
MOCK_UNARY_CONSTRAINT(negate, 0, , !actual)
MOCK_UNARY_CONSTRAINT(evaluate, 0, , actual())
MOCK_NARY_CONSTRAINT(less, 1, (expected), actual < expected)
MOCK_NARY_CONSTRAINT(greater, 1, (expected), actual > expected)
MOCK_NARY_CONSTRAINT(less_equal, 1, (expected), actual <= expected)
MOCK_NARY_CONSTRAINT(greater_equal, 1, (expected), actual >= expected)
#if BOOST_VERSION < 105900
# define MOCK_SMALL() boost::test_tools::check_is_small(actual, tolerance)
# define MOCK_PERCENT_TOLERANCE() \
boost::test_tools::check_is_close(actual, expected, boost::test_tools::percent_tolerance(tolerance))
# define MOCK_FRACTION_TOLERANCE() \
boost::test_tools::check_is_close(actual, expected, boost::test_tools::fraction_tolerance(tolerance))
#else // BOOST_VERSION < 105900
namespace detail {
template<typename T, typename Tolerance>
bool is_small(const T& t, const Tolerance& tolerance)
{
return boost::math::fpc::small_with_tolerance<T>(tolerance)(t);
}
template<typename T1, typename T2, typename Tolerance>
bool is_close(const T1& t1, const T2& t2, const Tolerance& tolerance)
{
typedef std::common_type_t<T1, T2> common_type;
return boost::math::fpc::close_at_tolerance<common_type>(tolerance, boost::math::fpc::FPC_STRONG)(t1, t2);
}
} // namespace detail
# define MOCK_SMALL() detail::is_small(actual, tolerance)
# define MOCK_PERCENT_TOLERANCE() detail::is_close(actual, expected, boost::math::fpc::percent_tolerance(tolerance))
# define MOCK_FRACTION_TOLERANCE() detail::is_close(actual, expected, tolerance)
#endif // BOOST_VERSION < 105900
#ifdef small
# pragma push_macro("small")
# undef small
# define MOCK_SMALL_DEFINED
#endif
MOCK_NARY_CONSTRAINT(small, 1, (tolerance), (MOCK_SMALL()))
#ifdef MOCK_SMALL_DEFINED
# pragma pop_macro("small")
#endif
MOCK_NARY_CONSTRAINT(close, 2, (expected, tolerance), (MOCK_PERCENT_TOLERANCE()))
MOCK_NARY_CONSTRAINT(close_fraction, 2, (expected, tolerance), (MOCK_FRACTION_TOLERANCE()))
#undef MOCK_PERCENT_TOLERANCE
#undef MOCK_FRACTION_TOLERANCE
#ifdef near
# pragma push_macro("near")
# undef near
# define MOCK_NEAR_DEFINED
#endif
MOCK_NARY_CONSTRAINT(near, 2, (expected, tolerance), std::abs(actual - expected) <= tolerance)
#ifdef MOCK_NEAR_DEFINED
# pragma pop_macro("near")
#endif
namespace detail {
template<class T, class U = T, class = void>
struct has_equal_to : std::false_type
{};
template<class T, class U>
struct has_equal_to<T, U, void_t<decltype(std::declval<T>() == std::declval<U>())>> : std::true_type
{};
template<typename Expected>
struct equal
{
explicit equal(Expected expected) : expected_(expected) {}
template<typename Actual>
bool operator()(const Actual& actual,
std::enable_if_t<has_equal_to<Actual, unwrap_reference_t<Expected>>::value>* = 0) const
{
return actual == unwrap_ref(expected_);
}
template<typename Actual>
bool operator()(const Actual& actual,
std::enable_if_t<!has_equal_to<Actual, unwrap_reference_t<Expected>>::value>* = 0) const
{
return actual && *actual == unwrap_ref(expected_);
}
friend std::ostream& operator<<(std::ostream& s, const equal& e)
{
return s << "equal( " << mock::format(e.expected_) << " )";
}
Expected expected_;
};
template<typename Expected>
struct same
{
explicit same(const Expected& expected) : expected_(std::addressof(unwrap_ref(expected))) {}
template<typename Actual>
bool operator()(const Actual& actual) const
{
return std::addressof(actual) == expected_;
}
friend std::ostream& operator<<(std::ostream& os, const same& s)
{
return os << "same( " << mock::format(*s.expected_) << " )";
}
const unwrap_reference_t<Expected>* expected_;
};
template<typename Expected>
struct retrieve
{
explicit retrieve(Expected& expected) : expected_(std::addressof(unwrap_ref(expected))) {}
template<typename Actual>
bool operator()(
const Actual& actual,
std::enable_if_t<!std::is_convertible<const Actual*, unwrap_reference_t<Expected>>::value>* = 0) const
{
*expected_ = actual;
return true;
}
template<typename Actual>
bool operator()(
Actual&& actual,
std::enable_if_t<!std::is_convertible<const Actual*, unwrap_reference_t<Expected>>::value>* = 0) const
{
*expected_ = std::move(actual);
return true;
}
template<typename Actual>
bool operator()(Actual& actual,
std::enable_if_t<std::is_convertible<Actual*, unwrap_reference_t<Expected>>::value>* = 0) const
{
*expected_ = std::addressof(actual);
return true;
}
friend std::ostream& operator<<(std::ostream& s, const retrieve& r)
{
return s << "retrieve( " << mock::format(*r.expected_) << " )";
}
unwrap_reference_t<Expected>* expected_;
};
template<typename Expected>
struct assign
{
explicit assign(const Expected& expected) : expected_(expected) {}
template<typename Actual>
bool operator()(Actual& actual) const
{
actual = unwrap_ref(expected_);
return true;
}
template<typename Actual>
bool operator()(Actual* actual,
std::enable_if_t<std::is_convertible<unwrap_reference_t<Expected>, Actual>::value>* = 0) const
{
if(!actual)
return false;
*actual = unwrap_ref(expected_);
return true;
}
friend std::ostream& operator<<(std::ostream& s, const assign& a)
{
return s << "assign( " << mock::format(a.expected_) << " )";
}
Expected expected_;
};
template<typename Expected>
struct contain
{
explicit contain(const Expected& expected) : expected_(expected) {}
bool operator()(const std::string& actual) const
{
return actual.find(unwrap_ref(expected_)) != std::string::npos;
}
friend std::ostream& operator<<(std::ostream& s, const contain& n)
{
return s << "contain( " << mock::format(n.expected_) << " )";
}
Expected expected_;
};
} // namespace detail
template<typename T>
constraint<detail::equal<T>> equal(T&& t)
{
return detail::equal<T>(std::forward<T>(t));
}
template<typename T>
constraint<detail::same<T>> same(T& t)
{
return detail::same<T>(t);
}
template<typename T>
constraint<detail::retrieve<T>> retrieve(T& t)
{
return detail::retrieve<T>(t);
}
template<typename T>
constraint<detail::assign<T>> assign(T t)
{
return detail::assign<T>(t);
}
template<typename T>
constraint<detail::contain<T>> contain(T t)
{
return detail::contain<T>(t);
}
template<typename T>
constraint<T> call(T t)
{
return constraint<T>(t);
}
} // namespace mock
#endif // MOCK_CONSTRAINTS_HPP_INCLUDED

View File

@ -0,0 +1,137 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_ACTION_HPP_INCLUDED
#define MOCK_ACTION_HPP_INCLUDED
#include "../config.hpp"
#include <functional>
#include <memory>
#include <type_traits>
namespace mock { namespace detail {
template<typename Result, typename Signature>
class action_base
{
private:
typedef std::function<Signature> functor_type;
typedef std::function<Result()> action_type;
protected:
// Meant to be subclassed and not be directly used
// Non-relocatable (contained functions may wrap references/pointers which could be invalidated)
action_base() = default;
action_base(const action_base&) = delete;
action_base(action_base&&) = delete;
action_base& operator=(const action_base&) = delete;
action_base& operator=(action_base&&) = delete;
public:
const functor_type& functor() const { return f_; }
bool valid() const { return f_ || a_; }
Result trigger() const { return a_(); }
void calls(const functor_type& f)
{
if(!f)
throw std::invalid_argument("null functor");
f_ = f;
}
template<typename Exception>
void throws(Exception e)
{
a_ = [e]() -> Result { throw e; };
}
protected:
void set(const action_type& a) { a_ = a; }
template<typename Y>
void set(const std::reference_wrapper<Y>& r)
{
a_ = [r]() -> Result { return r.get(); };
}
private:
functor_type f_;
action_type a_;
};
/// Type erased value storage
struct value
{
value() = default;
value(const value&) = delete;
value& operator=(const value&) = delete;
virtual ~value() = default;
};
/// Actual value storage,
/// holds an instance of T (stripped of reference qualifiers)
template<typename T>
struct value_imp : value
{
using type = std::remove_const_t<std::remove_reference_t<T>>;
template<typename U>
value_imp(U&& t) : t_(std::forward<U>(t))
{}
type t_;
};
template<typename Result, typename Signature>
class action : public action_base<Result, Signature>
{
public:
template<typename Value>
void returns(const Value& v)
{
this->set(std::ref(store(v)));
}
template<typename Y>
void returns(const std::reference_wrapper<Y>& r)
{
this->set(r);
}
template<typename Value>
void moves(Value&& v)
{
auto vRef = std::ref(store(std::move(v)));
this->set([vRef]() { return std::move(vRef.get()); });
}
private:
template<typename T>
typename value_imp<T>::type& store(T&& t)
{
v_ = std::make_unique<value_imp<T>>(std::forward<T>(t));
return static_cast<value_imp<T>&>(*v_).t_;
}
template<typename T>
std::remove_reference_t<Result>& store(T* t)
{
v_ = std::make_unique<value_imp<Result>>(t);
return static_cast<value_imp<Result>&>(*v_).t_;
}
std::unique_ptr<value> v_;
};
template<typename Signature>
class action<void, Signature> : public action_base<void, Signature>
{
public:
action()
{
this->set([]() {});
}
};
}} // namespace mock::detail
#endif // MOCK_ACTION_HPP_INCLUDED

View File

@ -0,0 +1,36 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_ADDRESSOF_HPP_INCLUDED
#define MOCK_ADDRESSOF_HPP_INCLUDED
#include "../config.hpp"
#include <boost/utility/addressof.hpp>
namespace mock
{
namespace detail
{
using boost::addressof;
#ifdef MOCK_NULLPTR
inline const std::nullptr_t* addressof( const std::nullptr_t& p )
{
return &p;
}
inline std::nullptr_t* addressof( std::nullptr_t& p )
{
return &p;
}
#endif
}
} // mock
#endif // MOCK_ADDRESSOF_HPP_INCLUDED

View File

@ -0,0 +1,47 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_CHILD_HPP_INCLUDED
#define MOCK_CHILD_HPP_INCLUDED
#include "../config.hpp"
#include "parent.hpp"
#include "type_name.hpp"
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <ostream>
namespace mock { namespace detail {
class child
{
public:
child() : parent_(0) {}
void update(parent& p,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name)
{
if(instance != "?." || name_.empty())
p = parent(instance, type);
parent_ = &p;
name_ = name;
}
friend std::ostream& operator<<(std::ostream& s, const child& c)
{
if(c.parent_)
s << *c.parent_;
return s << c.name_;
}
private:
const parent* parent_;
boost::unit_test::const_string name_;
};
}} // namespace mock::detail
#endif // MOCK_CHILD_HPP_INCLUDED

View File

@ -0,0 +1,42 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_CONTEXT_HPP_INCLUDED
#define MOCK_CONTEXT_HPP_INCLUDED
#include "../config.hpp"
#include "type_name.hpp"
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <ostream>
namespace mock { namespace detail {
class verifiable;
class context
{
public:
context() = default;
context(const context&) = delete;
context& operator=(const context&) = delete;
virtual ~context() = default;
virtual void add(const void* p,
verifiable& v,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name) = 0;
virtual void add(verifiable& v) = 0;
virtual void remove(verifiable& v) = 0;
virtual void serialize(std::ostream& s, const verifiable& v) const = 0;
};
}} // namespace mock::detail
#endif // MOCK_CONTEXT_HPP_INCLUDED

View File

@ -0,0 +1,183 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_EXPECTATION_HPP_INCLUDED
#define MOCK_EXPECTATION_HPP_INCLUDED
#include "../matcher.hpp"
#include "../sequence.hpp"
#include "action.hpp"
#include "invocation.hpp"
#include "matcher_base.hpp"
#include <memory>
#include <tuple>
#include <type_traits>
#include <vector>
namespace mock { namespace detail {
template<typename... Args>
class default_matcher : public matcher_base<Args...>
{
private:
bool operator()(ref_arg_t<Args>...) override { return true; }
void serialize(std::ostream& s) const override
{
constexpr auto arity = sizeof...(Args);
for(unsigned i = 0; i < arity; ++i)
{
if(i)
s << ", ";
s << "any";
}
}
};
template<typename ConstraintPack, typename... Args>
class single_matcher;
template<typename... Constraints, typename... Args>
class single_matcher<void(Constraints...), Args...> : public matcher_base<Args...>
{
static_assert(sizeof...(Args) > 0, "This class is only useful for functions with arguments");
static_assert(sizeof...(Constraints) == sizeof...(Args), "Need exactly 1 constraint per argument");
public:
single_matcher(Constraints... constraints) : matchers_(matcher<Args, Constraints>(constraints)...) {}
private:
template<std::size_t... I>
bool is_valid_impl(std::index_sequence<I...>, ref_arg_t<Args>... t)
{
using expander = bool[];
bool result = true;
(void)expander{ result &= std::get<I>(matchers_)(static_cast<ref_arg_t<Args>>(t))... };
return result;
}
bool operator()(ref_arg_t<Args>... t) override
{
return is_valid_impl(std::make_index_sequence<sizeof...(Args)>{}, static_cast<ref_arg_t<Args>>(t)...);
}
template<std::size_t... I>
void serialize_impl(std::index_sequence<I...>, std::ostream& s) const
{
using expander = int[];
s << std::get<0>(matchers_);
(void)expander{ 0, (s << ", " << std::get<I + 1>(matchers_), 0)... };
}
void serialize(std::ostream& s) const override
{
serialize_impl(std::make_index_sequence<sizeof...(Args) - 1>{}, s);
}
private:
std::tuple<matcher<Args, Constraints>...> matchers_;
};
template<typename F, typename... Args>
class multi_matcher : public matcher_base<Args...>
{
static_assert(sizeof...(Args) > 0, "This class is only useful for functions with arguments");
public:
multi_matcher(const F& f) : f_(f) {}
private:
bool operator()(ref_arg_t<Args>... t) override { return f_(static_cast<ref_arg_t<Args>>(t)...); }
void serialize(std::ostream& s) const override { s << mock::format(f_); }
private:
F f_;
};
template<typename Signature>
class expectation;
template<typename R, typename... Args>
class expectation<R(Args...)> : public action<R, R(Args...)>
{
static constexpr std::size_t arity = sizeof...(Args);
public:
expectation() : expectation("unknown location", 0) {}
expectation(const char* file, int line)
: invocation_(std::make_unique<unlimited>()), matcher_(std::make_unique<default_matcher<Args...>>()),
file_(file), line_(line)
{}
expectation(expectation&&) = default;
expectation(expectation const&) = default;
expectation& operator=(expectation&&) = default;
expectation& operator=(expectation const&) = default;
~expectation()
{
for(auto& sequence : sequences_)
sequence->remove(this);
}
void invoke(std::unique_ptr<invocation> i) { invocation_ = std::move(i); }
template<typename... Constraints>
std::enable_if_t<(arity > 0u) && sizeof...(Constraints) == arity> with(Constraints... c)
{
matcher_ = std::make_unique<single_matcher<void(Constraints...), Args...>>(c...);
}
template<typename Constraint, std::size_t Arity = arity>
std::enable_if_t<(Arity > 1u)> with(const Constraint& c)
{
matcher_ = std::make_unique<multi_matcher<Constraint, Args...>>(c);
}
void add(sequence& s)
{
s.impl_->add(this);
sequences_.push_back(s.impl_);
}
bool verify() const { return invocation_->verify(); }
bool is_valid(ref_arg_t<Args>... t) const
{
return !invocation_->exhausted() && (*matcher_)(static_cast<ref_arg_t<Args>>(t)...);
}
bool invoke() const
{
for(auto& sequence : sequences_)
{
if(!sequence->is_valid(this))
return false;
}
bool result = invocation_->invoke();
for(auto& sequence : sequences_)
sequence->invalidate(this);
return result;
}
const char* file() const { return file_; }
int line() const { return line_; }
friend std::ostream& operator<<(std::ostream& s, const expectation& e)
{
s << (e.invocation_->exhausted() ? 'v' : '.') << ' ' << *e.invocation_;
constexpr bool hasArguments = arity > 0u;
if(hasArguments)
s << ".with( " << *e.matcher_ << " )";
return s;
}
private:
std::unique_ptr<invocation> invocation_;
std::unique_ptr<matcher_base<Args...>> matcher_;
std::vector<std::shared_ptr<sequence_impl>> sequences_;
const char* file_;
int line_;
};
}} // namespace mock::detail
#endif // MOCK_EXPECTATION_HPP_INCLUDED

View File

@ -0,0 +1,276 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "matcher_base_template.hpp"
#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \
BOOST_PP_COMMA_IF(n) c##n##_( c##n )
#define MOCK_EXPECTATION_MEMBER(z, n, d) \
matcher< T##n, Constraint_##n > c##n##_;
#define MOCK_EXPECTATION_IS_VALID(z, n, d) \
BOOST_PP_IF(n, &&,) c##n##_( mock::detail::move_if_not_lvalue_reference< T##n >( a##n ) )
#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
BOOST_PP_IF(n, << ", " <<,) c##n##_
#define MOCK_EXPECTATION_SERIALIZE_ANY(z, n, d) \
BOOST_PP_IF(n, << ", " <<,) "any"
#define MOCK_EXPECTATION_PARAM(z, n, Args) \
mock::detail::move_if_not_lvalue_reference< T##n >( a##n )
#define MOCK_REF_ARG(z, n, d) \
typename ref_arg< T##n >::type a##n
#define MOCK_REF_ARG_T(z, n, d) \
typename ref_arg< T##n >::type
namespace mock
{
namespace detail
{
template< typename Signature > class default_matcher;
template<
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
class default_matcher< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{
private:
virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG_T, _) )
{
return true;
}
virtual void serialize( std::ostream& s ) const
{
s << "" BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_SERIALIZE_ANY, _);
}
};
#ifndef MOCK_NUM_ARGS_0
template< typename Constraint, typename Signature > class single_matcher;
template<
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_),
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T)
>
class single_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_) ),
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{
public:
single_matcher(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
: BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_INITIALIZE, _)
{}
private:
virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) )
{
return BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_IS_VALID, _);
}
virtual void serialize( std::ostream& s ) const
{
s << BOOST_PP_REPEAT(MOCK_NUM_ARGS,
MOCK_EXPECTATION_SERIALIZE, _);
}
private:
BOOST_PP_REPEAT(
MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, _)
};
template< typename F, typename Signature > class multi_matcher;
template< typename F,
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
class multi_matcher< F, void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: public matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{
public:
multi_matcher( const F& f )
: f_( f )
{}
private:
virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) )
{
return f_( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) );
}
virtual void serialize( std::ostream& s ) const
{
s << mock::format( f_ );
}
private:
F f_;
};
#endif
template< typename Signature > class expectation;
template< typename R
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) >
class expectation< R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
: public action< R, R (BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS,T)) >
{
public:
expectation()
: invocation_( boost::make_shared< unlimited >() )
, matcher_(
boost::make_shared<
default_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> () )
, file_( "unknown location" )
, line_( 0 )
{}
expectation( const char* file, int line )
: invocation_( boost::make_shared< unlimited >() )
, matcher_(
boost::make_shared<
default_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> () )
, file_( file )
, line_( line )
{}
~expectation()
{
for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it )
(*it)->remove( this );
}
void invoke( const boost::shared_ptr< invocation >& i )
{
invocation_ = i;
}
#ifndef MOCK_NUM_ARGS_0
template<
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_)
>
expectation& with(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
{
matcher_.reset(
new single_matcher<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, Constraint_) ),
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) ) );
return *this;
}
#if MOCK_NUM_ARGS > 1
template< typename Constraint >
expectation& with( const Constraint& c )
{
matcher_.reset(
new multi_matcher<
Constraint,
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>( c ) );
return *this;
}
#endif
#endif
void add( sequence& s )
{
s.impl_->add( this );
sequences_.push_back( s.impl_ );
}
bool verify() const
{
return invocation_->verify();
}
bool is_valid(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) ) const
{
return !invocation_->exhausted()
&& (*matcher_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _) );
}
bool invoke() const
{
for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it )
if( ! (*it)->is_valid( this ) )
return false;
bool result = invocation_->invoke();
for( sequences_cit it = sequences_.begin();
it != sequences_.end(); ++it )
(*it)->invalidate( this );
return result;
}
const char* file() const
{
return file_;
}
int line() const
{
return line_;
}
friend std::ostream& operator<<(
std::ostream& s, const expectation& e )
{
return s << ( e.invocation_->exhausted() ? 'v' : '.' )
<< ' ' << *e.invocation_
#ifndef MOCK_NUM_ARGS_0
<< ".with( " << *e.matcher_ << " )"
#endif
;
}
private:
typedef std::vector<
boost::shared_ptr< sequence_impl >
> sequences_type;
typedef sequences_type::const_iterator sequences_cit;
boost::shared_ptr< invocation > invocation_;
boost::shared_ptr<
matcher_base<
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
>
> matcher_;
sequences_type sequences_;
const char* file_;
int line_;
};
}
} // mock
#undef MOCK_EXPECTATION_INITIALIZE
#undef MOCK_EXPECTATION_MEMBER
#undef MOCK_EXPECTATION_IS_VALID
#undef MOCK_EXPECTATION_SERIALIZE
#undef MOCK_EXPECTATION_SERIALIZE_ANY
#undef MOCK_EXPECTATION_PARAM
#undef MOCK_REF_ARG
#undef MOCK_REF_ARG_T
#undef MOCK_RV_REF

View File

@ -0,0 +1,41 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_FORMATTER_HPP_INCLUDED
#define MOCK_FORMATTER_HPP_INCLUDED
#include "../config.hpp"
#include "../stream.hpp"
#include <memory>
namespace mock { namespace detail {
template<typename T>
struct formatter
{
explicit formatter(const T& t) : t_(std::addressof(t)) {}
void serialize(stream& s) const { detail::serialize(s, *t_); }
const T* t_;
};
template<typename T>
stream& operator<<(stream& s, const formatter<T>& f)
{
f.serialize(s);
return s;
}
template<typename T>
std::ostream& operator<<(std::ostream& s, const formatter<T>& f)
{
stream ss(s);
f.serialize(ss);
return s;
}
}} // namespace mock::detail
#endif // MOCK_FORMATTER_HPP_INCLUDED

View File

@ -0,0 +1,81 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_FUNCTION_HPP_INCLUDED
#define MOCK_FUNCTION_HPP_INCLUDED
#include "../config.hpp"
#include "../log.hpp"
#include "../sequence.hpp"
#include "context.hpp"
#include "function_impl.hpp"
#include "type_name.hpp"
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <ostream>
namespace mock { namespace detail {
template<typename Signature>
class function;
template<typename R, typename... Ts>
class function<R(Ts...)>
{
private:
typedef function_impl<R(Ts...)> impl_type;
typedef typename impl_type::wrapper_type expectation_type;
typedef typename impl_type::error_type error_type;
public:
function() : impl_(std::make_shared<impl_type>()) {}
bool verify() const { return impl_->verify(); }
bool verify(const char* file, int line) const
{
error_type::pass(file, line);
return impl_->verify();
}
void reset() { impl_->reset(); }
void reset(const char* file, int line)
{
error_type::pass(file, line);
impl_->reset();
}
expectation_type expect(const char* file, int line)
{
error_type::pass(file, line);
return impl_->expect(file, line);
}
expectation_type expect() { return impl_->expect(); }
R operator()(Ts... args) const { return (*impl_)(static_cast<ref_arg_t<Ts>>(args)...); }
friend std::ostream& operator<<(std::ostream& s, const function& f) { return s << *f.impl_; }
function& operator()(context& c, boost::unit_test::const_string instance)
{
impl_->add(c, impl_.get(), instance, boost::none, "");
return *this;
}
void configure(context& c,
const void* p,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name) const
{
impl_->add(c, p, instance, type, name);
}
private:
std::shared_ptr<impl_type> impl_;
};
}} // namespace mock::detail
#endif // MOCK_FUNCTION_HPP_INCLUDED

View File

@ -0,0 +1,361 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_FUNCTION_IMPL_HPP_INCLUDED
#define MOCK_FUNCTION_IMPL_HPP_INCLUDED
#include "../error.hpp"
#include "expectation.hpp"
#include "mutex.hpp"
#include "verifiable.hpp"
#include <boost/test/utils/lazy_ostream.hpp>
#include <list>
#include <memory>
#ifndef MOCK_ERROR_POLICY
# error no error policy has been set
#endif
namespace mock { namespace detail {
template<typename R, typename E>
struct wrapper_base
{
wrapper_base(E& e) : e_(&e) {}
template<typename T>
void returns(T t)
{
e_->returns(t);
}
E* e_;
};
template<typename E>
struct wrapper_base<void, E>
{
wrapper_base(E& e) : e_(&e) {}
E* e_;
};
template<typename R, typename E>
struct wrapper_base<R*, E>
{
wrapper_base(E& e) : e_(&e) {}
void returns(R* r) { e_->returns(r); }
template<typename Y>
void returns(const std::reference_wrapper<Y>& r)
{
e_->returns(r);
}
E* e_;
};
inline int exceptions()
{
#ifdef MOCK_UNCAUGHT_EXCEPTIONS
using namespace std;
return uncaught_exceptions();
#else
return std::uncaught_exception() ? 1 : 0;
#endif
}
template<typename... Arg>
class lazy_args;
template<typename Signature>
class function_impl;
template<typename R, typename... Args>
class function_impl<R(Args...)> : public verifiable, public std::enable_shared_from_this<function_impl<R(Args...)>>
{
public:
typedef safe_error<R, MOCK_ERROR_POLICY<R>> error_type;
public:
function_impl() : context_(0), valid_(true), exceptions_(exceptions()), mutex_(std::make_shared<mutex>()) {}
virtual ~function_impl()
{
if(valid_ && exceptions_ >= exceptions())
{
for(const auto& expectation : expectations_)
{
if(!expectation.verify())
{
error_type::fail("untriggered expectation",
boost::unit_test::lazy_ostream::instance()
<< lazy_context(this) << lazy_expectations(this),
expectation.file(),
expectation.line());
}
}
}
if(context_)
context_->remove(*this);
}
virtual bool verify() const
{
lock _(mutex_);
for(const auto& expectation : expectations_)
{
if(!expectation.verify())
{
valid_ = false;
error_type::fail("verification failed",
boost::unit_test::lazy_ostream::instance()
<< lazy_context(this) << lazy_expectations(this),
expectation.file(),
expectation.line());
}
}
return valid_;
}
virtual void reset()
{
lock _(mutex_);
valid_ = true;
std::shared_ptr<function_impl> guard = this->shared_from_this();
expectations_.clear();
}
private:
typedef expectation<R(Args...)> expectation_type;
class wrapper : public wrapper_base<R, expectation_type>
{
private:
typedef wrapper_base<R, expectation_type> base_type;
static constexpr std::size_t arity = sizeof...(Args);
public:
wrapper(const std::shared_ptr<mutex>& m, expectation_type& e) : base_type(e), lock_(m) {}
wrapper(const wrapper&) = delete;
wrapper(wrapper&& x) = default;
wrapper& operator=(const wrapper&) = delete;
wrapper& operator=(wrapper&& x) = default;
wrapper& once()
{
this->e_->invoke(std::make_unique<detail::once>());
return *this;
}
wrapper& never()
{
this->e_->invoke(std::make_unique<detail::never>());
return *this;
}
wrapper& exactly(std::size_t count)
{
this->e_->invoke(std::make_unique<detail::exactly>(count));
return *this;
}
wrapper& at_least(std::size_t min)
{
this->e_->invoke(std::make_unique<detail::at_least>(min));
return *this;
}
wrapper& at_most(std::size_t max)
{
this->e_->invoke(std::make_unique<detail::at_most>(max));
return *this;
}
wrapper& between(std::size_t min, std::size_t max)
{
this->e_->invoke(std::make_unique<detail::between>(min, max));
return *this;
}
/// Callable only for functions taking arguments
/// Number of constraints must match the number of arguments
/// or a single constraint checking all arguments must be passed
template<typename... Constraints>
std::enable_if_t<(arity > 0u && (sizeof...(Constraints) == arity || sizeof...(Constraints) == 1u)),
wrapper&>
with(Constraints... c)
{
this->e_->with(c...);
return *this;
}
/// Ensure the expectation is met in the given sequence(s)
template<class... MockSequences>
wrapper& in(sequence& s0, MockSequences&... s)
{
using expander = int[];
(void)expander{ (this->e_->add(s0), 0), (this->e_->add(s), 0)... };
return *this;
}
template<typename TT>
void calls(TT t)
{
this->e_->calls(t);
}
template<typename TT>
void throws(TT t)
{
this->e_->throws(t);
}
template<typename TT>
void moves(TT&& t)
{
this->e_->moves(std::move(t));
}
lock lock_;
};
public:
typedef wrapper wrapper_type;
wrapper expect(const char* file, int line)
{
lock _(mutex_);
expectations_.emplace_back(file, line);
valid_ = true;
return wrapper(mutex_, expectations_.back());
}
wrapper expect()
{
lock _(mutex_);
expectations_.emplace_back();
valid_ = true;
return wrapper(mutex_, expectations_.back());
}
R operator()(Args... args) const
{
// Due to lifetime rules of references this must be created and consumed in one line
#define MOCK_FUNCTION_CONTEXT \
boost::unit_test::lazy_ostream::instance() \
<< lazy_context(this) << lazy_args<Args...>(args...) << lazy_expectations(this)
lock _(mutex_);
valid_ = false;
for(const auto& expectation : expectations_)
{
if(expectation.is_valid(static_cast<ref_arg_t<Args>>(args)...))
{
if(!expectation.invoke())
{
error_type::fail(
"sequence failed", MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
return error_type::abort();
}
if(!expectation.valid())
{
error_type::fail(
"missing action", MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
return error_type::abort();
}
valid_ = true;
error_type::call(MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
if(expectation.functor())
return expectation.functor()(static_cast<ref_arg_t<Args>>(args)...);
return expectation.trigger();
}
}
error_type::fail("unexpected call", MOCK_FUNCTION_CONTEXT);
return error_type::abort();
#undef MOCK_FUNCTION_CONTEXT
}
void add(context& c,
const void* p,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name)
{
lock _(mutex_);
if(!context_)
c.add(*this);
c.add(p, *this, instance, type, name);
context_ = &c;
}
friend std::ostream& operator<<(std::ostream& s, const function_impl& impl)
{
lock _(impl.mutex_);
return s << lazy_context(&impl) << lazy_expectations(&impl);
}
struct lazy_context
{
lazy_context(const function_impl* impl) : impl_(impl) {}
friend std::ostream& operator<<(std::ostream& s, const lazy_context& c)
{
if(c.impl_->context_)
c.impl_->context_->serialize(s, *c.impl_);
else
s << '?';
return s;
}
const function_impl* impl_;
};
struct lazy_expectations
{
lazy_expectations(const function_impl* impl) : impl_(impl) {}
friend std::ostream& operator<<(std::ostream& s, const lazy_expectations& e)
{
for(const auto& expectation : e.impl_->expectations_)
s << std::endl << expectation;
return s;
}
const function_impl* impl_;
};
std::list<expectation_type> expectations_;
context* context_;
mutable bool valid_;
const int exceptions_;
const std::shared_ptr<mutex> mutex_;
};
template<typename ArgFirst, typename... ArgRest>
class lazy_args<ArgFirst, ArgRest...> : lazy_args<ArgRest...>
{
ArgFirst& arg_;
public:
lazy_args(ArgFirst& arg, std::add_lvalue_reference_t<ArgRest>... args)
: lazy_args<ArgRest...>(args...), arg_(arg)
{}
std::ostream& print(std::ostream& s) const
{
s << ' ' << mock::format(arg_) << ',';
return lazy_args<ArgRest...>::print(s);
}
};
template<typename ArgFirst>
class lazy_args<ArgFirst>
{
ArgFirst& arg_;
public:
lazy_args(ArgFirst& arg) : arg_(arg) {}
std::ostream& print(std::ostream& s) const { return s << ' ' << mock::format(arg_) << ' '; }
};
template<>
class lazy_args<>
{
public:
std::ostream& print(std::ostream& s) const { return s; }
};
template<typename... Args>
std::ostream& operator<<(std::ostream& s, const lazy_args<Args...>& a)
{
s << '(';
return a.print(s) << ')';
}
}} // namespace mock::detail
#endif // MOCK_FUNCTION_IMPL_HPP_INCLUDED

View File

@ -0,0 +1,329 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "expectation_template.hpp"
#ifndef MOCK_ERROR_POLICY
# error no error policy has been set
#endif
#define MOCK_FUNCTION_FORMAT(z, n, N) \
<< ' ' << mock::format( t##n ) \
<< BOOST_PP_IF(BOOST_PP_EQUAL(N,n), ' ', ',')
#define MOCK_FUNCTION_CONTEXT \
boost::unit_test::lazy_ostream::instance() \
<< lazy_context( this ) \
<< '(' BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_FUNCTION_FORMAT, \
BOOST_PP_DEC(MOCK_NUM_ARGS)) \
<< ')' \
<< lazy_expectations( this )
#define MOCK_MOVE(z, n, d) \
mock::detail::move_if_not_lvalue_reference< T##n >( t##n )
namespace mock
{
namespace detail
{
template< typename Signature > class function_impl;
template< typename R
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) >
class function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: public verifiable, public boost::enable_shared_from_this<
function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )> >
{
public:
typedef safe_error< R, MOCK_ERROR_POLICY< R > > error_type;
public:
function_impl()
: context_( 0 )
, valid_( true )
, exceptions_( exceptions() )
, mutex_( boost::make_shared< mutex >() )
{}
virtual ~function_impl()
{
if( valid_ && exceptions_ >= exceptions() )
for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it )
if( ! it->verify() )
error_type::fail( "untriggered expectation",
boost::unit_test::lazy_ostream::instance()
<< lazy_context( this )
<< lazy_expectations( this ),
it->file(), it->line() );
if( context_ )
context_->remove( *this );
}
virtual bool verify() const
{
lock _( mutex_ );
for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it )
if( ! it->verify() )
{
valid_ = false;
error_type::fail( "verification failed",
boost::unit_test::lazy_ostream::instance()
<< lazy_context( this )
<< lazy_expectations( this ),
it->file(), it->line() );
}
return valid_;
}
virtual void reset()
{
lock _( mutex_ );
valid_ = true;
boost::shared_ptr< function_impl > guard =
this->shared_from_this();
expectations_.clear();
}
private:
typedef expectation<
R( BOOST_PP_ENUM_PARAMS( MOCK_NUM_ARGS, T ) )
> expectation_type;
class wrapper : public wrapper_base< R, expectation_type >
{
private:
typedef wrapper_base< R, expectation_type > base_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(wrapper)
public:
wrapper( const boost::shared_ptr< mutex >& m, expectation_type& e )
: base_type( e )
, lock_( m )
{}
wrapper( BOOST_RV_REF( wrapper ) x )
: base_type( x )
, lock_( boost::move( x.lock_) )
{}
wrapper& operator=( BOOST_RV_REF( wrapper ) x )
{
static_cast< base_type& >( *this ) = x;
lock_ = boost::move( x.lock_ );
return *this;
}
wrapper& once()
{
this->e_->invoke( boost::make_shared< detail::once >() );
return *this;
}
wrapper& never()
{
this->e_->invoke( boost::make_shared< detail::never >() );
return *this;
}
wrapper& exactly( std::size_t count )
{
this->e_->invoke(
boost::make_shared< detail::exactly >( count ) );
return *this;
}
wrapper& at_least( std::size_t min )
{
this->e_->invoke(
boost::make_shared< detail::at_least >( min ) );
return *this;
}
wrapper& at_most( std::size_t max )
{
this->e_->invoke(
boost::make_shared< detail::at_most >( max ) );
return *this;
}
wrapper& between( std::size_t min, std::size_t max )
{
this->e_->invoke(
boost::make_shared< detail::between >( min, max ) );
return *this;
}
#ifndef MOCK_NUM_ARGS_0
template<
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_)
>
wrapper& with(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c) )
{
this->e_->with(
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, c) );
return *this;
}
#if MOCK_NUM_ARGS > 1
template< typename Constraint >
wrapper& with( const Constraint& c )
{
this->e_->with( c );
return *this;
}
#endif
#endif
#define MOCK_FUNCTION_IN_ADD(z, n, d) \
this->e_->add( s##n );
#define MOCK_FUNCTION_IN(z, n, d) \
wrapper& in( BOOST_PP_ENUM_PARAMS(n, sequence& s) ) \
{ \
BOOST_PP_REPEAT(n, MOCK_FUNCTION_IN_ADD, _) \
return *this; \
}
BOOST_PP_REPEAT(MOCK_MAX_SEQUENCES,
MOCK_FUNCTION_IN, _)
#undef MOCK_FUNCTION_IN
#undef MOCK_FUNCTION_IN_ADD
template< typename TT >
void calls( TT t )
{
this->e_->calls( t );
}
template< typename TT >
void throws( TT t )
{
this->e_->throws( t );
}
template< typename TT >
void moves( BOOST_RV_REF(TT) t )
{
this->e_->moves( boost::move( t ) );
}
lock lock_;
};
public:
typedef wrapper wrapper_type;
wrapper expect( const char* file, int line )
{
lock _( mutex_ );
expectations_.push_back( expectation_type( file, line ) );
valid_ = true;
return wrapper( mutex_, expectations_.back() );
}
wrapper expect()
{
lock _( mutex_ );
expectations_.push_back( expectation_type() );
valid_ = true;
return wrapper( mutex_, expectations_.back() );
}
R operator()(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
{
lock _( mutex_ );
valid_ = false;
for( expectations_cit it = expectations_.begin();
it != expectations_.end(); ++it )
if( it->is_valid(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) ) )
{
if( ! it->invoke() )
{
error_type::fail( "sequence failed",
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
return error_type::abort();
}
if( ! it->valid() )
{
error_type::fail( "missing action",
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
return error_type::abort();
}
valid_ = true;
error_type::call(
MOCK_FUNCTION_CONTEXT, it->file(), it->line() );
if( it->functor() )
return it->functor()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) );
return it->trigger();
}
error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT );
return error_type::abort();
}
void add( context& c, const void* p,
boost::unit_test::const_string instance,
boost::optional< type_name > type,
boost::unit_test::const_string name )
{
lock _( mutex_ );
if( ! context_ )
c.add( *this );
c.add( p, *this, instance, type, name );
context_ = &c;
}
friend std::ostream& operator<<(
std::ostream& s, const function_impl& impl )
{
lock _( impl.mutex_ );
return s << lazy_context( &impl ) << lazy_expectations( &impl );
}
struct lazy_context
{
lazy_context( const function_impl* impl )
: impl_( impl )
{}
friend std::ostream& operator<<(
std::ostream& s, const lazy_context& c )
{
if( c.impl_->context_ )
c.impl_->context_->serialize( s, *c.impl_ );
else
s << '?';
return s;
}
const function_impl* impl_;
};
struct lazy_expectations
{
lazy_expectations( const function_impl* impl )
: impl_( impl )
{}
friend std::ostream& operator<<(
std::ostream& s, const lazy_expectations& e )
{
for( expectations_cit it = e.impl_->expectations_.begin();
it != e.impl_->expectations_.end(); ++it )
s << std::endl << *it;
return s;
}
const function_impl* impl_;
};
typedef std::list< expectation_type > expectations_type;
typedef typename expectations_type::const_iterator expectations_cit;
expectations_type expectations_;
context* context_;
mutable bool valid_;
const int exceptions_;
const boost::shared_ptr< mutex > mutex_;
};
}
} // mock
#undef MOCK_FUNCTION_FORMAT
#undef MOCK_FUNCTION_CONTEXT
#undef MOCK_MOVE

View File

@ -0,0 +1,11 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define MOCK_NUM_ARGS BOOST_PP_ITERATION()
#include "function_template.hpp"
#undef MOCK_NUM_ARGS

View File

@ -0,0 +1,106 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include "function_impl_template.hpp"
#define MOCK_MOVE(z, n, d) \
mock::detail::move_if_not_lvalue_reference< T##n >( t##n )
namespace mock
{
namespace detail
{
template< typename Signature > class function;
template< typename R
BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T) >
class function< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
{
public:
typedef R result_type;
template< typename Args >
struct sig
{
typedef R type;
};
private:
typedef function_impl<
R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
> impl_type;
typedef typename impl_type::wrapper_type expectation_type;
typedef typename impl_type::error_type error_type;
public:
function()
: impl_( boost::make_shared< impl_type >() )
{}
bool verify() const
{
return impl_->verify();
}
bool verify( const char* file, int line ) const
{
error_type::pass( file, line );
return impl_->verify();
}
void reset()
{
impl_->reset();
}
void reset( const char* file, int line )
{
error_type::pass( file, line );
impl_->reset();
}
expectation_type expect( const char* file, int line )
{
error_type::pass( file, line );
return impl_->expect( file, line );
}
expectation_type expect()
{
return impl_->expect();
}
R operator()(
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
{
return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_MOVE, _) );
}
friend std::ostream& operator<<( std::ostream& s, const function& f )
{
return s << *f.impl_;
}
function& operator()( context& c,
boost::unit_test::const_string instance )
{
impl_->add( c, impl_.get(), instance, boost::none, "" );
return *this;
}
void configure( context& c, const void* p,
boost::unit_test::const_string instance,
boost::optional< type_name > type,
boost::unit_test::const_string name ) const
{
impl_->add( c, p, instance, type, name );
}
private:
boost::shared_ptr< impl_type > impl_;
};
}
} // mock
#undef MOCK_MOVE

View File

@ -0,0 +1,54 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_FUNCTOR_HPP_INCLUDED
#define MOCK_FUNCTOR_HPP_INCLUDED
#include "../config.hpp"
#include "function.hpp"
#include "mutex.hpp"
#include "singleton.hpp"
namespace mock { namespace detail {
class functor_mutex_t : public singleton<functor_mutex_t>, public mutex
{
MOCK_SINGLETON_CONS(functor_mutex_t);
};
MOCK_SINGLETON_INST(functor_mutex)
template<typename Signature>
struct functor : function<Signature>
{
functor()
{
scoped_lock _(functor_mutex);
// MOCK_FUNCTOR creates 2 functor objects:
// The user-usable one with the passed name and a 2nd used by MOCK_EXPECT with a suffixed name
// We need the 2nd to be a copy of the first and use a static variable for storing a pointer to the first
static functor* f = nullptr;
if(f)
{
// Release the lock from the first call (see below) so other threads can create functors again
// after the function exits (the scoped_lock still holds the mutex)
functor_mutex.unlock();
// Copy the first functor to the current (2nd) one
*this = *f;
f = nullptr;
} else
{
// This is the first object, store its pointer
f = this;
// Lock the mutex again so only this thread can create new instances of a functor
// making sure that we copy the right instance above and not one from a concurrent thread
functor_mutex.lock();
}
}
};
}} // namespace mock::detail
#endif // MOCK_FUNCTOR_HPP_INCLUDED

View File

@ -0,0 +1,49 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_GROUP_HPP_INCLUDED
#define MOCK_GROUP_HPP_INCLUDED
#include "../config.hpp"
#include "verifiable.hpp"
#include <algorithm>
#include <functional>
#include <vector>
namespace mock { namespace detail {
class group
{
public:
void add(verifiable& v) { verifiables_.push_back(&v); }
void remove(verifiable& v)
{
verifiables_.erase(std::remove(verifiables_.begin(), verifiables_.end(), &v), verifiables_.end());
}
bool verify() const
{
bool valid = true;
for(const auto* verifiable : verifiables_)
if(!verifiable->verify())
valid = false;
return valid;
}
void reset()
{
const auto verifiables = verifiables_;
for(auto* verifiable : verifiables)
if(std::find(verifiables_.begin(), verifiables_.end(), verifiable) != verifiables_.end())
verifiable->reset();
}
private:
std::vector<verifiable*> verifiables_;
};
}} // namespace mock::detail
#endif // MOCK_GROUP_HPP_INCLUDED

View File

@ -0,0 +1,134 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_INVOCATION_HPP_INCLUDED
#define MOCK_INVOCATION_HPP_INCLUDED
#include "../config.hpp"
#include <limits>
#include <ostream>
#include <stdexcept>
namespace mock { namespace detail {
class invocation
{
public:
invocation() = default;
invocation(const invocation&) = delete;
invocation& operator=(const invocation&) = delete;
virtual ~invocation() = default;
virtual bool invoke() = 0;
virtual bool verify() const = 0;
virtual bool exhausted() const = 0;
friend std::ostream& operator<<(std::ostream& s, const invocation& i) { return i.serialize(s); }
private:
virtual std::ostream& serialize(std::ostream& s) const = 0;
};
class between : public invocation
{
public:
between(std::size_t min, std::size_t max) : min_(min), max_(max), count_(0)
{
if(min > max)
throw std::invalid_argument("'min' > 'max'");
}
virtual bool invoke()
{
if(count_ == max_)
return false;
++count_;
return true;
}
virtual bool exhausted() const { return count_ >= max_; }
virtual bool verify() const { return min_ <= count_ && count_ <= max_; }
protected:
const std::size_t min_, max_;
std::size_t count_;
private:
virtual std::ostream& serialize(std::ostream& s) const
{
return s << "between( " << count_ << "/[" << min_ << ',' << max_ << "] )";
}
};
class exactly : public between
{
public:
explicit exactly(std::size_t count) : between(count, count) {}
private:
virtual std::ostream& serialize(std::ostream& s) const
{
return s << "exactly( " << count_ << '/' << max_ << " )";
}
};
class never : public exactly
{
public:
never() : exactly(0) {}
private:
virtual std::ostream& serialize(std::ostream& s) const { return s << "never()"; }
};
class once : public exactly
{
public:
once() : exactly(1) {}
private:
virtual std::ostream& serialize(std::ostream& s) const { return s << "once()"; }
};
class at_least : public between
{
public:
explicit at_least(std::size_t min) : between(min, (std::numeric_limits<std::size_t>::max)()) {}
private:
virtual std::ostream& serialize(std::ostream& s) const
{
return s << "at_least( " << count_ << '/' << min_ << " )";
}
};
class at_most : public between
{
public:
explicit at_most(std::size_t max) : between(0, max) {}
private:
virtual std::ostream& serialize(std::ostream& s) const
{
return s << "at_most( " << count_ << '/' << max_ << " )";
}
};
class unlimited : public at_least
{
public:
unlimited() : at_least(0) {}
private:
virtual std::ostream& serialize(std::ostream& s) const { return s << "unlimited()"; }
};
}} // namespace mock::detail
#endif // MOCK_INVOCATION_HPP_INCLUDED

View File

@ -0,0 +1,26 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_IS_FUNCTOR_HPP_INCLUDED
#define MOCK_IS_FUNCTOR_HPP_INCLUDED
#include "../config.hpp"
#include "void_t.hpp"
#include <type_traits>
namespace mock { namespace detail {
/// Trait to return true if F is a functor that can be called with a single argument Arg
template<typename F, typename Arg, class = void>
struct is_functor : std::false_type
{};
template<typename F, typename Arg>
struct is_functor<F, Arg, void_t<decltype(std::declval<F>()(std::declval<Arg>()))>> : std::true_type
{};
}} // namespace mock::detail
#endif // MOCK_IS_FUNCTOR_HPP_INCLUDED

View File

@ -0,0 +1,38 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_MATCHER_BASE_HPP_INCLUDED
#define MOCK_MATCHER_BASE_HPP_INCLUDED
#include "ref_arg.hpp"
#include <ostream>
namespace mock { namespace detail {
template<typename... Args>
class matcher_base
{
public:
matcher_base() = default;
matcher_base(const matcher_base&) = delete;
matcher_base& operator=(const matcher_base&) = delete;
virtual ~matcher_base() = default;
virtual bool operator()(ref_arg_t<Args>...) = 0;
friend std::ostream& operator<<(std::ostream& s, const matcher_base& m)
{
m.serialize(s);
return s;
}
private:
virtual void serialize(std::ostream&) const = 0;
};
}} // namespace mock::detail
#endif // MOCK_MATCHER_BASE_HPP_INCLUDED

View File

@ -0,0 +1,42 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#define MOCK_REF_ARG(z, n, d) \
typename ref_arg< T##n >::type
namespace mock
{
namespace detail
{
template< typename Signature > class matcher_base;
template<
BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T) >
class matcher_base< void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) ) >
: boost::noncopyable
{
public:
virtual ~matcher_base() {}
virtual bool operator()(
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) ) = 0;
friend std::ostream& operator<<(
std::ostream& s, const matcher_base& m )
{
m.serialize( s );
return s;
}
private:
virtual void serialize( std::ostream& ) const = 0;
};
}
} // mock
#undef MOCK_REF_ARG

View File

@ -0,0 +1,113 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_MOCK_IMPL_HPP_INCLUDED
#define MOCK_MOCK_IMPL_HPP_INCLUDED
#include "function.hpp"
#include "functor.hpp"
#include "signature.hpp"
#include "signature_traits.hpp"
#include "type_name.hpp"
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <type_traits>
namespace mock { namespace detail {
/// Simplified trait to extract the argument type of a function signature with 1 argument
template<typename T>
struct arg_type;
template<typename T, typename U>
struct arg_type<T(U)>
{
using type = U;
};
/// Used in MOCK_PROTECT_SIGNATURE to unwrap the passed function signature
/// T is something like `void(std::map<int, float>)`
template<typename T>
using unwrap_signature_t = std::remove_pointer_t<typename arg_type<T>::type>;
}} // namespace mock::detail
#define MOCK_HELPER(t) t##_mock(mock::detail::root, BOOST_PP_STRINGIZE(t))
#define MOCK_ANONYMOUS_HELPER(t) t##_mock(mock::detail::root, "?.")
#define MOCK_METHOD_HELPER(S, t) \
mutable mock::detail::function<S> t##_mock_; \
mock::detail::function<S>& t##_mock(const mock::detail::context&, const boost::unit_test::const_string& instance) \
const \
{ \
mock::detail::configure(*this, \
t##_mock_, \
instance.substr(0, instance.rfind(BOOST_PP_STRINGIZE(t))), \
mock::detail::make_type_name(*this), \
BOOST_PP_STRINGIZE(t)); \
return t##_mock_; \
}
#define MOCK_PARAM(S) mock::detail::parameter_t < S
#define MOCK_DECL_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n > p##n
#define MOCK_DECL_PARAMS(n, S) BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S))
#define MOCK_DECL(M, n, S, c) mock::detail::result_type_t<S> M(MOCK_DECL_PARAMS(n, S)) c
#define MOCK_FORWARD_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n >> (p##n)
#define MOCK_FORWARD_PARAMS(n, S) BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, std::forward < MOCK_PARAM(S))
#define MOCK_METHOD_AUX(M, n, S, t, c) \
static_assert(n == mock::detail::function_arity_t<S>::value, "Arity mismatch"); \
MOCK_DECL(M, n, S, c) { return MOCK_ANONYMOUS_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); }
#define MOCK_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t, ) \
MOCK_METHOD_AUX(M, n, S, t, const) \
MOCK_METHOD_HELPER(S, t)
#define MOCK_CONST_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t, const) \
MOCK_METHOD_HELPER(S, t)
#define MOCK_NON_CONST_METHOD_EXT(M, n, S, t) \
MOCK_METHOD_AUX(M, n, S, t, ) \
MOCK_METHOD_HELPER(S, t)
#define MOCK_FUNCTION_HELPER(S, t, s) \
s mock::detail::function<S>& t##_mock(mock::detail::context& context, boost::unit_test::const_string instance) \
{ \
static mock::detail::function<S> f; \
return f(context, instance); \
}
#define MOCK_CONSTRUCTOR_AUX(T, n, A, t) \
T(MOCK_DECL_PARAMS(n, void A)) { MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, void A)); } \
MOCK_FUNCTION_HELPER(void A, t, static)
#define MOCK_FUNCTION_AUX(F, n, S, t, s) \
MOCK_FUNCTION_HELPER(S, t, s) \
static_assert(n == mock::detail::function_arity_t<S>::value, "Arity mismatch"); \
s MOCK_DECL(F, n, S, ) { return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S)); }
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0
#define MOCK_VARIADIC_ELEM_1(e0, e1, ...) e1
#define MOCK_VARIADIC_ELEM_2(e0, e1, e2, ...) e2
#define MOCK_REPLACED_MACRO_ERROR(oldName, newName) static_assert(false, #oldName " has been replaced by " #newName)
// Replaced macros
#define MOCK_CONST_CONVERSION_OPERATOR_TPL(...) \
MOCK_REPLACED_MACRO_ERROR(MOCK_CONST_CONVERSION_OPERATOR_TPL, MOCK_CONST_CONVERSION_OPERATOR)
#define MOCK_CONST_METHOD_EXT_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_CONST_METHOD_EXT_TPL, MOCK_CONST_METHOD)
#define MOCK_CONST_METHOD_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_CONST_METHOD_TPL, MOCK_CONST_METHOD)
#define MOCK_CONVERSION_OPERATOR_TPL(...) \
MOCK_REPLACED_MACRO_ERROR(MOCK_CONVERSION_OPERATOR_TPL, MOCK_CONVERSION_OPERATOR)
#define MOCK_FUNCTOR_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_FUNCTOR_TPL, MOCK_FUNCTOR)
#define MOCK_METHOD_EXT_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_METHOD_EXT_TPL, MOCK_METHOD)
#define MOCK_METHOD_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_METHOD_TPL, MOCK_METHOD)
#define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(...) \
MOCK_REPLACED_MACRO_ERROR(MOCK_NON_CONST_CONVERSION_OPERATOR_TPL, MOCK_NON_CONST_CONVERSION_OPERATOR)
#define MOCK_NON_CONST_METHOD_EXT_TPL(...) \
MOCK_REPLACED_MACRO_ERROR(MOCK_NON_CONST_METHOD_EXT_TPL, MOCK_NON_CONST_METHOD)
#define MOCK_NON_CONST_METHOD_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_NON_CONST_METHOD_TPL, MOCK_NON_CONST_METHOD)
#define MOCK_STATIC_METHOD_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_STATIC_METHOD_TPL, MOCK_STATIC_METHOD)
#define MOCK_CONSTRUCTOR_TPL(...) MOCK_REPLACED_MACRO_ERROR(MOCK_CONSTRUCTOR_TPL, MOCK_CONSTRUCTOR)
#endif // MOCK_MOCK_IMPL_HPP_INCLUDED

View File

@ -0,0 +1,78 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2018
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_MOVE_HELPER_HPP_INCLUDED
#define MOCK_MOVE_HELPER_HPP_INCLUDED
#include "../config.hpp"
#include <boost/type_traits/conditional.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/add_rvalue_reference.hpp>
#include <boost/type_traits/decay.hpp>
namespace mock
{
namespace detail
{
#ifdef MOCK_RVALUE_REFERENCES
template< typename T >
struct forward_type
{
typedef T type;
};
template< typename T >
struct ref_arg
{
typedef typename boost::conditional<
boost::is_reference< T >::value,
T,
typename boost::add_rvalue_reference< T >::type >::type type;
};
template< typename T >
inline T&& move_if_not_lvalue_reference(typename boost::remove_reference< T >::type& t)
{
return static_cast< T&& >(t);
}
template< typename T >
inline T&& move_if_not_lvalue_reference(typename boost::remove_reference< T >::type&& t)
{
return static_cast< T&& >(t);
}
#else
template< typename T >
struct forward_type
{
typedef typename boost::decay< const T >::type type;
};
template< class T>
struct forward_type< boost::rv< T > >
{
typedef T type;
};
template< typename T >
struct ref_arg
{
typedef typename boost::conditional<
boost::is_reference< T >::value,
T,
const typename boost::add_reference< T >::type >::type type;
};
template< typename T >
inline typename boost::remove_reference< T >::type& move_if_not_lvalue_reference(typename boost::remove_reference< T >::type& t)
{
return t;
}
#endif
}
}
#endif // MOCK_MOVE_HELPER_HPP_INCLUDED

View File

@ -0,0 +1,134 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_MUTEX_HPP_INCLUDED
#define MOCK_MUTEX_HPP_INCLUDED
#include "../config.hpp"
#include "singleton.hpp"
#include <memory>
#ifdef MOCK_THREAD_SAFE
# ifdef MOCK_HDR_MUTEX
# include <mutex>
# else
# include <boost/thread/lock_guard.hpp>
# include <boost/thread/recursive_mutex.hpp>
# endif
namespace mock { namespace detail {
# ifdef MOCK_HDR_MUTEX
typedef std::recursive_mutex mutex;
typedef std::lock_guard<mutex> scoped_lock;
# else
typedef boost::recursive_mutex mutex;
typedef boost::lock_guard<mutex> scoped_lock;
# endif
struct lock
{
public:
lock(const std::shared_ptr<mutex>& m) : m_(m) { m_->lock(); }
~lock()
{
if(m_)
m_->unlock();
}
lock(const lock&) = delete;
lock(lock&& x) = default;
lock& operator=(const lock&) = delete;
lock& operator=(lock&& x) = default;
private:
std::shared_ptr<mutex> m_;
};
}} // namespace mock::detail
#else // MOCK_THREAD_SAFE
namespace mock { namespace detail {
struct mutex
{
mutex() = default;
mutex(const mutex&) = delete;
mutex& operator=(const mutex&) = delete;
void lock() {}
void unlock() {}
};
// Dummy lock classes.
// Constructor + Destructor make it RAII classes for compilers and avoid unused variable warnings
struct scoped_lock
{
scoped_lock(const scoped_lock&) = delete;
scoped_lock& operator=(const scoped_lock&) = delete;
scoped_lock(mutex&) {}
~scoped_lock() {}
};
class lock
{
public:
lock(const std::shared_ptr<mutex>&) {}
~lock() {}
lock(const lock&) = delete;
lock(lock&&) = default;
lock& operator=(const lock&) = delete;
lock& operator=(lock&&) = default;
};
}} // namespace mock::detail
#endif // MOCK_THREAD_SAFE
namespace mock { namespace detail {
class error_mutex_t : public singleton<error_mutex_t>, public mutex
{
MOCK_SINGLETON_CONS(error_mutex_t);
};
MOCK_SINGLETON_INST(error_mutex)
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable : 4702)
#endif
template<typename Result, typename Error>
struct safe_error
{
static Result abort()
{
scoped_lock _(error_mutex);
return Error::abort();
}
template<typename Context>
static void fail(const char* message,
const Context& context,
const char* file = "unknown location",
int line = 0)
{
scoped_lock _(error_mutex);
Error::fail(message, context, file, line);
}
template<typename Context>
static void call(const Context& context, const char* file, int line)
{
scoped_lock _(error_mutex);
Error::call(context, file, line);
}
static void pass(const char* file, int line)
{
scoped_lock _(error_mutex);
Error::pass(file, line);
}
};
#ifdef BOOST_MSVC
# pragma warning(pop)
#endif
}} // namespace mock::detail
#endif // MOCK_MUTEX_HPP_INCLUDED

View File

@ -0,0 +1,83 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_OBJECT_IMPL_HPP_INCLUDED
#define MOCK_OBJECT_IMPL_HPP_INCLUDED
#include "../config.hpp"
#include "child.hpp"
#include "context.hpp"
#include "mutex.hpp"
#include "parent.hpp"
#include "root.hpp"
#include "type_name.hpp"
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
namespace mock { namespace detail {
class object_impl : public context, public verifiable, public std::enable_shared_from_this<object_impl>
{
public:
object_impl() : mutex_(std::make_shared<mutex>()) {}
virtual void add(const void* /*p*/,
verifiable& v,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name)
{
lock _(mutex_);
if(children_.empty())
detail::root.add(*this);
children_[&v].update(parent_, instance, type, name);
}
virtual void add(verifiable& v)
{
lock _(mutex_);
group_.add(v);
}
virtual void remove(verifiable& v)
{
lock _(mutex_);
group_.remove(v);
children_.erase(&v);
if(children_.empty())
detail::root.remove(*this);
}
virtual void serialize(std::ostream& s, const verifiable& v) const
{
lock _(mutex_);
const auto it = children_.find(&v);
if(it != children_.end())
s << it->second;
else
s << "?";
}
virtual bool verify() const
{
lock _(mutex_);
return group_.verify();
}
virtual void reset()
{
lock _(mutex_);
std::shared_ptr<object_impl> guard = shared_from_this();
group_.reset();
}
private:
group group_;
parent parent_;
std::map<const verifiable*, child> children_;
const std::shared_ptr<mutex> mutex_;
};
}} // namespace mock::detail
#endif // MOCK_OBJECT_IMPL_HPP_INCLUDED

View File

@ -0,0 +1,34 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_PARAMETER_HPP_INCLUDED
#define MOCK_PARAMETER_HPP_INCLUDED
#include "../config.hpp"
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/mpl/at.hpp>
namespace mock
{
namespace detail
{
template< typename Signature, int n >
struct parameter
{
typedef typename
boost::mpl::at_c<
typename
boost::function_types::parameter_types< Signature >,
n
>::type type;
};
}
} // mock
#endif // MOCK_PARAMETER_HPP_INCLUDED

View File

@ -0,0 +1,40 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_PARENT_HPP_INCLUDED
#define MOCK_PARENT_HPP_INCLUDED
#include "../config.hpp"
#include "type_name.hpp"
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <ostream>
namespace mock { namespace detail {
class parent
{
public:
parent() = default;
parent(boost::unit_test::const_string instance, boost::optional<type_name> type)
: instance_(instance), type_(type)
{}
friend std::ostream& operator<<(std::ostream& s, const parent& p)
{
s << p.instance_;
if(p.type_)
s << *p.type_ << "::";
return s;
}
private:
boost::unit_test::const_string instance_;
boost::optional<type_name> type_;
};
}} // namespace mock::detail
#endif // MOCK_PARENT_HPP_INCLUDED

View File

@ -0,0 +1,22 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2018
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_REF_ARG_HPP_INCLUDED
#define MOCK_REF_ARG_HPP_INCLUDED
#include <type_traits>
namespace mock { namespace detail {
/// Make T a reference type:
/// If T is already a reference type, return T, else return an rvalue reference to T
/// Useful to pass along arguments keeping the ability to modify them (e.g. move from them)
template<typename T>
using ref_arg_t = typename std::conditional<std::is_reference<T>::value, T, std::add_rvalue_reference_t<T>>::type;
}} // namespace mock::detail
#endif // MOCK_REF_ARG_HPP_INCLUDED

119
thirdparty/turtle/turtle/detail/root.hpp vendored Normal file
View File

@ -0,0 +1,119 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_ROOT_HPP_INCLUDED
#define MOCK_ROOT_HPP_INCLUDED
#include "../config.hpp"
#include "child.hpp"
#include "context.hpp"
#include "group.hpp"
#include "mutex.hpp"
#include "parent.hpp"
#include "singleton.hpp"
#include <boost/optional.hpp>
#include <map>
#include <ostream>
namespace mock { namespace detail {
class root_t : public singleton<root_t>, public context
{
public:
virtual void add(const void* p,
verifiable& v,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name)
{
scoped_lock _(mutex_);
auto it = children_.lower_bound(&v);
if(it == children_.end() || children_.key_comp()(&v, it->first))
it = children_.insert(it, std::make_pair(&v, counter_child(parents_, p)));
it->second.update(instance, type, name);
}
virtual void add(verifiable& v)
{
scoped_lock _(mutex_);
group_.add(v);
}
virtual void remove(verifiable& v)
{
scoped_lock _(mutex_);
group_.remove(v);
children_.erase(&v);
}
bool verify() const
{
scoped_lock _(mutex_);
return group_.verify();
}
void reset()
{
scoped_lock _(mutex_);
group_.reset();
}
virtual void serialize(std::ostream& s, const verifiable& v) const
{
scoped_lock _(mutex_);
const auto it = children_.find(&v);
if(it != children_.end())
s << it->second;
else
s << "?";
}
private:
typedef std::map<const void*, std::pair<parent, std::size_t>> parents_t;
class counter_child
{
public:
counter_child(parents_t& parents, const void* p)
: parents_(&parents), it_(parents.insert(std::make_pair(p, parents_t::mapped_type())).first)
{
++it_->second.second;
}
counter_child(const counter_child& rhs) : parents_(rhs.parents_), it_(rhs.it_), child_(rhs.child_)
{
++it_->second.second;
}
~counter_child()
{
if(--it_->second.second == 0)
parents_->erase(it_);
}
void update(boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name)
{
child_.update(it_->second.first, instance, type, name);
}
friend std::ostream& operator<<(std::ostream& s, const counter_child& c) { return s << c.child_; }
private:
counter_child& operator=(const counter_child&);
parents_t* parents_;
parents_t::iterator it_;
child child_;
};
parents_t parents_;
std::map<const verifiable*, counter_child> children_;
group group_;
mutable mutex mutex_;
MOCK_SINGLETON_CONS(root_t);
};
MOCK_SINGLETON_INST(root)
}} // namespace mock::detail
#endif // MOCK_ROOT_HPP_INCLUDED

View File

@ -0,0 +1,55 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_SEQUENCE_IMPL_HPP_INCLUDED
#define MOCK_SEQUENCE_IMPL_HPP_INCLUDED
#include "../config.hpp"
#include "mutex.hpp"
#include <algorithm>
#include <memory>
#include <vector>
namespace mock { namespace detail {
class sequence_impl
{
public:
sequence_impl() : mutex_(std::make_shared<mutex>()) {}
void add(void* e)
{
lock _(mutex_);
elements_.push_back(e);
}
void remove(void* e)
{
lock _(mutex_);
elements_.erase(std::remove(elements_.begin(), elements_.end(), e), elements_.end());
}
bool is_valid(const void* e) const
{
lock _(mutex_);
return std::find(elements_.begin(), elements_.end(), e) != elements_.end();
}
void invalidate(const void* e)
{
lock _(mutex_);
const auto it = std::find(elements_.begin(), elements_.end(), e);
if(it != elements_.end())
elements_.erase(elements_.begin(), it);
}
private:
std::vector<void*> elements_;
const std::shared_ptr<mutex> mutex_;
};
}} // namespace mock::detail
#endif // MOCK_SEQUENCE_IMPL_HPP_INCLUDED

View File

@ -0,0 +1,77 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_SIGNATURE_HPP_INCLUDED
#define MOCK_SIGNATURE_HPP_INCLUDED
#include "../config.hpp"
#include <type_traits>
namespace mock { namespace detail {
#define MOCK_NOARG
#define MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ref) \
template<typename R, typename... Args> \
struct strip_function_qualifiers<R(Args...) cv ref> \
{ \
using type = R(Args...); \
}; \
template<typename R, typename... Args> \
struct strip_function_qualifiers<R(Args..., ...) cv ref> \
{ \
using type = R(Args..., ...); \
};
#define MOCK_STRIP_FUNCTION_QUALIFIERS_REF(cv) \
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, ) \
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &) \
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &&)
template<typename>
struct strip_function_qualifiers;
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(MOCK_NOARG)
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(const)
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(volatile)
MOCK_STRIP_FUNCTION_QUALIFIERS_REF(const volatile)
#undef MOCK_NOARG
#undef MOCK_STRIP_FUNCTION_QUALIFIERS
#undef MOCK_STRIP_FUNCTION_QUALIFIERS_REF
template<typename M>
struct signature;
template<typename R, typename... Args>
struct signature<R(Args...)>
{
using type = R(Args...);
};
template<typename Sig, typename C>
struct signature<Sig(C::*)> : signature<typename strip_function_qualifiers<Sig>::type>
{};
/// Return the (non-member) function signature out of (any) signature
template<typename M>
using signature_t = typename signature<M>::type;
/// CRTP class to define the base_type typedef
template<typename T>
struct base
{
using base_type = T;
};
// If an error is generated by the line below it means the method is ambiguous.
// Specify its signature to disambiguate
template<typename T>
T ambiguous_method_requires_to_specify_signature(const T&);
}} // namespace mock::detail
#define MOCK_SIGNATURE(M) \
mock::detail::signature_t<decltype(mock::detail::ambiguous_method_requires_to_specify_signature(&base_type::M))>
#endif // MOCK_SIGNATURE_HPP_INCLUDED

View File

@ -0,0 +1,62 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_SIGNATURE_TRAITS_HPP_INCLUDED
#define MOCK_SIGNATURE_TRAITS_HPP_INCLUDED
#include "../config.hpp"
#include <cstddef>
namespace mock { namespace detail {
/// Helper class to store a tuple/list of types
template<class...>
struct tuple;
/// Get the type at the given index in the tuple
template<std::size_t index, class Tuple>
struct tuple_element;
template<std::size_t I, class H, class... T>
struct tuple_element<I, tuple<H, T...>> : tuple_element<I - 1, tuple<T...>>
{};
template<class H, class... T>
struct tuple_element<0, tuple<H, T...>>
{
using type = H;
};
/// Provides information about a given function signature
/// Member types: return_type, args
/// Member constant: arity
template<typename Signature>
struct signature_traits;
template<typename R, typename... Args>
struct signature_traits<R(Args...)>
{
using return_type = R;
static constexpr std::size_t arity = sizeof...(Args);
using args = tuple<Args...>;
};
/// Return the result type of the function signature
template<typename Signature>
using result_type_t = typename signature_traits<Signature>::return_type;
/// Return the arity of the function signature
template<typename Signature>
using function_arity_t = std::integral_constant<std::size_t, signature_traits<Signature>::arity>;
/// Return the type at the given index of the function signature
template<typename Signature, std::size_t idx>
using parameter_t = typename tuple_element<idx, typename signature_traits<Signature>::args>::type;
}} // namespace mock::detail
#endif // MOCK_SIGNATURE_TRAITS_HPP_INCLUDED

View File

@ -0,0 +1,44 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2014
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_SINGLETON_HPP
#define MOCK_SINGLETON_HPP
#include <boost/config.hpp>
namespace mock { namespace detail {
template<typename Derived>
class singleton
{
public:
static Derived& instance()
{
static Derived the_inst;
return the_inst;
}
singleton(singleton const&) = delete;
singleton& operator=(singleton const&) = delete;
protected:
singleton() = default;
~singleton() = default;
};
}} // namespace mock::detail
// Add a private ctor to the type to prevent misuse
#define MOCK_SINGLETON_CONS(type) \
private: \
friend class mock::detail::singleton<type>; \
type() = default
#define MOCK_SINGLETON_INST(inst) static BOOST_JOIN(inst, _t)& inst = BOOST_JOIN(inst, _t)::instance();
#endif // MOCK_SINGLETON_HPP

View File

@ -0,0 +1,119 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_TYPE_NAME_HPP_INCLUDED
#define MOCK_TYPE_NAME_HPP_INCLUDED
#include "../config.hpp"
#include <boost/algorithm/string/erase.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/version.hpp>
#include <memory>
#include <ostream>
#include <stdexcept>
#include <typeinfo>
#ifdef __GNUC__
# include <cstdlib>
# include <cxxabi.h>
#endif
namespace mock { namespace detail {
class type_name
{
public:
explicit type_name(const std::type_info& info) : info_(&info) {}
friend std::ostream& operator<<(std::ostream& s, const type_name& t)
{
t.serialize(s, *t.info_);
return s;
}
private:
static void serialize(std::ostream& s, const std::type_info& info)
{
const char* name = info.name();
#ifdef __GNUC__
int status = 0;
struct Deleter
{
void operator()(const void* p) { std::free(const_cast<void*>(p)); }
};
std::unique_ptr<const char, Deleter> demangled(abi::__cxa_demangle(name, 0, 0, &status));
if(!status && demangled)
name = demangled.get();
#endif
serialize(s, name);
}
typedef std::string::size_type size_type;
static void serialize(std::ostream& s, std::string name)
{
const size_type nm = rfind(name, ':') + 1;
const size_type tpl = name.find('<', nm);
s << clean(name.substr(nm, tpl - nm));
if(tpl == std::string::npos)
return;
s << '<';
list(s, name.substr(tpl + 1, name.rfind('>') - tpl - 1));
s << '>';
}
static void list(std::ostream& s, const std::string& name)
{
const size_type comma = rfind(name, ',');
if(comma != std::string::npos)
{
list(s, name.substr(0, comma));
s << ", ";
}
serialize(s, name.substr(comma + 1));
}
static std::string clean(std::string name)
{
boost::algorithm::trim(name);
boost::algorithm::erase_all(name, "class ");
boost::algorithm::erase_all(name, "struct ");
boost::algorithm::erase_all(name, "__ptr64");
boost::algorithm::replace_all(name, " &", "&");
boost::algorithm::replace_all(name, "& ", "&");
boost::algorithm::replace_all(name, " *", "*");
boost::algorithm::replace_all(name, "* ", "*");
return name;
}
static size_type rfind(const std::string& name, char c)
{
size_type count = 0;
for(size_type i = name.size() - 1; i > 0; --i)
{
if(name[i] == '>')
++count;
else if(name[i] == '<')
--count;
if(name[i] == c && count == 0)
return i;
}
return std::string::npos;
}
const std::type_info* info_;
};
template<typename T>
type_name make_type_name()
{
return type_name(typeid(T));
}
template<typename T>
type_name make_type_name(const T&)
{
return type_name(typeid(T));
}
}} // namespace mock::detail
#endif // MOCK_TYPE_NAME_HPP_INCLUDED

View File

@ -0,0 +1,29 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_VERIFIABLE_HPP_INCLUDED
#define MOCK_VERIFIABLE_HPP_INCLUDED
#include "../config.hpp"
namespace mock { namespace detail {
class verifiable
{
public:
verifiable() = default;
verifiable(const verifiable&) = delete;
verifiable& operator=(const verifiable&) = delete;
virtual ~verifiable() = default;
virtual bool verify() const = 0;
virtual void reset() = 0;
};
}} // namespace mock::detail
#endif // MOCK_VERIFIABLE_HPP_INCLUDED

View File

@ -0,0 +1,23 @@
// http://turtle.sourceforge.net
//
// Copyright Alexander Grund 2020
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_VOID_T_HPP_INCLUDED
#define MOCK_VOID_T_HPP_INCLUDED
namespace mock { namespace detail {
template<typename...>
struct make_void
{
using type = void;
};
/// Standard helper to implement the detection idiom. Returns always void
template<typename... Ts>
using void_t = typename make_void<Ts...>::type;
}} // namespace mock::detail
#endif // MOCK_VOID_T_HPP_INCLUDED

70
thirdparty/turtle/turtle/error.hpp vendored Normal file
View File

@ -0,0 +1,70 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_ERROR_HPP_INCLUDED
#define MOCK_ERROR_HPP_INCLUDED
#include "config.hpp"
#ifdef MOCK_USE_BOOST_TEST
# include "exception.hpp"
# include <boost/exception/enable_current_exception.hpp>
# include <boost/test/framework.hpp>
# include <boost/test/test_tools.hpp>
# include <boost/test/unit_test_suite.hpp>
# include <boost/version.hpp>
namespace mock {
template<typename Result>
struct error
{
static Result abort()
{
boost::unit_test::framework::test_unit_aborted(boost::unit_test::framework::current_test_case());
throw boost::enable_current_exception(exception());
}
static void pass(const char* file, int line)
{
boost::unit_test::unit_test_log.set_checkpoint(file, static_cast<std::size_t>(line));
}
template<typename Context>
static void fail(const char* message, const Context& context, const char* file = "unknown location", int line = 0)
{
boost::unit_test::framework::assertion_result(
# if BOOST_VERSION < 105900
false
# else
boost::unit_test::AR_FAILED
# endif
);
boost::unit_test::unit_test_log << boost::unit_test::log::begin(file, static_cast<std::size_t>(line))
<< boost::unit_test::log_all_errors << message << ": " << context
<< boost::unit_test::log::end();
}
template<typename Context>
static void call(const Context& context, const char* file, int line)
{
boost::unit_test::framework::assertion_result(
# if BOOST_VERSION < 105900
true
# else
boost::unit_test::AR_PASSED
# endif
);
boost::unit_test::unit_test_log << boost::unit_test::log::begin(file, static_cast<std::size_t>(line))
<< boost::unit_test::log_successful_tests
<< "mock expectation fulfilled: " << context << boost::unit_test::log::end();
}
};
} // namespace mock
#endif // MOCK_USE_BOOST_TEST
#endif // MOCK_ERROR_HPP_INCLUDED

23
thirdparty/turtle/turtle/exception.hpp vendored Normal file
View File

@ -0,0 +1,23 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_EXCEPTION_HPP_INCLUDED
#define MOCK_EXCEPTION_HPP_INCLUDED
#include "config.hpp"
#ifdef MOCK_USE_BOOST_TEST
# include <boost/test/execution_monitor.hpp>
namespace mock {
struct exception : virtual boost::execution_aborted
{};
} // namespace mock
#endif // MOCK_USE_BOOST_TEST
#endif // MOCK_EXCEPTION_HPP_INCLUDED

24
thirdparty/turtle/turtle/format.hpp vendored Normal file
View File

@ -0,0 +1,24 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_FORMAT_HPP_INCLUDED
#define MOCK_FORMAT_HPP_INCLUDED
#include "config.hpp"
#include "detail/formatter.hpp"
namespace mock {
template<typename T>
detail::formatter<T> format(const T& t)
{
return detail::formatter<T>(t);
}
} // namespace mock
#endif // MOCK_FORMAT_HPP_INCLUDED

196
thirdparty/turtle/turtle/log.hpp vendored Normal file
View File

@ -0,0 +1,196 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_LOG_HPP_INCLUDED
#define MOCK_LOG_HPP_INCLUDED
#include "config.hpp"
#include "format.hpp"
#include "stream.hpp"
#include <boost/detail/container_fwd.hpp>
#include <boost/none.hpp>
#include <memory>
#include <type_traits>
namespace boost {
template<typename T>
class shared_ptr;
template<typename T>
class weak_ptr;
template<typename T>
class reference_wrapper;
template<typename T>
class optional;
namespace phoenix {
template<typename T>
struct actor;
}
namespace lambda {
template<typename T>
class lambda_functor;
}
namespace assign_detail {
template<typename T>
class generic_list;
}
} // namespace boost
namespace mock {
namespace detail {
template<typename T>
void serialize(stream& s, const T& begin, const T& end)
{
s << '(';
for(T it = begin; it != end; ++it)
s << (it == begin ? "" : ",") << mock::format(*it);
s << ')';
}
template<typename T>
struct is_callable_impl : std::false_type
{};
template<typename R, typename... Args>
struct is_callable_impl<R(Args...)> : std::true_type
{};
template<typename T>
struct is_callable : is_callable_impl<std::remove_cv_t<T>>
{};
} // namespace detail
template<typename T1, typename T2>
stream& operator<<(stream& s, const std::pair<T1, T2>& p)
{
return s << '(' << mock::format(p.first) << ',' << mock::format(p.second) << ')';
}
template<typename T, typename A>
stream& operator<<(stream& s, const std::deque<T, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename T, typename A>
stream& operator<<(stream& s, const std::list<T, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename T, typename A>
stream& operator<<(stream& s, const std::vector<T, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename K, typename T, typename C, typename A>
stream& operator<<(stream& s, const std::map<K, T, C, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename K, typename T, typename C, typename A>
stream& operator<<(stream& s, const std::multimap<K, T, C, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename T, typename C, typename A>
stream& operator<<(stream& s, const std::set<T, C, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename T, typename C, typename A>
stream& operator<<(stream& s, const std::multiset<T, C, A>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename T>
stream& operator<<(stream& s, const boost::assign_detail::generic_list<T>& t)
{
detail::serialize(s, t.begin(), t.end());
return s;
}
template<typename T>
stream& operator<<(stream& s, const boost::reference_wrapper<T>& t)
{
return s << mock::format(t.get());
}
template<typename T>
stream& operator<<(stream& s, const std::reference_wrapper<T>& t)
{
return s << mock::format(t.get());
}
template<typename T>
stream& operator<<(stream& s, const boost::shared_ptr<T>& t)
{
return s << mock::format(t.get());
}
template<typename T>
stream& operator<<(stream& s, const boost::weak_ptr<T>& t)
{
return s << mock::format(t.lock());
}
inline stream& operator<<(stream& s, const boost::none_t&)
{
return s << "none";
}
template<typename T>
stream& operator<<(stream& s, const boost::optional<T>& t)
{
if(t)
return s << mock::format(t.get());
return s << boost::none;
}
template<typename T>
stream& operator<<(stream& s, const std::shared_ptr<T>& t)
{
return s << mock::format(t.get());
}
template<typename T>
stream& operator<<(stream& s, const std::weak_ptr<T>& t)
{
return s << mock::format(t.lock());
}
template<typename T, typename D>
stream& operator<<(stream& s, const std::unique_ptr<T, D>& p)
{
return s << mock::format(p.get());
}
template<typename T>
stream& operator<<(stream& s, const boost::lambda::lambda_functor<T>&)
{
return s << '?';
}
template<typename T>
stream& operator<<(stream& s, const boost::phoenix::actor<T>&)
{
return s << '?';
}
inline stream& operator<<(stream& s, std::nullptr_t)
{
return s << "nullptr";
}
template<typename T>
std::enable_if_t<detail::is_callable<T>::value, stream&> operator<<(stream& s, T*)
{
return s << '?';
}
template<typename T>
std::enable_if_t<!detail::is_callable<T>::value, stream&> operator<<(stream& s, T* t)
{
*s.s_ << t;
return s;
}
} // namespace mock
#endif // MOCK_LOG_HPP_INCLUDED

74
thirdparty/turtle/turtle/matcher.hpp vendored Normal file
View File

@ -0,0 +1,74 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_MATCHER_HPP_INCLUDED
#define MOCK_MATCHER_HPP_INCLUDED
#include "config.hpp"
#include "constraints.hpp"
#include "detail/is_functor.hpp"
#include "detail/ref_arg.hpp"
#include "log.hpp"
#include <cstring>
#include <functional>
#include <type_traits>
namespace mock {
template<typename Actual, typename Expected, typename Enable = void>
class matcher
{
public:
explicit matcher(Expected expected) : expected_(expected) {}
bool operator()(std::add_lvalue_reference_t<const Actual> actual)
{
return mock::equal(mock::unwrap_ref(expected_)).c_(actual);
}
friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.expected_); }
private:
Expected expected_;
};
template<>
class matcher<const char*, const char*>
{
public:
explicit matcher(const char* expected) : expected_(expected) {}
bool operator()(const char* actual) { return std::strcmp(actual, expected_) == 0; }
friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.expected_); }
private:
const char* expected_;
};
template<typename Actual, typename Constraint>
class matcher<Actual, mock::constraint<Constraint>>
{
public:
explicit matcher(const constraint<Constraint>& c) : c_(c.c_) {}
bool operator()(detail::ref_arg_t<Actual> actual) { return c_(static_cast<detail::ref_arg_t<Actual>>(actual)); }
friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.c_); }
private:
Constraint c_;
};
template<typename Actual, typename Functor>
class matcher<Actual, Functor, std::enable_if_t<detail::is_functor<Functor, Actual>::value>>
{
public:
explicit matcher(const Functor& f) : c_(f) {}
bool operator()(detail::ref_arg_t<Actual> actual) { return c_(static_cast<detail::ref_arg_t<Actual>>(actual)); }
friend std::ostream& operator<<(std::ostream& s, const matcher& m) { return s << mock::format(m.c_); }
private:
Functor c_;
};
} // namespace mock
#endif // MOCK_MATCHER_HPP_INCLUDED

116
thirdparty/turtle/turtle/mock.hpp vendored Normal file
View File

@ -0,0 +1,116 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_MOCK_HPP_INCLUDED
#define MOCK_MOCK_HPP_INCLUDED
#include "cleanup.hpp"
#include "config.hpp"
#include "detail/mock_impl.hpp"
#include "object.hpp"
#include "reset.hpp"
#include "verify.hpp"
/// MOCK_CLASS( name )
/// Define a class
#define MOCK_CLASS(name) struct name : mock::object
/// MOCK_BASE_CLASS( name, base )
/// Define a class deriving from a base class
#define MOCK_BASE_CLASS(name, ...) struct name : __VA_ARGS__, mock::object, mock::detail::base<__VA_ARGS__>
/// MOCK_PROTECT_SIGNATURE( signature )
/// Use this with MOCK_FUNCTION/MOCK_*_METHOD if the return type contains commas
#define MOCK_PROTECT_SIGNATURE(...) mock::detail::unwrap_signature_t<void(__VA_ARGS__)>
/// MOCK_FUNCTOR( name, signature )
/// Define a callable variable/member
#define MOCK_FUNCTOR(name, ...) mock::detail::functor<__VA_ARGS__> name, name##_mock
/// MOCK_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
/// generates both const and non-const conversion operators
#define MOCK_CONVERSION_OPERATOR(M, T, identifier) \
M T() const { return MOCK_ANONYMOUS_HELPER(identifier)(); } \
M T() { return MOCK_ANONYMOUS_HELPER(identifier)(); } \
MOCK_METHOD_HELPER(T(), identifier)
/// MOCK_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
/// generates only a const conversion operator
#define MOCK_CONST_CONVERSION_OPERATOR(M, T, identifier) \
M T() const { return MOCK_ANONYMOUS_HELPER(identifier)(); } \
MOCK_METHOD_HELPER(T(), identifier)
/// MOCK_NON_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
/// generates only a non-const conversion operator
#define MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, identifier) \
M T() { return MOCK_ANONYMOUS_HELPER(identifier)(); } \
MOCK_METHOD_HELPER(T(), identifier)
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
/// As constructors do not have a return type, the usual signature gets restricted here to just the parameters.
#define MOCK_CONSTRUCTOR(T, arity, parameters, identifier) MOCK_CONSTRUCTOR_AUX(T, arity, parameters, identifier)
/// MOCK_DESTRUCTOR( [calling convention] ~name, identifier )
#define MOCK_DESTRUCTOR(T, identifier) \
T() \
{ \
try \
{ \
MOCK_ANONYMOUS_HELPER(identifier)(); \
} catch(...) \
{} \
} \
MOCK_METHOD_HELPER(void(), identifier)
/// MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] )
/// generates both const and non-const methods
/// The 'signature' can be omitted if it can be uniquely identified from the base class
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_METHOD(M, ...) \
MOCK_METHOD_EXT(M, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
/// MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
/// generates only the const version of the method
/// The 'signature' can be omitted if it can be uniquely identified from the base class
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_CONST_METHOD(M, ...) \
MOCK_CONST_METHOD_EXT(M, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
/// MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] )
/// generates only the non-const version of the method
/// The 'signature' can be omitted if it can be uniquely identified from the base class
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_NON_CONST_METHOD(M, ...) \
MOCK_NON_CONST_METHOD_EXT(M, \
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, MOCK_SIGNATURE(M), ), \
MOCK_VARIADIC_ELEM_2(__VA_ARGS__, M, M, ))
/// MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] )
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_FUNCTION(F, arity, ...) \
MOCK_FUNCTION_AUX(F, arity, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), inline)
/// MOCK_STATIC_METHOD( [calling convention] name, arity, signature[, identifier] )
/// if 'identifier' is omitted it will default to 'name'
#define MOCK_STATIC_METHOD(F, arity, ...) \
MOCK_FUNCTION_AUX(F, arity, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static)
/// MOCK_EXPECT( identifier )
/// Begin setting up expectation for the identifier
#define MOCK_EXPECT(identifier) MOCK_HELPER(identifier).expect(__FILE__, __LINE__)
/// MOCK_RESET( identifier )
/// Reset all pending expectations for the identifier
#define MOCK_RESET(identifier) MOCK_HELPER(identifier).reset(__FILE__, __LINE__)
/// MOCK_VERIFY( identifier )
/// Verify all expectations for the identifier have been met
#define MOCK_VERIFY(identifier) MOCK_HELPER(identifier).verify(__FILE__, __LINE__)
#endif // MOCK_MOCK_HPP_INCLUDED

70
thirdparty/turtle/turtle/object.hpp vendored Normal file
View File

@ -0,0 +1,70 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_OBJECT_HPP_INCLUDED
#define MOCK_OBJECT_HPP_INCLUDED
#include "config.hpp"
#include "detail/object_impl.hpp"
#include "detail/root.hpp"
#include "detail/type_name.hpp"
#include <boost/optional.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <memory>
#include <type_traits>
namespace mock {
class object;
namespace detail {
template<typename E>
E& configure(const object& o,
E& e,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name);
template<typename T, typename E>
E& configure(const T& t,
E& e,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name,
std::enable_if_t<!std::is_base_of<object, T>::value>* = 0)
{
e.configure(detail::root, &t, instance, type, name);
return e;
}
} // namespace detail
class object
{
public:
object() : impl_(std::make_shared<detail::object_impl>()) {}
protected:
~object() = default;
public:
std::shared_ptr<detail::object_impl> impl_;
};
namespace detail {
template<typename E>
E& configure(const object& o,
E& e,
boost::unit_test::const_string instance,
boost::optional<type_name> type,
boost::unit_test::const_string name)
{
e.configure(*o.impl_, o.impl_.get(), instance, type, name);
return e;
}
} // namespace detail
} // namespace mock
#endif // MOCK_OBJECT_HPP_INCLUDED

33
thirdparty/turtle/turtle/reset.hpp vendored Normal file
View File

@ -0,0 +1,33 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_RESET_HPP_INCLUDED
#define MOCK_RESET_HPP_INCLUDED
#include "config.hpp"
#include "detail/functor.hpp"
#include "detail/root.hpp"
#include "object.hpp"
namespace mock {
inline void reset()
{
detail::root.reset();
}
inline void reset(const object& o)
{
o.impl_->reset();
}
template<typename Signature>
void reset(detail::functor<Signature>& f)
{
f.reset();
}
} // namespace mock
#endif // MOCK_RESET_HPP_INCLUDED

26
thirdparty/turtle/turtle/sequence.hpp vendored Normal file
View File

@ -0,0 +1,26 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2008
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_SEQUENCE_HPP_INCLUDED
#define MOCK_SEQUENCE_HPP_INCLUDED
#include "config.hpp"
#include "detail/sequence_impl.hpp"
#include <memory>
namespace mock {
class sequence
{
public:
sequence() : impl_(std::make_shared<detail::sequence_impl>()) {}
std::shared_ptr<detail::sequence_impl> impl_;
};
} // namespace mock
#endif // MOCK_SEQUENCE_HPP_INCLUDED

114
thirdparty/turtle/turtle/stream.hpp vendored Normal file
View File

@ -0,0 +1,114 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2011
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_STREAM_HPP_INCLUDED
#define MOCK_STREAM_HPP_INCLUDED
#include "config.hpp"
#include <memory>
#include <ostream>
namespace mock {
struct stream
{
explicit stream(std::ostream& s) : s_(&s) {}
std::ostream* s_;
};
#ifdef MOCK_USE_CONVERSIONS
namespace detail { namespace conversion {
struct sink
{
template<typename T>
sink(const T&)
{}
};
inline std::ostream& operator<<(std::ostream& s, const sink&) { return s << '?'; }
struct holder
{
holder() = default;
holder(const holder&) = delete;
holder& operator=(const holder&) = delete;
virtual ~holder() = default;
virtual void serialize(std::ostream& s) const = 0;
};
template<typename T>
struct holder_imp : holder
{
explicit holder_imp(const T& t) : t_(t) {}
virtual void serialize(std::ostream& s) const
{
// if an error about an ambiguous conversion is generated by the
// line below the solution is to add a serialization operator to a
// mock::stream for T
s << t_;
}
const T& t_;
};
struct any
{
template<typename T>
any(const T& t) : h_(std::make_unique<holder_imp<T>>(t))
{}
std::unique_ptr<holder> h_;
};
}} // namespace detail::conversion
inline stream& operator<<(stream& s, const detail::conversion::any& d)
{
d.h_->serialize(*s.s_);
return s;
}
#else // MOCK_USE_CONVERSIONS
namespace detail { namespace conversion {
template<typename S, typename T>
S& operator<<(S& s, const T&)
{
return s << '?';
}
}} // namespace detail::conversion
template<typename T>
stream& operator<<(stream& s, const T& t)
{
using namespace detail::conversion;
*s.s_ << t;
return s;
}
#endif // MOCK_USE_CONVERSIONS
namespace detail {
template<typename T>
void serialize(stream& s, const T& t)
{
// if an error about an ambiguous conversion is generated by the
// line below the solution is to add a serialization operator to a
// mock::stream for T
s << t;
}
inline void serialize(stream& s, bool b) { s << (b ? "true" : "false"); }
template<typename C, typename T, typename A>
void serialize(stream& s, const std::basic_string<C, T, A>& str)
{
s << '"' << str << '"';
}
inline void serialize(stream& s, const char* const str) { s << '"' << str << '"'; }
inline void serialize(stream& s, unsigned char c) { s << static_cast<int>(c); }
} // namespace detail
} // namespace mock
#endif // MOCK_STREAM_HPP_INCLUDED

View File

@ -0,0 +1,41 @@
// http://turtle.sourceforge.net
//
// Copyright Alexander Grund 2020
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
#define MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
#include <functional>
#include <type_traits>
namespace mock {
template<class T>
struct unwrap_reference
{
using type = T;
};
template<class T>
struct unwrap_reference<std::reference_wrapper<T>>
{
using type = T;
};
template<class T>
struct unwrap_reference<const std::reference_wrapper<T>>
{
using type = T;
};
template<class T>
using unwrap_reference_t = typename unwrap_reference<T>::type;
template<class T>
BOOST_FORCEINLINE unwrap_reference_t<T>& unwrap_ref(T& t) noexcept
{
return t;
}
} // namespace mock
#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED

33
thirdparty/turtle/turtle/verify.hpp vendored Normal file
View File

@ -0,0 +1,33 @@
// http://turtle.sourceforge.net
//
// Copyright Mathieu Champlon 2012
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef MOCK_VERIFY_HPP_INCLUDED
#define MOCK_VERIFY_HPP_INCLUDED
#include "config.hpp"
#include "detail/functor.hpp"
#include "detail/root.hpp"
#include "object.hpp"
namespace mock {
inline bool verify()
{
return detail::root.verify();
}
inline bool verify(const object& o)
{
return o.impl_->verify();
}
template<typename Signature>
bool verify(const detail::functor<Signature>& f)
{
return f.verify();
}
} // namespace mock
#endif // MOCK_VERIFY_HPP_INCLUDED