Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/statechart/test/TransitionTest.cpp @ 29

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

updated boost from 1_33_1 to 1_34_1

File size: 22.7 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2// Copyright 2004-2007 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 "OuterOrthogonal.hpp"
10#include "InnermostDefault.hpp"
11
12#include <boost/statechart/state_machine.hpp>
13#include <boost/statechart/null_exception_translator.hpp>
14#include <boost/statechart/exception_translator.hpp>
15#include <boost/statechart/event.hpp>
16#include <boost/statechart/transition.hpp>
17#include <boost/statechart/custom_reaction.hpp>
18
19#include <boost/mpl/list.hpp>
20
21#include <boost/test/test_tools.hpp>
22
23#include <typeinfo>
24#include <string>
25#include <vector>
26#include <iostream>
27#include <algorithm>
28#include <stdexcept>
29
30
31
32namespace sc = boost::statechart;
33namespace mpl = boost::mpl;
34
35
36
37typedef std::string ActionDescription();
38typedef ActionDescription * ActionDescriptionPtr;
39typedef std::vector< ActionDescriptionPtr > ActionDescriptionSequence;
40typedef ActionDescriptionSequence::const_iterator SequenceIterator;
41typedef void Action( ActionDescriptionSequence & );
42typedef Action * ActionPtr;
43
44template< class State >
45std::string EntryDescription()
46{
47  static const std::string entry = "Entry: ";
48  return entry + typeid( State ).name() + "\n";
49}
50
51template< class State >
52std::string ExitFnDescription()
53{
54  static const std::string exitFunction = "exit(): ";
55  return exitFunction + typeid( State ).name() + "\n";
56}
57
58template< class State >
59std::string DtorDescription()
60{
61  static const std::string destructor = "Destructor: ";
62  return destructor + typeid( State ).name() + "\n";
63}
64
65template< class Context, class Event >
66std::string TransDescription()
67{
68  static const std::string transition = "Transition: ";
69  static const std::string event = " with Event: ";
70  return transition + typeid( Context ).name() +
71    event + typeid( Event ).name() + "\n";
72}
73
74template< ActionPtr pAction >
75std::string ThrowDescription()
76{
77  static const std::string throwing = "Throwing exception in ";
78  ActionDescriptionSequence sequence;
79  pAction( sequence );
80  return throwing + sequence.front()();
81}
82
83
84template< class State >
85void Entry( ActionDescriptionSequence & sequence )
86{
87  sequence.push_back( &::EntryDescription< State > );
88}
89
90template< class State >
91void ExitFn( ActionDescriptionSequence & sequence )
92{
93  sequence.push_back( &::ExitFnDescription< State > );
94}
95
96template< class State >
97void Dtor( ActionDescriptionSequence & sequence )
98{
99  sequence.push_back( &::DtorDescription< State > );
100}
101
102template< class State >
103void Exit( ActionDescriptionSequence & sequence )
104{
105  ExitFn< State >( sequence );
106  Dtor< State >( sequence );
107}
108
109template< class Context, class Event >
110void Trans( ActionDescriptionSequence & sequence )
111{
112  sequence.push_back( &::TransDescription< Context, Event > );
113}
114
115template< ActionPtr pAction >
116void Throw( ActionDescriptionSequence & sequence )
117{
118  sequence.push_back( &::ThrowDescription< pAction > );
119}
120
121const int arrayLength = 30;
122typedef ActionPtr ActionArray[ arrayLength ];
123
124
125class TransitionTestException : public std::runtime_error
126{
127  public:
128    TransitionTestException() : std::runtime_error( "Oh la la!" ) {}
129};
130
131
132// This test state machine is a beefed-up version of the one presented in
133// "Practical Statecharts in C/C++" by Miro Samek, CMP Books 2002
134struct A : sc::event< A > {};
135struct B : sc::event< B > {};
136struct C : sc::event< C > {};
137struct D : sc::event< D > {};
138struct E : sc::event< E > {};
139struct F : sc::event< F > {};
140struct G : sc::event< G > {};
141struct H : sc::event< H > {};
142
143
144template< class M > struct S0;
145template< class Translator >
146struct TransitionTest : sc::state_machine<
147  TransitionTest< Translator >, S0< TransitionTest< Translator > >,
148  std::allocator< void >, Translator >
149{
150  public:
151    //////////////////////////////////////////////////////////////////////////
152    TransitionTest() : pThrowAction_( 0 ), unconsumedEventCount_( 0 ) {}
153
154    ~TransitionTest()
155    {
156      // Since state destructors access the state machine object, we need to
157      // make sure that all states are destructed before this subtype
158      // portion is destructed.
159      this->terminate();
160    }
161
162    void CompareToExpectedActionSequence( ActionArray & actions )
163    {
164      expectedSequence_.clear();
165
166      // Copy all non-null pointers in actions into expectedSequence_
167      for ( ActionPtr * pCurrent = &actions[ 0 ];
168        ( pCurrent != &actions[ arrayLength ] ) && ( *pCurrent != 0 );
169        ++pCurrent )
170      {
171        ( *pCurrent )( expectedSequence_ );
172      }
173
174      if ( ( expectedSequence_.size() != actualSequence_.size() ) ||
175        !std::equal( expectedSequence_.begin(),
176          expectedSequence_.end(), actualSequence_.begin() ) )
177      {
178        std::string message = "\nExpected action sequence:\n";
179
180        for ( SequenceIterator pExpected = expectedSequence_.begin();
181          pExpected != expectedSequence_.end(); ++pExpected )
182        {
183          message += ( *pExpected )();
184        }
185
186        message += "\nActual action sequence:\n";
187
188        for ( SequenceIterator pActual = actualSequence_.begin();
189          pActual != actualSequence_.end(); ++pActual )
190        {
191          message += ( *pActual )();
192        }
193
194        BOOST_FAIL( message.c_str() );
195      }
196
197      actualSequence_.clear();
198    }
199
200    void ClearActualSequence()
201    {
202      actualSequence_.clear();
203    }
204
205    void ThrowAction( ActionPtr pThrowAction )
206    {
207      pThrowAction_ = pThrowAction;
208    }
209
210    template< class State >
211    void ActualEntry()
212    {
213      StoreActualAction< &::Entry< State > >();
214    }
215
216    template< class State >
217    void ActualExitFunction()
218    {
219      StoreActualAction< &::ExitFn< State > >();
220    }
221   
222    template< class State >
223    void ActualDestructor()
224    {
225      StoreActualAction< &::Dtor< State > >();
226    }
227   
228    template< class Context, class Event >
229    void ActualTransition()
230    {
231      StoreActualAction< &::Trans< Context, Event > >();
232    }
233
234    void unconsumed_event( const sc::event_base & )
235    {
236      ++unconsumedEventCount_;
237    }
238
239    unsigned int GetUnconsumedEventCount() const
240    {
241      return unconsumedEventCount_;
242    }
243
244  private:
245    //////////////////////////////////////////////////////////////////////////
246    template< ActionPtr pAction >
247    void StoreActualAction()
248    {
249      if ( pAction == pThrowAction_ )
250      {
251        Throw< pAction >( actualSequence_ );
252        throw TransitionTestException();
253      }
254      else
255      {
256        pAction( actualSequence_ );
257      }
258    }
259
260    ActionPtr pThrowAction_;
261    ActionDescriptionSequence actualSequence_;
262    ActionDescriptionSequence expectedSequence_;
263    unsigned int unconsumedEventCount_;
264};
265
266template< class M > struct S1;
267template< class M > struct S211;
268template< class M >
269struct S0 : Orthogonal0< S0< M >, M, S1< M > >
270{
271  typedef Orthogonal0< S0< M >, M, S1< M > > my_base;
272  public:
273    typedef sc::transition< E, S211< M > > reactions;
274
275    S0( typename my_base::my_context ctx ) : my_base( ctx ) {}
276
277    void Transit( const A & evt ) { TransitImpl( evt ); }
278    void Transit( const B & evt ) { TransitImpl( evt ); }
279    void Transit( const C & evt ) { TransitImpl( evt ); }
280    void Transit( const D & evt ) { TransitImpl( evt ); }
281    void Transit( const F & evt ) { TransitImpl( evt ); }
282    void Transit( const G & evt ) { TransitImpl( evt ); }
283    void Transit( const H & evt ) { TransitImpl( evt ); }
284
285  private:
286    template< class Event >
287    void TransitImpl( const Event & )
288    {
289      this->outermost_context().template ActualTransition< S0< M >, Event >();
290    }
291};
292
293  template< class M > struct S11;
294  template< class M > struct S21;
295  template< class M >
296  struct S2 : Orthogonal2< S2< M >, S0< M >, S21< M > >
297  {
298    typedef Orthogonal2< S2< M >, S0< M >, S21< M > > my_base;
299    typedef mpl::list<
300      sc::transition< C, S1< M >, S0< M >, &S0< M >::Transit >,
301      sc::transition< F, S11< M >, S0< M >, &S0< M >::Transit >
302    > reactions;
303
304    S2( typename my_base::my_context ctx ) : my_base( ctx ) {}
305  };
306
307    template< class M >
308    struct S21 : Orthogonal1<
309      S21< M >, typename S2< M >::template orthogonal< 2 >, S211< M > >
310    {
311      typedef Orthogonal1<
312        S21< M >, typename S2< M >::template orthogonal< 2 >, S211< M >
313      > my_base;
314      typedef mpl::list<
315        sc::transition< H, S21< M >, S0< M >, &S0< M >::Transit >,
316        sc::transition< B, S211< M >, S0< M >, &S0< M >::Transit >
317      > reactions;
318
319      S21( typename my_base::my_context ctx ) : my_base( ctx ) {}
320    };
321
322      template< class M >
323      struct S211 : InnermostDefault<
324        S211< M >, typename S21< M >::template orthogonal< 1 > >
325      {
326        typedef InnermostDefault<
327          S211< M >, typename S21< M >::template orthogonal< 1 > > my_base;
328        typedef mpl::list<
329          sc::transition< D, S21< M >, S0< M >, &S0< M >::Transit >,
330          sc::transition< G, S0< M > >
331        > reactions;
332
333        S211( typename my_base::my_context ctx ) : my_base( ctx ) {}
334      };
335
336  template< class M >
337  struct S1 : Orthogonal1< S1< M >, S0< M >, S11< M > >
338  {
339    typedef Orthogonal1< S1< M >, S0< M >, S11< M > > my_base;
340    typedef mpl::list<
341      sc::transition< A, S1< M >, S0< M >, &S0< M >::Transit >,
342      sc::transition< B, S11< M >, S0< M >, &S0< M >::Transit >,
343      sc::transition< C, S2< M >, S0< M >, &S0< M >::Transit >,
344      sc::transition< D, S0< M > >,
345      sc::transition< F, S211< M >, S0< M >, &S0< M >::Transit >
346    > reactions;
347
348    S1( typename my_base::my_context ctx ) : my_base( ctx ) {}
349  };
350
351    template< class M >
352    struct S11 : InnermostDefault<
353      S11< M >, typename S1< M >::template orthogonal< 1 > >
354    {
355      typedef InnermostDefault<
356        S11< M >, typename S1< M >::template orthogonal< 1 > > my_base;
357      typedef mpl::list<
358        sc::transition< G, S211< M >, S0< M >, &S0< M >::Transit >,
359        sc::custom_reaction< H >
360      > reactions;
361
362      S11( typename my_base::my_context ctx ) : my_base( ctx ) {}
363
364      sc::result react( const H & )
365      {
366        this->outermost_context().template ActualTransition< S11< M >, H >();
367        return this->discard_event();
368      }
369    };
370
371
372struct X1;
373struct TransitionEventBaseTest :
374  sc::state_machine< TransitionEventBaseTest, X1 >
375{
376  public:
377    TransitionEventBaseTest() : actionCallCounter_( 0 ) {}
378
379    void Transit( const sc::event_base & eventBase )
380    {
381      BOOST_REQUIRE(
382        ( dynamic_cast< const B * >( &eventBase ) != 0 ) ||
383        ( dynamic_cast< const D * >( &eventBase ) != 0 ) );
384      ++actionCallCounter_;
385    }
386
387    unsigned int GetActionCallCounter() const
388    {
389      return actionCallCounter_;
390    }
391
392  private:
393    unsigned int actionCallCounter_;
394};
395
396struct X2 : sc::simple_state< X2, TransitionEventBaseTest >
397{
398  typedef sc::transition< sc::event_base, X1,
399    TransitionEventBaseTest, &TransitionEventBaseTest::Transit > reactions;
400};
401
402struct X1 : sc::simple_state< X1, TransitionEventBaseTest >
403{
404  typedef sc::transition< sc::event_base, X2 > reactions;
405};
406
407template< class M >
408void TestTransitions( M & machine )
409{
410  machine.initiate();
411  ActionArray init = 
412  {
413    Entry< S0< M > >,
414    Entry< S1< M > >,
415    Entry< Default0< S1< M > > >,
416    Entry< S11< M > >,
417    Entry< Default2< S1< M > > >,
418    Entry< Default1< S0< M > > >,
419    Entry< Default2< S0< M > > >
420  };
421  machine.CompareToExpectedActionSequence( init );
422
423  machine.process_event( A() );
424  ActionArray a1 =
425  {
426    Exit< Default2< S1< M > > >,
427    Exit< S11< M > >,
428    Exit< Default0< S1< M > > >,
429    Exit< S1< M > >,
430    Trans< S0< M >, A >,
431    Entry< S1< M > >,
432    Entry< Default0< S1< M > > >,
433    Entry< S11< M > >,
434    Entry< Default2< S1< M > > >
435  };
436  machine.CompareToExpectedActionSequence( a1 );
437
438  machine.process_event( B() );
439  ActionArray b1 =
440  {
441    Exit< Default2< S1< M > > >,
442    Exit< S11< M > >,
443    Exit< Default0< S1< M > > >,
444    Exit< S1< M > >,
445    Trans< S0< M >, B >,
446    Entry< S1< M > >,
447    Entry< Default0< S1< M > > >,
448    Entry< S11< M > >,
449    Entry< Default2< S1< M > > >
450  };
451  machine.CompareToExpectedActionSequence( b1 );
452
453  machine.process_event( C() );
454  ActionArray c1 =
455  {
456    Exit< Default2< S1< M > > >,
457    Exit< S11< M > >,
458    Exit< Default0< S1< M > > >,
459    Exit< S1< M > >,
460    Trans< S0< M >, C >,
461    Entry< S2< M > >,
462    Entry< Default0< S2< M > > >,
463    Entry< Default1< S2< M > > >,
464    Entry< S21< M > >,
465    Entry< Default0< S21< M > > >,
466    Entry< S211< M > >,
467    Entry< Default2< S21< M > > >
468  };
469  machine.CompareToExpectedActionSequence( c1 );
470
471  machine.process_event( D() );
472  ActionArray d2 =
473  {
474    Exit< Default2< S21< M > > >,
475    Exit< S211< M > >,
476    Exit< Default0< S21< M > > >,
477    Exit< S21< M > >,
478    Trans< S0< M >, D >,
479    Entry< S21< M > >,
480    Entry< Default0< S21< M > > >,
481    Entry< S211< M > >,
482    Entry< Default2< S21< M > > >
483  };
484  machine.CompareToExpectedActionSequence( d2 );
485
486  machine.process_event( E() );
487  ActionArray e2 =
488  {
489    Exit< Default2< S0< M > > >,
490    Exit< Default1< S0< M > > >,
491    Exit< Default2< S21< M > > >,
492    Exit< S211< M > >,
493    Exit< Default0< S21< M > > >,
494    Exit< S21< M > >,
495    Exit< Default1< S2< M > > >,
496    Exit< Default0< S2< M > > >,
497    Exit< S2< M > >,
498    Exit< S0< M > >,
499    Entry< S0< M > >,
500    Entry< S2< M > >,
501    Entry< Default0< S2< M > > >,
502    Entry< Default1< S2< M > > >,
503    Entry< S21< M > >,
504    Entry< Default0< S21< M > > >,
505    Entry< S211< M > >,
506    Entry< Default2< S21< M > > >,
507    Entry< Default1< S0< M > > >,
508    Entry< Default2< S0< M > > >
509  };
510  machine.CompareToExpectedActionSequence( e2 );
511
512  machine.process_event( F() );
513  ActionArray f2 =
514  {
515    Exit< Default2< S21< M > > >,
516    Exit< S211< M > >,
517    Exit< Default0< S21< M > > >,
518    Exit< S21< M > >,
519    Exit< Default1< S2< M > > >,
520    Exit< Default0< S2< M > > >,
521    Exit< S2< M > >,
522    Trans< S0< M >, F >,
523    Entry< S1< M > >,
524    Entry< Default0< S1< M > > >,
525    Entry< S11< M > >,
526    Entry< Default2< S1< M > > >
527  };
528  machine.CompareToExpectedActionSequence( f2 );
529
530  machine.process_event( G() );
531  ActionArray g1 =
532  {
533    Exit< Default2< S1< M > > >,
534    Exit< S11< M > >,
535    Exit< Default0< S1< M > > >,
536    Exit< S1< M > >,
537    Trans< S0< M >, G >,
538    Entry< S2< M > >,
539    Entry< Default0< S2< M > > >,
540    Entry< Default1< S2< M > > >,
541    Entry< S21< M > >,
542    Entry< Default0< S21< M > > >,
543    Entry< S211< M > >,
544    Entry< Default2< S21< M > > >
545  };
546  machine.CompareToExpectedActionSequence( g1 );
547
548  machine.process_event( H() );
549  ActionArray h2 =
550  {
551    Exit< Default2< S21< M > > >,
552    Exit< S211< M > >,
553    Exit< Default0< S21< M > > >,
554    Exit< S21< M > >,
555    Trans< S0< M >, H >,
556    Entry< S21< M > >,
557    Entry< Default0< S21< M > > >,
558    Entry< S211< M > >,
559    Entry< Default2< S21< M > > >
560  };
561  machine.CompareToExpectedActionSequence( h2 );
562
563  BOOST_REQUIRE( machine.GetUnconsumedEventCount() == 0 );
564  machine.process_event( A() );
565  BOOST_REQUIRE( machine.GetUnconsumedEventCount() == 1 );
566  ActionArray a2 =
567  {
568  };
569  machine.CompareToExpectedActionSequence( a2 );
570
571  machine.process_event( B() );
572  ActionArray b2 =
573  {
574    Exit< Default2< S21< M > > >,
575    Exit< S211< M > >,
576    Exit< Default0< S21< M > > >,
577    Exit< S21< M > >,
578    Trans< S0< M >, B >,
579    Entry< S21< M > >,
580    Entry< Default0< S21< M > > >,
581    Entry< S211< M > >,
582    Entry< Default2< S21< M > > >
583  };
584  machine.CompareToExpectedActionSequence( b2 );
585
586  machine.process_event( C() );
587  ActionArray c2 =
588  {
589    Exit< Default2< S21< M > > >,
590    Exit< S211< M > >,
591    Exit< Default0< S21< M > > >,
592    Exit< S21< M > >,
593    Exit< Default1< S2< M > > >,
594    Exit< Default0< S2< M > > >,
595    Exit< S2< M > >,
596    Trans< S0< M >, C >,
597    Entry< S1< M > >,
598    Entry< Default0< S1< M > > >,
599    Entry< S11< M > >,
600    Entry< Default2< S1< M > > >
601  };
602  machine.CompareToExpectedActionSequence( c2 );
603
604  machine.process_event( D() );
605  ActionArray d1 = 
606  {
607    Exit< Default2< S0< M > > >,
608    Exit< Default1< S0< M > > >,
609    Exit< Default2< S1< M > > >,
610    Exit< S11< M > >,
611    Exit< Default0< S1< M > > >,
612    Exit< S1< M > >,
613    Exit< S0< M > >,
614    Entry< S0< M > >,
615    Entry< S1< M > >,
616    Entry< Default0< S1< M > > >,
617    Entry< S11< M > >,
618    Entry< Default2< S1< M > > >,
619    Entry< Default1< S0< M > > >,
620    Entry< Default2< S0< M > > >
621  };
622  machine.CompareToExpectedActionSequence( d1 );
623
624  machine.process_event( F() );
625  ActionArray f1 =
626  {
627    Exit< Default2< S1< M > > >,
628    Exit< S11< M > >,
629    Exit< Default0< S1< M > > >,
630    Exit< S1< M > >,
631    Trans< S0< M >, F >,
632    Entry< S2< M > >,
633    Entry< Default0< S2< M > > >,
634    Entry< Default1< S2< M > > >,
635    Entry< S21< M > >,
636    Entry< Default0< S21< M > > >,
637    Entry< S211< M > >,
638    Entry< Default2< S21< M > > >
639  };
640  machine.CompareToExpectedActionSequence( f1 );
641
642  machine.process_event( G() );
643  ActionArray g2 =
644  {
645    Exit< Default2< S0< M > > >,
646    Exit< Default1< S0< M > > >,
647    Exit< Default2< S21< M > > >,
648    Exit< S211< M > >,
649    Exit< Default0< S21< M > > >,
650    Exit< S21< M > >,
651    Exit< Default1< S2< M > > >,
652    Exit< Default0< S2< M > > >,
653    Exit< S2< M > >,
654    Exit< S0< M > >,
655    Entry< S0< M > >,
656    Entry< S1< M > >,
657    Entry< Default0< S1< M > > >,
658    Entry< S11< M > >,
659    Entry< Default2< S1< M > > >,
660    Entry< Default1< S0< M > > >,
661    Entry< Default2< S0< M > > >
662  };
663  machine.CompareToExpectedActionSequence( g2 );
664
665  machine.process_event( H() );
666  ActionArray h1 =
667  {
668    Trans< S11< M >, H >
669  };
670  machine.CompareToExpectedActionSequence( h1 );
671
672  machine.process_event( E() );
673  ActionArray e1 =
674  {
675    Exit< Default2< S0< M > > >,
676    Exit< Default1< S0< M > > >,
677    Exit< Default2< S1< M > > >,
678    Exit< S11< M > >,
679    Exit< Default0< S1< M > > >,
680    Exit< S1< M > >,
681    Exit< S0< M > >,
682    Entry< S0< M > >,
683    Entry< S2< M > >,
684    Entry< Default0< S2< M > > >,
685    Entry< Default1< S2< M > > >,
686    Entry< S21< M > >,
687    Entry< Default0< S21< M > > >,
688    Entry< S211< M > >,
689    Entry< Default2< S21< M > > >,
690    Entry< Default1< S0< M > > >,
691    Entry< Default2< S0< M > > >
692  };
693  machine.CompareToExpectedActionSequence( e1 );
694
695  machine.terminate();
696  ActionArray term =
697  {
698    Exit< Default2< S0< M > > >,
699    Exit< Default1< S0< M > > >,
700    Exit< Default2< S21< M > > >,
701    Exit< S211< M > >,
702    Exit< Default0< S21< M > > >,
703    Exit< S21< M > >,
704    Exit< Default1< S2< M > > >,
705    Exit< Default0< S2< M > > >,
706    Exit< S2< M > >,
707    Exit< S0< M > >
708  };
709  machine.CompareToExpectedActionSequence( term );
710
711  machine.ThrowAction( Entry< Default0< S1< M > > > );
712  BOOST_REQUIRE_THROW( machine.initiate(), TransitionTestException );
713  ActionArray initThrow1 = 
714  {
715    Entry< S0< M > >,
716    Entry< S1< M > >,
717    Throw< Entry< Default0< S1< M > > > >,
718    Dtor< S1< M > >,
719    Dtor< S0< M > >
720  };
721  machine.CompareToExpectedActionSequence( initThrow1 );
722  BOOST_REQUIRE( machine.terminated() );
723
724  machine.ThrowAction( Entry< S11< M > > );
725  BOOST_REQUIRE_THROW( machine.initiate(), TransitionTestException );
726  ActionArray initThrow2 = 
727  {
728    Entry< S0< M > >,
729    Entry< S1< M > >,
730    Entry< Default0< S1< M > > >,
731    Throw< Entry< S11< M > > >,
732    Dtor< Default0< S1< M > > >,
733    Dtor< S1< M > >,
734    Dtor< S0< M > >
735  };
736  machine.CompareToExpectedActionSequence( initThrow2 );
737  BOOST_REQUIRE( machine.terminated() );
738
739  machine.ThrowAction( Trans< S0< M >, A > );
740  machine.initiate();
741  BOOST_REQUIRE_THROW( machine.process_event( A() ), TransitionTestException );
742  ActionArray a1Throw1 =
743  {
744    Entry< S0< M > >,
745    Entry< S1< M > >,
746    Entry< Default0< S1< M > > >,
747    Entry< S11< M > >,
748    Entry< Default2< S1< M > > >,
749    Entry< Default1< S0< M > > >,
750    Entry< Default2< S0< M > > >,
751    Exit< Default2< S1< M > > >,
752    Exit< S11< M > >,
753    Exit< Default0< S1< M > > >,
754    Exit< S1< M > >,
755    Throw< Trans< S0< M >, A > >,
756    Dtor< Default2< S0< M > > >,
757    Dtor< Default1< S0< M > > >,
758    Dtor< S0< M > >
759  };
760  machine.CompareToExpectedActionSequence( a1Throw1 );
761  BOOST_REQUIRE( machine.terminated() );
762
763  machine.ThrowAction( Entry< S211< M > > );
764  machine.initiate();
765  BOOST_REQUIRE_THROW( machine.process_event( C() ), TransitionTestException );
766  ActionArray c1Throw1 =
767  {
768    Entry< S0< M > >,
769    Entry< S1< M > >,
770    Entry< Default0< S1< M > > >,
771    Entry< S11< M > >,
772    Entry< Default2< S1< M > > >,
773    Entry< Default1< S0< M > > >,
774    Entry< Default2< S0< M > > >,
775    Exit< Default2< S1< M > > >,
776    Exit< S11< M > >,
777    Exit< Default0< S1< M > > >,
778    Exit< S1< M > >,
779    Trans< S0< M >, C >,
780    Entry< S2< M > >,
781    Entry< Default0< S2< M > > >,
782    Entry< Default1< S2< M > > >,
783    Entry< S21< M > >,
784    Entry< Default0< S21< M > > >,
785    Throw< Entry< S211< M > > >,
786    Dtor< Default2< S0< M > > >,
787    Dtor< Default1< S0< M > > >,
788    Dtor< Default0< S21< M > > >,
789    Dtor< S21< M > >,
790    Dtor< Default1< S2< M > > >,
791    Dtor< Default0< S2< M > > >,
792    Dtor< S2< M > >,
793    Dtor< S0< M > >
794  };
795  machine.CompareToExpectedActionSequence( c1Throw1 );
796  BOOST_REQUIRE( machine.terminated() );
797
798  machine.ThrowAction( ExitFn< S11< M > > );
799  machine.initiate();
800  BOOST_REQUIRE_THROW( machine.process_event( C() ), TransitionTestException );
801  ActionArray c1Throw2 =
802  {
803    Entry< S0< M > >,
804    Entry< S1< M > >,
805    Entry< Default0< S1< M > > >,
806    Entry< S11< M > >,
807    Entry< Default2< S1< M > > >,
808    Entry< Default1< S0< M > > >,
809    Entry< Default2< S0< M > > >,
810    Exit< Default2< S1< M > > >,
811    Throw< ExitFn< S11< M > > >,
812    Dtor< S11< M > >,
813    Dtor< Default2< S0< M > > >,
814    Dtor< Default1< S0< M > > >,
815    Dtor< Default0< S1< M > > >,
816    Dtor< S1< M > >,
817    Dtor< S0< M > >
818  };
819  machine.CompareToExpectedActionSequence( c1Throw2 );
820  BOOST_REQUIRE( machine.terminated() );
821  BOOST_REQUIRE( machine.GetUnconsumedEventCount() == 1 );
822}
823
824
825int test_main( int, char* [] )
826{
827  TransitionTest< sc::null_exception_translator > null_machine;
828  TestTransitions( null_machine );
829  TransitionTest< sc::exception_translator<> > machine;
830  TestTransitions( machine );
831
832  TransitionEventBaseTest eventBaseMachine;
833  eventBaseMachine.initiate();
834  BOOST_REQUIRE_NO_THROW( eventBaseMachine.state_cast< const X1 & >() );
835  eventBaseMachine.process_event( A() );
836  BOOST_REQUIRE_NO_THROW( eventBaseMachine.state_cast< const X2 & >() );
837  BOOST_REQUIRE( eventBaseMachine.GetActionCallCounter() == 0 );
838  eventBaseMachine.process_event( B() );
839  BOOST_REQUIRE_NO_THROW( eventBaseMachine.state_cast< const X1 & >() );
840  BOOST_REQUIRE( eventBaseMachine.GetActionCallCounter() == 1 );
841  eventBaseMachine.process_event( C() );
842  BOOST_REQUIRE_NO_THROW( eventBaseMachine.state_cast< const X2 & >() );
843  BOOST_REQUIRE( eventBaseMachine.GetActionCallCounter() == 1 );
844  eventBaseMachine.process_event( D() );
845  BOOST_REQUIRE_NO_THROW( eventBaseMachine.state_cast< const X1 & >() );
846  BOOST_REQUIRE( eventBaseMachine.GetActionCallCounter() == 2 );
847
848  return 0;
849}
Note: See TracBrowser for help on using the repository browser.