1// Copyright 2024 Christophe Henry
2// henry UNDERSCORE christophe AT hotmail DOT com
3// This is an extended version of the state machine available in the boost::mpl library
4// Distributed under the same license as the original.
5// Copyright for the original version:
6// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
7// under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10
11#include <boost/msm/front/puml/puml.hpp>
12
13#ifndef BOOST_MSM_NONSTANDALONE_TEST
14#define BOOST_TEST_MODULE puml_test_2
15#endif
16#include <boost/test/unit_test.hpp>
17
18using namespace boost::msm::front;
19using namespace boost::msm::front::puml;
20
21namespace
22{
23
24 BOOST_AUTO_TEST_CASE( puml_test_2 )
25 {
26 constexpr auto stt20_ = R"([*]-> StateA
27 StateA -> StateB: evt1/ A2 [G1]
28 StateA : flag F1
29 StateA -> StateC: evt2/ A2 [G1])";
30 auto stt20 =
31 boost::msm::front::puml::create_transition_table([&]() {return stt20_; });
32 static_assert(std::is_same_v<
33 decltype(stt20),
34 boost::fusion::vector<
35 Row<State <by_name("StateA"), boost::fusion::vector<Flag<by_name("F1")>>>,
36 Event <by_name("evt1")>,
37 State <by_name("StateB")>,
38 Action <by_name("A2")>,
39 Guard <by_name("G1")> >,
40 Row<State <by_name("StateA"), boost::fusion::vector<Flag<by_name("F1")>>>,
41 Event <by_name("evt2")>,
42 State <by_name("StateC")>,
43 Action <by_name("A2")>,
44 Guard <by_name("G1")> >
45 >
46 >);
47
48 constexpr auto stt21_ = R"([*]-> StateA
49 StateA -> StateB: evt1/ A2 [G1]
50 StateA : flag F1
51 StateA : flag F2)";
52 auto stt21 =
53 boost::msm::front::puml::create_transition_table([&]() {return stt21_; });
54 static_assert(std::is_same_v<
55 decltype(stt21),
56 boost::fusion::vector<
57 Row<State <by_name("StateA"), boost::fusion::vector<Flag<by_name("F1")>, Flag<by_name("F2")>>>,
58 Event <by_name("evt1")>,
59 State <by_name("StateB")>,
60 Action <by_name("A2")>,
61 Guard <by_name("G1")> >
62 >
63 >);
64
65 constexpr auto stt22_ = R"([*]-> StateA
66 StateA -> StateB: evt1/ A2 [G1]
67 StateA : flag F1
68 StateB : flag F2)";
69 auto stt22 =
70 boost::msm::front::puml::create_transition_table([&]() {return stt22_; });
71 static_assert(std::is_same_v<
72 decltype(stt22),
73 boost::fusion::vector<
74 Row<State <by_name("StateA"), boost::fusion::vector<Flag<by_name("F1")>>>,
75 Event <by_name("evt1")>,
76 State <by_name("StateB"), boost::fusion::vector<Flag<by_name("F2")>>>,
77 Action <by_name("A2")>,
78 Guard <by_name("G1")> >
79 >
80 >);
81
82 constexpr auto stt23_ = R"([*]-> StateA
83 StateA -> StateB: evt1/ A2 [G1]
84 StateA : flag F1
85 StateA : flag F2
86 StateB : flag F2)";
87 auto stt23 =
88 boost::msm::front::puml::create_transition_table([&]() {return stt23_; });
89 static_assert(std::is_same_v<
90 decltype(stt23),
91 boost::fusion::vector<
92 Row<State <by_name("StateA"), boost::fusion::vector<Flag<by_name("F1")>, Flag<by_name("F2")>>>,
93 Event <by_name("evt1")>,
94 State <by_name("StateB"), boost::fusion::vector<Flag<by_name("F2")>>>,
95 Action <by_name("A2")>,
96 Guard <by_name("G1")> >
97 >
98 >);
99
100 constexpr auto stt24_ = R"([*]-> StateA
101 StateA -> StateB: evt1/ A2 [G1]
102 StateA : entry A1
103 StateA : entry A2
104 StateB : entry A1
105 )";
106 auto stt24 =
107 boost::msm::front::puml::create_transition_table([&]() {return stt24_; });
108
109 static_assert(std::is_same_v<
110 decltype(stt24),
111 boost::fusion::vector<
112 Row<
113 State < by_name("StateA"),
114 boost::fusion::vector<>,
115 boost::fusion::vector<
116 boost::msm::front::puml::detail::pair_type <
117 Action<by_name("A1")>,
118 none
119 >,
120 boost::msm::front::puml::detail::pair_type <
121 Action<by_name("A2")>,
122 none
123 >
124 >
125 >,
126 Event <by_name("evt1")>,
127 State < by_name("StateB"),
128 boost::fusion::vector<>,
129 boost::fusion::vector<
130 boost::msm::front::puml::detail::pair_type <
131 Action<by_name("A1")>,
132 none
133 >
134 >>,
135 Action <by_name("A2")>,
136 Guard <by_name("G1")> >
137 >
138 >);
139
140 constexpr auto stt25_ = R"([*]-> StateA
141 StateA -> StateB: evt1/ A2 [G1]
142 StateA : entry A1 [G1]
143 StateA : entry A2
144 StateB : entry A1 [G1]
145 StateB : entry A2
146 )";
147 auto stt25 =
148 boost::msm::front::puml::create_transition_table([&]() {return stt25_; });
149
150 static_assert(std::is_same_v<
151 decltype(stt25),
152 boost::fusion::vector<
153 Row<
154 State < by_name("StateA"),
155 boost::fusion::vector<>,
156 boost::fusion::vector<
157 boost::msm::front::puml::detail::pair_type <
158 Action<by_name("A1")>,
159 Guard<by_name("G1")>
160 >,
161 boost::msm::front::puml::detail::pair_type <
162 Action<by_name("A2")>,
163 none
164 >
165 >
166 >,
167 Event <by_name("evt1")>,
168 State < by_name("StateB"),
169 boost::fusion::vector<>,
170 boost::fusion::vector<
171 boost::msm::front::puml::detail::pair_type <
172 Action<by_name("A1")>,
173 Guard<by_name("G1")>
174 >,
175 boost::msm::front::puml::detail::pair_type <
176 Action<by_name("A2")>,
177 none
178 >
179 >
180 >,
181 Action <by_name("A2")>,
182 Guard <by_name("G1")> >
183 >
184 >);
185
186 constexpr auto stt26_ = R"([*]-> StateA
187 StateA -> StateB: evt1/ A2 [G1]
188 StateA : entry A1,A2 [G1 && G2]
189 StateB : entry A1,A2 [G1&&G2])";
190 auto stt26 =
191 boost::msm::front::puml::create_transition_table([&]() {return stt26_; });
192
193 static_assert(std::is_same_v<
194 decltype(stt26),
195 boost::fusion::vector<
196 Row<
197 State < by_name("StateA"),
198 boost::fusion::vector<>,
199 boost::fusion::vector<
200 boost::msm::front::puml::detail::pair_type <
201 boost::msm::front::ActionSequence_< boost::fusion::vector<
202 Action<by_name("A1")>, Action<by_name("A2")>
203 >>,
204 And_<Guard <by_name("G1")>, Guard <by_name("G2")>>
205 >
206 >
207 >,
208 Event <by_name("evt1")>,
209 State < by_name("StateB"),
210 boost::fusion::vector<>,
211 boost::fusion::vector<
212 boost::msm::front::puml::detail::pair_type <
213 boost::msm::front::ActionSequence_< boost::fusion::vector<
214 Action<by_name("A1")>, Action<by_name("A2")>
215 >>,
216 And_<Guard <by_name("G1")>, Guard <by_name("G2")>>
217 >
218 >
219 >,
220 Action <by_name("A2")>,
221 Guard <by_name("G1")> >
222 >
223 >);
224
225 constexpr auto stt27_ = R"([*]-> StateA
226 StateA -> StateB: evt1/ A2 [G1]
227 StateA : exit A1,A2 [G1 && G2]
228 StateB : entry A1,A2 [G1&&G2])";
229 auto stt27 =
230 boost::msm::front::puml::create_transition_table([&]() {return stt27_; });
231
232 static_assert(std::is_same_v<
233 decltype(stt27),
234 boost::fusion::vector<
235 Row<
236 State < by_name("StateA"),
237 boost::fusion::vector<>,
238 boost::fusion::vector<>,
239 boost::fusion::vector<
240 boost::msm::front::puml::detail::pair_type <
241 boost::msm::front::ActionSequence_< boost::fusion::vector<
242 Action<by_name("A1")>, Action<by_name("A2")>
243 >>,
244 And_<Guard <by_name("G1")>, Guard <by_name("G2")>>
245 >
246 >
247 >,
248 Event <by_name("evt1")>,
249 State < by_name("StateB"),
250 boost::fusion::vector<>,
251 boost::fusion::vector<
252 boost::msm::front::puml::detail::pair_type <
253 boost::msm::front::ActionSequence_< boost::fusion::vector<
254 Action<by_name("A1")>, Action<by_name("A2")>
255 >>,
256 And_<Guard <by_name("G1")>, Guard <by_name("G2")>>
257 >
258 >
259 >,
260 Action <by_name("A2")>,
261 Guard <by_name("G1")> >
262 >
263 >);
264
265 constexpr auto stt28_ = R"([*]-> StateA
266 StateA -> StateB: evt1/ A2 [G1]
267 StateB -> [*])";
268 auto stt28 =
269 boost::msm::front::puml::create_transition_table([&]() {return stt28_; });
270 static_assert(std::is_same_v<
271 decltype(stt28),
272 boost::fusion::vector<
273 Row<State <by_name("StateA")>,
274 Event <by_name("evt1")>,
275 State <by_name("StateB"), boost::fusion::vector<boost::msm::TerminateFlag>>,
276 Action <by_name("A2")>,
277 Guard <by_name("G1")> >
278 >
279 >);
280
281
282 constexpr auto stt29_ = R"(
283 @startuml Player
284 skinparam linetype polyline
285 state Player{
286 [*]-> StateA
287 StateA -> StateB: evt1/ A2 [G1]
288 --
289 [*]-> StateC
290 StateC -> TerminalState : terminate_event
291 TerminalState -> [*]
292 }
293 @enduml
294 )";
295 auto stt29 =
296 boost::msm::front::puml::create_transition_table([&]() {return stt29_; });
297 static_assert(std::is_same_v<
298 decltype(stt29),
299 boost::fusion::vector<
300 Row<State <by_name("StateA")>,
301 Event <by_name("evt1")>,
302 State <by_name("StateB")>,
303 Action <by_name("A2")>,
304 Guard <by_name("G1")> >,
305 Row<State <by_name("StateC")>,
306 Event <by_name("terminate_event")>,
307 State <by_name("TerminalState"), boost::fusion::vector<boost::msm::TerminateFlag>>,
308 none,
309 none>
310 >
311 >);
312 static_assert(boost::msm::front::puml::detail::count_terminates(s: stt29_) == 1);
313 static_assert(boost::msm::front::puml::detail::count_inits(s: stt29_) == 2);
314
315 //std::cout << "dbg1:" << typeid(stt25).name() << std::endl << std::endl;
316 //std::cout << "dbg2:" << typeid(stt29).name() << std::endl << std::endl;
317 }
318}
319
320

source code of boost/libs/msm/test/puml_syntax_2.cpp