statemachine 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +15 -0
 - data/TODO +4 -0
 - data/lib/statemachine.rb +5 -0
 - data/lib/statemachine/builder.rb +111 -0
 - data/lib/statemachine/proc_calling.rb +6 -41
 - data/lib/statemachine/state.rb +7 -30
 - data/lib/statemachine/state_machine.rb +63 -54
 - data/lib/statemachine/super_state.rb +10 -42
 - data/lib/statemachine/transition.rb +23 -21
 - data/lib/statemachine/version.rb +2 -2
 - data/spec/builder_spec.rb +131 -0
 - data/spec/sm_action_parameterization_spec.rb +38 -53
 - data/spec/sm_entry_exit_actions_spec.rb +35 -27
 - data/spec/sm_odds_n_ends_spec.rb +47 -5
 - data/spec/sm_simple_spec.rb +3 -36
 - data/spec/sm_super_state_spec.rb +13 -54
 - data/spec/sm_turnstile_spec.rb +18 -20
 - data/spec/spec_helper.rb +15 -11
 - data/spec/transition_spec.rb +68 -58
 - metadata +7 -3
 
    
        data/spec/sm_odds_n_ends_spec.rb
    CHANGED
    
    | 
         @@ -5,7 +5,6 @@ context "State Machine Odds And Ends" do 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
              setup do
         
     | 
| 
       7 
7 
     | 
    
         
             
                create_switch
         
     | 
| 
       8 
     | 
    
         
            -
                @sm.run
         
     | 
| 
       9 
8 
     | 
    
         
             
              end
         
     | 
| 
       10 
9 
     | 
    
         | 
| 
       11 
10 
     | 
    
         
             
              specify "method missing delegates to super in case of no event" do
         
     | 
| 
         @@ -13,15 +12,58 @@ context "State Machine Odds And Ends" do 
     | 
|
| 
       13 
12 
     | 
    
         
             
              end
         
     | 
| 
       14 
13 
     | 
    
         | 
| 
       15 
14 
     | 
    
         
             
              specify "set state with string" do
         
     | 
| 
       16 
     | 
    
         
            -
                @sm.state. 
     | 
| 
      
 15 
     | 
    
         
            +
                @sm.state.should_be :off
         
     | 
| 
       17 
16 
     | 
    
         
             
                @sm.state = "on"
         
     | 
| 
       18 
     | 
    
         
            -
                @sm.state. 
     | 
| 
      
 17 
     | 
    
         
            +
                @sm.state.should_be :on
         
     | 
| 
       19 
18 
     | 
    
         
             
              end
         
     | 
| 
       20 
19 
     | 
    
         | 
| 
       21 
20 
     | 
    
         
             
              specify "set state with symbol" do
         
     | 
| 
       22 
     | 
    
         
            -
                @sm.state. 
     | 
| 
      
 21 
     | 
    
         
            +
                @sm.state.should_be :off
         
     | 
| 
       23 
22 
     | 
    
         
             
                @sm.state = :on
         
     | 
| 
       24 
     | 
    
         
            -
                @sm.state. 
     | 
| 
      
 23 
     | 
    
         
            +
                @sm.state.should_be :on
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
              
         
     | 
| 
      
 26 
     | 
    
         
            +
              specify "process event accepts strings" do
         
     | 
| 
      
 27 
     | 
    
         
            +
                @sm.process_event("toggle")
         
     | 
| 
      
 28 
     | 
    
         
            +
                @sm.state.should_be :on
         
     | 
| 
       25 
29 
     | 
    
         
             
              end
         
     | 
| 
       26 
30 
     | 
    
         | 
| 
       27 
31 
     | 
    
         
             
            end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            context "Special States" do
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              setup do
         
     | 
| 
      
 36 
     | 
    
         
            +
                @sm = StateMachine.build do |s|
         
     | 
| 
      
 37 
     | 
    
         
            +
                  s.superstate :operate do |o|
         
     | 
| 
      
 38 
     | 
    
         
            +
                    o.trans :on, :toggle, :off
         
     | 
| 
      
 39 
     | 
    
         
            +
                    o.trans :off, :toggle, :on
         
     | 
| 
      
 40 
     | 
    
         
            +
                    o.event :fiddle, :middle
         
     | 
| 
      
 41 
     | 
    
         
            +
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  s.trans :middle, :fiddle, :operate_H
         
     | 
| 
      
 43 
     | 
    
         
            +
                  s.trans :middle, :push, :stuck
         
     | 
| 
      
 44 
     | 
    
         
            +
                  s.trans :middle, :dream, :on_H
         
     | 
| 
      
 45 
     | 
    
         
            +
                  s.start_state :middle
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
              
         
     | 
| 
      
 49 
     | 
    
         
            +
              specify "states without transitions are valid" do
         
     | 
| 
      
 50 
     | 
    
         
            +
                @sm.push
         
     | 
| 
      
 51 
     | 
    
         
            +
                @sm.state.should_be :stuck
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
              
         
     | 
| 
      
 54 
     | 
    
         
            +
              specify "no history allowed for concrete states" do
         
     | 
| 
      
 55 
     | 
    
         
            +
                lambda {
         
     | 
| 
      
 56 
     | 
    
         
            +
                    @sm.dream
         
     | 
| 
      
 57 
     | 
    
         
            +
                  }.should_raise(StateMachine::StateMachineException, "No history exists for 'on' state since it is not a super state.")
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              specify "error when trying to use history that doesn't exist yet" do
         
     | 
