Browse Source

Trompeloeil update to latest version.

main
offa 5 years ago
parent
commit
83c4450e8e
1 changed files with 81 additions and 30 deletions
  1. +81
    -30
      test/trompeloeil/trompeloeil.hpp

+ 81
- 30
test/trompeloeil/trompeloeil.hpp View File

/* /*
* Trompeloeil C++ mocking framework * Trompeloeil C++ mocking framework
* *
* Copyright Björn Fahller 2014-2018
* Copyright Björn Fahller 2014-2019
* Copyright (C) 2017, 2018 Andrew Paxie * Copyright (C) 2017, 2018 Andrew Paxie
* *
* Use, modification and distribution is subject to the * Use, modification and distribution is subject to the


#endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */ #endif /* !(TROMPELOEIL_CPLUSPLUS == 201103L) */


static constexpr bool trompeloeil_movable_mock = false;

namespace trompeloeil namespace trompeloeil
{ {
template <typename T> template <typename T>
}; };


template <typename T, typename U> template <typename T, typename U>
using equality_comparison = decltype(std::declval<T>() == std::declval<U>());
using equality_comparison = decltype((std::declval<T>() == std::declval<U>())
? true
: false);


template <typename T, typename U> template <typename T, typename U>
using is_equal_comparable = is_detected<equality_comparison, T, U>; using is_equal_comparable = is_detected<equality_comparison, T, U>;
{ {
os << "{ "; os << "{ ";
const char* sep = ""; const char* sep = "";
for (auto& elem : t)
auto const end = std::end(t);
for (auto i = std::begin(t); i != end; ++i)
{ {
os << sep; os << sep;
::trompeloeil::print(os, elem);
::trompeloeil::print(os, *i);
sep = ", "; sep = ", ";
} }
os << " }"; os << " }";
return {std::move(pred), std::move(print), std::forward<T>(t)...}; return {std::move(pred), std::move(print), std::forward<T>(t)...};
} }



template < template <
typename T, typename T,
typename R = make_matcher_return<T, lambdas::any_predicate, lambdas::any_printer>> typename R = make_matcher_return<T, lambdas::any_predicate, lambdas::any_printer>>
inline inline
auto auto
any_matcher(char const* type_name)
any_matcher_impl(char const* type_name, std::false_type)
TROMPELOEIL_TRAILING_RETURN_TYPE(R) TROMPELOEIL_TRAILING_RETURN_TYPE(R)
{ {
return make_matcher<T>(lambdas::any_predicate(), lambdas::any_printer(type_name)); return make_matcher<T>(lambdas::any_predicate(), lambdas::any_printer(type_name));
} }


template <typename T>
wildcard
any_matcher_impl(char const*, std::true_type);

template <typename T>
inline
auto
any_matcher(char const* name)
TROMPELOEIL_TRAILING_RETURN_TYPE(decltype(any_matcher_impl<T>(name, std::is_array<T>{})))
{
static_assert(!std::is_array<T>::value,
"array parameter type decays to pointer type for ANY()"
" matcher. Please rephrase as pointer instead");
return any_matcher_impl<T>(name, std::is_array<T>{});
}
template < template <
typename T = wildcard, typename T = wildcard,
typename V, typename V,
} }
}; };


template <typename Sig>
template <bool movable, typename Sig>
struct expectations struct expectations
{ {
expectations() = default;
expectations(expectations&&) = default;
~expectations() {
active.decommission();
saturated.decommission();
}
call_matcher_list<Sig> active{};
call_matcher_list<Sig> saturated{};
};

template <typename Sig>
struct expectations<false, Sig>
{
expectations() = default;
expectations(expectations&&)
{
static_assert(std::is_same<Sig,void>::value,
"By default, mock objects are not movable. "
"To make a mock object movable, see: "
"https://github.com/rollbear/trompeloeil/blob/master/docs/reference.md#movable_mock");
}
~expectations() { ~expectations() {
active.decommission(); active.decommission();
saturated.decommission(); saturated.decommission();
} }
call_matcher_list<Sig> active;
call_matcher_list<Sig> saturated;
call_matcher_list<Sig> active{};
call_matcher_list<Sig> saturated{};
}; };


