motion-state-machine 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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