| 
      
 61 
     | 
    
         
            +
                lambda {
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @sm.fiddle
         
     | 
| 
      
 63 
     | 
    
         
            +
                  }.should_raise(StateMachine::StateMachineException, "'operate' superstate doesn't have any history yet.")
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
    
        data/spec/sm_simple_spec.rb
    CHANGED
    
    | 
         @@ -7,52 +7,19 @@ context "simple cases:" do 
     | 
|
| 
       7 
7 
     | 
    
         
             
                @proc = Proc.new {@count = @count + 1}
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
              specify "one transition has states" do
         
     | 
| 
       11 
     | 
    
         
            -
                @sm.add(:on, :flip, :off, @proc)
         
     | 
| 
       12 
     | 
    
         
            -
                
         
     | 
| 
       13 
     | 
    
         
            -
                @sm.states.length.should_be 2
         
     | 
| 
       14 
     | 
    
         
            -
                @sm[:on].should_not_be nil
         
     | 
| 
       15 
     | 
    
         
            -
                @sm[:off].should_not_be nil
         
     | 
| 
       16 
     | 
    
         
            -
              end
         
     | 
| 
       17 
     | 
    
         
            -
                
         
     | 
| 
       18 
     | 
    
         
            -
              specify "one trasition create connects states with transition" do
         
     | 
| 
       19 
     | 
    
         
            -
                @sm.add(:on, :flip, :off, @proc)
         
     | 
| 
       20 
     | 
    
         
            -
                origin = @sm[:on]
         
     | 
| 
       21 
     | 
    
         
            -
                destination = @sm[:off]
         
     | 
| 
       22 
     | 
    
         
            -
                
         
     | 
| 
       23 
     | 
    
         
            -
                origin.transitions.length.should_be 1
         
     | 
| 
       24 
     | 
    
         
            -
                destination.transitions.length.should_be 0
         
     | 
| 
       25 
     | 
    
         
            -
                transition = origin[:flip]
         
     | 
| 
       26 
     | 
    
         
            -
                check_transition(transition, :on, :off, :flip, @proc)
         
     | 
| 
       27 
     | 
    
         
            -
              end
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
10 
     | 
    
         
             
              specify "reset" do
         
     | 
| 
       30 
     | 
    
         
            -
                @sm. 
     | 
| 
       31 
     | 
    
         
            -
                @sm.run
         
     | 
| 
      
 11 
     | 
    
         
            +
                StateMachine.build(@sm) { |s| s.trans :start, :blah, :end, @proc }
         
     | 
| 
       32 
12 
     | 
    
         
             
                @sm.process_event(:blah)
         
     | 
| 
       33 
13 
     | 
    
         | 
| 
       34 
14 
     | 
    
         
             
                @sm.reset
         
     | 
| 
       35 
15 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                @sm.state. 
     | 
| 
       37 
     | 
    
         
            -
              end
         
     | 
| 
       38 
     | 
    
         
            -
              
         
     | 
| 
       39 
     | 
    
         
            -
              specify "exception when state machine is not running" do
         
     | 
| 
       40 
     | 
    
         
            -
                @sm.add(:on, :flip, :off)
         
     | 
| 
       41 
     | 
    
         
            -
                
         
     | 
| 
       42 
     | 
    
         
            -
                begin
         
     | 
| 
       43 
     | 
    
         
            -
                  @sm.process_event(:flip)
         
     | 
| 
       44 
     | 
    
         
            -
                rescue StateMachine::StateMachineException => e
         
     | 
| 
       45 
     | 
    
         
            -
                  e.message.should_equal "The state machine isn't in any state.  Did you forget to call run?"
         
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                @sm.state.should_be :start
         
     | 
| 
       47 
17 
     | 
    
         
             
              end
         
     | 
| 
       48 
18 
     | 
    
         | 
| 
       49 
19 
     | 
    
         
             
              specify "no proc in transition" do
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                @sm.run
         
     | 
| 
      
 20 
     | 
    
         
            +
                 StateMachine.build(@sm) { |s| s.trans :on, :flip, :off }
         
     | 
| 
       52 
21 
     | 
    
         | 
| 
       53 
22 
     | 
    
         
             
                @sm.flip
         
     | 
| 
       54 
23 
     | 
    
         
             
              end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
              
         
     | 
| 
       57 
24 
     | 
    
         | 
| 
       58 
25 
     | 
    
         
             
            end
         
     | 
    
        data/spec/sm_super_state_spec.rb
    CHANGED
    
    | 
         @@ -7,16 +7,23 @@ context "Turn Stile" do 
     | 
|
| 
       7 
7 
     | 
    
         
             
                create_turnstile
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
                @out_out_order = false
         
     | 
| 
       10 
     | 
    
         
            -
                @sm.add(:operative, :maintain, :maintenance, Proc.new { @out_of_order = true } )
         
     | 
| 
       11 
     | 
    
         
            -
                @sm.add(:maintenance, :operate, :operative, Proc.new { @out_of_order = false } )
         
     | 
| 
       12 
     | 
    
         
            -
                @sm[:operative].add_substates(:locked, :unlocked)
         
     | 
| 
       13 
10 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
                @sm. 
     | 
| 
      
 11 
     | 
    
         
            +
                @sm = StateMachine.build do |s|
         
     | 
| 
      
 12 
     | 
    
         
            +
                  s.superstate :operative do |o|
         
     | 
| 
      
 13 
     | 
    
         
            +
                    o.trans :locked, :coin, :unlocked, @unlock
         
     | 
| 
      
 14 
     | 
    
         
            +
                    o.trans :unlocked, :pass, :locked, @lock
         
     | 
| 
      
 15 
     | 
    
         
            +
                    o.trans :locked, :pass, :locked, @alarm
         
     | 
| 
      
 16 
     | 
    
         
            +
                    o.trans :unlocked, :coin, :locked, @thankyou
         
     | 
| 
      
 17 
     | 
    
         
            +
                    o.event :maintain, :maintenance, Proc.new { @out_of_order = true }
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  s.trans :maintenance, :operate, :operative, Proc.new { @out_of_order = false } 
         
     | 
| 
      
 20 
     | 
    
         
            +
                  s.start_state :locked
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
       15 
22 
     | 
    
         
             
              end
         
     | 
| 
       16 
23 
     | 
    
         | 
| 
       17 
24 
     | 
    
         
             
              specify "substates respond to superstate transitions" do
         
     | 
| 
       18 
25 
     | 
    
         
             
                @sm.process_event(:maintain)
         
     | 
| 
       19 
     | 
    
         
            -
                @sm.state. 
     | 
| 
      
 26 
     | 
    
         
            +
                @sm.state.should_be :maintenance
         
     | 
| 
       20 
27 
     | 
    
         
             
                @locked.should_be true
         
     | 
| 
       21 
28 
     | 
    
         
             
                @out_of_order.should_be true
         
     | 
| 
       22 
29 
     | 
    
         
             
              end
         
     | 
| 
         @@ -24,57 +31,9 @@ context "Turn Stile" do 
     | 
|
| 
       24 
31 
     | 
    
         
             
              specify "after transitions, substates respond to superstate transitions" do
         
     | 
| 
       25 
32 
     | 
    
         
             
                @sm.coin
         
     | 
| 
       26 
33 
     | 
    
         
             
                @sm.maintain
         
     | 
| 
       27 
     | 
    
         
            -
                @sm.state. 
     | 
| 
      
 34 
     | 
    
         
            +
                @sm.state.should_be :maintenance
         
     | 
| 
       28 
35 
     | 
    
         
             
                @locked.should_be false
         
     | 
| 
       29 
36 
     | 
    
         
             
                @out_of_order.should_be true
         
     | 
| 
       30 
37 
     | 
    
         
             
              end
         
     | 
| 
       31 
38 
     | 
    
         | 
| 
       32 
     | 
    
         
            -
              specify "transitions back to superstate go to history state" do
         
     | 
| 
       33 
     | 
    
         
            -
                @sm[:operative].use_history
         
     | 
| 
       34 
     | 
    
         
            -
                @sm.maintain
         
     | 
| 
       35 
     | 
    
         
            -
                @sm.operate
         
     | 
| 
       36 
     | 
    
         
            -
                @sm.state.id.should_be :locked
         
     | 
| 
       37 
     | 
    
         
            -
                @out_of_order.should_be false
         
     | 
| 
       38 
     | 
    
         
            -
                
         
     | 
| 
       39 
     | 
    
         
            -
                @sm.coin
         
     | 
| 
       40 
     | 
    
         
            -
                @sm.maintain
         
     | 
| 
       41 
     | 
    
         
            -
                @sm.operate
         
     | 
| 
       42 
     | 
    
         
            -
                @sm.state.id.should_be :unlocked
         
     | 
| 
       43 
     | 
    
         
            -
              end
         
     | 
| 
       44 
     | 
    
         
            -
              
         
     | 
| 
       45 
     | 
    
         
            -
              specify "missing substates are added" do
         
     | 
| 
       46 
     | 
    
         
            -
                @sm[:operative].add_substates(:blah)
         
     | 
| 
       47 
     | 
    
         
            -
                @sm[:blah].should_not_be nil
         
     | 
| 
       48 
     | 
    
         
            -
                @sm[:blah].superstate.id.should_be :operative
         
     | 
| 
       49 
     | 
    
         
            -
              end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
              specify "recursive superstates not allowed" do
         
     | 
| 
       52 
     | 
    
         
            -
                begin
         
     | 
| 
       53 
     | 
    
         
            -
                  @sm[:operative].add_substates(:operative)
         
     | 
| 
       54 
     | 
    
         
            -
                  self.should_fail_with_message("exception expected")
         
     | 
| 
       55 
     | 
    
         
            -
                rescue StateMachine::StateMachineException => e
         
     | 
| 
       56 
     | 
    
         
            -
                  e.message.should_equal "Cyclic substates not allowed. (operative)"
         
     | 
| 
       57 
     | 
    
         
            -
                end
         
     | 
| 
       58 
     | 
    
         
            -
              end
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
              specify "recursive superstates (2 levels) not allowed" do
         
     | 
| 
       61 
     | 
    
         
            -
                begin
         
     | 
| 
       62 
     | 
    
         
            -
                  @sm[:operative].add_substates(:blah)
         
     | 
