diff --git a/CHANGELOG.md b/CHANGELOG.md index 153118f2..3b7ab6ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 -------------------------------------------------------------------------------- diff --git a/include/boost/beast/_experimental/test/handler.hpp b/include/boost/beast/_experimental/test/handler.hpp new file mode 100644 index 00000000..a2cb7e79 --- /dev/null +++ b/include/boost/beast/_experimental/test/handler.hpp @@ -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 +#include +#include +#include + +namespace boost { +namespace beast { +namespace test { + +namespace detail { + +class handler +{ + boost::optional 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 + void + operator()(error_code ec, Args&&... args) + { + BEAST_EXPECT(! pass_); // can't call twice + BEAST_EXPECTS(! ec_ || ec == *ec_, + ec.message()); + pass_ = true; + } + + template::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