Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/statechart/test/TerminationTest.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: 8.0 KB
RevLine 
[29]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/event.hpp>
11#include <boost/statechart/simple_state.hpp>
12#include <boost/statechart/termination.hpp>
13
14#include <boost/mpl/list.hpp>
15
16#include <boost/test/test_tools.hpp>
17
18#include <set>
19#include <map>
20#include <string>
21
22
23
24namespace sc = boost::statechart;
25namespace mpl = boost::mpl;
26
27
28
29struct EvTerminateA : sc::event< EvTerminateA > {};
30struct EvTerminateB : sc::event< EvTerminateB > {};
31struct EvTerminateC : sc::event< EvTerminateC > {};
32struct EvTerminateD : sc::event< EvTerminateD > {};
33struct EvTerminateE : sc::event< EvTerminateE > {};
34struct EvTerminateF : sc::event< EvTerminateF > {};
35struct EvTerminateG : sc::event< EvTerminateG > {};
36
37struct A;
38struct TerminationTest : sc::state_machine< TerminationTest, A >
39{
40  public:
41    //////////////////////////////////////////////////////////////////////////
42    TerminationTest();
43
44    void AssertInState( const std::string & stateNames ) const
45    {
46      stateNamesCache_.clear();
47
48      for ( state_iterator currentState = state_begin();
49        currentState != state_end(); ++currentState )
50      {
51        AddName( currentState->dynamic_type() );
52
53        const state_base_type * outerState = currentState->outer_state_ptr();
54
55        while ( outerState != 0 )
56        {
57          AddName( outerState->dynamic_type() );
58          outerState = outerState->outer_state_ptr();
59        }
60      }
61
62      std::string::const_iterator expectedName = stateNames.begin();
63
64      BOOST_REQUIRE( stateNames.size() == stateNamesCache_.size() );
65
66      for ( StateNamesCache::const_iterator actualName =
67        stateNamesCache_.begin(); actualName != stateNamesCache_.end();
68        ++actualName, ++expectedName )
69      {
70        BOOST_REQUIRE( ( *actualName )[ 0 ] == *expectedName );
71      }
72    }
73
74  private:
75    //////////////////////////////////////////////////////////////////////////
76    void AddName( state_base_type::id_type stateType ) const
77    {
78      const StateNamesMap::const_iterator found =
79        stateNamesMap_.find( stateType );
80      BOOST_REQUIRE( found != stateNamesMap_.end() );
81      stateNamesCache_.insert( found->second );
82    }
83
84    typedef std::map< state_base_type::id_type, std::string > StateNamesMap;
85    typedef std::set< std::string > StateNamesCache;
86
87    StateNamesMap stateNamesMap_;
88    mutable StateNamesCache stateNamesCache_;
89};
90
91template<
92  class MostDerived,
93  class Context,
94  class InnerInitial = mpl::list<> >
95struct MyState : sc::simple_state< MostDerived, Context, InnerInitial >
96{
97  public:
98    MyState() : exitCalled_( false ) {}
99
100    ~MyState()
101    {
102      // BOOST_REQUIRE throws an exception when the test fails. If the state
103      // is destructed as part of a stack unwind, abort() is called what is
104      // presumably also detected by the test monitor.
105      BOOST_REQUIRE( exitCalled_ );
106    }
107
108    void exit()
109    {
110      exitCalled_ = true;
111    }
112
113  private:
114    bool exitCalled_;
115};
116
117
118struct B;
119struct C;
120struct A : MyState< A, TerminationTest, mpl::list< B, C > >
121{
122  typedef sc::termination< EvTerminateA > reactions;
123};
124
125  struct B : MyState< B, A::orthogonal< 0 > >
126  {
127    typedef sc::termination< EvTerminateB > reactions;
128  };
129
130  struct D;
131  struct E;
132  struct C : MyState< C, A::orthogonal< 1 >, mpl::list< D, E > >
133  {
134    typedef sc::termination< EvTerminateC > reactions;
135  };
136
137    struct D : MyState< D, C::orthogonal< 0 > >
138    {
139      typedef sc::termination< EvTerminateD > reactions;
140    };
141
142    struct F;
143    struct G;
144    struct E : MyState< E, C::orthogonal< 1 >, mpl::list< F, G > >
145    {
146      typedef sc::termination< EvTerminateE > reactions;
147    };
148
149      struct F : MyState< F, E::orthogonal< 0 > >
150      {
151        typedef sc::termination< EvTerminateF > reactions;
152      };
153
154      struct G : MyState< G, E::orthogonal< 1 > >
155      {
156        typedef sc::termination< EvTerminateG > reactions;
157      };
158
159TerminationTest::TerminationTest()
160{
161  // We're not using custom type information to make this test work even when
162  // BOOST_STATECHART_USE_NATIVE_RTTI is defined
163  stateNamesMap_[ A::static_type() ] = "A";
164  stateNamesMap_[ B::static_type() ] = "B";
165  stateNamesMap_[ C::static_type() ] = "C";
166  stateNamesMap_[ D::static_type() ] = "D";
167  stateNamesMap_[ E::static_type() ] = "E";
168  stateNamesMap_[ F::static_type() ] = "F";
169  stateNamesMap_[ G::static_type() ] = "G";
170}
171
172
173struct X;
174struct TerminationEventBaseTest :
175  sc::state_machine< TerminationEventBaseTest, X > {};
176
177struct X : sc::simple_state< X, TerminationEventBaseTest >
178{
179  typedef sc::termination< sc::event_base > reactions;
180};
181
182
183int test_main( int, char* [] )
184{
185  TerminationTest machine;
186  machine.AssertInState( "" );
187
188  machine.initiate();
189  machine.AssertInState( "ABCDEFG" );
190  machine.process_event( EvTerminateE() );
191  machine.AssertInState( "ABCD" );
192  machine.process_event( EvTerminateE() );
193  machine.AssertInState( "ABCD" );
194
195  machine.initiate();
196  machine.AssertInState( "ABCDEFG" );
197  machine.process_event( EvTerminateC() );
198  machine.AssertInState( "AB" );
199  machine.process_event( EvTerminateC() );
200  machine.AssertInState( "AB" );
201
202  machine.initiate();
203  machine.AssertInState( "ABCDEFG" );
204  machine.process_event( EvTerminateA() );
205  machine.AssertInState( "" );
206  machine.process_event( EvTerminateA() );
207  machine.AssertInState( "" );
208
209  machine.initiate();
210  machine.AssertInState( "ABCDEFG" );
211  machine.process_event( EvTerminateG() );
212  machine.AssertInState( "ABCDEF" );
213  machine.process_event( EvTerminateG() );
214  machine.AssertInState( "ABCDEF" );
215  machine.process_event( EvTerminateF() );
216  machine.AssertInState( "ABCD" );
217  machine.process_event( EvTerminateF() );
218  machine.AssertInState( "ABCD" );
219  machine.process_event( EvTerminateD() );
220  machine.AssertInState( "AB" );
221  machine.process_event( EvTerminateD() );
222  machine.AssertInState( "AB" );
223  machine.process_event( EvTerminateB() );
224  machine.AssertInState( "" );
225  machine.process_event( EvTerminateB() );
226  machine.AssertInState( "" );
227
228  machine.initiate();
229  machine.AssertInState( "ABCDEFG" );
230  machine.process_event( EvTerminateB() );
231  machine.AssertInState( "ACDEFG" );
232  machine.process_event( EvTerminateB() );
233  machine.AssertInState( "ACDEFG" );
234  machine.process_event( EvTerminateD() );
235  machine.AssertInState( "ACEFG" );
236  machine.process_event( EvTerminateD() );
237  machine.AssertInState( "ACEFG" );
238  machine.process_event( EvTerminateF() );
239  machine.AssertInState( "ACEG" );
240  machine.process_event( EvTerminateF() );
241  machine.AssertInState( "ACEG" );
242  machine.process_event( EvTerminateG() );
243  machine.AssertInState( "" );
244  machine.process_event( EvTerminateG() );
245  machine.AssertInState( "" );
246
247  machine.initiate();
248  machine.AssertInState( "ABCDEFG" );
249  machine.process_event( EvTerminateE() );
250  machine.AssertInState( "ABCD" );
251  machine.process_event( EvTerminateE() );
252  machine.AssertInState( "ABCD" );
253  machine.process_event( EvTerminateC() );
254  machine.AssertInState( "AB" );
255  machine.process_event( EvTerminateC() );
256  machine.AssertInState( "AB" );
257  machine.process_event( EvTerminateA() );
258  machine.AssertInState( "" );
259  machine.process_event( EvTerminateA() );
260  machine.AssertInState( "" );
261
262  machine.initiate();
263  machine.AssertInState( "ABCDEFG" );
264  machine.initiate();
265  machine.AssertInState( "ABCDEFG" );
266  machine.terminate();
267  machine.AssertInState( "" );
268  machine.terminate();
269  machine.AssertInState( "" );
270
271
272  TerminationEventBaseTest eventBaseMachine;
273  eventBaseMachine.initiate();
274  BOOST_REQUIRE( !eventBaseMachine.terminated() );
275  eventBaseMachine.process_event( EvTerminateA() );
276  BOOST_REQUIRE( eventBaseMachine.terminated() );
277  eventBaseMachine.initiate();
278  BOOST_REQUIRE( !eventBaseMachine.terminated() );
279  eventBaseMachine.process_event( EvTerminateB() );
280  BOOST_REQUIRE( eventBaseMachine.terminated() );
281
282  return 0;
283}
Note: See TracBrowser for help on using the repository browser.