| 
       63 
     | 
    
         
            -
                  @sm[:blah].add_substates(:operative)
         
     | 
| 
       64 
     | 
    
         
            -
                  self.should_fail_with_message("exception expected")
         
     | 
| 
       65 
     | 
    
         
            -
                rescue StateMachine::StateMachineException => e
         
     | 
| 
       66 
     | 
    
         
            -
                  e.message.should_equal "Cyclic substates not allowed. (blah)"
         
     | 
| 
       67 
     | 
    
         
            -
                end
         
     | 
| 
       68 
     | 
    
         
            -
              end
         
     | 
| 
       69 
     | 
    
         
            -
              
         
     | 
| 
       70 
     | 
    
         
            -
              specify "exception when add_substates called without args" do
         
     | 
| 
       71 
     | 
    
         
            -
                begin
         
     | 
| 
       72 
     | 
    
         
            -
                  @sm[:locked].add_substates()
         
     | 
| 
       73 
     | 
    
         
            -
                  self.should_fail_with_message("exception expected")
         
     | 
| 
       74 
     | 
    
         
            -
                rescue StateMachine::StateMachineException => e
         
     | 
| 
       75 
     | 
    
         
            -
                  e.message.should_equal "At least one parameter is required for add_substates."
         
     | 
| 
       76 
     | 
    
         
            -
                end
         
     | 
| 
       77 
     | 
    
         
            -
              end
         
     | 
| 
       78 
     | 
    
         
            -
              
         
     | 
| 
       79 
     | 
    
         
            -
              
         
     | 
| 
       80 
39 
     | 
    
         
             
            end
         
     | 
    
        data/spec/sm_turnstile_spec.rb
    CHANGED
    
    | 
         @@ -5,27 +5,25 @@ context "Turn Stile" do 
     | 
|
| 
       5 
5 
     | 
    
         | 
| 
       6 
6 
     | 
    
         
             
              setup do
         
     | 
| 
       7 
7 
     | 
    
         
             
                create_turnstile
         
     | 
| 
       8 
     | 
    
         
            -
                @sm.run
         
     | 
| 
       9 
8 
     | 
    
         
             
              end
         
     | 
| 
       10 
9 
     | 
    
         | 
| 
       11 
10 
     | 
    
         
             
              specify "connections" do
         
     | 
| 
       12 
     | 
    
         
            -
                @sm. 
     | 
| 
       13 
     | 
    
         
            -
                 
     | 
| 
       14 
     | 
    
         
            -
                unlocked_state = @sm[:unlocked]
         
     | 
| 
      
 11 
     | 
    
         
            +
                locked_state = @sm.get_state(:locked)
         
     | 
| 
      
 12 
     | 
    
         
            +
                unlocked_state = @sm.get_state(:unlocked)
         
     | 
| 
       15 
13 
     | 
    
         | 
| 
       16 
14 
     | 
    
         
             
                locked_state.transitions.length.should_be 2
         
     | 
| 
       17 
15 
     | 
    
         
             
                unlocked_state.transitions.length.should_be 2
         
     | 
| 
       18 
16 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
                check_transition(locked_state[:coin], :locked, :unlocked, :coin, @unlock)
         
     | 
| 
       20 
     | 
    
         
            -
                check_transition(locked_state[:pass], :locked, :locked, :pass, @alarm)
         
     | 
| 
       21 
     | 
    
         
            -
                check_transition(unlocked_state[:pass], :unlocked, :locked, :pass, @lock)
         
     | 
| 
       22 
     | 
    
         
            -
                check_transition(unlocked_state[:coin], :unlocked, :locked, :coin, @thankyou)
         
     | 
| 
      
 17 
     | 
    
         
            +
                check_transition(locked_state.transitions[:coin], :locked, :unlocked, :coin, @unlock)
         
     | 
| 
      
 18 
     | 
    
         
            +
                check_transition(locked_state.transitions[:pass], :locked, :locked, :pass, @alarm)
         
     | 
| 
      
 19 
     | 
    
         
            +
                check_transition(unlocked_state.transitions[:pass], :unlocked, :locked, :pass, @lock)
         
     | 
| 
      
 20 
     | 
    
         
            +
                check_transition(unlocked_state.transitions[:coin], :unlocked, :locked, :coin, @thankyou)
         
     | 
| 
       23 
21 
     | 
    
         
             
              end
         
     | 
| 
       24 
22 
     | 
    
         | 
| 
       25 
23 
     | 
    
         
             
              specify "start state" do
         
     | 
| 
       26 
     | 
    
         
            -
                @sm. 
     | 
| 
       27 
     | 
    
         
            -
                @sm.start_state.should.be  
     | 
| 
       28 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 24 
     | 
    
         
            +
                @sm.reset
         
     | 
| 
      
 25 
     | 
    
         
            +
                @sm.start_state.should.be :locked
         
     | 
| 
      
 26 
     | 
    
         
            +
                @sm.state.should.be :locked
         
     | 
| 
       29 
27 
     | 
    
         
             
              end
         
     | 
| 
       30 
28 
     | 
    
         | 
| 
       31 
29 
     | 
    
         
             
              specify "bad event" do
         
     | 
| 
         @@ -33,31 +31,31 @@ context "Turn Stile" do 
     | 
|
| 
       33 
31 
     | 
    
         
             
                  @sm.process_event(:blah)
         
     | 
