Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/statechart/test/HistoryTest.cpp @ 45

Last change on this file since 45 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 11.9 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2// Copyright 2005-2006 Andreas Huber Doenni
3// Distributed under the Boost Software License, Version 1.0. (See accompany-
4// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5//////////////////////////////////////////////////////////////////////////////
6
7
8
9#include <boost/statechart/state_machine.hpp>
10#include <boost/statechart/simple_state.hpp>
11#include <boost/statechart/event.hpp>
12#include <boost/statechart/transition.hpp>
13#include <boost/statechart/shallow_history.hpp>
14#include <boost/statechart/deep_history.hpp>
15
16#include <boost/mpl/list.hpp>
17#include <boost/shared_ptr.hpp>
18
19#include <boost/test/test_tools.hpp>
20
21#include <stdexcept>
22
23
24namespace sc = boost::statechart;
25namespace mpl = boost::mpl;
26
27
28
29struct EvToB : sc::event< EvToB > {};
30
31struct EvToD : sc::event< EvToD > {};
32struct EvToDShallow : sc::event< EvToDShallow > {};
33struct EvToDDeep : sc::event< EvToDDeep > {};
34struct EvToDShallowLocal : sc::event< EvToDShallowLocal > {};
35struct EvToDDeepLocal : sc::event< EvToDDeepLocal > {};
36
37struct EvToF : sc::event< EvToF > {};
38struct EvToFShallow : sc::event< EvToFShallow > {};
39struct EvToFDeep : sc::event< EvToFDeep > {};
40
41struct EvToH : sc::event< EvToH > {};
42struct EvToI : sc::event< EvToI > {};
43
44struct EvToM : sc::event< EvToM > {};
45struct EvToQ : sc::event< EvToQ > {};
46
47struct EvWhatever : sc::event< EvWhatever > {};
48
49struct A;
50struct HistoryTest : sc::state_machine< HistoryTest, A >
51{
52  void unconsumed_event( const sc::event_base & )
53  {
54    throw std::runtime_error( "Event was not consumed!" );
55  }
56};
57
58struct B;
59struct D;
60struct F;
61struct H;
62struct I;
63struct M;
64struct Q;
65struct A : sc::simple_state< A, HistoryTest, B >
66{
67  typedef mpl::list<
68    sc::transition< EvToB, B >,
69    sc::transition< EvToD, D >,
70    sc::transition< EvToDShallow, sc::shallow_history< D > >,
71    sc::transition< EvToDDeep, sc::deep_history< D > >,
72    sc::transition< EvToF, F >,
73    sc::transition< EvToFShallow, sc::shallow_history< F > >,
74    sc::transition< EvToFDeep, sc::deep_history< F > >,
75    sc::transition< EvToH, H >,
76    sc::transition< EvToI, I >,
77    sc::transition< EvToM, M >,
78    sc::transition< EvToQ, Q >
79  > reactions;
80};
81
82  struct J;
83  struct N;
84  struct B : sc::simple_state<
85    B, A, mpl::list< sc::shallow_history< J >, sc::deep_history< N > >,
86    sc::has_full_history > {};
87
88    struct J : sc::simple_state< J, B::orthogonal< 0 > > {};
89    struct L;
90    struct K : sc::simple_state< K, B::orthogonal< 0 >, L > {};
91
92      struct L : sc::simple_state< L, K > {};
93      struct M : sc::simple_state< M, K > {};
94
95    struct N : sc::simple_state< N, B::orthogonal< 1 > > {};
96    struct P;
97    struct O : sc::simple_state< O, B::orthogonal< 1 >, P > {};
98
99      struct P : sc::simple_state< P, O > {};
100      struct Q : sc::simple_state< Q, O > {};
101
102  struct C : sc::simple_state< C, A, D, sc::has_full_history > {};
103
104    struct D : sc::simple_state< D, C > {};
105    struct E : sc::simple_state< E, C, F, sc::has_full_history > {};
106
107      struct F : sc::simple_state< F, E > {};
108      struct G : sc::simple_state< G, E, H >
109      {
110        typedef mpl::list<
111          sc::transition< EvToDShallowLocal, sc::shallow_history< D > >,
112          sc::transition< EvToDDeepLocal, sc::deep_history< D > >
113        > reactions;
114      };
115
116        struct H : sc::simple_state< H, G > {};
117        struct I : sc::simple_state< I, G > {};
118
119
120int test_main( int, char* [] )
121{
122  boost::shared_ptr< HistoryTest > pM =
123    boost::shared_ptr< HistoryTest >( new HistoryTest() );
124
125  // state_downcast sanity check
126  BOOST_REQUIRE_THROW( pM->state_downcast< const B & >(), std::bad_cast );
127  pM->initiate();
128  BOOST_REQUIRE_THROW( pM->state_downcast< const D & >(), std::bad_cast );
129
130  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
131
132  // No history has been saved yet -> default state
133  pM->process_event( EvToDShallow() );
134  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
135  pM->process_event( EvToDShallow() );
136  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
137
138  pM->process_event( EvToI() );
139  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
140  // Direct inner is E when history is saved -> F
141  pM->process_event( EvToDShallow() );
142  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
143
144  pM->process_event( EvToH() );
145  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
146  // Direct inner is E when history is saved -> F
147  pM->process_event( EvToDShallow() );
148  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
149
150  pM->process_event( EvToF() );
151  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
152  pM->process_event( EvToB() );
153  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
154  // Direct inner was E when history was saved -> F
155  pM->process_event( EvToDShallow() );
156  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
157
158  pM->initiate();
159  // History was cleared in termination -> default state
160  pM->process_event( EvToDShallow() );
161  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
162
163  pM->process_event( EvToI() );
164  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
165  pM->process_event( EvToB() );
166  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
167  pM->clear_shallow_history< C, 0 >();
168  // History was cleared -> default state
169  pM->process_event( EvToDShallow() );
170  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
171
172  pM = boost::shared_ptr< HistoryTest >( new HistoryTest() );
173  pM->initiate();
174  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
175
176  // No history has been saved yet -> default state
177  pM->process_event( EvToDDeep() );
178  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
179  pM->process_event( EvToDDeep() );
180  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
181
182  pM->process_event( EvToI() );
183  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
184  pM->process_event( EvToB() );
185  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
186  pM->process_event( EvToDDeep() );
187  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
188
189  pM->process_event( EvToH() );
190  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
191  pM->process_event( EvToB() );
192  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
193  pM->process_event( EvToDDeep() );
194  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
195
196  pM->process_event( EvToF() );
197  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
198  pM->process_event( EvToB() );
199  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
200  pM->process_event( EvToDDeep() );
201  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
202
203  pM->initiate();
204  // History was cleared in termination -> default state
205  pM->process_event( EvToDDeep() );
206  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
207
208  pM->process_event( EvToI() );
209  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
210  pM->process_event( EvToB() );
211  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
212  pM->clear_deep_history< C, 0 >();
213  // History was cleared -> default state
214  pM->process_event( EvToDDeep() );
215  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const D & >() );
216
217
218  pM = boost::shared_ptr< HistoryTest >( new HistoryTest() );
219  pM->initiate();
220  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
221
222  // No history has been saved yet -> default state
223  pM->process_event( EvToFShallow() );
224  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
225  pM->process_event( EvToFShallow() );
226  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
227
228  pM->process_event( EvToI() );
229  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
230  // Direct inner is G when history is saved -> H
231  pM->process_event( EvToFShallow() );
232  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
233
234  pM->process_event( EvToH() );
235  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
236  pM->process_event( EvToB() );
237  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
238  // Direct inner was G when history was saved -> H
239  pM->process_event( EvToFShallow() );
240  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
241
242  pM->process_event( EvToI() );
243  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
244  pM->initiate();
245  // History was cleared in termination -> default state
246  pM->process_event( EvToFShallow() );
247  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
248
249  pM->process_event( EvToI() );
250  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
251  pM->process_event( EvToB() );
252  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
253  pM->clear_shallow_history< E, 0 >();
254  // History was cleared -> default state
255  pM->process_event( EvToFShallow() );
256  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
257
258  pM = boost::shared_ptr< HistoryTest >( new HistoryTest() );
259  pM->initiate();
260  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
261
262  // No history has been saved yet -> default state
263  pM->process_event( EvToFDeep() );
264  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
265  pM->process_event( EvToFDeep() );
266  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
267
268  pM->process_event( EvToI() );
269  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
270  pM->process_event( EvToB() );
271  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
272  pM->process_event( EvToFDeep() );
273  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
274
275  pM->process_event( EvToH() );
276  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
277  pM->process_event( EvToB() );
278  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
279  pM->process_event( EvToFDeep() );
280  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const H & >() );
281
282  pM->process_event( EvToF() );
283  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
284  pM->process_event( EvToB() );
285  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
286  pM->process_event( EvToFDeep() );
287  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
288
289  pM->initiate();
290  // History was cleared in termination -> default state
291  pM->process_event( EvToFDeep() );
292  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
293
294  pM->process_event( EvToI() );
295  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
296  pM->process_event( EvToB() );
297  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const B & >() );
298  pM->clear_deep_history< E, 0 >();
299  // History was cleared -> default state
300  pM->process_event( EvToFDeep() );
301  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
302
303  // Test local history (new with UML 2.0)
304  pM->initiate();
305  // unconsumed_event sanity check
306  BOOST_REQUIRE_THROW( pM->process_event( EvWhatever() ), std::runtime_error );
307  pM->process_event( EvToI() );
308  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
309  pM->process_event( EvToDShallowLocal() );
310  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const F & >() );
311  pM->process_event( EvToI() );
312  pM->process_event( EvToDDeepLocal() );
313  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const I & >() );
314
315  // Given that history transitions and history initial states are implemented
316  // with the same code we just make a few sanity checks and trust that the
317  // rest will work just like we tested above.
318  pM->process_event( EvToB() );
319  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const J & >() );
320  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const N & >() );
321  pM->process_event( EvToM() );
322  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const M & >() );
323  // Direct inner is K when history is saved -> L
324  pM->process_event( EvToB() );
325  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const L & >() );
326
327  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const N & >() );
328  pM->process_event( EvToQ() );
329  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const Q & >() );
330  pM->process_event( EvToB() );
331  BOOST_REQUIRE_NO_THROW( pM->state_downcast< const Q & >() );
332
333  return 0;
334}
Note: See TracBrowser for help on using the repository browser.