1// Copyright (c) 2022 Klemens D. Morgenstern
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5#ifndef BOOST_COBALT_TEST2_HPP
6#define BOOST_COBALT_TEST2_HPP
7
8#include <boost/cobalt/task.hpp>
9#include <boost/cobalt/run.hpp>
10#include <boost/cobalt/spawn.hpp>
11
12#include <boost/test/unit_test.hpp>
13
14
15inline void test_run(boost::cobalt::task<void> (*func) ())
16{
17 using namespace boost;
18#if !defined(BOOST_COBALT_NO_PMR)
19 cobalt::pmr::unsynchronized_pool_resource res;
20 cobalt::this_thread::set_default_resource(&res);
21#endif
22 {
23 asio::io_context ctx;
24 cobalt::this_thread::set_executor(ctx.get_executor());
25 spawn(context&: ctx, t: func(),
26 token: +[](std::exception_ptr e)
27 {
28 BOOST_CHECK(e == nullptr);
29 });
30 std::size_t n;
31 n = ctx.run();
32
33 if (::getenv(name: "BOOST_COBALT_BRUTE_FORCE"))
34 while (n-- > 0)
35 {
36 ctx.restart();
37 spawn(context&: ctx, t: func(),
38 token: +[](std::exception_ptr e)
39 {
40 BOOST_CHECK(e == nullptr);
41 });
42 for (std::size_t i = n; i > 0; i--)
43 ctx.run_one();
44 }
45 }
46#if !defined(BOOST_COBALT_NO_PMR)
47 cobalt::this_thread::set_default_resource(cobalt::pmr::get_default_resource());
48#endif
49}
50
51// tag::test_case_macro[]
52#define CO_TEST_CASE(Function) \
53static ::boost::cobalt::task<void> Function##_impl(); \
54BOOST_AUTO_TEST_CASE(Function) \
55{ \
56 test_run(&Function##_impl); \
57} \
58static ::boost::cobalt::task<void> Function##_impl()
59// end::test_case_macro[]
60
61struct stop
62{
63 bool await_ready() {return false;}
64 template<typename Promise>
65 void await_suspend(std::coroutine_handle<Promise> h) { boost::cobalt::detail::self_destroy(h); }
66 void await_resume() {}
67};
68
69struct immediate
70{
71 int state = 0;
72 immediate() = default;
73 immediate(const immediate & i);
74 bool await_ready() {BOOST_CHECK(state++ == 0 ); return true;}
75 void await_suspend(std::coroutine_handle<>) { BOOST_REQUIRE(false); }
76 void await_resume() {BOOST_CHECK(state++ == 1);}
77
78 ~immediate()
79 {
80 if (state != 0)
81 BOOST_CHECK(state == 2);
82 }
83};
84
85struct immediate_bool
86{
87 int state = 0;
88
89 bool await_ready() {BOOST_CHECK(state++ == 0); return false;}
90 bool await_suspend(std::coroutine_handle<>) { BOOST_CHECK(state++ == 1); return false; }
91 void await_resume() {BOOST_CHECK(state++ == 2);}
92
93 ~immediate_bool()
94 {
95 if (state != 0)
96 BOOST_CHECK(state == 3);
97 }
98};
99
100struct immediate_handle
101{
102 int state = 0;
103
104 bool await_ready() {BOOST_CHECK(state++ == 0); return false;}
105 std::coroutine_handle<> await_suspend(std::coroutine_handle<> h) { BOOST_CHECK(state++ == 1); return h; }
106 void await_resume() {BOOST_CHECK(state++ == 2);}
107
108 ~immediate_handle()
109 {
110 if (state != 0)
111 BOOST_CHECK(state == 3);
112 }
113};
114
115
116struct posted
117{
118 int state = 0;
119
120 bool await_ready() {BOOST_CHECK(state++ == 0); return false;}
121 void await_suspend(std::coroutine_handle<> h)
122 {
123 BOOST_CHECK(state++ == 1);
124 boost::asio::post(ex: boost::cobalt::this_thread::get_executor(), token&: h);
125 }
126 void await_resume() {BOOST_CHECK(state++ == 2);}
127 ~posted()
128 {
129 if (state != 0)
130 BOOST_CHECK(state == 3);
131 }
132};
133
134struct posted_bool
135{
136 int state = 0;
137
138 bool await_ready() {BOOST_CHECK(state++ == 0); return false;}
139 bool await_suspend(std::coroutine_handle<> h)
140 {
141 BOOST_CHECK(state++ == 1);
142 boost::asio::post(ex: boost::cobalt::this_thread::get_executor(), token&: h);
143 return true;
144 }
145 void await_resume() {BOOST_CHECK(state++ == 2);}
146 ~posted_bool()
147 {
148 if (state != 0)
149 BOOST_CHECK(state == 3);
150 }
151};
152
153struct posted_handle
154{
155 int state = 0;
156
157 bool await_ready() {BOOST_CHECK(state++ == 0); return false;}
158 std::coroutine_handle<> await_suspend(std::coroutine_handle<> h)
159 {
160 BOOST_CHECK(state++ == 1);
161 return boost::cobalt::detail::post_coroutine(
162 exec: boost::cobalt::this_thread::get_executor(), token: h
163 );
164 }
165 void await_resume() {BOOST_CHECK(state++ == 2);}
166 ~posted_handle()
167 {
168 if (state != 0)
169 BOOST_CHECK(state == 3);
170 }
171};
172
173#endif //BOOST_COBALT_TEST2_HPP
174

source code of boost/libs/cobalt/test/test.hpp