motion-state-machine 0.8.1

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.
@@ -0,0 +1,48 @@
1
+ describe StateMachine::TimedTransition do
2
+
3
+ before do
4
+ @state_machine = StateMachine::Base.new start_state: :timing_out
5
+ action = proc { @fired = true }
6
+ @state_machine.when :timing_out do |state|
7
+ @transition = state.transition_to(:timed_out, after: 0.5, action: action).first
8
+ state.transition_to :canceled, on: :cancel
9
+ end
10
+ end
11
+
12
+ it "should be created correctly" do
13
+ @transition.should.is_a(StateMachine::TimedTransition)
14
+ end
15
+
16
+ describe "after entering the state that is timing out" do
17
+ before do
18
+ @fired = false
19
+ @other_queue = Dispatch::Queue.concurrent :default
20
+ @other_queue.sync do
21
+ @state_machine.start! # will arm the transition
22
+ end
23
+ @state_machine.current_state.symbol.should == :timing_out
24
+ @fired.should == false
25
+ end
26
+
27
+ it "it should execute at the given time if not cancelled" do
28
+ sleep 0.49
29
+ @state_machine.current_state.symbol.should == :timing_out
30
+ @fired.should == false
31
+ sleep 0.02
32
+ @state_machine.current_state.symbol.should == :timed_out
33
+ @fired.should == true
34
+ end
35
+
36
+ it "should not execute if leaving the state before timeout" do
37
+ sleep 0.49
38
+ @fired.should == false
39
+ @other_queue.async do
40
+ @state_machine.event :cancel
41
+ end
42
+ sleep 0.02
43
+ @state_machine.current_state.symbol.should == :canceled
44
+ @fired.should == false
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,157 @@
1
+ describe StateMachine::Transition do
2
+ before do
3
+ @state_machine = StateMachine::Base.new start_state: :awake
4
+ @source_state = @state_machine.state :awake
5
+ @destination_state = @state_machine.state :tired
6
+ @options = {
7
+ state_machine: @state_machine,
8
+ from: :awake,
9
+ to: :tired,
10
+ on: :work_done
11
+ }
12
+ StateMachine::Transition.event_type = :on
13
+ end
14
+
15
+ describe "#initialize(options)" do
16
+ it "should not raise if correctly initialized" do
17
+ proc {StateMachine::Transition.new @options}.should.not.raise
18
+ end
19
+
20
+ it "should raise if it should be internal, but source state != destination state" do
21
+ @options[:from].should != @options[:to]
22
+ proc {StateMachine::Transition.new @options.merge(internal: true)}.
23
+ should.raise ArgumentError, /Internal/
24
+ end
25
+ end
26
+
27
+ describe "after initialization" do
28
+ before do
29
+ @transition = StateMachine::Transition.new @options
30
+ end
31
+
32
+ describe "#allowed?" do
33
+ it "should be true if no guard blocks are given" do
34
+ @transition.should.be.allowed
35
+ end
36
+
37
+ it "should have the correct logic results according to a logic table" do
38
+ # :unless :if allowed?
39
+ {
40
+ [nil, nil] => true,
41
+ [nil, false] => false,
42
+ [nil, true] => true,
43
+ [false, nil] => true,
44
+ [false, false] => false,
45
+ [false, true] => true,
46
+ [true, nil] => false,
47
+ [true, false] => false,
48
+ [true, true] => false,
49
+ }.each do |guards, result|
50
+ transition = StateMachine::Transition.new @options.dup
51
+ transition.options[:unless] = proc {guards[0]} unless guards[0].nil?
52
+ transition.options[:if] = proc {guards[1]} unless guards[1].nil?
53
+ transition.allowed?.should == result
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ describe "#unguarded_execute" do
60
+ it "should call its source state's exit method if not internal" do
61
+ exit_action_called = false
62
+ @state_machine.when(:awake) do |state|
63
+ state.on_exit do
64
+ exit_action_called = true
65
+ end
66
+ end
67
+ @state_machine.start!
68
+ exit_action_called.should == false
69
+ @transition.send :unguarded_execute
70
+ exit_action_called.should == true
71
+ end
72
+
73
+ it "should not call its source state's exit method if internal" do
74
+ @transition.options[:internal] = true
75
+ exit_action_called = false
76
+ @state_machine.when(:awake) do |state|
77
+ state.on_exit do
78
+ exit_action_called = true
79
+ end
80
+ end
81
+ @state_machine.start!
82
+ exit_action_called.should == false
83
+ @transition.send :unguarded_execute
84
+ exit_action_called.should == false
85
+ end
86
+
87
+ it "should call its destination state's enter method if not internal" do
88
+ entry_action_called = false
89
+ @state_machine.when(:tired) do |state|
90
+ state.on_entry do
91
+ entry_action_called = true
92
+ end
93
+ end
94
+ @state_machine.start!
95
+ entry_action_called.should == false
96
+ @transition.send :unguarded_execute
97
+ entry_action_called.should == true
98
+ end
99
+
100
+ it "should not call its destination state's enter method if internal" do
101
+ @transition.options[:internal] = true
102
+ entry_action_called = false
103
+ @state_machine.when(:tired) do |state|
104
+ state.on_entry do
105
+ entry_action_called = true
106
+ end
107
+ end
108
+ @state_machine.start!
109
+ entry_action_called.should == false
110
+ @transition.send :unguarded_execute
111
+ entry_action_called.should == false
112
+ end
113
+
114
+ it "should call its action block if given" do
115
+ called = false
116
+ argument = nil
117
+ @transition.options[:action] = proc do |state_machine|
118
+ called = true
119
+ argument = state_machine
120
+ end
121
+ @state_machine.start!
122
+ called.should == false
123
+ @transition.send :unguarded_execute
124
+ called.should == true
125
+ argument.should == @state_machine
126
+ end
127
+
128
+ it "should not be guarded, but directly execute" do
129
+ @transition.options[:if] = proc { false }
130
+ @transition.options[:unless] = proc { true }
131
+ @state_machine.start!
132
+ @state_machine.current_state.symbol.should == :awake
133
+ @transition.send :unguarded_execute
134
+ @state_machine.current_state.symbol.should == :tired
135
+ end
136
+ end
137
+
138
+ describe "#handle_in_source_state" do
139
+ it "should raise if called before the state machine is started" do
140
+ @state_machine.current_state.symbol.should == :waiting_for_start
141
+ proc {@transition.send :handle_in_source_state}.
142
+ should.raise RuntimeError, /started/
143
+ end
144
+
145
+ it "should raise if called outside the initial queue" do
146
+ @state_machine.start!
147
+ other_queue = Dispatch::Queue.concurrent(:default)
148
+ other_queue.to_s.should != Dispatch::Queue.main.to_s
149
+ other_queue.sync do
150
+ proc {@transition.send :handle_in_source_state}.should.raise RuntimeError, /queue/
151
+ end
152
+ @state_machine.current_state.symbol.should == :awake
153
+ end
154
+ end
155
+ end
156
+
157
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: motion-state-machine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.8.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Sebastian Burkhart
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70177501197480 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70177501197480
25
+ description: A finite state machine for RubyMotion with a flavor of Grand Central
26
+ Dispatch.
27
+ email:
28
+ - sebastianburkhart@me.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - .gitignore
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - lib/motion-state-machine.rb
39
+ - lib/motion-state-machine/base.rb
40
+ - lib/motion-state-machine/spec_app_delegate.rb
41
+ - lib/motion-state-machine/state.rb
42
+ - lib/motion-state-machine/transition.rb
43
+ - lib/motion-state-machine/version.rb
44
+ - motion-state-machine.gemspec
45
+ - spec/motion-state-machine/base_spec.rb
46
+ - spec/motion-state-machine/benchmark_spec.rb
47
+ - spec/motion-state-machine/notification_transition_spec.rb
48
+ - spec/motion-state-machine/send_event_transition_spec.rb
49
+ - spec/motion-state-machine/state_spec.rb
50
+ - spec/motion-state-machine/timed_transition_spec.rb
51
+ - spec/motion-state-machine/transition_spec.rb
52
+ homepage: https://github.com/opyh/motion-state-machine
53
+ licenses: []
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ! '>='
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ segments:
65
+ - 0
66
+ hash: 774551363156047026
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ segments:
74
+ - 0
75
+ hash: 774551363156047026
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 1.8.10
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Comes with a nice syntax for state and transition definition. Supports triggering
82
+ via events, timeouts and NSNotifications.
83
+ test_files:
84
+ - spec/motion-state-machine/base_spec.rb
85
+ - spec/motion-state-machine/benchmark_spec.rb
86
+ - spec/motion-state-machine/notification_transition_spec.rb
87
+ - spec/motion-state-machine/send_event_transition_spec.rb
88
+ - spec/motion-state-machine/state_spec.rb
89
+ - spec/motion-state-machine/timed_transition_spec.rb
90
+ - spec/motion-state-machine/transition_spec.rb