template <typename Sig, typename ... P> template <typename Sig, typename ... P>
return_of_t<Sig> mock_func(std::false_type, P&& ...); return_of_t<Sig> mock_func(std::false_type, P&& ...);




template <typename Sig, typename ... P>
template <bool movable, typename Sig, typename ... P>
return_of_t<Sig> return_of_t<Sig>
mock_func(std::true_type, mock_func(std::true_type,
expectations<Sig>& e,
expectations<movable, Sig>& e,
char const *func_name, char const *func_name,
char const *sig_name, char const *sig_name,
P&& ... p) P&& ... p)
using T::T; using T::T;
}; };


#if defined(TROMPELOEIL_USER_DEFINED_COMPILE_TIME_REPORTER)
extern template struct reporter<specialized>;
#endif // TROMPELOEIL_USER_DEFINED_COMPILE_TIME_REPORTER
} }


#define TROMPELOEIL_LINE_ID(name) \ #define TROMPELOEIL_LINE_ID(name) \
static_assert(TROMPELOEIL_LINE_ID(cardinality_match)::value, \ static_assert(TROMPELOEIL_LINE_ID(cardinality_match)::value, \
"Function signature does not have " #num " parameters"); \ "Function signature does not have " #num " parameters"); \
using TROMPELOEIL_LINE_ID(matcher_list_t) = ::trompeloeil::call_matcher_list<sig>;\ using TROMPELOEIL_LINE_ID(matcher_list_t) = ::trompeloeil::call_matcher_list<sig>;\
using TROMPELOEIL_LINE_ID(expectation_list_t) = ::trompeloeil::expectations<sig>; \
using TROMPELOEIL_LINE_ID(expectation_list_t) = \
::trompeloeil::expectations<trompeloeil_movable_mock, sig>; \
\
struct TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \ struct TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \
{ \ { \
const char* trompeloeil_expectation_file; \ const char* trompeloeil_expectation_file; \
using T_ ## name = typename std::remove_reference<decltype(*this)>::type; \ using T_ ## name = typename std::remove_reference<decltype(*this)>::type; \
\ \
using pmf_s_t = typename ::trompeloeil::signature_to_member_function< \ using pmf_s_t = typename ::trompeloeil::signature_to_member_function< \
T_ ## name, decltype(*this), sig>::type; \
T_ ## name, decltype(*this), sig>::type const; \
\ \
using pmf_e_t = typename ::trompeloeil::signature_to_member_function< \ using pmf_e_t = typename ::trompeloeil::signature_to_member_function< \
T_ ## name, TROMPELOEIL_LINE_ID(tag_type_trompeloeil), sig>::type; \
T_ ## name, TROMPELOEIL_LINE_ID(tag_type_trompeloeil), sig>::type const; \
\ \
auto s_ptr = static_cast<pmf_s_t>(&T_ ## name::trompeloeil_self_ ## name); \
auto e_ptr = static_cast<pmf_e_t>(&T_ ## name::trompeloeil_tag_ ## name); \
pmf_s_t const s_ptr = &T_ ## name::trompeloeil_self_ ## name; \
pmf_e_t const e_ptr = &T_ ## name::trompeloeil_tag_ ## name; \
\ \
::trompeloeil::ignore(s_ptr, e_ptr); \ ::trompeloeil::ignore(s_ptr, e_ptr); \
\ \
return ::trompeloeil::mock_func<sig>(TROMPELOEIL_LINE_ID(cardinality_match){}, \
TROMPELOEIL_LINE_ID(expectations), \
#name, \
#sig \
TROMPELOEIL_PARAMS(num)); \
return ::trompeloeil::mock_func<trompeloeil_movable_mock, sig>( \
TROMPELOEIL_LINE_ID(cardinality_match){}, \
TROMPELOEIL_LINE_ID(expectations), \
#name, \
#sig \
TROMPELOEIL_PARAMS(num)); \
} \ } \
\ \
auto \ auto \
return {nullptr, 0ul, nullptr}; \ return {nullptr, 0ul, nullptr}; \
} \ } \
\ \
mutable TROMPELOEIL_LINE_ID(expectation_list_t) TROMPELOEIL_LINE_ID(expectations)
mutable TROMPELOEIL_LINE_ID(expectation_list_t) TROMPELOEIL_LINE_ID(expectations){}




#define TROMPELOEIL_LPAREN ( #define TROMPELOEIL_LPAREN (
#define TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, obj_s, func_s, ...) \ #define TROMPELOEIL_REQUIRE_CALL_V_LAMBDA(obj, func, obj_s, func_s, ...) \
[&] \ [&] \
{ \ { \
using s_t = decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_self_, func)); \
using e_t = decltype((obj).TROMPELOEIL_CONCAT(trompeloeil_tag_,func)); \
using trompeloeil_s_t = decltype((obj) \
.TROMPELOEIL_CONCAT(trompeloeil_self_, func)); \
using trompeloeil_e_t = decltype((obj) \
.TROMPELOEIL_CONCAT(trompeloeil_tag_,func)); \
\ \
return TROMPELOEIL_REQUIRE_CALL_LAMBDA_OBJ(obj, func, obj_s, func_s) \ return TROMPELOEIL_REQUIRE_CALL_LAMBDA_OBJ(obj, func, obj_s, func_s) \
__VA_ARGS__ \ __VA_ARGS__ \




#define TROMPELOEIL_REQUIRE_CALL_LAMBDA_OBJ(obj, func, obj_s, func_s) \ #define TROMPELOEIL_REQUIRE_CALL_LAMBDA_OBJ(obj, func, obj_s, func_s) \
::trompeloeil::call_validator_t<s_t>{(obj)} + \
::trompeloeil::call_validator_t<trompeloeil_s_t>{(obj)} + \
::trompeloeil::detail::conditional_t<false, \ ::trompeloeil::detail::conditional_t<false, \
decltype((obj).func), \ decltype((obj).func), \
e_t> \
trompeloeil_e_t> \
{__FILE__, static_cast<unsigned long>(__LINE__), obj_s "." func_s}.func {__FILE__, static_cast<unsigned long>(__LINE__), obj_s "." func_s}.func




#define TROMPELOEIL_WITH_(capture, arg_s, ...) \ #define TROMPELOEIL_WITH_(capture, arg_s, ...) \
with( \ with( \
arg_s, \ arg_s, \
[capture](e_t::trompeloeil_call_params_type_t const& trompeloeil_x) \
[capture] \
(trompeloeil_e_t::trompeloeil_call_params_type_t const& trompeloeil_x) \
{ \ { \
auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \ auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \ auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \


#define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \ #define TROMPELOEIL_SIDE_EFFECT_(capture, ...) \
sideeffect( \ sideeffect( \
[capture](e_t::trompeloeil_call_params_type_t& trompeloeil_x) { \
[capture](trompeloeil_e_t::trompeloeil_call_params_type_t& trompeloeil_x) {\
auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \ auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \ auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \ auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \


#define TROMPELOEIL_RETURN_(capture, ...) \ #define TROMPELOEIL_RETURN_(capture, ...) \
handle_return( \ handle_return( \
[capture](e_t::trompeloeil_call_params_type_t& trompeloeil_x) \
-> e_t::trompeloeil_return_of_t \
[capture](trompeloeil_e_t::trompeloeil_call_params_type_t& trompeloeil_x) \
-> trompeloeil_e_t::trompeloeil_return_of_t \
{ \ { \
auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \ auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \ auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \


#define TROMPELOEIL_THROW_(capture, ...) \ #define TROMPELOEIL_THROW_(capture, ...) \
handle_throw( \ handle_throw( \
[capture](e_t::trompeloeil_call_params_type_t& trompeloeil_x) { \
[capture](trompeloeil_e_t::trompeloeil_call_params_type_t& trompeloeil_x) {\
auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \ auto& _1 = ::trompeloeil::mkarg<1>(trompeloeil_x); \
auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \ auto& _2 = ::trompeloeil::mkarg<2>(trompeloeil_x); \
auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \ auto& _3 = ::trompeloeil::mkarg<3>(trompeloeil_x); \

Loading…
Cancel
Save