Add experimental test/handler.hpp

This commit is contained in:
Vinnie Falco
2019-02-15 15:18:33 -08:00
parent 18447553ca
commit a781285e2f
2 changed files with 145 additions and 0 deletions

View File

@ -4,6 +4,7 @@ Version 215:
* Remove bind_back_handler
* bind_front_handler works with member functions
* Examples use bind_front_handler
* Add experimental test/handler.hpp
--------------------------------------------------------------------------------

View File

@ -0,0 +1,144 @@
//
// Copyright (c) 2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// 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)
//
// Official repository: https://github.com/boostorg/beast
//
#ifndef BOOST_BEAST_TEST_HANDLER_HPP
#define BOOST_BEAST_TEST_HANDLER_HPP
#include <boost/beast/_experimental/unit_test/suite.hpp>
#include <boost/beast/core/error.hpp>
#include <boost/core/exchange.hpp>
#include <boost/optional.hpp>
namespace boost {
namespace beast {
namespace test {
namespace detail {
class handler
{
boost::optional<error_code> ec_;
bool pass_ = false;
public:
handler() = default;
explicit
handler(error_code ec)
: ec_(ec)
{
}
explicit
handler(boost::none_t)
{
}
handler(handler&& other)
: ec_(other.ec_)
, pass_(boost::exchange(other.pass_, true))
{
}
~handler()
{
BEAST_EXPECT(pass_);
}
template<class... Args>
void
operator()(error_code ec, Args&&... args)
{
BEAST_EXPECT(! pass_); // can't call twice
BEAST_EXPECTS(! ec_ || ec == *ec_,
ec.message());
pass_ = true;
}
template<class Arg0, class... Args,
class = typename std::enable_if<
! std::is_convertible<Arg0, error_code>::value>::type>
void
operator()(Arg0&&, Args&&...)
{
BEAST_EXPECT(! pass_); // can't call twice
BEAST_EXPECT(! ec_);
pass_ = true;
}
};
} // detail
/** Return a test CompletionHandler which requires success.
The returned handler can be invoked with any signature whose
first parameter is an `error_code`. The handler fails the test
if:
@li The handler is destroyed without being invoked, or
@li The handler is invoked with a non-successful error code.
*/
inline
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::handler
#endif
success_handler() noexcept
{
return detail::handler(error_code{});
}
/** Return a test CompletionHandler which requires invocation.
The returned handler can be invoked with any signature.
The handler fails the test if:
@li The handler is destroyed without being invoked.
*/
inline
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::handler
#endif
any_handler() noexcept
{
return detail::handler(boost::none);
}
/** Return a test CompletionHandler which requires a specific error code.
This handler can be invoked with any signature whose first
parameter is an `error_code`. The handler fails the test if:
@li The handler is destroyed without being invoked.
@li The handler is invoked with an error code different from
what is specified.
@param ec The error code to specify.
*/
inline
#if BOOST_BEAST_DOXYGEN
__implementation_defined__
#else
detail::handler
#endif
fail_handler(error_code ec) noexcept
{
return detail::handler(ec);
}
} // test
} // beast
} // boost
#endif