mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Format code using Clang-Format 10 and enforce via CI
Makes the format of the code base uniform.
This commit is contained in:
parent
b5bb500bd2
commit
ee72e8b9d8
97 changed files with 11189 additions and 10842 deletions
|
|
@ -11,34 +11,33 @@
|
|||
|
||||
#include <catch.hpp>
|
||||
|
||||
template< typename Result >
|
||||
template<typename Result>
|
||||
struct catch_mock_error_policy
|
||||
{
|
||||
static Result abort()
|
||||
{
|
||||
FAIL( "Aborted" );
|
||||
throw std::runtime_error( "unreachable" );
|
||||
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 )
|
||||
|
||||
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 );
|
||||
CAPTURE(context);
|
||||
FAIL_CHECK(message << " in: " << file << ":" << line);
|
||||
}
|
||||
|
||||
template< typename Context >
|
||||
static void call( const Context& context, const char* file, int 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 );
|
||||
CAPTURE(context);
|
||||
INFO(file << ":" << line);
|
||||
}
|
||||
|
||||
static void pass(const char* file, int line) { INFO(file << ":" << line); }
|
||||
};
|
||||
|
||||
#define MOCK_ERROR_POLICY catch_mock_error_policy
|
||||
|
|
|
|||
|
|
@ -10,30 +10,25 @@
|
|||
#define MOCK_CLEANUP_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "verify.hpp"
|
||||
#include "reset.hpp"
|
||||
#include "verify.hpp"
|
||||
#ifdef MOCK_USE_BOOST_TEST
|
||||
#include <boost/test/unit_test_suite.hpp>
|
||||
# include <boost/test/unit_test_suite.hpp>
|
||||
#endif
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
struct cleanup
|
||||
{
|
||||
struct cleanup
|
||||
{
|
||||
~cleanup()
|
||||
{
|
||||
mock::reset();
|
||||
}
|
||||
};
|
||||
~cleanup() { mock::reset(); }
|
||||
};
|
||||
|
||||
#ifdef MOCK_USE_BOOST_TEST
|
||||
BOOST_GLOBAL_FIXTURE( cleanup )
|
||||
#if BOOST_VERSION >= 105900
|
||||
;
|
||||
#endif
|
||||
BOOST_GLOBAL_FIXTURE(cleanup)
|
||||
# if BOOST_VERSION >= 105900
|
||||
;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
} // mock
|
||||
|
||||
} // namespace mock
|
||||
|
||||
#endif // MOCK_CLEANUP_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -14,29 +14,28 @@
|
|||
#include <boost/config.hpp>
|
||||
|
||||
#ifndef MOCK_ERROR_POLICY
|
||||
# define MOCK_ERROR_POLICY mock::error
|
||||
# define MOCK_USE_BOOST_TEST
|
||||
# define MOCK_ERROR_POLICY mock::error
|
||||
# define MOCK_USE_BOOST_TEST
|
||||
#endif
|
||||
|
||||
#ifndef MOCK_MAX_ARGS
|
||||
# define MOCK_MAX_ARGS 9
|
||||
# define MOCK_MAX_ARGS 9
|
||||
#endif
|
||||
|
||||
#ifndef MOCK_MAX_SEQUENCES
|
||||
# define MOCK_MAX_SEQUENCES 10
|
||||
# define MOCK_MAX_SEQUENCES 10
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX)
|
||||
# ifndef MOCK_NO_HDR_MUTEX
|
||||
# define MOCK_HDR_MUTEX
|
||||
# endif
|
||||
# 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
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -12,243 +12,284 @@
|
|||
#include "config.hpp"
|
||||
#include "log.hpp"
|
||||
#include "unwrap_reference.hpp"
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/array.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/variadic/to_array.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/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/array.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <boost/preprocessor/variadic/to_array.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
template<typename Constraint>
|
||||
struct constraint
|
||||
{
|
||||
template< typename Constraint >
|
||||
struct constraint
|
||||
{
|
||||
constraint() {}
|
||||
constraint( const Constraint& c )
|
||||
: c_( c )
|
||||
{}
|
||||
Constraint c_;
|
||||
};
|
||||
constraint() {}
|
||||
constraint(const Constraint& c) : c_(c) {}
|
||||
Constraint c_;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template< typename Lhs, typename Rhs >
|
||||
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
|
||||
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 );
|
||||
return lhs_(actual) && rhs_(actual);
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const and_& a )
|
||||
friend std::ostream& operator<<(std::ostream& s, const and_& a)
|
||||
{
|
||||
return s << "( " << mock::format( a.lhs_ )
|
||||
<< " && " << mock::format( a.rhs_ ) << " )";
|
||||
return s << "( " << mock::format(a.lhs_) << " && " << mock::format(a.rhs_) << " )";
|
||||
}
|
||||
|
||||
private:
|
||||
Lhs lhs_;
|
||||
Rhs rhs_;
|
||||
};
|
||||
|
||||
template< typename Lhs, typename 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
|
||||
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 );
|
||||
return lhs_(actual) || rhs_(actual);
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const or_& o )
|
||||
friend std::ostream& operator<<(std::ostream& s, const or_& o)
|
||||
{
|
||||
return s << "( " << mock::format( o.lhs_ )
|
||||
<< " || " << mock::format( o.rhs_ )<< " )";
|
||||
return s << "( " << mock::format(o.lhs_) << " || " << mock::format(o.rhs_) << " )";
|
||||
}
|
||||
|
||||
private:
|
||||
Lhs lhs_;
|
||||
Rhs rhs_;
|
||||
};
|
||||
|
||||
template< typename Constraint >
|
||||
template<typename Constraint>
|
||||
class not_
|
||||
{
|
||||
public:
|
||||
explicit not_( const Constraint& c )
|
||||
: c_( c )
|
||||
{}
|
||||
template< typename Actual >
|
||||
bool operator()( const Actual& actual ) const
|
||||
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_ );
|
||||
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::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 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
|
||||
|
||||
template< typename Constraint >
|
||||
const constraint< detail::not_< Constraint > >
|
||||
operator!( const constraint< Constraint >& c )
|
||||
{
|
||||
return detail::not_< Constraint >( c.c_ );
|
||||
}
|
||||
} // 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_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_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_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_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_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_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)
|
||||
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_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_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_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_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)
|
||||
BOOST_PP_IF(n, MOCK_NARY_CONSTRAINT, MOCK_UNARY_CONSTRAINT)(Name, n, Args, Expr)
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# define MOCK_VARIADIC_SIZE(...) \
|
||||
# define MOCK_VARIADIC_SIZE(...) \
|
||||
BOOST_PP_CAT(MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
|
||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \
|
||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),)
|
||||
32, \
|
||||
31, \
|
||||
30, \
|
||||
29, \
|
||||
28, \
|
||||
27, \
|
||||
26, \
|
||||
25, \
|
||||
24, \
|
||||
23, \
|
||||
22, \
|
||||
21, \
|
||||
20, \
|
||||
19, \
|
||||
18, \
|
||||
17, \
|
||||
16, \
|
||||
15, \
|
||||
14, \
|
||||
13, \
|
||||
12, \
|
||||
11, \
|
||||
10, \
|
||||
9, \
|
||||
8, \
|
||||
7, \
|
||||
6, \
|
||||
5, \
|
||||
4, \
|
||||
3, \
|
||||
2, \
|
||||
1, ), )
|
||||
#else // BOOST_MSVC
|
||||
# define MOCK_VARIADIC_SIZE(...) \
|
||||
# define MOCK_VARIADIC_SIZE(...) \
|
||||
MOCK_VARIADIC_SIZE_I(__VA_ARGS__, \
|
||||
32, 31, 30, 29, 28, 27, 26, 25, 24, 23, \
|
||||
22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
|
||||
12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
|
||||
32, \
|
||||
31, \
|
||||
30, \
|
||||
29, \
|
||||
28, \
|
||||
27, \
|
||||
26, \
|
||||
25, \
|
||||
24, \
|
||||
23, \
|
||||
22, \
|
||||
21, \
|
||||
20, \
|
||||
19, \
|
||||
18, \
|
||||
17, \
|
||||
16, \
|
||||
15, \
|
||||
14, \
|
||||
13, \
|
||||
12, \
|
||||
11, \
|
||||
10, \
|
||||
9, \
|
||||
8, \
|
||||
7, \
|
||||
6, \
|
||||
5, \
|
||||
4, \
|
||||
3, \
|
||||
2, \
|
||||
1, )
|
||||
#endif // BOOST_MSVC
|
||||
#define MOCK_VARIADIC_SIZE_I( \
|
||||
e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, \
|
||||
e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, \
|
||||
e25, e26, e27, e28, e29, e30, e31, size, ...) size
|
||||
#define MOCK_VARIADIC_SIZE_I(e0, \
|
||||
e1, \
|
||||
e2, \
|
||||
e3, \
|
||||
e4, \
|
||||
e5, \
|
||||
e6, \
|
||||
e7, \
|
||||
e8, \
|
||||
e9, \
|
||||
e10, \
|
||||
e11, \
|
||||
e12, \
|
||||
e13, \
|
||||
e14, \
|
||||
e15, \
|
||||
e16, \
|
||||
e17, \
|
||||
e18, \
|
||||
e19, \
|
||||
e20, \
|
||||
e21, \
|
||||
e22, \
|
||||
e23, \
|
||||
e24, \
|
||||
e25, \
|
||||
e26, \
|
||||
e27, \
|
||||
e28, \
|
||||
e29, \
|
||||
e30, \
|
||||
e31, \
|
||||
size, \
|
||||
...) \
|
||||
size
|
||||
|
||||
#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))
|
||||
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_AUX(Name, Size, Tuple) MOCK_CONSTRAINT_AUX_AUX(Name, BOOST_PP_DEC(Size), (Size, Tuple))
|
||||
|
||||
#define MOCK_CONSTRAINT(Name, ...) \
|
||||
MOCK_CONSTRAINT_AUX( \
|
||||
Name, MOCK_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
|
||||
#define MOCK_CONSTRAINT(Name, ...) MOCK_CONSTRAINT_AUX(Name, MOCK_VARIADIC_SIZE(__VA_ARGS__), (__VA_ARGS__))
|
||||
|
||||
#endif // MOCK_CONSTRAINT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -12,300 +12,243 @@
|
|||
#include "config.hpp"
|
||||
#include "constraint.hpp"
|
||||
#include "detail/move_helper.hpp"
|
||||
#include "unwrap_reference.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>
|
||||
# include <boost/test/tools/floating_point_comparison.hpp>
|
||||
#else
|
||||
#include <boost/test/floating_point_comparison.hpp>
|
||||
# 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() )
|
||||
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 )
|
||||
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 ) )
|
||||
# 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 )
|
||||
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 );
|
||||
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 )
|
||||
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 );
|
||||
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 )
|
||||
# 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
|
||||
# pragma push_macro("small")
|
||||
# undef small
|
||||
# define MOCK_SMALL_DEFINED
|
||||
#endif
|
||||
MOCK_NARY_CONSTRAINT( small, 1, ( tolerance ),
|
||||
( MOCK_SMALL() ) )
|
||||
MOCK_NARY_CONSTRAINT(small, 1, (tolerance), (MOCK_SMALL()))
|
||||
#ifdef MOCK_SMALL_DEFINED
|
||||
# pragma pop_macro( "small" )
|
||||
# pragma pop_macro("small")
|
||||
#endif
|
||||
|
||||
MOCK_NARY_CONSTRAINT( close, 2, ( expected, tolerance ),
|
||||
( MOCK_PERCENT_TOLERANCE() ) )
|
||||
MOCK_NARY_CONSTRAINT(close, 2, (expected, tolerance), (MOCK_PERCENT_TOLERANCE()))
|
||||
|
||||
MOCK_NARY_CONSTRAINT( close_fraction, 2, ( expected, tolerance ),
|
||||
( MOCK_FRACTION_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
|
||||
# pragma push_macro("near")
|
||||
# undef near
|
||||
# define MOCK_NEAR_DEFINED
|
||||
#endif
|
||||
MOCK_NARY_CONSTRAINT( near, 2, ( expected, tolerance ),
|
||||
std::abs( actual - expected ) <= tolerance )
|
||||
MOCK_NARY_CONSTRAINT(near, 2, (expected, tolerance), std::abs(actual - expected) <= tolerance)
|
||||
#ifdef MOCK_NEAR_DEFINED
|
||||
# pragma pop_macro( "near" )
|
||||
# pragma pop_macro("near")
|
||||
#endif
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace detail {
|
||||
template<class T, class U = T, class = void>
|
||||
struct has_equal_to: std::false_type
|
||||
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
|
||||
struct has_equal_to<T, U, void_t<decltype(std::declval<T>() == std::declval<U>())>> : std::true_type
|
||||
{};
|
||||
|
||||
template< typename Expected >
|
||||
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
|
||||
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_ );
|
||||
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
|
||||
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_ );
|
||||
return actual && *actual == unwrap_ref(expected_);
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const equal& e )
|
||||
friend std::ostream& operator<<(std::ostream& s, const equal& e)
|
||||
{
|
||||
return s << "equal( " << mock::format( e.expected_ ) << " )";
|
||||
return s << "equal( " << mock::format(e.expected_) << " )";
|
||||
}
|
||||
Expected expected_;
|
||||
};
|
||||
|
||||
template< typename 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
|
||||
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_;
|
||||
return std::addressof(actual) == expected_;
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& os, const same& s )
|
||||
friend std::ostream& operator<<(std::ostream& os, const same& s)
|
||||
{
|
||||
return os << "same( " << mock::format( *s.expected_ ) << " )";
|
||||
return os << "same( " << mock::format(*s.expected_) << " )";
|
||||
}
|
||||
const unwrap_reference_t< Expected >* expected_;
|
||||
const unwrap_reference_t<Expected>* expected_;
|
||||
};
|
||||
|
||||
template< typename 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
|
||||
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
|
||||
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 );
|
||||
*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
|
||||
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 );
|
||||
*expected_ = std::addressof(actual);
|
||||
return true;
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const retrieve& r )
|
||||
friend std::ostream& operator<<(std::ostream& s, const retrieve& r)
|
||||
{
|
||||
return s << "retrieve( " << mock::format( *r.expected_ ) << " )";
|
||||
return s << "retrieve( " << mock::format(*r.expected_) << " )";
|
||||
}
|
||||
unwrap_reference_t< Expected >* expected_;
|
||||
unwrap_reference_t<Expected>* expected_;
|
||||
};
|
||||
|
||||
template< typename Expected >
|
||||
template<typename Expected>
|
||||
struct assign
|
||||
{
|
||||
explicit assign( const Expected& expected )
|
||||
: expected_( expected )
|
||||
{}
|
||||
template< typename Actual >
|
||||
bool operator()( Actual& actual ) const
|
||||
explicit assign(const Expected& expected) : expected_(expected) {}
|
||||
template<typename Actual>
|
||||
bool operator()(Actual& actual) const
|
||||
{
|
||||
actual = unwrap_ref( expected_ );
|
||||
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
|
||||
template<typename Actual>
|
||||
bool operator()(Actual* actual,
|
||||
std::enable_if_t<std::is_convertible<unwrap_reference_t<Expected>, Actual>::value>* = 0) const
|
||||
{
|
||||
if( ! actual )
|
||||
if(!actual)
|
||||
return false;
|
||||
*actual = unwrap_ref( expected_ );
|
||||
*actual = unwrap_ref(expected_);
|
||||
return true;
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const assign& a )
|
||||
friend std::ostream& operator<<(std::ostream& s, const assign& a)
|
||||
{
|
||||
return s << "assign( " << mock::format( a.expected_ ) << " )";
|
||||
return s << "assign( " << mock::format(a.expected_) << " )";
|
||||
}
|
||||
Expected expected_;
|
||||
};
|
||||
|
||||
template< typename Expected >
|
||||
template<typename Expected>
|
||||
struct contain
|
||||
{
|
||||
explicit contain( const Expected& expected )
|
||||
: expected_( expected )
|
||||
{}
|
||||
bool operator()( const std::string& actual ) const
|
||||
explicit contain(const Expected& expected) : expected_(expected) {}
|
||||
bool operator()(const std::string& actual) const
|
||||
{
|
||||
return actual.find( unwrap_ref( expected_ ) )
|
||||
!= std::string::npos;
|
||||
return actual.find(unwrap_ref(expected_)) != std::string::npos;
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const contain& n )
|
||||
friend std::ostream& operator<<(std::ostream& s, const contain& n)
|
||||
{
|
||||
return s << "contain( " << mock::format( n.expected_ ) << " )";
|
||||
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::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< 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 );
|
||||
}
|
||||
} // mock
|
||||
template<typename T>
|
||||
constraint<T> call(T t)
|
||||
{
|
||||
return constraint<T>(t);
|
||||
}
|
||||
} // namespace mock
|
||||
|
||||
#endif // MOCK_CONSTRAINTS_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -14,16 +14,13 @@
|
|||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Result, typename Signature >
|
||||
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;
|
||||
typedef std::function<Signature> functor_type;
|
||||
typedef std::function<Result()> action_type;
|
||||
|
||||
protected:
|
||||
// Meant to be subclassed and not be directly used
|
||||
|
|
@ -33,41 +30,29 @@ namespace detail
|
|||
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_(); }
|
||||
|
||||
const functor_type& functor() const
|
||||
void calls(const functor_type& f)
|
||||
{
|
||||
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" );
|
||||
if(!f)
|
||||
throw std::invalid_argument("null functor");
|
||||
f_ = f;
|
||||
}
|
||||
|
||||
template< typename Exception >
|
||||
void throws( Exception e )
|
||||
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 )
|
||||
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(); };
|
||||
}
|
||||
|
|
@ -77,26 +62,26 @@ namespace detail
|
|||
action_type a_;
|
||||
};
|
||||
|
||||
template< typename Result, typename Signature >
|
||||
class action : public action_base< Result, Signature >
|
||||
template<typename Result, typename Signature>
|
||||
class action : public action_base<Result, Signature>
|
||||
{
|
||||
public:
|
||||
template< typename Value >
|
||||
void returns( const Value& v )
|
||||
template<typename Value>
|
||||
void returns(const Value& v)
|
||||
{
|
||||
this->set( std::ref( store( v ) ) );
|
||||
this->set(std::ref(store(v)));
|
||||
}
|
||||
template< typename Y >
|
||||
void returns( const std::reference_wrapper< Y >& r )
|
||||
template<typename Y>
|
||||
void returns(const std::reference_wrapper<Y>& r)
|
||||
{
|
||||
this->set( r );
|
||||
this->set(r);
|
||||
}
|
||||
|
||||
template< typename Value >
|
||||
void moves( Value&& v )
|
||||
template<typename Value>
|
||||
void moves(Value&& v)
|
||||
{
|
||||
auto vRef = std::ref( store( std::move( v ) ) );
|
||||
this->set([vRef](){ return std::move(vRef.get()); });
|
||||
auto vRef = std::ref(store(std::move(v)));
|
||||
this->set([vRef]() { return std::move(vRef.get()); });
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -107,44 +92,43 @@ namespace detail
|
|||
value& operator=(const value&) = delete;
|
||||
virtual ~value() = default;
|
||||
};
|
||||
template< typename T >
|
||||
template<typename T>
|
||||
struct value_imp : value
|
||||
{
|
||||
typedef std::remove_const_t<std::remove_reference_t<T>> type;
|
||||
|
||||
template< typename U >
|
||||
value_imp( U&& t ) : t_( std::forward<U>( t ) )
|
||||
template<typename U>
|
||||
value_imp(U&& t) : t_(std::forward<U>(t))
|
||||
{}
|
||||
type t_;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
typename value_imp<T>::type& store( T&& t )
|
||||
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_;
|
||||
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 )
|
||||
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_;
|
||||
v_ = std::make_unique<value_imp<Result>>(t);
|
||||
return static_cast<value_imp<Result>&>(*v_).t_;
|
||||
}
|
||||
|
||||
std::unique_ptr< value > v_;
|
||||
std::unique_ptr<value> v_;
|
||||
};
|
||||
|
||||
template< typename Signature >
|
||||
class action< void, Signature > : public action_base< void, Signature >
|
||||
template<typename Signature>
|
||||
class action<void, Signature> : public action_base<void, Signature>
|
||||
{
|
||||
public:
|
||||
action()
|
||||
{
|
||||
this->set( [](){} );
|
||||
this->set([]() {});
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_ACTION_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,43 +10,38 @@
|
|||
#define MOCK_CHILD_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include "parent.hpp"
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include "type_name.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
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 )
|
||||
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 );
|
||||
if(instance != "?." || name_.empty())
|
||||
p = parent(instance, type);
|
||||
parent_ = &p;
|
||||
name_ = name;
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const child& c )
|
||||
friend std::ostream& operator<<(std::ostream& s, const child& c)
|
||||
{
|
||||
if( c.parent_ )
|
||||
if(c.parent_)
|
||||
s << *c.parent_;
|
||||
return s << c.name_;
|
||||
}
|
||||
|
||||
private:
|
||||
const parent* parent_;
|
||||
boost::unit_test::const_string name_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_CHILD_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -15,10 +15,7 @@
|
|||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
class verifiable;
|
||||
|
||||
class context
|
||||
|
|
@ -30,17 +27,16 @@ namespace detail
|
|||
|
||||
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 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;
|
||||
virtual void serialize(std::ostream& s, const verifiable& v) const = 0;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_CONTEXT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -8,115 +8,83 @@
|
|||
|
||||
#include "matcher_base_template.hpp"
|
||||
|
||||
#define MOCK_EXPECTATION_INITIALIZE(z, n, d) \
|
||||
BOOST_PP_COMMA_IF(n) c##n##_( c##n )
|
||||
#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_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##_( std::forward< T##n >( a##n ) )
|
||||
#define MOCK_EXPECTATION_IS_VALID(z, n, d) BOOST_PP_IF(n, &&, ) c##n##_(std::forward<T##n>(a##n))
|
||||
|
||||
#define MOCK_EXPECTATION_SERIALIZE(z, n, d) \
|
||||
BOOST_PP_IF(n, << ", " <<,) c##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_SERIALIZE_ANY(z, n, d) BOOST_PP_IF(n, << ", " <<, ) "any"
|
||||
|
||||
#define MOCK_EXPECTATION_PARAM(z, n, Args) \
|
||||
std::forward< T##n >( a##n )
|
||||
#define MOCK_EXPECTATION_PARAM(z, n, Args) std::forward<T##n>(a##n)
|
||||
|
||||
#define MOCK_REF_ARG(z, n, d) \
|
||||
typename ref_arg< T##n >::type 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
|
||||
#define MOCK_REF_ARG_T(z, n, d) typename ref_arg<T##n>::type
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Signature > class default_matcher;
|
||||
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) ) >
|
||||
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, _) )
|
||||
virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG_T, _)) { return true; }
|
||||
virtual void serialize(std::ostream& s) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
{
|
||||
s << "" BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_SERIALIZE_ANY, _);
|
||||
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<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) ) >
|
||||
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, _)
|
||||
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, _) )
|
||||
virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _))
|
||||
{
|
||||
return BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_IS_VALID, _);
|
||||
return BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_IS_VALID, _);
|
||||
}
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
virtual void serialize(std::ostream& s) const
|
||||
{
|
||||
s << BOOST_PP_REPEAT(MOCK_NUM_ARGS,
|
||||
MOCK_EXPECTATION_SERIALIZE, _);
|
||||
s << BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_SERIALIZE, _);
|
||||
}
|
||||
|
||||
private:
|
||||
BOOST_PP_REPEAT(
|
||||
MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, _)
|
||||
};
|
||||
BOOST_PP_REPEAT(MOCK_NUM_ARGS, MOCK_EXPECTATION_MEMBER, _)
|
||||
};
|
||||
|
||||
template< typename F, typename Signature > class multi_matcher;
|
||||
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) ) >
|
||||
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 )
|
||||
{}
|
||||
multi_matcher(const F& f) : f_(f) {}
|
||||
|
||||
private:
|
||||
virtual bool operator()(
|
||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) )
|
||||
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_ );
|
||||
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_;
|
||||
|
|
@ -124,144 +92,103 @@ namespace detail
|
|||
|
||||
#endif
|
||||
|
||||
template< typename Signature > class expectation;
|
||||
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)) >
|
||||
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_( std::make_unique< unlimited >() )
|
||||
, matcher_(
|
||||
std::make_unique<
|
||||
default_matcher<
|
||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||
>
|
||||
> () )
|
||||
, file_( "unknown location" )
|
||||
, line_( 0 )
|
||||
: invocation_(std::make_unique<unlimited>()),
|
||||
matcher_(std::make_unique<default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>()),
|
||||
file_("unknown location"), line_(0)
|
||||
{}
|
||||
expectation( const char* file, int line )
|
||||
: invocation_( std::make_unique< unlimited >() )
|
||||
, matcher_(
|
||||
std::make_unique<
|
||||
default_matcher<
|
||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||
>
|
||||
> () )
|
||||
, file_( file )
|
||||
, line_( line )
|
||||
expectation(const char* file, int line)
|
||||
: invocation_(std::make_unique<unlimited>()),
|
||||
matcher_(std::make_unique<default_matcher<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>()), file_(file),
|
||||
line_(line)
|
||||
{}
|
||||
|
||||
expectation(expectation &&) = default;
|
||||
expectation(expectation&&) = default;
|
||||
expectation(expectation const&) = default;
|
||||
expectation& operator=(expectation &&) = default;
|
||||
expectation& operator=(expectation&&) = default;
|
||||
expectation& operator=(expectation const&) = default;
|
||||
|
||||
~expectation()
|
||||
{
|
||||
for( auto& sequence: sequences_)
|
||||
sequence->remove( this );
|
||||
for(auto& sequence : sequences_)
|
||||
sequence->remove(this);
|
||||
}
|
||||
|
||||
void invoke( std::unique_ptr< invocation > i )
|
||||
{
|
||||
invocation_ = std::move(i);
|
||||
}
|
||||
void invoke(std::unique_ptr<invocation> i) { invocation_ = std::move(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) )
|
||||
template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename Constraint_)>
|
||||
expectation& with(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, Constraint_, c))
|
||||
{
|
||||
matcher_ = std::make_unique<
|
||||
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) );
|
||||
matcher_ = std::make_unique<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 )
|
||||
# if MOCK_NUM_ARGS > 1
|
||||
template<typename Constraint>
|
||||
expectation& with(const Constraint& c)
|
||||
{
|
||||
matcher_ = std::make_unique<
|
||||
multi_matcher<
|
||||
Constraint,
|
||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||
>>( c );
|
||||
matcher_ = std::make_unique<multi_matcher<Constraint, void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>>(c);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
void add( sequence& s )
|
||||
void add(sequence& s)
|
||||
{
|
||||
s.impl_->add( this );
|
||||
sequences_.push_back( s.impl_ );
|
||||
s.impl_->add(this);
|
||||
sequences_.push_back(s.impl_);
|
||||
}
|
||||
|
||||
bool verify() const
|
||||
{
|
||||
return invocation_->verify();
|
||||
}
|
||||
bool verify() const { return invocation_->verify(); }
|
||||
|
||||
bool is_valid(
|
||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) ) const
|
||||
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, _) );
|
||||
return !invocation_->exhausted() && (*matcher_)(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_EXPECTATION_PARAM, _));
|
||||
}
|
||||
|
||||
bool invoke() const
|
||||
{
|
||||
for( auto& sequence: sequences_)
|
||||
for(auto& sequence : sequences_)
|
||||
{
|
||||
if( ! sequence->is_valid( this ) )
|
||||
if(!sequence->is_valid(this))
|
||||
return false;
|
||||
}
|
||||
bool result = invocation_->invoke();
|
||||
for( auto& sequence: sequences_)
|
||||
sequence->invalidate( this );
|
||||
for(auto& sequence : sequences_)
|
||||
sequence->invalidate(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* file() const
|
||||
{
|
||||
return file_;
|
||||
}
|
||||
int line() const
|
||||
{
|
||||
return line_;
|
||||
}
|
||||
const char* file() const { return file_; }
|
||||
int line() const { return line_; }
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const expectation& e )
|
||||
friend std::ostream& operator<<(std::ostream& s, const expectation& e)
|
||||
{
|
||||
return s << ( e.invocation_->exhausted() ? 'v' : '.' )
|
||||
<< ' ' << *e.invocation_
|
||||
return s << (e.invocation_->exhausted() ? 'v' : '.') << ' ' << *e.invocation_
|
||||
#ifndef MOCK_NUM_ARGS_0
|
||||
<< ".with( " << *e.matcher_ << " )"
|
||||
<< ".with( " << *e.matcher_ << " )"
|
||||
#endif
|
||||
;
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr< invocation > invocation_;
|
||||
std::unique_ptr<
|
||||
matcher_base<
|
||||
void( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||
>
|
||||
> matcher_;
|
||||
std::vector< std::shared_ptr<sequence_impl> > sequences_;
|
||||
std::unique_ptr<invocation> invocation_;
|
||||
std::unique_ptr<matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>> matcher_;
|
||||
std::vector<std::shared_ptr<sequence_impl>> sequences_;
|
||||
const char* file_;
|
||||
int line_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#undef MOCK_EXPECTATION_INITIALIZE
|
||||
#undef MOCK_EXPECTATION_MEMBER
|
||||
|
|
|
|||
|
|
@ -13,38 +13,29 @@
|
|||
#include "../stream.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename T >
|
||||
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_ );
|
||||
}
|
||||
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 )
|
||||
template<typename T>
|
||||
stream& operator<<(stream& s, const formatter<T>& f)
|
||||
{
|
||||
f.serialize( s );
|
||||
f.serialize(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
std::ostream& operator<<( std::ostream& s, const formatter< T >& f )
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream& s, const formatter<T>& f)
|
||||
{
|
||||
stream ss( s );
|
||||
f.serialize( ss );
|
||||
stream ss(s);
|
||||
f.serialize(ss);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_FORMATTER_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,74 +10,62 @@
|
|||
#define MOCK_FUNCTION_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../constraints.hpp"
|
||||
#include "../error.hpp"
|
||||
#include "../log.hpp"
|
||||
#include "../constraints.hpp"
|
||||
#include "../sequence.hpp"
|
||||
#include "../matcher.hpp"
|
||||
#include "../sequence.hpp"
|
||||
#include "action.hpp"
|
||||
#include "verifiable.hpp"
|
||||
#include "invocation.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include "context.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "invocation.hpp"
|
||||
#include "move_helper.hpp"
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include "mutex.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include "verifiable.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/preprocessor/comparison/equal.hpp>
|
||||
#include <boost/preprocessor/comparison/greater.hpp>
|
||||
#include <boost/preprocessor/iteration/iterate.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/test/utils/lazy_ostream.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <list>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename R, typename E >
|
||||
namespace mock { namespace detail {
|
||||
template<typename R, typename E>
|
||||
struct wrapper_base
|
||||
{
|
||||
wrapper_base( E& e )
|
||||
: e_( &e )
|
||||
{}
|
||||
wrapper_base(E& e) : e_(&e) {}
|
||||
|
||||
template< typename T >
|
||||
void returns( T t )
|
||||
template<typename T>
|
||||
void returns(T t)
|
||||
{
|
||||
e_->returns( t );
|
||||
e_->returns(t);
|
||||
}
|
||||
|
||||
E* e_;
|
||||
};
|
||||
template< typename E >
|
||||
struct wrapper_base< void, E >
|
||||
template<typename E>
|
||||
struct wrapper_base<void, E>
|
||||
{
|
||||
wrapper_base( E& e )
|
||||
: e_( &e )
|
||||
{}
|
||||
wrapper_base(E& e) : e_(&e) {}
|
||||
|
||||
E* e_;
|
||||
};
|
||||
template< typename R, typename E >
|
||||
struct wrapper_base< R*, E >
|
||||
template<typename R, typename E>
|
||||
struct wrapper_base<R*, E>
|
||||
{
|
||||
wrapper_base( E& e )
|
||||
: e_( &e )
|
||||
{}
|
||||
wrapper_base(E& e) : e_(&e) {}
|
||||
|
||||
void returns( R* r )
|
||||
void returns(R* r) { e_->returns(r); }
|
||||
template<typename Y>
|
||||
void returns(const std::reference_wrapper<Y>& r)
|
||||
{
|
||||
e_->returns( r );
|
||||
}
|
||||
template< typename Y >
|
||||
void returns( const std::reference_wrapper< Y >& r )
|
||||
{
|
||||
e_->returns( r );
|
||||
e_->returns(r);
|
||||
}
|
||||
|
||||
E* e_;
|
||||
|
|
@ -92,8 +80,7 @@ namespace detail
|
|||
return std::uncaught_exception() ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#define MOCK_NUM_ARGS 0
|
||||
#define MOCK_NUM_ARGS_0
|
||||
|
|
|
|||
|
|
@ -9,79 +9,65 @@
|
|||
#include "expectation_template.hpp"
|
||||
|
||||
#ifndef MOCK_ERROR_POLICY
|
||||
# error no error policy has been set
|
||||
# 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_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_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_FORWARD(z, n, d) \
|
||||
std::forward< T##n >( t##n )
|
||||
#define MOCK_FORWARD(z, n, d) std::forward<T##n>(t##n)
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Signature > class function_impl;
|
||||
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 std::enable_shared_from_this<
|
||||
function_impl< R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )> >
|
||||
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 std::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;
|
||||
typedef safe_error<R, MOCK_ERROR_POLICY<R>> error_type;
|
||||
|
||||
public:
|
||||
function_impl()
|
||||
: context_( 0 )
|
||||
, valid_( true )
|
||||
, exceptions_( exceptions() )
|
||||
, mutex_( std::make_shared< mutex >() )
|
||||
{}
|
||||
function_impl() : context_(0), valid_(true), exceptions_(exceptions()), mutex_(std::make_shared<mutex>()) {}
|
||||
virtual ~function_impl()
|
||||
{
|
||||
if( valid_ && exceptions_ >= exceptions() )
|
||||
if(valid_ && exceptions_ >= exceptions())
|
||||
{
|
||||
for( const auto& expectation: expectations_ )
|
||||
for(const auto& expectation : expectations_)
|
||||
{
|
||||
if( ! expectation.verify() )
|
||||
if(!expectation.verify())
|
||||
{
|
||||
error_type::fail( "untriggered expectation",
|
||||
boost::unit_test::lazy_ostream::instance()
|
||||
<< lazy_context( this )
|
||||
<< lazy_expectations( this ),
|
||||
expectation.file(), expectation.line() );
|
||||
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 );
|
||||
if(context_)
|
||||
context_->remove(*this);
|
||||
}
|
||||
|
||||
virtual bool verify() const
|
||||
{
|
||||
lock _( mutex_ );
|
||||
for( const auto& expectation: expectations_ )
|
||||
lock _(mutex_);
|
||||
for(const auto& expectation : expectations_)
|
||||
{
|
||||
if( ! expectation.verify() )
|
||||
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() );
|
||||
error_type::fail("verification failed",
|
||||
boost::unit_test::lazy_ostream::instance()
|
||||
<< lazy_context(this) << lazy_expectations(this),
|
||||
expectation.file(),
|
||||
expectation.line());
|
||||
}
|
||||
}
|
||||
return valid_;
|
||||
|
|
@ -89,115 +75,103 @@ namespace detail
|
|||
|
||||
virtual void reset()
|
||||
{
|
||||
lock _( mutex_ );
|
||||
lock _(mutex_);
|
||||
valid_ = true;
|
||||
std::shared_ptr< function_impl > guard =
|
||||
this->shared_from_this();
|
||||
std::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;
|
||||
typedef expectation<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))> expectation_type;
|
||||
|
||||
class wrapper : public wrapper_base< R, expectation_type >
|
||||
class wrapper : public wrapper_base<R, expectation_type>
|
||||
{
|
||||
private:
|
||||
typedef wrapper_base< R, expectation_type > base_type;
|
||||
typedef wrapper_base<R, expectation_type> base_type;
|
||||
|
||||
public:
|
||||
wrapper( const std::shared_ptr< mutex >& m, expectation_type& e )
|
||||
: base_type( e )
|
||||
, lock_( m )
|
||||
{}
|
||||
wrapper(const std::shared_ptr<mutex>& m, expectation_type& e) : base_type(e), lock_(m) {}
|
||||
wrapper(const wrapper&) = delete;
|
||||
wrapper( wrapper&& x ) = default;
|
||||
wrapper(wrapper&& x) = default;
|
||||
wrapper& operator=(const wrapper&) = delete;
|
||||
wrapper& operator=( wrapper&& x ) = default;
|
||||
wrapper& operator=(wrapper&& x) = default;
|
||||
wrapper& once()
|
||||
{
|
||||
this->e_->invoke( std::make_unique< detail::once >() );
|
||||
this->e_->invoke(std::make_unique<detail::once>());
|
||||
return *this;
|
||||
}
|
||||
wrapper& never()
|
||||
{
|
||||
this->e_->invoke( std::make_unique< detail::never >() );
|
||||
this->e_->invoke(std::make_unique<detail::never>());
|
||||
return *this;
|
||||
}
|
||||
wrapper& exactly( std::size_t count )
|
||||
wrapper& exactly(std::size_t count)
|
||||
{
|
||||
this->e_->invoke( std::make_unique< detail::exactly >( count ) );
|
||||
this->e_->invoke(std::make_unique<detail::exactly>(count));
|
||||
return *this;
|
||||
}
|
||||
wrapper& at_least( std::size_t min )
|
||||
wrapper& at_least(std::size_t min)
|
||||
{
|
||||
this->e_->invoke( std::make_unique< detail::at_least >( min ) );
|
||||
this->e_->invoke(std::make_unique<detail::at_least>(min));
|
||||
return *this;
|
||||
}
|
||||
wrapper& at_most( std::size_t max )
|
||||
wrapper& at_most(std::size_t max)
|
||||
{
|
||||
this->e_->invoke( std::make_unique< detail::at_most >( max ) );
|
||||
this->e_->invoke(std::make_unique<detail::at_most>(max));
|
||||
return *this;
|
||||
}
|
||||
wrapper& between( std::size_t min, std::size_t max )
|
||||
wrapper& between(std::size_t min, std::size_t max)
|
||||
{
|
||||
this->e_->invoke( std::make_unique< detail::between >( min, max ) );
|
||||
this->e_->invoke(std::make_unique<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) )
|
||||
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) );
|
||||
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 )
|
||||
# if MOCK_NUM_ARGS > 1
|
||||
template<typename Constraint>
|
||||
wrapper& with(const Constraint& c)
|
||||
{
|
||||
this->e_->with( c );
|
||||
this->e_->with(c);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define MOCK_FUNCTION_IN_ADD(z, n, d) \
|
||||
this->e_->add( s##n );
|
||||
#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; \
|
||||
#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, _)
|
||||
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 )
|
||||
template<typename TT>
|
||||
void calls(TT t)
|
||||
{
|
||||
this->e_->calls( t );
|
||||
this->e_->calls(t);
|
||||
}
|
||||
template< typename TT >
|
||||
void throws( TT t )
|
||||
template<typename TT>
|
||||
void throws(TT t)
|
||||
{
|
||||
this->e_->throws( t );
|
||||
this->e_->throws(t);
|
||||
}
|
||||
template< typename TT >
|
||||
void moves( TT&& t )
|
||||
template<typename TT>
|
||||
void moves(TT&& t)
|
||||
{
|
||||
this->e_->moves( std::move( t ) );
|
||||
this->e_->moves(std::move(t));
|
||||
}
|
||||
|
||||
lock lock_;
|
||||
|
|
@ -206,82 +180,78 @@ namespace detail
|
|||
public:
|
||||
typedef wrapper wrapper_type;
|
||||
|
||||
wrapper expect( const char* file, int line )
|
||||
wrapper expect(const char* file, int line)
|
||||
{
|
||||
lock _( mutex_ );
|
||||
expectations_.emplace_back( file, line );
|
||||
lock _(mutex_);
|
||||
expectations_.emplace_back(file, line);
|
||||
valid_ = true;
|
||||
return wrapper( mutex_, expectations_.back() );
|
||||
return wrapper(mutex_, expectations_.back());
|
||||
}
|
||||
wrapper expect()
|
||||
{
|
||||
lock _( mutex_ );
|
||||
expectations_.emplace_back( );
|
||||
lock _(mutex_);
|
||||
expectations_.emplace_back();
|
||||
valid_ = true;
|
||||
return wrapper( mutex_, expectations_.back() );
|
||||
return wrapper(mutex_, expectations_.back());
|
||||
}
|
||||
|
||||
R operator()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
|
||||
R operator()(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t)) const
|
||||
{
|
||||
lock _( mutex_ );
|
||||
lock _(mutex_);
|
||||
valid_ = false;
|
||||
for( const auto& expectation: expectations_ )
|
||||
for(const auto& expectation : expectations_)
|
||||
{
|
||||
if( expectation.is_valid(
|
||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) ) )
|
||||
if(expectation.is_valid(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _)))
|
||||
{
|
||||
if( ! expectation.invoke() )
|
||||
if(!expectation.invoke())
|
||||
{
|
||||
error_type::fail( "sequence failed",
|
||||
MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
|
||||
error_type::fail(
|
||||
"sequence failed", MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
|
||||
return error_type::abort();
|
||||
}
|
||||
if( ! expectation.valid() )
|
||||
if(!expectation.valid())
|
||||
{
|
||||
error_type::fail( "missing action",
|
||||
MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line() );
|
||||
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()(
|
||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
|
||||
error_type::call(MOCK_FUNCTION_CONTEXT, expectation.file(), expectation.line());
|
||||
if(expectation.functor())
|
||||
return expectation.functor()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _));
|
||||
return expectation.trigger();
|
||||
}
|
||||
}
|
||||
error_type::fail( "unexpected call", MOCK_FUNCTION_CONTEXT );
|
||||
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 )
|
||||
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 );
|
||||
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 )
|
||||
friend std::ostream& operator<<(std::ostream& s, const function_impl& impl)
|
||||
{
|
||||
lock _( impl.mutex_ );
|
||||
return s << lazy_context( &impl ) << lazy_expectations( &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 )
|
||||
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_ );
|
||||
if(c.impl_->context_)
|
||||
c.impl_->context_->serialize(s, *c.impl_);
|
||||
else
|
||||
s << '?';
|
||||
return s;
|
||||
|
|
@ -291,26 +261,23 @@ namespace detail
|
|||
|
||||
struct lazy_expectations
|
||||
{
|
||||
lazy_expectations( const function_impl* impl )
|
||||
: impl_( impl )
|
||||
{}
|
||||
friend std::ostream& operator<<( std::ostream& s, const lazy_expectations& e )
|
||||
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_ )
|
||||
for(const auto& expectation : e.impl_->expectations_)
|
||||
s << std::endl << expectation;
|
||||
return s;
|
||||
}
|
||||
const function_impl* impl_;
|
||||
};
|
||||
|
||||
std::list< expectation_type > expectations_;
|
||||
std::list<expectation_type> expectations_;
|
||||
context* context_;
|
||||
mutable bool valid_;
|
||||
const int exceptions_;
|
||||
const std::shared_ptr< mutex > mutex_;
|
||||
const std::shared_ptr<mutex> mutex_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#undef MOCK_FUNCTION_FORMAT
|
||||
#undef MOCK_FUNCTION_CONTEXT
|
||||
|
|
|
|||
|
|
@ -8,90 +8,68 @@
|
|||
|
||||
#include "function_impl_template.hpp"
|
||||
|
||||
#define MOCK_FORWARD(z, n, d) \
|
||||
std::forward< T##n >( t##n )
|
||||
#define MOCK_FORWARD(z, n, d) std::forward<T##n>(t##n)
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Signature > class function;
|
||||
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) ) >
|
||||
template<typename R BOOST_PP_ENUM_TRAILING_PARAMS(MOCK_NUM_ARGS, typename T)>
|
||||
class function<R(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
|
||||
{
|
||||
private:
|
||||
typedef function_impl<
|
||||
R ( BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T) )
|
||||
> impl_type;
|
||||
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_( std::make_shared< impl_type >() )
|
||||
{}
|
||||
function() : impl_(std::make_shared<impl_type>()) {}
|
||||
|
||||
bool verify() const
|
||||
bool verify() const { return impl_->verify(); }
|
||||
bool verify(const char* file, int line) const
|
||||
{
|
||||
error_type::pass(file, line);
|
||||
return impl_->verify();
|
||||
}
|
||||
bool verify( const char* file, int line ) const
|
||||
void reset() { impl_->reset(); }
|
||||
void reset(const char* file, int line)
|
||||
{
|
||||
error_type::pass( file, line );
|
||||
return impl_->verify();
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
impl_->reset();
|
||||
}
|
||||
void reset( const char* file, int line )
|
||||
{
|
||||
error_type::pass( file, line );
|
||||
error_type::pass(file, line);
|
||||
impl_->reset();
|
||||
}
|
||||
|
||||
expectation_type expect( const char* file, int line )
|
||||
expectation_type expect(const char* file, int line)
|
||||
{
|
||||
error_type::pass( file, line );
|
||||
return impl_->expect( file, line );
|
||||
error_type::pass(file, line);
|
||||
return impl_->expect(file, line);
|
||||
}
|
||||
expectation_type expect()
|
||||
expectation_type expect() { return impl_->expect(); }
|
||||
|
||||
R operator()(BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t)) const
|
||||
{
|
||||
return impl_->expect();
|
||||
return (*impl_)(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _));
|
||||
}
|
||||
|
||||
R operator()(
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(MOCK_NUM_ARGS, T, t) ) const
|
||||
{
|
||||
return (*impl_)( BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_FORWARD, _) );
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& s, const function& f) { return s << *f.impl_; }
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const function& f )
|
||||
function& operator()(context& c, boost::unit_test::const_string instance)
|
||||
{
|
||||
return s << *f.impl_;
|
||||
}
|
||||
|
||||
function& operator()( context& c,
|
||||
boost::unit_test::const_string instance )
|
||||
{
|
||||
impl_->add( c, impl_.get(), instance, boost::none, "" );
|
||||
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
|
||||
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 );
|
||||
impl_->add(c, p, instance, type, name);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr< impl_type > impl_;
|
||||
std::shared_ptr<impl_type> impl_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#undef MOCK_FORWARD
|
||||
|
|
|
|||
|
|
@ -14,39 +14,32 @@
|
|||
#include "mutex.hpp"
|
||||
#include "singleton.hpp"
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class functor_mutex_t :
|
||||
public singleton< functor_mutex_t >,
|
||||
public mutex
|
||||
namespace mock { namespace detail {
|
||||
class functor_mutex_t : public singleton<functor_mutex_t>, public mutex
|
||||
{
|
||||
MOCK_SINGLETON_CONS( functor_mutex_t );
|
||||
MOCK_SINGLETON_CONS(functor_mutex_t);
|
||||
};
|
||||
MOCK_SINGLETON_INST( functor_mutex )
|
||||
MOCK_SINGLETON_INST(functor_mutex)
|
||||
|
||||
template< typename Signature >
|
||||
struct functor : function< Signature >
|
||||
template<typename Signature>
|
||||
struct functor : function<Signature>
|
||||
{
|
||||
functor()
|
||||
{
|
||||
scoped_lock _( functor_mutex );
|
||||
scoped_lock _(functor_mutex);
|
||||
static functor* f = 0;
|
||||
if( f )
|
||||
if(f)
|
||||
{
|
||||
*this = *f;
|
||||
f = 0;
|
||||
functor_mutex.unlock();
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
functor_mutex.lock();
|
||||
f = this;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_FUNCTOR_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -11,48 +11,39 @@
|
|||
|
||||
#include "../config.hpp"
|
||||
#include "verifiable.hpp"
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
class group
|
||||
{
|
||||
public:
|
||||
void add( verifiable& v )
|
||||
void add(verifiable& v) { verifiables_.push_back(&v); }
|
||||
void remove(verifiable& v)
|
||||
{
|
||||
verifiables_.push_back( &v );
|
||||
}
|
||||
void remove( verifiable& v )
|
||||
{
|
||||
verifiables_.erase(
|
||||
std::remove( verifiables_.begin(), verifiables_.end(), &v ),
|
||||
verifiables_.end() );
|
||||
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() )
|
||||
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() )
|
||||
for(auto* verifiable : verifiables)
|
||||
if(std::find(verifiables_.begin(), verifiables_.end(), verifiable) != verifiables_.end())
|
||||
verifiable->reset();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector< verifiable* > verifiables_;
|
||||
std::vector<verifiable*> verifiables_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_GROUP_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,14 +10,11 @@
|
|||
#define MOCK_INVOCATION_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include <stdexcept>
|
||||
#include <ostream>
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
class invocation
|
||||
{
|
||||
public:
|
||||
|
|
@ -32,66 +29,51 @@ namespace detail
|
|||
|
||||
virtual bool exhausted() const = 0;
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const invocation& i )
|
||||
{
|
||||
return i.serialize( s );
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& s, const invocation& i) { return i.serialize(s); }
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const = 0;
|
||||
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 )
|
||||
between(std::size_t min, std::size_t max) : min_(min), max_(max), count_(0)
|
||||
{
|
||||
if( min > max )
|
||||
throw std::invalid_argument( "'min' > 'max'" );
|
||||
if(min > max)
|
||||
throw std::invalid_argument("'min' > 'max'");
|
||||
}
|
||||
|
||||
virtual bool invoke()
|
||||
{
|
||||
if( count_ == max_ )
|
||||
if(count_ == max_)
|
||||
return false;
|
||||
++count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool exhausted() const
|
||||
{
|
||||
return count_ >= max_;
|
||||
}
|
||||
virtual bool exhausted() const { return count_ >= max_; }
|
||||
|
||||
virtual bool verify() const
|
||||
{
|
||||
return min_ <= count_ && 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
|
||||
virtual std::ostream& serialize(std::ostream& s) const
|
||||
{
|
||||
return s << "between( " << count_
|
||||
<< "/[" << min_ << ',' << max_ << "] )";
|
||||
return s << "between( " << count_ << "/[" << min_ << ',' << max_ << "] )";
|
||||
}
|
||||
};
|
||||
|
||||
class exactly : public between
|
||||
{
|
||||
public:
|
||||
explicit exactly( std::size_t count )
|
||||
: between( count, count )
|
||||
{}
|
||||
explicit exactly(std::size_t count) : between(count, count) {}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
virtual std::ostream& serialize(std::ostream& s) const
|
||||
{
|
||||
return s << "exactly( " << count_ << '/' << max_ << " )";
|
||||
}
|
||||
|
|
@ -100,40 +82,28 @@ namespace detail
|
|||
class never : public exactly
|
||||
{
|
||||
public:
|
||||
never()
|
||||
: exactly( 0 )
|
||||
{}
|
||||
never() : exactly(0) {}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "never()";
|
||||
}
|
||||
virtual std::ostream& serialize(std::ostream& s) const { return s << "never()"; }
|
||||
};
|
||||
|
||||
class once : public exactly
|
||||
{
|
||||
public:
|
||||
once()
|
||||
: exactly( 1 )
|
||||
{}
|
||||
once() : exactly(1) {}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "once()";
|
||||
}
|
||||
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)() )
|
||||
{}
|
||||
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
|
||||
virtual std::ostream& serialize(std::ostream& s) const
|
||||
{
|
||||
return s << "at_least( " << count_ << '/' << min_ << " )";
|
||||
}
|
||||
|
|
@ -142,12 +112,10 @@ namespace detail
|
|||
class at_most : public between
|
||||
{
|
||||
public:
|
||||
explicit at_most( std::size_t max )
|
||||
: between( 0, max )
|
||||
{}
|
||||
explicit at_most(std::size_t max) : between(0, max) {}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
virtual std::ostream& serialize(std::ostream& s) const
|
||||
{
|
||||
return s << "at_most( " << count_ << '/' << max_ << " )";
|
||||
}
|
||||
|
|
@ -156,17 +124,11 @@ namespace detail
|
|||
class unlimited : public at_least
|
||||
{
|
||||
public:
|
||||
unlimited()
|
||||
: at_least( 0 )
|
||||
{}
|
||||
unlimited() : at_least(0) {}
|
||||
|
||||
private:
|
||||
virtual std::ostream& serialize( std::ostream& s ) const
|
||||
{
|
||||
return s << "unlimited()";
|
||||
}
|
||||
virtual std::ostream& serialize(std::ostream& s) const { return s << "unlimited()"; }
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_INVOCATION_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -13,18 +13,14 @@
|
|||
#include "void_t.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
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 >
|
||||
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
|
||||
template<typename F, typename Arg>
|
||||
struct is_functor<F, Arg, void_t<decltype(std::declval<F>()(std::declval<Arg>()))>> : std::true_type
|
||||
{};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_IS_FUNCTOR_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -6,18 +6,14 @@
|
|||
// (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
|
||||
#define MOCK_REF_ARG(z, n, d) typename ref_arg<T##n>::type
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename Signature > class matcher_base;
|
||||
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) ) >
|
||||
template<BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, typename T)>
|
||||
class matcher_base<void(BOOST_PP_ENUM_PARAMS(MOCK_NUM_ARGS, T))>
|
||||
{
|
||||
public:
|
||||
matcher_base() = default;
|
||||
|
|
@ -25,19 +21,17 @@ namespace detail
|
|||
matcher_base& operator=(const matcher_base&) = delete;
|
||||
virtual ~matcher_base() = default;
|
||||
|
||||
virtual bool operator()(
|
||||
BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _) ) = 0;
|
||||
virtual bool operator()(BOOST_PP_ENUM(MOCK_NUM_ARGS, MOCK_REF_ARG, _)) = 0;
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& s, const matcher_base& m )
|
||||
friend std::ostream& operator<<(std::ostream& s, const matcher_base& m)
|
||||
{
|
||||
m.serialize( s );
|
||||
m.serialize(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void serialize( std::ostream& ) const = 0;
|
||||
virtual void serialize(std::ostream&) const = 0;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#undef MOCK_REF_ARG
|
||||
|
|
|
|||
|
|
@ -11,17 +11,9 @@
|
|||
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< typename T >
|
||||
using ref_arg = std::conditional<
|
||||
std::is_reference< T >::value,
|
||||
T,
|
||||
std::add_rvalue_reference_t< T >
|
||||
>;
|
||||
}
|
||||
}
|
||||
namespace mock { namespace detail {
|
||||
template<typename T>
|
||||
using ref_arg = std::conditional<std::is_reference<T>::value, T, std::add_rvalue_reference_t<T>>;
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_MOVE_HELPER_HPP_INCLUDED
|
||||
#endif // MOCK_MOVE_HELPER_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -15,65 +15,52 @@
|
|||
|
||||
#ifdef MOCK_THREAD_SAFE
|
||||
|
||||
#ifdef MOCK_HDR_MUTEX
|
||||
#include <mutex>
|
||||
#else
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <boost/thread/lock_guard.hpp>
|
||||
#endif
|
||||
# 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
|
||||
namespace mock { namespace detail {
|
||||
# ifdef MOCK_HDR_MUTEX
|
||||
typedef std::recursive_mutex mutex;
|
||||
typedef std::lock_guard< mutex > scoped_lock;
|
||||
#else
|
||||
typedef std::lock_guard<mutex> scoped_lock;
|
||||
# else
|
||||
typedef boost::recursive_mutex mutex;
|
||||
typedef boost::lock_guard< mutex > scoped_lock;
|
||||
#endif
|
||||
typedef boost::lock_guard<mutex> scoped_lock;
|
||||
# endif
|
||||
|
||||
struct lock
|
||||
{
|
||||
public:
|
||||
lock( const std::shared_ptr< mutex >& m )
|
||||
: m_( m )
|
||||
{
|
||||
m_->lock();
|
||||
}
|
||||
lock(const std::shared_ptr<mutex>& m) : m_(m) { m_->lock(); }
|
||||
~lock()
|
||||
{
|
||||
if( m_ )
|
||||
if(m_)
|
||||
m_->unlock();
|
||||
}
|
||||
lock( const lock& ) = delete;
|
||||
lock( lock&& x ) = default;
|
||||
lock& operator=( const lock& ) = delete;
|
||||
lock& operator=( lock&& x ) = default;
|
||||
lock(const lock&) = delete;
|
||||
lock(lock&& x) = default;
|
||||
lock& operator=(const lock&) = delete;
|
||||
lock& operator=(lock&& x) = default;
|
||||
|
||||
private:
|
||||
std::shared_ptr< mutex > m_;
|
||||
std::shared_ptr<mutex> m_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#else // MOCK_THREAD_SAFE
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
struct mutex
|
||||
{
|
||||
mutex() = default;
|
||||
mutex(const mutex&) = delete;
|
||||
mutex& operator=(const mutex&) = delete;
|
||||
|
||||
void lock()
|
||||
{}
|
||||
void unlock()
|
||||
{}
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
};
|
||||
// Dummy lock classes.
|
||||
// Constructor + Destructor make it RAII classes for compilers and avoid unused variable warnings
|
||||
|
|
@ -82,70 +69,66 @@ namespace detail
|
|||
scoped_lock(const scoped_lock&) = delete;
|
||||
scoped_lock& operator=(const scoped_lock&) = delete;
|
||||
|
||||
scoped_lock( mutex& ) {}
|
||||
scoped_lock(mutex&) {}
|
||||
~scoped_lock() {}
|
||||
};
|
||||
class lock
|
||||
{
|
||||
public:
|
||||
lock( const std::shared_ptr< mutex >& ) {}
|
||||
lock(const std::shared_ptr<mutex>&) {}
|
||||
~lock() {}
|
||||
lock(const lock&) = delete;
|
||||
lock( lock&& ) = default;
|
||||
lock& operator=( const lock& ) = delete;
|
||||
lock& operator=( lock&& ) = default;
|
||||
lock(lock&&) = default;
|
||||
lock& operator=(const lock&) = delete;
|
||||
lock& operator=(lock&&) = default;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_THREAD_SAFE
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class error_mutex_t : public singleton< error_mutex_t >,
|
||||
public mutex
|
||||
namespace mock { namespace detail {
|
||||
class error_mutex_t : public singleton<error_mutex_t>, public mutex
|
||||
{
|
||||
MOCK_SINGLETON_CONS( error_mutex_t );
|
||||
MOCK_SINGLETON_CONS(error_mutex_t);
|
||||
};
|
||||
MOCK_SINGLETON_INST( error_mutex )
|
||||
MOCK_SINGLETON_INST(error_mutex)
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable: 4702 )
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4702)
|
||||
#endif
|
||||
template< typename Result, typename Error >
|
||||
template<typename Result, typename Error>
|
||||
struct safe_error
|
||||
{
|
||||
static Result abort()
|
||||
{
|
||||
scoped_lock _( error_mutex );
|
||||
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 )
|
||||
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 );
|
||||
scoped_lock _(error_mutex);
|
||||
Error::fail(message, context, file, line);
|
||||
}
|
||||
template< typename Context >
|
||||
static void call( const Context& context, const char* file, int line )
|
||||
template<typename Context>
|
||||
static void call(const Context& context, const char* file, int line)
|
||||
{
|
||||
scoped_lock _( error_mutex );
|
||||
Error::call( context, file, line );
|
||||
scoped_lock _(error_mutex);
|
||||
Error::call(context, file, line);
|
||||
}
|
||||
static void pass( const char* file, int line )
|
||||
static void pass(const char* file, int line)
|
||||
{
|
||||
scoped_lock _( error_mutex );
|
||||
Error::pass( file, line );
|
||||
scoped_lock _(error_mutex);
|
||||
Error::pass(file, line);
|
||||
}
|
||||
};
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning( pop )
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_MUTEX_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,56 +10,51 @@
|
|||
#define MOCK_OBJECT_IMPL_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "root.hpp"
|
||||
#include "parent.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include "context.hpp"
|
||||
#include "child.hpp"
|
||||
#include "context.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.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 >
|
||||
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 >() )
|
||||
{}
|
||||
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 )
|
||||
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 );
|
||||
lock _(mutex_);
|
||||
if(children_.empty())
|
||||
detail::root.add(*this);
|
||||
children_[&v].update(parent_, instance, type, name);
|
||||
}
|
||||
virtual void add( verifiable& v )
|
||||
virtual void add(verifiable& v)
|
||||
{
|
||||
lock _( mutex_ );
|
||||
group_.add( v );
|
||||
lock _(mutex_);
|
||||
group_.add(v);
|
||||
}
|
||||
virtual void remove( verifiable& v )
|
||||
virtual void remove(verifiable& v)
|
||||
{
|
||||
lock _( mutex_ );
|
||||
group_.remove( v );
|
||||
children_.erase( &v );
|
||||
if( children_.empty() )
|
||||
detail::root.remove( *this );
|
||||
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
|
||||
virtual void serialize(std::ostream& s, const verifiable& v) const
|
||||
{
|
||||
lock _( mutex_ );
|
||||
const auto it = children_.find( &v );
|
||||
if( it != children_.end() )
|
||||
lock _(mutex_);
|
||||
const auto it = children_.find(&v);
|
||||
if(it != children_.end())
|
||||
s << it->second;
|
||||
else
|
||||
s << "?";
|
||||
|
|
@ -67,23 +62,22 @@ namespace detail
|
|||
|
||||
virtual bool verify() const
|
||||
{
|
||||
lock _( mutex_ );
|
||||
lock _(mutex_);
|
||||
return group_.verify();
|
||||
}
|
||||
virtual void reset()
|
||||
{
|
||||
lock _( mutex_ );
|
||||
std::shared_ptr< object_impl > guard = shared_from_this();
|
||||
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_;
|
||||
std::map<const verifiable*, child> children_;
|
||||
const std::shared_ptr<mutex> mutex_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_OBJECT_IMPL_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -11,58 +11,55 @@
|
|||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template< class... >
|
||||
namespace mock { namespace detail {
|
||||
template<class...>
|
||||
struct tuple;
|
||||
|
||||
template< std::size_t I, class T >
|
||||
template<std::size_t I, class T>
|
||||
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<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 >
|
||||
|
||||
template<class H, class... T>
|
||||
struct tuple_element<0, tuple<H, T...>>
|
||||
{
|
||||
using type = H;
|
||||
using type = H;
|
||||
};
|
||||
|
||||
template< typename Signature >
|
||||
template<typename Signature>
|
||||
struct result_type;
|
||||
|
||||
template< typename R, typename... Args >
|
||||
struct result_type< R(Args...) >
|
||||
template<typename R, typename... Args>
|
||||
struct result_type<R(Args...)>
|
||||
{
|
||||
using type = R;
|
||||
};
|
||||
|
||||
template< typename Signature >
|
||||
template<typename Signature>
|
||||
struct function_arity;
|
||||
|
||||
template< typename R, typename... Args >
|
||||
struct function_arity< R(Args...) >
|
||||
template<typename R, typename... Args>
|
||||
struct function_arity<R(Args...)>
|
||||
{
|
||||
static constexpr size_t value = sizeof...(Args);
|
||||
};
|
||||
|
||||
template< typename Signature >
|
||||
template<typename Signature>
|
||||
struct parameter_types;
|
||||
|
||||
template< typename R, typename... Args >
|
||||
struct parameter_types< R(Args...) >
|
||||
template<typename R, typename... Args>
|
||||
struct parameter_types<R(Args...)>
|
||||
{
|
||||
using type = tuple<Args...>;
|
||||
};
|
||||
|
||||
template< typename Signature, int n >
|
||||
template<typename Signature, int n>
|
||||
struct parameter
|
||||
{
|
||||
static_assert(n < function_arity<Signature>::value, "Function signature has not that many parameters");
|
||||
using type = typename tuple_element< n, typename parameter_types<Signature>::type >::type;
|
||||
using type = typename tuple_element<n, typename parameter_types<Signature>::type>::type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -74,7 +71,6 @@ namespace detail
|
|||
};
|
||||
template<typename T>
|
||||
using parameter_type_t = typename parameter_type<T>::type;
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_PARAMETER_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -11,35 +11,30 @@
|
|||
|
||||
#include "../config.hpp"
|
||||
#include "type_name.hpp"
|
||||
#include <boost/test/utils/basic_cstring/io.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/test/utils/basic_cstring/io.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
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 )
|
||||
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 )
|
||||
friend std::ostream& operator<<(std::ostream& s, const parent& p)
|
||||
{
|
||||
s << p.instance_;
|
||||
if( p.type_ )
|
||||
if(p.type_)
|
||||
s << *p.type_ << "::";
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::unit_test::const_string instance_;
|
||||
boost::optional< type_name > type_;
|
||||
boost::optional<type_name> type_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_PARENT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,110 +10,96 @@
|
|||
#define MOCK_ROOT_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "parent.hpp"
|
||||
#include "group.hpp"
|
||||
#include "context.hpp"
|
||||
#include "child.hpp"
|
||||
#include "context.hpp"
|
||||
#include "group.hpp"
|
||||
#include "mutex.hpp"
|
||||
#include "parent.hpp"
|
||||
#include "singleton.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
#include <ostream>
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
class root_t : public singleton< root_t >, public context
|
||||
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 )
|
||||
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 );
|
||||
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 )
|
||||
virtual void add(verifiable& v)
|
||||
{
|
||||
scoped_lock _( mutex_ );
|
||||
group_.add( v );
|
||||
scoped_lock _(mutex_);
|
||||
group_.add(v);
|
||||
}
|
||||
|
||||
virtual void remove( verifiable& v )
|
||||
virtual void remove(verifiable& v)
|
||||
{
|
||||
scoped_lock _( mutex_ );
|
||||
group_.remove( v );
|
||||
children_.erase( &v );
|
||||
scoped_lock _(mutex_);
|
||||
group_.remove(v);
|
||||
children_.erase(&v);
|
||||
}
|
||||
|
||||
bool verify() const
|
||||
{
|
||||
scoped_lock _( mutex_ );
|
||||
scoped_lock _(mutex_);
|
||||
return group_.verify();
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
scoped_lock _( mutex_ );
|
||||
scoped_lock _(mutex_);
|
||||
group_.reset();
|
||||
}
|
||||
|
||||
virtual void serialize( std::ostream& s, const verifiable& v ) const
|
||||
virtual void serialize(std::ostream& s, const verifiable& v) const
|
||||
{
|
||||
scoped_lock _( mutex_ );
|
||||
const auto it = children_.find( &v );
|
||||
if( it != children_.end() )
|
||||
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;
|
||||
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 )
|
||||
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_ )
|
||||
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_ );
|
||||
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 )
|
||||
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_;
|
||||
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& );
|
||||
counter_child& operator=(const counter_child&);
|
||||
|
||||
parents_t* parents_;
|
||||
parents_t::iterator it_;
|
||||
|
|
@ -121,14 +107,13 @@ namespace detail
|
|||
};
|
||||
|
||||
parents_t parents_;
|
||||
std::map< const verifiable*, counter_child > children_;
|
||||
std::map<const verifiable*, counter_child> children_;
|
||||
group group_;
|
||||
mutable mutex mutex_;
|
||||
|
||||
MOCK_SINGLETON_CONS( root_t );
|
||||
MOCK_SINGLETON_CONS(root_t);
|
||||
};
|
||||
MOCK_SINGLETON_INST( root )
|
||||
}
|
||||
} // mock
|
||||
MOCK_SINGLETON_INST(root)
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_ROOT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -15,49 +15,41 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
class sequence_impl
|
||||
{
|
||||
public:
|
||||
sequence_impl()
|
||||
: mutex_( std::make_shared< mutex >() )
|
||||
{}
|
||||
sequence_impl() : mutex_(std::make_shared<mutex>()) {}
|
||||
|
||||
void add( void* e )
|
||||
void add(void* e)
|
||||
{
|
||||
lock _( mutex_ );
|
||||
elements_.push_back( e );
|
||||
lock _(mutex_);
|
||||
elements_.push_back(e);
|
||||
}
|
||||
void remove( void* e )
|
||||
void remove(void* e)
|
||||
{
|
||||
lock _( mutex_ );
|
||||
elements_.erase( std::remove( elements_.begin(),
|
||||
elements_.end(), e ), elements_.end() );
|
||||
lock _(mutex_);
|
||||
elements_.erase(std::remove(elements_.begin(), elements_.end(), e), elements_.end());
|
||||
}
|
||||
|
||||
bool is_valid( const void* e ) const
|
||||
bool is_valid(const void* e) const
|
||||
{
|
||||
lock _( mutex_ );
|
||||
return std::find( elements_.begin(), elements_.end(), e )
|
||||
!= elements_.end();
|
||||
lock _(mutex_);
|
||||
return std::find(elements_.begin(), elements_.end(), e) != elements_.end();
|
||||
}
|
||||
|
||||
void invalidate( const void* e )
|
||||
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 );
|
||||
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_;
|
||||
std::vector<void*> elements_;
|
||||
const std::shared_ptr<mutex> mutex_;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_SEQUENCE_IMPL_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -12,22 +12,23 @@
|
|||
#include "../config.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
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(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, ) \
|
||||
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &) \
|
||||
MOCK_STRIP_FUNCTION_QUALIFIERS(cv, &&)
|
||||
|
||||
template<typename>
|
||||
|
|
@ -40,20 +41,20 @@ namespace detail
|
|||
#undef MOCK_STRIP_FUNCTION_QUALIFIERS
|
||||
#undef MOCK_STRIP_FUNCTION_QUALIFIERS_REF
|
||||
|
||||
template< typename M >
|
||||
template<typename M>
|
||||
struct signature;
|
||||
|
||||
template< typename R, typename... Args>
|
||||
struct signature< R(Args...) >
|
||||
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 >
|
||||
template<typename Sig, typename C>
|
||||
struct signature<Sig(C::*)> : signature<typename strip_function_qualifiers<Sig>::type>
|
||||
{};
|
||||
|
||||
template< typename T >
|
||||
template<typename T>
|
||||
struct base
|
||||
{
|
||||
typedef T base_type;
|
||||
|
|
@ -62,16 +63,12 @@ namespace detail
|
|||
// 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& );
|
||||
}
|
||||
} // mock
|
||||
template<typename T>
|
||||
T& ambiguous_method_requires_to_specify_signature(const T&);
|
||||
}} // namespace mock::detail
|
||||
|
||||
#define MOCK_SIGNATURE(M) \
|
||||
mock::detail::signature< \
|
||||
std::remove_cv_t< std::remove_reference_t < decltype( \
|
||||
mock::detail::ambiguous_method_requires_to_specify_signature( &base_type::M ) \
|
||||
) > > \
|
||||
>::type
|
||||
#define MOCK_SIGNATURE(M) \
|
||||
mock::detail::signature<std::remove_cv_t<std::remove_reference_t<decltype( \
|
||||
mock::detail::ambiguous_method_requires_to_specify_signature(&base_type::M))>>>::type
|
||||
|
||||
#endif // MOCK_SIGNATURE_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -11,36 +11,34 @@
|
|||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace mock {
|
||||
namespace detail {
|
||||
namespace mock { namespace detail {
|
||||
|
||||
template< typename Derived >
|
||||
class singleton {
|
||||
public:
|
||||
static Derived& instance()
|
||||
template<typename Derived>
|
||||
class singleton
|
||||
{
|
||||
static Derived the_inst;
|
||||
return the_inst;
|
||||
}
|
||||
public:
|
||||
static Derived& instance()
|
||||
{
|
||||
static Derived the_inst;
|
||||
return the_inst;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(singleton(singleton const&))
|
||||
BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
|
||||
singleton(singleton const&) = delete;
|
||||
singleton& operator=(singleton const&) = delete;
|
||||
|
||||
protected:
|
||||
BOOST_DEFAULTED_FUNCTION(singleton(), {})
|
||||
BOOST_DEFAULTED_FUNCTION(~singleton(), {})
|
||||
};
|
||||
protected:
|
||||
singleton() = default;
|
||||
~singleton() = default;
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // mock
|
||||
}} // 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_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();
|
||||
#define MOCK_SINGLETON_INST(inst) static BOOST_JOIN(inst, _t)& inst = BOOST_JOIN(inst, _t)::instance();
|
||||
|
||||
#endif // MOCK_SINGLETON_HPP
|
||||
|
|
|
|||
|
|
@ -10,37 +10,33 @@
|
|||
#define MOCK_TYPE_NAME_HPP_INCLUDED
|
||||
|
||||
#include "../config.hpp"
|
||||
#include <boost/test/utils/basic_cstring/io.hpp>
|
||||
#include <boost/algorithm/string/replace.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 <stdexcept>
|
||||
#include <memory>
|
||||
#include <typeinfo>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
#ifdef __GNUC__
|
||||
#include <cxxabi.h>
|
||||
#include <cstdlib>
|
||||
# include <cstdlib>
|
||||
# include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
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 )
|
||||
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_ );
|
||||
t.serialize(s, *t.info_);
|
||||
return s;
|
||||
}
|
||||
|
||||
private:
|
||||
static void serialize( std::ostream& s, const std::type_info& info )
|
||||
static void serialize(std::ostream& s, const std::type_info& info)
|
||||
{
|
||||
const char* name = info.name();
|
||||
#ifdef __GNUC__
|
||||
|
|
@ -49,60 +45,59 @@ namespace detail
|
|||
{
|
||||
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 )
|
||||
serialize( s, demangled.get() );
|
||||
std::unique_ptr<const char, Deleter> demangled(abi::__cxa_demangle(name, 0, 0, &status));
|
||||
if(!status && demangled)
|
||||
serialize(s, demangled.get());
|
||||
else
|
||||
#endif
|
||||
serialize( s, name );
|
||||
serialize(s, name);
|
||||
}
|
||||
|
||||
typedef std::string::size_type size_type;
|
||||
|
||||
static void serialize( std::ostream& s, std::string name )
|
||||
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 )
|
||||
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 ) );
|
||||
list(s, name.substr(tpl + 1, name.rfind('>') - tpl - 1));
|
||||
s << '>';
|
||||
}
|
||||
static void list( std::ostream& s, const std::string& name )
|
||||
static void list(std::ostream& s, const std::string& name)
|
||||
{
|
||||
const size_type comma = rfind( name, ',' );
|
||||
if( comma != std::string::npos )
|
||||
const size_type comma = rfind(name, ',');
|
||||
if(comma != std::string::npos)
|
||||
{
|
||||
list( s, name.substr( 0, comma ) );
|
||||
list(s, name.substr(0, comma));
|
||||
s << ", ";
|
||||
}
|
||||
serialize( s, name.substr( comma + 1 ) );
|
||||
serialize(s, name.substr(comma + 1));
|
||||
}
|
||||
static std::string clean( std::string name )
|
||||
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, "* ", "*" );
|
||||
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 )
|
||||
static size_type rfind(const std::string& name, char c)
|
||||
{
|
||||
size_type count = 0;
|
||||
for( size_type i = name.size() - 1; i > 0; --i )
|
||||
for(size_type i = name.size() - 1; i > 0; --i)
|
||||
{
|
||||
if( name[ i ] == '>' )
|
||||
if(name[i] == '>')
|
||||
++count;
|
||||
else if( name[ i ] == '<' )
|
||||
else if(name[i] == '<')
|
||||
--count;
|
||||
if( name[ i ] == c && count == 0 )
|
||||
if(name[i] == c && count == 0)
|
||||
return i;
|
||||
}
|
||||
return std::string::npos;
|
||||
|
|
@ -110,17 +105,16 @@ namespace detail
|
|||
|
||||
const std::type_info* info_;
|
||||
};
|
||||
template< typename T >
|
||||
template<typename T>
|
||||
type_name make_type_name()
|
||||
{
|
||||
return type_name( typeid(T) );
|
||||
return type_name(typeid(T));
|
||||
}
|
||||
template< typename T >
|
||||
type_name make_type_name( const T& )
|
||||
template<typename T>
|
||||
type_name make_type_name(const T&)
|
||||
{
|
||||
return type_name( typeid(T) );
|
||||
return type_name(typeid(T));
|
||||
}
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_TYPE_NAME_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@
|
|||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
class verifiable
|
||||
{
|
||||
public:
|
||||
|
|
@ -27,7 +24,6 @@ namespace detail
|
|||
|
||||
virtual void reset() = 0;
|
||||
};
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_VERIFIABLE_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -9,10 +9,7 @@
|
|||
#ifndef MOCK_VOID_T_HPP_INCLUDED
|
||||
#define MOCK_VOID_T_HPP_INCLUDED
|
||||
|
||||
namespace mock
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
namespace mock { namespace detail {
|
||||
template<typename...>
|
||||
struct make_void
|
||||
{
|
||||
|
|
@ -21,7 +18,6 @@ namespace detail
|
|||
/// Standard helper to implement the detection idiom. Returns always void
|
||||
template<typename... Ts>
|
||||
using void_t = typename make_void<Ts...>::type;
|
||||
}
|
||||
} // mock
|
||||
}} // namespace mock::detail
|
||||
|
||||
#endif // MOCK_VOID_T_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -11,69 +11,59 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#ifdef MOCK_USE_BOOST_TEST
|
||||
#include "exception.hpp"
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/test/unit_test_suite.hpp>
|
||||
#include <boost/exception/enable_current_exception.hpp>
|
||||
# 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
|
||||
namespace mock {
|
||||
template<typename Result>
|
||||
struct error
|
||||
{
|
||||
template< typename Result >
|
||||
struct error
|
||||
static Result abort()
|
||||
{
|
||||
static Result abort()
|
||||
{
|
||||
boost::unit_test::framework::test_unit_aborted(
|
||||
boost::unit_test::framework::current_test_case() );
|
||||
throw boost::enable_current_exception( exception() );
|
||||
}
|
||||
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 ) );
|
||||
}
|
||||
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 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();
|
||||
}
|
||||
};
|
||||
} // mock
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,12 @@
|
|||
|
||||
#include "config.hpp"
|
||||
#ifdef MOCK_USE_BOOST_TEST
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
# include <boost/test/execution_monitor.hpp>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
struct exception : virtual boost::execution_aborted
|
||||
{};
|
||||
} // mock
|
||||
namespace mock {
|
||||
struct exception : virtual boost::execution_aborted
|
||||
{};
|
||||
} // namespace mock
|
||||
|
||||
#endif // MOCK_USE_BOOST_TEST
|
||||
|
||||
|
|
|
|||
|
|
@ -12,14 +12,13 @@
|
|||
#include "config.hpp"
|
||||
#include "detail/formatter.hpp"
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
template<typename T>
|
||||
detail::formatter<T> format(const T& t)
|
||||
{
|
||||
template< typename T >
|
||||
detail::formatter< T > format( const T& t )
|
||||
{
|
||||
return detail::formatter< T >( t );
|
||||
}
|
||||
return detail::formatter<T>(t);
|
||||
}
|
||||
|
||||
} // mock
|
||||
} // namespace mock
|
||||
|
||||
#endif // MOCK_FORMAT_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,190 +10,187 @@
|
|||
#define MOCK_LOG_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "stream.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 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 phoenix {
|
||||
template<typename T>
|
||||
struct actor;
|
||||
}
|
||||
namespace lambda
|
||||
{
|
||||
template< typename T > class lambda_functor;
|
||||
}
|
||||
namespace assign_detail
|
||||
{
|
||||
template< typename T > class generic_list;
|
||||
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 )
|
||||
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 );
|
||||
for(T it = begin; it != end; ++it)
|
||||
s << (it == begin ? "" : ",") << mock::format(*it);
|
||||
s << ')';
|
||||
}
|
||||
template<typename T>
|
||||
struct is_callable_impl: std::false_type
|
||||
struct is_callable_impl : std::false_type
|
||||
{};
|
||||
template<typename R, typename... Args>
|
||||
struct is_callable_impl<R(Args...)>: std::true_type
|
||||
struct is_callable_impl<R(Args...)> : std::true_type
|
||||
{};
|
||||
template<typename T>
|
||||
struct is_callable: is_callable_impl< std::remove_cv_t<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 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, 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 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 << '?';
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
} // mock
|
||||
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
|
||||
|
|
|
|||
|
|
@ -10,95 +10,71 @@
|
|||
#define MOCK_MATCHER_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "log.hpp"
|
||||
#include "constraints.hpp"
|
||||
#include "detail/is_functor.hpp"
|
||||
#include "detail/move_helper.hpp"
|
||||
#include "log.hpp"
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
template<typename Actual, typename Expected, typename Enable = void>
|
||||
class matcher
|
||||
{
|
||||
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)
|
||||
{
|
||||
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_;
|
||||
};
|
||||
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_); }
|
||||
|
||||
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_;
|
||||
};
|
||||
private:
|
||||
Expected expected_;
|
||||
};
|
||||
|
||||
template< typename Actual, typename Constraint >
|
||||
class matcher< Actual, mock::constraint< Constraint > >
|
||||
{
|
||||
public:
|
||||
explicit matcher( const constraint< Constraint >& c )
|
||||
: c_( c.c_ )
|
||||
{}
|
||||
bool operator()( typename detail::ref_arg< Actual >::type actual )
|
||||
{
|
||||
return c_( std::forward< typename detail::ref_arg< Actual >::type >( actual ) );
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
|
||||
{
|
||||
return s << mock::format( m.c_ );
|
||||
}
|
||||
private:
|
||||
Constraint c_;
|
||||
};
|
||||
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_); }
|
||||
|
||||
template< typename Actual, typename Functor >
|
||||
class matcher< Actual, Functor,
|
||||
std::enable_if_t<
|
||||
detail::is_functor< Functor, Actual >::value
|
||||
>
|
||||
>
|
||||
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()(typename detail::ref_arg<Actual>::type actual)
|
||||
{
|
||||
public:
|
||||
explicit matcher( const Functor& f )
|
||||
: c_( f )
|
||||
{}
|
||||
bool operator()( typename detail::ref_arg< Actual >::type actual )
|
||||
{
|
||||
return c_( std::forward< typename detail::ref_arg< Actual >::type >( actual ) );
|
||||
}
|
||||
friend std::ostream& operator<<( std::ostream& s, const matcher& m )
|
||||
{
|
||||
return s << mock::format( m.c_ );
|
||||
}
|
||||
private:
|
||||
Functor c_;
|
||||
};
|
||||
} // mock
|
||||
return c_(std::forward<typename detail::ref_arg<Actual>::type>(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()(typename detail::ref_arg<Actual>::type actual)
|
||||
{
|
||||
return c_(std::forward<typename detail::ref_arg<Actual>::type>(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
|
||||
|
|
|
|||
|
|
@ -9,168 +9,153 @@
|
|||
#ifndef MOCK_MOCK_HPP_INCLUDED
|
||||
#define MOCK_MOCK_HPP_INCLUDED
|
||||
|
||||
#include "cleanup.hpp"
|
||||
#include "config.hpp"
|
||||
#include "detail/function.hpp"
|
||||
#include "detail/functor.hpp"
|
||||
#include "detail/parameter.hpp"
|
||||
#include "detail/signature.hpp"
|
||||
#include "detail/type_name.hpp"
|
||||
#include "object.hpp"
|
||||
#include "reset.hpp"
|
||||
#include "verify.hpp"
|
||||
#include "cleanup.hpp"
|
||||
#include "detail/functor.hpp"
|
||||
#include "detail/function.hpp"
|
||||
#include "detail/type_name.hpp"
|
||||
#include "detail/signature.hpp"
|
||||
#include "detail/parameter.hpp"
|
||||
#include <boost/preprocessor/repetition/repeat.hpp>
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
|
||||
/// MOCK_CLASS( name )
|
||||
/// Define a class
|
||||
#define MOCK_CLASS(T) \
|
||||
struct T : mock::object
|
||||
#define MOCK_CLASS(T) struct T : mock::object
|
||||
|
||||
/// MOCK_PROTECT_FUNCTION_SIG( signature )
|
||||
/// Use this with MOCK_FUNCTION/MOCK_*_METHOD if the return type contains commas
|
||||
#define MOCK_PROTECT_FUNCTION_SIG(...) \
|
||||
mock::detail::parameter_type_t<void (__VA_ARGS__)>
|
||||
#define MOCK_PROTECT_FUNCTION_SIG(...) mock::detail::parameter_type_t<void(__VA_ARGS__)>
|
||||
|
||||
/// Internal compatibility macro if function signature is passed via BOOST_IDENTITY_TYPE
|
||||
/// TODO: Remove support for doing that and move remove_pointer_t to MOCK_PROTECT_FUNCTION_SIG
|
||||
#define MOCK_FUNCTION_TYPE(...) \
|
||||
std::remove_pointer_t< __VA_ARGS__ >
|
||||
#define MOCK_FUNCTION_TYPE(...) std::remove_pointer_t<__VA_ARGS__>
|
||||
|
||||
/// MOCK_BASE_CLASS( name, base )
|
||||
/// Define a class deriving from a base class
|
||||
#define MOCK_BASE_CLASS(T, ...) \
|
||||
struct T : __VA_ARGS__, mock::object, mock::detail::base< __VA_ARGS__ >
|
||||
#define MOCK_BASE_CLASS(T, ...) struct T : __VA_ARGS__, mock::object, mock::detail::base<__VA_ARGS__>
|
||||
|
||||
/// MOCK_FUNCTOR( name, signature )
|
||||
/// Define a callable variable/member
|
||||
#define MOCK_FUNCTOR(f, ...) \
|
||||
mock::detail::functor< MOCK_FUNCTION_TYPE(__VA_ARGS__) > f, f##_mock
|
||||
#define MOCK_FUNCTOR(f, ...) mock::detail::functor<MOCK_FUNCTION_TYPE(__VA_ARGS__)> f, f##_mock
|
||||
/// MOCK_FUNCTOR_TPL( name, signature )
|
||||
#define MOCK_FUNCTOR_TPL(f, ...) static_assert(false, "MOCK_FUNCTOR_TPL has been replaced by MOCK_FUNCTOR")
|
||||
|
||||
#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_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< MOCK_FUNCTION_TYPE(S) > t##_mock_; \
|
||||
mock::detail::function< MOCK_FUNCTION_TYPE(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_METHOD_HELPER(S, t) \
|
||||
mutable mock::detail::function<MOCK_FUNCTION_TYPE(S)> t##_mock_; \
|
||||
mock::detail::function<MOCK_FUNCTION_TYPE(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, tpn) \
|
||||
tpn mock::detail::parameter< MOCK_FUNCTION_TYPE(S)
|
||||
#define MOCK_DECL_PARAM(z, n, d) \
|
||||
BOOST_PP_COMMA_IF(n) d, n >::type p##n
|
||||
#define MOCK_DECL_PARAMS(n, S, tpn) \
|
||||
BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn))
|
||||
#define MOCK_PARAM(S, tpn) tpn mock::detail::parameter < MOCK_FUNCTION_TYPE(S)
|
||||
#define MOCK_DECL_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n > ::type p##n
|
||||
#define MOCK_DECL_PARAMS(n, S, tpn) BOOST_PP_REPEAT(n, MOCK_DECL_PARAM, MOCK_PARAM(S, tpn))
|
||||
#define MOCK_DECL(M, n, S, c, tpn) \
|
||||
tpn mock::detail::result_type< \
|
||||
MOCK_FUNCTION_TYPE(S) >::type M( \
|
||||
MOCK_DECL_PARAMS(n, S, tpn) ) c
|
||||
tpn mock::detail::result_type<MOCK_FUNCTION_TYPE(S)>::type M(MOCK_DECL_PARAMS(n, S, tpn)) c
|
||||
|
||||
#define MOCK_FORWARD_PARAM(z, n, d) \
|
||||
BOOST_PP_COMMA_IF(n) d, n >::type >( p##n )
|
||||
#define MOCK_FORWARD_PARAMS(n, S, tpn) \
|
||||
BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, \
|
||||
std::forward< MOCK_PARAM(S, tpn))
|
||||
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
|
||||
MOCK_DECL(M, n, S, c, tpn) \
|
||||
{ \
|
||||
static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE(S) >::value, "Arity mismatch" ); \
|
||||
return MOCK_ANONYMOUS_HELPER(t)( \
|
||||
MOCK_FORWARD_PARAMS(n, S, tpn) ); \
|
||||
#define MOCK_FORWARD_PARAM(z, n, d) BOOST_PP_COMMA_IF(n) d, n > ::type > (p##n)
|
||||
#define MOCK_FORWARD_PARAMS(n, S, tpn) BOOST_PP_REPEAT(n, MOCK_FORWARD_PARAM, std::forward < MOCK_PARAM(S, tpn))
|
||||
#define MOCK_METHOD_AUX(M, n, S, t, c, tpn) \
|
||||
MOCK_DECL(M, n, S, c, tpn) \
|
||||
{ \
|
||||
static_assert(n == mock::detail::function_arity<MOCK_FUNCTION_TYPE(S)>::value, "Arity mismatch"); \
|
||||
return MOCK_ANONYMOUS_HELPER(t)(MOCK_FORWARD_PARAMS(n, S, tpn)); \
|
||||
}
|
||||
|
||||
#define MOCK_METHOD_EXT(M, n, S, t) \
|
||||
MOCK_METHOD_AUX(M, n, S, t,,) \
|
||||
MOCK_METHOD_AUX(M, n, S, t, const,) \
|
||||
#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_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_AUX(M, n, S, t, , ) \
|
||||
MOCK_METHOD_HELPER(S, t)
|
||||
|
||||
#define MOCK_METHOD_EXT_TPL(M, n, S, t) \
|
||||
MOCK_METHOD_AUX(M, n, S, t,, typename) \
|
||||
#define MOCK_METHOD_EXT_TPL(M, n, S, t) \
|
||||
MOCK_METHOD_AUX(M, n, S, t, , typename) \
|
||||
MOCK_METHOD_AUX(M, n, S, t, const, typename) \
|
||||
MOCK_METHOD_HELPER(S, t)
|
||||
#define MOCK_CONST_METHOD_EXT_TPL(M, n, S, t) \
|
||||
#define MOCK_CONST_METHOD_EXT_TPL(M, n, S, t) \
|
||||
MOCK_METHOD_AUX(M, n, S, t, const, typename) \
|
||||
MOCK_METHOD_HELPER(S, t)
|
||||
#define MOCK_NON_CONST_METHOD_EXT_TPL(M, n, S, t) \
|
||||
MOCK_METHOD_AUX(M, n, S, t,, typename) \
|
||||
MOCK_METHOD_AUX(M, n, S, t, , typename) \
|
||||
MOCK_METHOD_HELPER(S, t)
|
||||
|
||||
/// MOCK_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
||||
/// generates both const and non-const operators
|
||||
#define MOCK_CONVERSION_OPERATOR(M, T, t) \
|
||||
#define MOCK_CONVERSION_OPERATOR(M, T, t) \
|
||||
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
|
||||
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
|
||||
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
|
||||
MOCK_METHOD_HELPER(T(), t)
|
||||
/// MOCK_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
||||
/// generates only a const operator
|
||||
#define MOCK_CONST_CONVERSION_OPERATOR(M, T, t) \
|
||||
#define MOCK_CONST_CONVERSION_OPERATOR(M, T, t) \
|
||||
M T() const { return MOCK_ANONYMOUS_HELPER(t)(); } \
|
||||
MOCK_METHOD_HELPER(T(), t)
|
||||
/// MOCK_NON_CONST_CONVERSION_OPERATOR( [calling convention] name, type, identifier )
|
||||
/// generates only a non-const operator
|
||||
#define MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t) \
|
||||
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
|
||||
M T() { return MOCK_ANONYMOUS_HELPER(t)(); } \
|
||||
MOCK_METHOD_HELPER(T(), t)
|
||||
|
||||
#define MOCK_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_CONVERSION_OPERATOR(M, T, t)
|
||||
#define MOCK_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_CONST_CONVERSION_OPERATOR(M, T, t)
|
||||
#define MOCK_NON_CONST_CONVERSION_OPERATOR_TPL(M, T, t) MOCK_NON_CONST_CONVERSION_OPERATOR(M, T, t)
|
||||
|
||||
#define MOCK_FUNCTION_HELPER(S, t, s, tpn) \
|
||||
s mock::detail::function< MOCK_FUNCTION_TYPE(S) >& t##_mock( \
|
||||
mock::detail::context& context, \
|
||||
boost::unit_test::const_string instance ) \
|
||||
{ \
|
||||
static mock::detail::function< MOCK_FUNCTION_TYPE(S) > f; \
|
||||
return f( context, instance ); \
|
||||
#define MOCK_FUNCTION_HELPER(S, t, s, tpn) \
|
||||
s mock::detail::function<MOCK_FUNCTION_TYPE(S)>& t##_mock(mock::detail::context& context, \
|
||||
boost::unit_test::const_string instance) \
|
||||
{ \
|
||||
static mock::detail::function<MOCK_FUNCTION_TYPE(S)> f; \
|
||||
return f(context, instance); \
|
||||
}
|
||||
|
||||
#define MOCK_CONSTRUCTOR_AUX(T, n, A, t, tpn) \
|
||||
T( MOCK_DECL_PARAMS(n, void A, tpn) ) \
|
||||
{ \
|
||||
MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, void A, tpn) ); \
|
||||
} \
|
||||
#define MOCK_CONSTRUCTOR_AUX(T, n, A, t, tpn) \
|
||||
T(MOCK_DECL_PARAMS(n, void A, tpn)) { MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, void A, tpn)); } \
|
||||
MOCK_FUNCTION_HELPER(void A, t, static, tpn)
|
||||
|
||||
/// 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, n, A, t) \
|
||||
MOCK_CONSTRUCTOR_AUX(T, n, A, t,)
|
||||
#define MOCK_CONSTRUCTOR(T, n, A, t) MOCK_CONSTRUCTOR_AUX(T, n, A, t, )
|
||||
/// MOCK_CONSTRUCTOR( [calling convention] name, arity, parameters, identifier )
|
||||
/// must be used if the signature uses a template parameter of the class
|
||||
/// As constructors do not have a return type, the usual signature gets restricted here to just the parameters.
|
||||
#define MOCK_CONSTRUCTOR_TPL(T, n, A, t) \
|
||||
MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
|
||||
#define MOCK_CONSTRUCTOR_TPL(T, n, A, t) MOCK_CONSTRUCTOR_AUX(T, n, A, t, typename)
|
||||
|
||||
/// MOCK_DESTRUCTOR( [calling convention] ~name, identifier )
|
||||
#define MOCK_DESTRUCTOR(T, t) \
|
||||
T() { try { MOCK_ANONYMOUS_HELPER(t)(); } catch( ... ) {} } \
|
||||
#define MOCK_DESTRUCTOR(T, t) \
|
||||
T() \
|
||||
{ \
|
||||
try \
|
||||
{ \
|
||||
MOCK_ANONYMOUS_HELPER(t)(); \
|
||||
} catch(...) \
|
||||
{} \
|
||||
} \
|
||||
MOCK_METHOD_HELPER(void(), t)
|
||||
|
||||
#define MOCK_FUNCTION_AUX(F, n, S, t, s, tpn) \
|
||||
MOCK_FUNCTION_HELPER(S, t, s, tpn) \
|
||||
s MOCK_DECL(F, n, S,,tpn) \
|
||||
{ \
|
||||
static_assert( n == mock::detail::function_arity< MOCK_FUNCTION_TYPE(S) >::value, "Arity mismatch" ); \
|
||||
return MOCK_HELPER(t)( MOCK_FORWARD_PARAMS(n, S, tpn) ); \
|
||||
#define MOCK_FUNCTION_AUX(F, n, S, t, s, tpn) \
|
||||
MOCK_FUNCTION_HELPER(S, t, s, tpn) \
|
||||
s MOCK_DECL(F, n, S, , tpn) \
|
||||
{ \
|
||||
static_assert(n == mock::detail::function_arity<MOCK_FUNCTION_TYPE(S)>::value, "Arity mismatch"); \
|
||||
return MOCK_HELPER(t)(MOCK_FORWARD_PARAMS(n, S, tpn)); \
|
||||
}
|
||||
|
||||
#define MOCK_VARIADIC_ELEM_0(e0, ...) e0
|
||||
|
|
@ -179,79 +164,64 @@
|
|||
|
||||
/// MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] )
|
||||
/// generates both const and non-const methods
|
||||
#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, ))
|
||||
#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
|
||||
#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, ))
|
||||
#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
|
||||
#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, ))
|
||||
|
||||
#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_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||
/// must be used if the signature uses a template parameter of the class
|
||||
/// generates both const and non-const methods
|
||||
#define MOCK_METHOD_TPL(M, n, ...) \
|
||||
MOCK_METHOD_EXT_TPL(M, n, \
|
||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
||||
MOCK_METHOD_EXT_TPL(M, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
||||
/// MOCK_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||
/// must be used if the signature uses a template parameter of the class
|
||||
/// generates only the const version of the method
|
||||
#define MOCK_CONST_METHOD_TPL(M, n, ...) \
|
||||
MOCK_CONST_METHOD_EXT_TPL(M, n, \
|
||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
||||
MOCK_CONST_METHOD_EXT_TPL(M, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
||||
/// MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||
/// must be used if the signature uses a template parameter of the class
|
||||
/// generates only the non-const version of the method
|
||||
#define MOCK_NON_CONST_METHOD_TPL(M, n, ...) \
|
||||
MOCK_NON_CONST_METHOD_EXT_TPL(M, n, \
|
||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
||||
MOCK_NON_CONST_METHOD_EXT_TPL(M, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, M, ))
|
||||
|
||||
/// MOCK_FUNCTION( [calling convention] name, arity, signature[, identifier] )
|
||||
/// if 'identifier' is omitted it will default to 'name'
|
||||
#define MOCK_FUNCTION(F, n, ...) \
|
||||
MOCK_FUNCTION_AUX(F, n, \
|
||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
|
||||
inline,)
|
||||
MOCK_FUNCTION_AUX(F, n, 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, n, ...) \
|
||||
MOCK_FUNCTION_AUX(F, n, \
|
||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
|
||||
static,)
|
||||
MOCK_FUNCTION_AUX(F, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static, )
|
||||
|
||||
/// MOCK_STATIC_METHOD_TPL( [calling convention] name, arity, signature[, identifier] )
|
||||
/// must be used if the signature uses a template parameter of the class
|
||||
/// if 'identifier' is omitted it will default to 'name'
|
||||
#define MOCK_STATIC_METHOD_TPL(F, n, ...) \
|
||||
MOCK_FUNCTION_AUX(F, n, \
|
||||
MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), \
|
||||
MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), \
|
||||
static, typename)
|
||||
MOCK_FUNCTION_AUX( \
|
||||
F, n, MOCK_VARIADIC_ELEM_0(__VA_ARGS__, ), MOCK_VARIADIC_ELEM_1(__VA_ARGS__, F, ), static, typename)
|
||||
|
||||
/// MOCK_EXPECT( identifier )
|
||||
#define MOCK_EXPECT(t) MOCK_HELPER(t).expect( __FILE__, __LINE__ )
|
||||
#define MOCK_EXPECT(t) MOCK_HELPER(t).expect(__FILE__, __LINE__)
|
||||
/// MOCK_RESET( identifier )
|
||||
#define MOCK_RESET(t) MOCK_HELPER(t).reset( __FILE__, __LINE__ )
|
||||
#define MOCK_RESET(t) MOCK_HELPER(t).reset(__FILE__, __LINE__)
|
||||
/// MOCK_VERIFY( identifier )
|
||||
#define MOCK_VERIFY(t) MOCK_HELPER(t).verify( __FILE__, __LINE__ )
|
||||
#define MOCK_VERIFY(t) MOCK_HELPER(t).verify(__FILE__, __LINE__)
|
||||
|
||||
#endif // MOCK_MOCK_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,61 +10,61 @@
|
|||
#define MOCK_OBJECT_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "detail/object_impl.hpp"
|
||||
#include "detail/root.hpp"
|
||||
#include "detail/type_name.hpp"
|
||||
#include "detail/object_impl.hpp"
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
{
|
||||
class object;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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,
|
||||
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 )
|
||||
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( *o.impl_, o.impl_.get(), instance, type, name );
|
||||
e.configure(detail::root, &t, instance, type, name);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
} // mock
|
||||
} // 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
|
||||
|
|
|
|||
|
|
@ -10,25 +10,24 @@
|
|||
#define MOCK_RESET_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "object.hpp"
|
||||
#include "detail/root.hpp"
|
||||
#include "detail/functor.hpp"
|
||||
#include "detail/root.hpp"
|
||||
#include "object.hpp"
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
inline void reset()
|
||||
{
|
||||
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();
|
||||
}
|
||||
} // mock
|
||||
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
|
||||
|
|
|
|||
|
|
@ -13,17 +13,14 @@
|
|||
#include "detail/sequence_impl.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
class sequence
|
||||
{
|
||||
class sequence
|
||||
{
|
||||
public:
|
||||
sequence()
|
||||
: impl_( std::make_shared< detail::sequence_impl >() )
|
||||
{}
|
||||
public:
|
||||
sequence() : impl_(std::make_shared<detail::sequence_impl>()) {}
|
||||
|
||||
std::shared_ptr< detail::sequence_impl > impl_;
|
||||
};
|
||||
} // mock
|
||||
std::shared_ptr<detail::sequence_impl> impl_;
|
||||
};
|
||||
} // namespace mock
|
||||
|
||||
#endif // MOCK_SEQUENCE_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -13,33 +13,24 @@
|
|||
#include <memory>
|
||||
#include <ostream>
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
struct stream
|
||||
{
|
||||
struct stream
|
||||
{
|
||||
explicit stream( std::ostream& s )
|
||||
: s_( &s )
|
||||
{}
|
||||
std::ostream* s_;
|
||||
};
|
||||
explicit stream(std::ostream& s) : s_(&s) {}
|
||||
std::ostream* s_;
|
||||
};
|
||||
|
||||
#ifdef MOCK_USE_CONVERSIONS
|
||||
|
||||
namespace detail
|
||||
{
|
||||
namespace conversion
|
||||
{
|
||||
namespace detail { namespace conversion {
|
||||
struct sink
|
||||
{
|
||||
template< typename T >
|
||||
sink( const T& )
|
||||
template<typename T>
|
||||
sink(const T&)
|
||||
{}
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<( std::ostream& s, const sink& )
|
||||
{
|
||||
return s << '?';
|
||||
}
|
||||
inline std::ostream& operator<<(std::ostream& s, const sink&) { return s << '?'; }
|
||||
|
||||
struct holder
|
||||
{
|
||||
|
|
@ -48,16 +39,14 @@ namespace conversion
|
|||
holder& operator=(const holder&) = delete;
|
||||
|
||||
virtual ~holder() = default;
|
||||
virtual void serialize( std::ostream& s ) const = 0;
|
||||
virtual void serialize(std::ostream& s) const = 0;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
template<typename T>
|
||||
struct holder_imp : holder
|
||||
{
|
||||
explicit holder_imp( const T& t )
|
||||
: t_( t )
|
||||
{}
|
||||
virtual void serialize( std::ostream& s ) const
|
||||
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
|
||||
|
|
@ -69,72 +58,57 @@ namespace conversion
|
|||
|
||||
struct any
|
||||
{
|
||||
template< typename T >
|
||||
any( const T& t ): h_( std::make_unique< holder_imp<T> >( t ) )
|
||||
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;
|
||||
}
|
||||
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& )
|
||||
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;
|
||||
}
|
||||
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 )
|
||||
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 )
|
||||
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 );
|
||||
}
|
||||
}
|
||||
} // mock
|
||||
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
|
||||
|
|
|
|||
|
|
@ -12,31 +12,30 @@
|
|||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
template<class T>
|
||||
struct unwrap_reference
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
template<class T>
|
||||
BOOST_FORCEINLINE unwrap_reference_t<T>& unwrap_ref(T& t) noexcept
|
||||
{
|
||||
return t;
|
||||
}
|
||||
} // namespace mock
|
||||
|
||||
#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
|
||||
#endif // MOCK_UNWRAP_REFERENCE_HPP_INCLUDED
|
||||
|
|
|
|||
|
|
@ -10,25 +10,24 @@
|
|||
#define MOCK_VERIFY_HPP_INCLUDED
|
||||
|
||||
#include "config.hpp"
|
||||
#include "object.hpp"
|
||||
#include "detail/root.hpp"
|
||||
#include "detail/functor.hpp"
|
||||
#include "detail/root.hpp"
|
||||
#include "object.hpp"
|
||||
|
||||
namespace mock
|
||||
namespace mock {
|
||||
inline bool verify()
|
||||
{
|
||||
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();
|
||||
}
|
||||
} // mock
|
||||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue