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