| 
       34 
32 
     | 
    
         
             
                  self.should.fail_with_message("Exception expected")
         
     | 
| 
       35 
33 
     | 
    
         
             
                rescue Exception => e
         
     | 
| 
       36 
     | 
    
         
            -
                  e.class.should.be StateMachine:: 
     | 
| 
       37 
     | 
    
         
            -
                  e.to_s. 
     | 
| 
      
 34 
     | 
    
         
            +
                  e.class.should.be StateMachine::StateMachineException
         
     | 
| 
      
 35 
     | 
    
         
            +
                  e.to_s.should_eql "'locked' state does not respond to the 'blah' event."
         
     | 
| 
       38 
36 
     | 
    
         
             
                end
         
     | 
| 
       39 
37 
     | 
    
         
             
              end
         
     | 
| 
       40 
38 
     | 
    
         | 
| 
       41 
39 
     | 
    
         
             
              specify "locked state with a coin" do
         
     | 
| 
       42 
40 
     | 
    
         
             
                @sm.process_event(:coin)
         
     | 
| 
       43 
41 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 42 
     | 
    
         
            +
                @sm.state.should.be :unlocked
         
     | 
| 
       45 
43 
     | 
    
         
             
                @locked.should.be false
         
     | 
| 
       46 
44 
     | 
    
         
             
              end
         
     | 
| 
       47 
45 
     | 
    
         | 
| 
       48 
46 
     | 
    
         
             
              specify "locked state with pass event" do
         
     | 
| 
       49 
47 
     | 
    
         
             
                @sm.process_event(:pass)
         
     | 
| 
       50 
48 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 49 
     | 
    
         
            +
                @sm.state.should.be :locked
         
     | 
| 
       52 
50 
     | 
    
         
             
                @locked.should.be true
         
     | 
| 
       53 
     | 
    
         
            -
                @ 
     | 
| 
      
 51 
     | 
    
         
            +
                @alarm_status.should.be true
         
     | 
| 
       54 
52 
     | 
    
         
             
              end
         
     | 
| 
       55 
53 
     | 
    
         | 
| 
       56 
54 
     | 
    
         
             
              specify "unlocked state with coin" do
         
     | 
| 
       57 
55 
     | 
    
         
             
                @sm.process_event(:coin)
         
     | 
| 
       58 
56 
     | 
    
         
             
                @sm.process_event(:coin)
         
     | 
| 
       59 
57 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 58 
     | 
    
         
            +
                @sm.state.should.be :locked
         
     | 
| 
       61 
59 
     | 
    
         
             
                @thankyou_status.should.be true
         
     | 
| 
       62 
60 
     | 
    
         
             
              end
         
     | 
| 
       63 
61 
     | 
    
         | 
| 
         @@ -65,14 +63,14 @@ context "Turn Stile" do 
     | 
|
| 
       65 
63 
     | 
    
         
             
                @sm.process_event(:coin)
         
     | 
| 
       66 
64 
     | 
    
         
             
                @sm.process_event(:pass)
         
     | 
| 
       67 
65 
     | 
    
         | 
| 
       68 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 66 
     | 
    
         
            +
                @sm.state.should.be :locked
         
     | 
| 
       69 
67 
     | 
    
         
             
                @locked.should.be true
         
     | 
| 
       70 
68 
     | 
    
         
             
              end
         
     | 
| 
       71 
69 
     | 
    
         | 
| 
       72 
70 
     | 
    
         
             
              specify "events invoked via method_missing" do
         
     | 
| 
       73 
71 
     | 
    
         
             
                @sm.coin
         
     | 
| 
       74 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 72 
     | 
    
         
            +
                @sm.state.should.be :unlocked
         
     | 
| 
       75 
73 
     | 
    
         
             
                @sm.pass
         
     | 
| 
       76 
     | 
    
         
            -
                @sm.state.should.be  
     | 
| 
      
 74 
     | 
    
         
            +
                @sm.state.should.be :locked
         
     | 
| 
       77 
75 
     | 
    
         
             
              end
         
     | 
| 
       78 
76 
     | 
    
         
             
            end
         
     | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    | 
         @@ -1,21 +1,24 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            $:.unshift('lib')
         
     | 
| 
      
 1 
     | 
    
         
            +
            $:.unshift(File.dirname(__FILE__) + '/../lib')
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'spec'
         
     | 
| 
       2 
4 
     | 
    
         
             
            require 'statemachine'
         
     | 
| 
       3 
5 
     | 
    
         | 
| 
       4 
6 
     | 
    
         
             
            def check_transition(transition, origin_id, destination_id, event, action)
         
     | 
| 
       5 
7 
     | 
    
         
             
              transition.should_not_be nil
         
     | 
| 
       6 
8 
     | 
    
         
             
              transition.event.should_be event
         
     | 
| 
       7 
9 
     | 
    
         
             
              transition.action.should_be action
         
     | 
| 
       8 
     | 
    
         
            -
              transition. 
     | 
| 
       9 
     | 
    
         
            -
              transition. 
     | 
| 
      
 10 
     | 
    
         
            +
              transition.origin_id.should_be origin_id
         
     | 
| 
      
 11 
     | 
    
         
            +
              transition.destination_id.should_be destination_id
         
     | 
| 
       10 
