simple_state_machine 0.3.4 → 0.4.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/README.rdoc +8 -0
- data/VERSION +1 -1
- data/lib/simple_state_machine/simple_state_machine.rb +36 -7
- data/simple_state_machine.gemspec +2 -2
- data/spec/simple_state_machine_spec.rb +14 -0
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -36,6 +36,14 @@ This will prevent the state from being changed.
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
=== Example usage with exceptions
|
40
|
+
You can rescue exceptions and specify the failure state
|
41
|
+
|
42
|
+
def download_data
|
43
|
+
Service.download_data
|
44
|
+
end
|
45
|
+
event :download_data, :pending => :downloaded,
|
46
|
+
Service::ConnectionError => :download_failed
|
39
47
|
|
40
48
|
== More complete implementation
|
41
49
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -49,7 +49,7 @@ module SimpleStateMachine
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def add_transition event_name, from, to
|
52
|
-
transition = Transition.new(event_name
|
52
|
+
transition = Transition.new(event_name, from, to)
|
53
53
|
transitions << transition
|
54
54
|
transition
|
55
55
|
end
|
@@ -67,17 +67,32 @@ module SimpleStateMachine
|
|
67
67
|
@subject = subject
|
68
68
|
end
|
69
69
|
|
70
|
-
#
|
70
|
+
# Returns the next state for the subject for event_name
|
71
71
|
def next_state(event_name)
|
72
|
-
transition = transitions.select{|t| t.event_name
|
72
|
+
transition = transitions.select{|t| t.is_transition_for?(event_name) && @subject.send(state_method).to_s == t.from.to_s}.first
|
73
73
|
transition ? transition.to : nil
|
74
74
|
end
|
75
75
|
|
76
|
-
#
|
77
|
-
|
76
|
+
# Returns the error state for the subject for event_name and error
|
77
|
+
def error_state(event_name, error)
|
78
|
+
transition = transitions.select{|t| t.is_error_transition_for?(event_name, error) }.first
|
79
|
+
transition ? transition.to : nil
|
80
|
+
end
|
81
|
+
|
82
|
+
# Transitions to the next state if next_state exists.
|
83
|
+
# Calls illegal_event_callback event_name if no next_state is found
|
78
84
|
def transition(event_name)
|
79
85
|
if to = next_state(event_name)
|
80
|
-
|
86
|
+
begin
|
87
|
+
result = yield
|
88
|
+
rescue => e
|
89
|
+
if error_state = error_state(event_name, e)
|
90
|
+
@subject.send("#{state_method}=", error_state)
|
91
|
+
return result
|
92
|
+
else
|
93
|
+
raise
|
94
|
+
end
|
95
|
+
end
|
81
96
|
# TODO refactor out to AR module
|
82
97
|
if defined?(::ActiveRecord) && @subject.is_a?(::ActiveRecord::Base)
|
83
98
|
if @subject.errors.entries.empty?
|
@@ -116,7 +131,21 @@ module SimpleStateMachine
|
|
116
131
|
|
117
132
|
end
|
118
133
|
|
119
|
-
class Transition
|
134
|
+
class Transition
|
135
|
+
attr_reader :event_name, :from, :to
|
136
|
+
def initialize(event_name, from, to)
|
137
|
+
@event_name = event_name.to_s
|
138
|
+
@from = from.is_a?(Class) ? from : from.to_s
|
139
|
+
@to = to.to_s
|
140
|
+
end
|
141
|
+
|
142
|
+
def is_transition_for?(event_name)
|
143
|
+
self.event_name == event_name.to_s
|
144
|
+
end
|
145
|
+
|
146
|
+
def is_error_transition_for?(event_name, error)
|
147
|
+
is_transition_for?(event_name) && error.class == from
|
148
|
+
end
|
120
149
|
end
|
121
150
|
|
122
151
|
##
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{simple_state_machine}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Marek de Heus", "Petrik de Heus"]
|
12
|
-
s.date = %q{2010-09-
|
12
|
+
s.date = %q{2010-09-06}
|
13
13
|
s.description = %q{A simple DSL to decorate existing methods with logic that guards state transitions.}
|
14
14
|
s.email = ["FIX@example.com"]
|
15
15
|
s.extra_rdoc_files = [
|
@@ -42,6 +42,20 @@ describe SimpleStateMachine do
|
|
42
42
|
example.should be_state2
|
43
43
|
end
|
44
44
|
|
45
|
+
it "changes state to error_state when error should be caught" do
|
46
|
+
class_with_error = Class.new(SimpleExample)
|
47
|
+
class_with_error.instance_eval do
|
48
|
+
define_method :raise_error do
|
49
|
+
raise
|
50
|
+
end
|
51
|
+
event :raise_error, :state1 => :state2, RuntimeError => :failed
|
52
|
+
end
|
53
|
+
example = class_with_error.new
|
54
|
+
example.should be_state1
|
55
|
+
example.raise_error
|
56
|
+
example.should be_failed
|
57
|
+
end
|
58
|
+
|
45
59
|
it "raise an error if an invalid state_transition is called" do
|
46
60
|
example = SimpleExample.new
|
47
61
|
lambda { example.event2 }.should raise_error(SimpleStateMachine::Error, "You cannot 'event2' when state is 'state1'")
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_state_machine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 3
|
9
8
|
- 4
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Marek de Heus
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-09-
|
19
|
+
date: 2010-09-06 00:00:00 +02:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|