// // Copyright (c) 2022 Klemens Morgenstern (klemens.morgenstern@gmx.net) // // 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) // #include #include #include #include "test.hpp" #include #include #include #include using namespace boost; BOOST_AUTO_TEST_SUITE(promise); cobalt::promise test0() { co_return; } cobalt::promise test2(int i) { co_await test0(); co_return i; } cobalt::promise test1(asio::any_io_executor exec) { co_await test2(42); co_await test2(42); BOOST_CHECK(test2(42).get() == 42); co_await asio::post(exec, cobalt::use_op); co_return 452; } CO_TEST_CASE(cobalt_1) { co_await test1(co_await asio::this_coro::executor); co_return; } cobalt::promise should_unwind(asio::io_context & ctx) { co_await asio::post(ctx, cobalt::use_op); } BOOST_AUTO_TEST_CASE(unwind) { asio::io_context ctx; boost::cobalt::this_thread::set_executor(ctx.get_executor()); +should_unwind(ctx); } cobalt::promise return_(std::size_t) { return cobalt::noop(1234); } cobalt::promise return_(std::size_t, asio::executor_arg_t, boost::cobalt::executor ) { co_return 1234u; } cobalt::promise delay_r(asio::io_context &ctx, std::size_t ms, asio::executor_arg_t, asio::any_io_executor ) { auto tim = cobalt::use_op.as_default_on(asio::steady_timer(ctx, std::chrono::milliseconds{ms})); co_await tim.async_wait(); co_return ms; } cobalt::promise delay_r(asio::any_io_executor exec, std::size_t ms) { auto tim = cobalt::use_op.as_default_on(asio::steady_timer(exec, std::chrono::milliseconds{ms})); co_await tim.async_wait(); co_return ms; } cobalt::promise throw_() { throw std::runtime_error("throw_"); co_return ; } cobalt::promise throw_post() { co_await asio::post(cobalt::this_thread::get_executor(), cobalt::use_op); throw std::runtime_error("throw_post"); co_return ; } BOOST_AUTO_TEST_CASE(bad_executor_) { BOOST_REQUIRE(!cobalt::this_thread::has_executor()); try { auto t = test0(); BOOST_FAIL("Should throw"); } catch(std::exception & e) {BOOST_CHECK_EQUAL(e.what(), std::string_view("bad executor"));} } BOOST_AUTO_TEST_CASE(get) { asio::io_context ctx; cobalt::this_thread::set_executor(ctx.get_executor()); auto t = throw_(); BOOST_REQUIRE(t.ready()); BOOST_CHECK_THROW(t.get(), std::exception); } cobalt::promise delay_v(asio::io_context &ctx, std::size_t ms) { asio::steady_timer tim(ctx, std::chrono::milliseconds{ms}); co_await tim.async_wait(boost::cobalt::use_op); } CO_TEST_CASE(cancel_int) { BOOST_CHECK_THROW(co_await throw_(), std::exception); } CO_TEST_CASE(throw_cpl_delay) { BOOST_CHECK_THROW(co_await throw_post(), std::exception); } CO_TEST_CASE(stop_) try { BOOST_CHECK_THROW( co_await []() -> cobalt::promise { co_await stop(); }(), boost::system::system_error); } catch(...) { } struct promise_move_only { promise_move_only() = default; promise_move_only(promise_move_only &&) = default; promise_move_only & operator=(promise_move_only &&) = default; }; cobalt::promise pro_move_only_test() { co_return promise_move_only{}; } CO_TEST_CASE(move_only) { auto p = pro_move_only_test(); co_await p; p = pro_move_only_test(); co_await p; } BOOST_AUTO_TEST_SUITE_END();