12 
     | 
    
         
             
            end
         
     | 
| 
       11 
13 
     | 
    
         | 
| 
       12 
14 
     | 
    
         
             
            module SwitchStateMachine
         
     | 
| 
       13 
15 
     | 
    
         | 
| 
       14 
16 
     | 
    
         
             
              def create_switch
         
     | 
| 
       15 
17 
     | 
    
         
             
                @status = "off"
         
     | 
| 
       16 
     | 
    
         
            -
                @sm = StateMachine 
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 18 
     | 
    
         
            +
                @sm = StateMachine.build do |s|
         
     | 
| 
      
 19 
     | 
    
         
            +
                  s.trans :off, :toggle, :on, Proc.new { @status = "on" } 
         
     | 
| 
      
 20 
     | 
    
         
            +
                  s.trans :on, :toggle, :off, Proc.new { @status = "off" }
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
       19 
22 
     | 
    
         
             
              end
         
     | 
| 
       20 
23 
     | 
    
         | 
| 
       21 
24 
     | 
    
         
             
            end
         
     | 
| 
         @@ -31,11 +34,12 @@ module TurnstileStateMachine 
     | 
|
| 
       31 
34 
     | 
    
         
             
                @alarm = Proc.new { @alarm_status = true }
         
     | 
| 
       32 
35 
     | 
    
         
             
                @thankyou = Proc.new { @thankyou_status = true }
         
     | 
| 
       33 
36 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                @sm = StateMachine 
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
                @sm = StateMachine.build do |s|
         
     | 
| 
      
 38 
     | 
    
         
            +
                  s.trans :locked, :coin, :unlocked, @unlock
         
     | 
| 
      
 39 
     | 
    
         
            +
                  s.trans :unlocked, :pass, :locked, @lock
         
     | 
| 
      
 40 
     | 
    
         
            +
                  s.trans :locked, :pass, :locked, @alarm
         
     | 
| 
      
 41 
     | 
    
         
            +
                  s.trans :unlocked, :coin, :locked, @thankyou
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
       39 
43 
     | 
    
         
             
              end
         
     | 
| 
       40 
44 
     | 
    
         | 
| 
       41 
45 
     | 
    
         
             
            end
         
     | 
    
        data/spec/transition_spec.rb
    CHANGED
    
    | 
         @@ -3,95 +3,105 @@ require File.dirname(__FILE__) + '/spec_helper' 
     | 
|
| 
       3 
3 
     | 
    
         
             
            context "Transition Calculating Exits and Entries" do
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
              setup do
         
     | 
| 
       6 
     | 
    
         
            -
                @ 
     | 
| 
       7 
     | 
    
         
            -
                @b = StateMachine::State.new("b", nil)
         
     | 
| 
       8 
     | 
    
         
            -
                @c = StateMachine::State.new("c", nil)
         
     | 
| 
       9 
     | 
    
         
            -
                @d = StateMachine::State.new("d", nil)
         
     | 
| 
       10 
     | 
    
         
            -
                @e = StateMachine::State.new("e", nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                @transition = StateMachine::Transition.new(nil, nil, nil, nil)
         
     | 
| 
       11 
7 
     | 
    
         
             
              end
         
     | 
| 
       12 
8 
     | 
    
         | 
| 
       13 
9 
     | 
    
         
             
              specify "to nil" do
         
     | 
| 
       14 
     | 
    
         
            -
                 
     | 
| 
       15 
     | 
    
         
            -
                exits, entries = transition.exits_and_entries(@a)
         
     | 
| 
       16 
     | 
    
         
            -
                exits.to_s. 
     | 
| 
       17 
     | 
    
         
            -
                entries.to_s. 
     | 
| 
      
 10 
     | 
    
         
            +
                @a = StateMachine::State.new("a", nil, nil)
         
     | 
| 
      
 11 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, nil)
         
     | 
| 
      
 12 
     | 
    
         
            +
                exits.to_s.should_eql [@a].to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                entries.to_s.should_eql [].to_s
         
     | 
| 
       18 
14 
     | 
    
         
             
                entries.length.should_be 0
         
     | 
| 
       19 
15 
     | 
    
         
             
              end
         
     | 
| 
       20 
16 
     | 
    
         | 
| 
       21 
17 
     | 
    
         
             
              specify "to itself" do
         
     | 
| 
       22 
     | 
    
         
            -
                 
     | 
| 
       23 
     | 
    
         
            -
                exits, entries = transition.exits_and_entries(@a)
         
     | 
| 
       24 
     | 
    
         
            -
                exits.to_s. 
     | 
| 
       25 
     | 
    
         
            -
                entries.to_s. 
     | 
| 
      
 18 
     | 
    
         
            +
                @a = StateMachine::State.new("a", nil, nil)
         
     | 
| 
      
 19 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @a)
         
     | 
| 
      
 20 
     | 
    
         
            +
                exits.to_s.should_eql [@a].to_s
         
     | 
| 
      
 21 
     | 
    
         
            +
                entries.to_s.should_eql [@a].to_s
         
     | 
| 
       26 
22 
     | 
    
         
             
              end
         
     | 
| 
       27 
23 
     | 
    
         | 
| 
       28 
24 
     | 
    
         
             
              specify "to friend" do
         
     | 
| 
       29 
     | 
    
         
            -
                 
     | 
