File: SimpleInternalWithPuml.cpp

package info (click to toggle)
boost1.90 1.90.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 593,120 kB
  • sloc: cpp: 4,190,908; xml: 196,648; python: 34,618; ansic: 23,145; asm: 5,468; sh: 3,774; makefile: 1,161; perl: 1,020; sql: 728; ruby: 676; yacc: 478; java: 77; lisp: 24; csh: 6
file content (155 lines) | stat: -rw-r--r-- 8,534 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2024 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
// under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)


// back-end
#include "BackCommon.hpp"
//front-end
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/puml/puml.hpp>
#include "PumlCommon.hpp"

#ifndef BOOST_MSM_NONSTANDALONE_TEST
#define BOOST_TEST_MODULE simple_internal_with_puml
#endif
#include <boost/test/unit_test.hpp>

using namespace std;
namespace msm = boost::msm;
using namespace msm::front;
using namespace msm::front::puml;



namespace
{


    // front-end: define the FSM structure 
    struct player_ : public msm::front::state_machine_def<player_>
    {
        unsigned int start_playback_counter=0;
        unsigned int can_close_drawer_counter=0;
        unsigned int internal_action_counter=0;
        unsigned int internal_guard_counter=0;

        BOOST_MSM_PUML_DECLARE_TABLE(
            R"( 
            @startuml Player
            skinparam linetype polyline
            state Player{
                [*]-> Empty
                Stopped     -> Playing   : play         / start_playback
                Stopped     -> Open      : open_close   / open_drawer
                Stopped     -> Stopped   : stop

                Open        -> Empty     : open_close                             [can_close_drawer]
                
                Empty       --> Open     : open_close    / open_drawer
                Empty       ---> Stopped : cd_detected   / store_cd_info          [good_disk_format]
                Empty       -> Empty     : -internal_evt / internal_action        [internal_guard2]              
                Empty       -> Empty     : -to_ignore
                Empty       -> Empty     : -cd_detected                           [internal_guard]              
                Empty       -> Empty     : -internal_evt / internal_action_fct    [internal_guard_fct]              

                Playing     --> Stopped  : stop          / stop_playback
                Playing     -> Paused    : pause         / pause_playback
                Playing     --> Open     : open_close    / stop_and_open
                
                Paused      -> Playing   : end_pause     / resume_playback
                Paused      --> Stopped  : stop          / stop_playback
                Paused      --> Open     : open_close    / stop_and_open
            }
            @enduml
        )"
        )

        // Replaces the default no-transition response.
        template <class FSM,class Event>
        void no_transition(Event const&, FSM&,int)
        {
            BOOST_FAIL("no_transition called!");
        }
    };
    // Pick a back-end
    typedef get_test_machines<player_> players;


    BOOST_AUTO_TEST_CASE_TEMPLATE( simple_internal_with_puml_test, player, players )
    {     
        player p;

        p.start(); 
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 1, "Empty entry not called correctly");
        // internal events
        p.process_event(Event<by_name("to_ignore")>{});
        p.process_event(Event<by_name("internal_evt")>{});
        BOOST_CHECK_MESSAGE(p.internal_action_counter == 1, "Internal action not called correctly");
        BOOST_CHECK_MESSAGE(p.internal_guard_counter == 1, "Internal guard not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().empty_internal_action_counter == 0, "Empty internal action not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().empty_internal_guard_counter == 1, "Empty internal guard not called correctly");

        p.process_event(Event<by_name("open_close")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 1,"Open should be active"); //Open
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().exit_counter == 1,"Empty exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().entry_counter == 1,"Open entry not called correctly");

        p.process_event(Event<by_name("open_close")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");
        BOOST_CHECK_MESSAGE(p.can_close_drawer_counter == 1,"guard not called correctly");

        p.process_event(Event<by_name("cd_detected")>{"louie, louie", DISK_DVD});

        BOOST_CHECK_MESSAGE(p.current_state()[0] == 2,"Empty should be active"); //Empty
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Open")>&>().exit_counter == 1,"Open exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().entry_counter == 2,"Empty entry not called correctly");

        p.process_event(Event<by_name("cd_detected")>{"louie, louie", DISK_CD});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 0, "Stopped should be active"); //Stopped
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Empty")>&>().exit_counter == 2,"Empty exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 1,"Stopped entry not called correctly");
        BOOST_CHECK_MESSAGE(p.internal_guard_counter == 3, "Internal guard not called correctly");

        p.process_event(Event<by_name("play")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 3, "Playing should be active"); //Playing
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 1, "Stopped exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing")>&>().entry_counter == 1, "Playing entry not called correctly");
        BOOST_CHECK_MESSAGE(p.start_playback_counter == 1, "action not called correctly");

        p.process_event(Event<by_name("pause")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 4, "Paused should be active"); //Paused
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 1, "Playing exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().entry_counter == 1, "Paused entry not called correctly");

        // go back to Playing
        p.process_event(Event<by_name("end_pause")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 3,"Playing should be active"); //Playing
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().exit_counter == 1,"Paused exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing")>&>().entry_counter == 2,"Playing entry not called correctly");

        p.process_event(Event<by_name("pause")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 4,"Paused should be active"); //Paused
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Playing")>&>().exit_counter == 2,"Playing exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().entry_counter == 2,"Paused entry not called correctly");

        p.process_event(Event<by_name("stop")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Paused")>&>().exit_counter == 2,"Paused exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 2,"Stopped entry not called correctly");

        p.process_event(Event<by_name("stop")>{});
        BOOST_CHECK_MESSAGE(p.current_state()[0] == 0,"Stopped should be active"); //Stopped
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().exit_counter == 2,"Stopped exit not called correctly");
        BOOST_CHECK_MESSAGE(p.template get_state<State<by_name("Stopped")>&>().entry_counter == 3,"Stopped entry not called correctly");

    }
}