| 
       30 
     | 
    
         
            -
                 
     | 
| 
       31 
     | 
    
         
            -
                exits. 
     | 
| 
       32 
     | 
    
         
            -
                 
     | 
| 
      
 25 
     | 
    
         
            +
                @a = StateMachine::State.new("a", nil, nil)
         
     | 
| 
      
 26 
     | 
    
         
            +
                @b = StateMachine::State.new("b", nil, nil)
         
     | 
| 
      
 27 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @b)
         
     | 
| 
      
 28 
     | 
    
         
            +
                exits.to_s.should_eql [@a].to_s
         
     | 
| 
      
 29 
     | 
    
         
            +
                entries.to_s.should_eql [@b].to_s
         
     | 
| 
       33 
30 
     | 
    
         
             
              end
         
     | 
| 
       34 
31 
     | 
    
         | 
| 
       35 
32 
     | 
    
         
             
              specify "to parent" do
         
     | 
| 
       36 
     | 
    
         
            -
                @ 
     | 
| 
       37 
     | 
    
         
            -
                 
     | 
| 
       38 
     | 
    
         
            -
                exits, entries = transition.exits_and_entries(@a)
         
     | 
| 
       39 
     | 
    
         
            -
                exits.to_s. 
     | 
| 
       40 
     | 
    
         
            -
                entries.to_s. 
     | 
| 
      
 33 
     | 
    
         
            +
                @b = StateMachine::State.new("b", nil, nil)
         
     | 
| 
      
 34 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil)
         
     | 
| 
      
 35 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @b)
         
     | 
| 
      
 36 
     | 
    
         
            +
                exits.to_s.should_eql [@a, @b].to_s
         
     | 
| 
      
 37 
     | 
    
         
            +
                entries.to_s.should_eql [@b].to_s
         
     | 
| 
       41 
38 
     | 
    
         
             
              end
         
     | 
| 
       42 
39 
     | 
    
         | 
| 
       43 
40 
     | 
    
         
             
              specify "to uncle" do
         
     | 
| 
       44 
     | 
    
         
            -
                @ 
     | 
| 
       45 
     | 
    
         
            -
                 
     | 
| 
       46 
     | 
    
         
            -
                 
     | 
| 
       47 
     | 
    
         
            -
                exits 
     | 
| 
       48 
     | 
    
         
            -
                 
     | 
| 
      
 41 
     | 
    
         
            +
                @b = StateMachine::State.new("b", nil, nil)
         
     | 
| 
      
 42 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil)
         
     | 
| 
      
 43 
     | 
    
         
            +
                @c = StateMachine::State.new("c", nil, nil)
         
     | 
| 
      
 44 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @c)
         
     | 
| 
      
 45 
     | 
    
         
            +
                exits.to_s.should_eql [@a, @b].to_s
         
     | 
| 
      
 46 
     | 
    
         
            +
                entries.to_s.should_eql [@c].to_s
         
     | 
| 
       49 
47 
     | 
    
         
             
              end
         
     | 
| 
       50 
48 
     | 
    
         | 
| 
       51 
49 
     | 
    
         
             
              specify "to cousin" do
         
     | 
| 
       52 
     | 
    
         
            -
                @ 
     | 
| 
       53 
     | 
    
         
            -
                @ 
     | 
| 
       54 
     | 
    
         
            -
                 
     | 
| 
       55 
     | 
    
         
            -
                 
     | 
| 
       56 
     | 
    
         
            -
                exits 
     | 
| 
       57 
     | 
    
         
            -
                 
     | 
| 
      
 50 
     | 
    
         
            +
                @b = StateMachine::State.new("b", nil, nil)
         
     | 
| 
      
 51 
     | 
    
         
            +
                @d = StateMachine::State.new("d", nil, nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil)
         
     | 
| 
      
 53 
     | 
    
         
            +
                @c = StateMachine::State.new("c", @d, nil)
         
     | 
| 
      
 54 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @c)
         
     | 
| 
      
 55 
     | 
    
         
            +
                exits.to_s.should_eql [@a, @b].to_s
         
     | 
| 
      
 56 
     | 
    
         
            +
                entries.to_s.should_eql [@d, @c].to_s
         
     | 
| 
       58 
57 
     | 
    
         
             
              end
         
     | 
| 
       59 
58 
     | 
    
         | 
| 
       60 
59 
     | 
    
         
             
              specify "to nephew" do
         
     | 
| 
       61 
     | 
    
         
            -
                @ 
     | 
| 
       62 
     | 
    
         
            -
                 
     | 
| 
       63 
     | 
    
         
            -
                 
     | 
| 
       64 
     | 
    
         
            -
                exits. 
     | 
| 
       65 
     | 
    
         
            -
                 
     | 
| 
      
 60 
     | 
    
         
            +
                @b = StateMachine::State.new("b", nil, nil)
         
     | 
| 
      
 61 
     | 
    
         
            +
                @c = StateMachine::State.new("c", nil, nil)
         
     | 
| 
      
 62 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil)
         
     | 
| 
      
 63 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@c, @a)
         
     | 
| 
      
 64 
     | 
    
         
            +
                exits.to_s.should_eql [@c].to_s
         
     | 
| 
      
 65 
     | 
    
         
            +
                entries.to_s.should_eql [@b,@a].to_s
         
     | 
| 
       66 
66 
     | 
    
         
             
              end
         
     | 
| 
       67 
67 
     | 
    
         | 
| 
       68 
68 
     | 
    
         
             
              specify "to sister" do
         
     | 
| 
       69 
     | 
    
         
            -
                @ 
     | 
| 
       70 
     | 
    
         
            -
                @ 
     | 
| 
       71 
     | 
    
         
            -
                 
     | 
| 
       72 
     | 
    
         
            -
                exits, entries = transition.exits_and_entries(@a)
         
     | 
| 
       73 
     | 
    
         
            -
                exits.to_s. 
     | 
| 
       74 
     | 
    
         
            -
                entries.to_s. 
     | 
| 
      
 69 
     | 
    
         
            +
                @c = StateMachine::State.new("c", nil, nil)
         
     | 
| 
      
 70 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @c, nil)
         
     | 
| 
      
 71 
     | 
    
         
            +
                @b = StateMachine::State.new("b", @c, nil)
         
     | 
| 
      
 72 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @b)
         
     | 
| 
      
 73 
     | 
    
         
            +
                exits.to_s.should_eql [@a].to_s
         
     | 
| 
      
 74 
     | 
    
         
            +
                entries.to_s.should_eql [@b].to_s
         
     | 
| 
       75 
75 
     | 
    
         
             
              end
         
     | 
| 
       76 
76 
     | 
    
         | 
| 
       77 
77 
     | 
    
         
             
              specify "to second cousin" do
         
     | 
| 
       78 
     | 
    
         
            -
                @ 
     | 
| 
       79 
     | 
    
         
            -
                @b 
     | 
| 
       80 
     | 
    
         
            -
                @ 
     | 
| 
       81 
     | 
    
         
            -
                @e 
     | 
| 
       82 
     | 
    
         
            -
                 
     | 
| 
       83 
     | 
    
         
            -
                exits, entries = transition.exits_and_entries(@a)
         
     | 
| 
       84 
     | 
    
         
            -
                exits.to_s. 
     | 
| 
       85 
     | 
    
         
            -
                entries.to_s. 
     | 
| 
      
 78 
     | 
    
         
            +
                @c = StateMachine::State.new("c", nil, nil)
         
     | 
| 
      
 79 
     | 
    
         
            +
                @b = StateMachine::State.new("b", @c, nil)
         
     | 
| 
      
 80 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil)
         
     | 
| 
      
 81 
     | 
    
         
            +
                @e = StateMachine::State.new("e", @c, nil)
         
     | 
| 
      
 82 
     | 
    
         
            +
                @d = StateMachine::State.new("d", @e, nil)
         
     | 
| 
      
 83 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @d)
         
     | 
| 
      
 84 
     | 
    
         
            +
                exits.to_s.should_eql [@a, @b].to_s
         
     | 
| 
      
 85 
     | 
    
         
            +
                entries.to_s.should_eql [@e, @d].to_s
         
     | 
| 
       86 
86 
     | 
    
         
             
              end
         
     | 
| 
       87 
87 
     | 
    
         | 
| 
       88 
88 
     | 
    
         
             
              specify "to grandparent" do
         
     | 
| 
       89 
     | 
    
         
            -
                @ 
     | 
| 
       90 
     | 
    
         
            -
                @b 
     | 
| 
       91 
     | 
    
         
            -
                 
     | 
| 
       92 
     | 
    
         
            -
                exits, entries = transition.exits_and_entries(@a)
         
     | 
| 
       93 
     | 
    
         
            -
                exits.to_s. 
     | 
| 
       94 
     | 
    
         
            -
                entries.to_s. 
     | 
| 
      
 89 
     | 
    
         
            +
                @c = StateMachine::State.new("c", nil, nil)
         
     | 
| 
      
 90 
     | 
    
         
            +
                @b = StateMachine::State.new("b", @c, nil)
         
     | 
| 
      
 91 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil)
         
     | 
| 
      
 92 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@a, @c)
         
     | 
| 
      
 93 
     | 
    
         
            +
                exits.to_s.should_eql [@a, @b, @c].to_s
         
     | 
| 
      
 94 
     | 
    
         
            +
                entries.to_s.should_eql [@c].to_s
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              specify "to parent's grandchild" do
         
     | 
| 
      
 98 
     | 
    
         
            +
                @c = StateMachine::State.new("c", nil, nil)
         
     | 
| 
      
 99 
     | 
    
         
            +
                @b = StateMachine::State.new("b", @c, nil)
         
     | 
| 
      
 100 
     | 
    
         
            +
                @a = StateMachine::State.new("a", @b, nil) 
         
     | 
| 
      
 101 
     | 
    
         
            +
                @d = StateMachine::State.new("d", @c, nil)
         
     | 
| 
      
 102 
     | 
    
         
            +
                exits, entries = @transition.exits_and_entries(@d, @a)
         
     | 
| 
      
 103 
     | 
    
         
            +
                exits.to_s.should_eql [@d].to_s
         
     | 
| 
      
 104 
     | 
    
         
            +
                entries.to_s.should_eql [@b, @a].to_s
         
     | 
| 
       95 
105 
     | 
    
         
             
              end
         
     | 
| 
       96 
106 
     | 
    
         | 
| 
       97 
107 
     | 
    
         
             
            end
         
     |