transitions 0.1.13 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/active_model/transitions.rb +1 -1
- data/lib/transitions/event.rb +11 -0
- data/lib/transitions/machine.rb +6 -3
- data/lib/transitions/version.rb +1 -1
- data/lib/transitions.rb +5 -4
- data/test/machine/machine_template.rb +27 -0
- data/test/machine/test_fire_event_machine.rb +29 -0
- data/test/machine/test_machine.rb +9 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f76fbe7e05b93bbec46f0faa6723169979ec375
|
4
|
+
data.tar.gz: d968ddb9b44da30cb3b8f34bfa5f536e33d3a6a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39fecff9fec8636c7a99efbac2f32fed979717da83c552e9c73732582ffff3a7e987ef1ce9b1b4032abd6c3491c42f148fa477013c77e18da03e4230e393a3fa
|
7
|
+
data.tar.gz: 7829b0d74c9cb917f4569285eaebb4ed83c4ba73405b3e42e7419f5c2a0d3ead24e4f42bf30ccf5a2a26a61e7524556b45ee290756d2fdbda13e585c2764226a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# 0.2.0
|
2
|
+
|
3
|
+
* (troessner) Fix missing explicit returns in our callback handling
|
4
|
+
* (Lee Henson) add can_execute_event? to check against guard clauses
|
5
|
+
* (Randy Schmidt / r38y) Make reading state work for non-AR models.
|
6
|
+
|
1
7
|
# 0.1.13
|
2
8
|
|
3
9
|
* (Nathan Amick and Ryan Long) Allow passing non-Proc callables as guards
|
@@ -32,7 +32,7 @@ module ActiveModel
|
|
32
32
|
# The optional options argument is passed to find when reloading so you may
|
33
33
|
# do e.g. record.reload(:lock => true) to reload the same record with an
|
34
34
|
# exclusive row lock.
|
35
|
-
def reload(
|
35
|
+
def reload(*)
|
36
36
|
super.tap do
|
37
37
|
sm = self.class.get_state_machine
|
38
38
|
remove_instance_variable(sm.current_state_variable) if instance_variable_defined?(sm.current_state_variable)
|
data/lib/transitions/event.rb
CHANGED
@@ -16,6 +16,13 @@ module Transitions
|
|
16
16
|
machine.klass.send(:define_method, "can_#{name.to_s}?") do |*args|
|
17
17
|
machine.events_for(current_state).include?(name.to_sym)
|
18
18
|
end
|
19
|
+
|
20
|
+
machine.klass.send(:define_method, "can_execute_#{name.to_s}?") do |*args|
|
21
|
+
event = name.to_sym
|
22
|
+
|
23
|
+
send("can_#{name.to_s}?", *args) &&
|
24
|
+
machine.events[event].can_execute_transition_from_state?(current_state, self, *args)
|
25
|
+
end
|
19
26
|
end
|
20
27
|
update(options, &block)
|
21
28
|
end
|
@@ -42,6 +49,10 @@ module Transitions
|
|
42
49
|
@transitions.any? { |t| t.from? state }
|
43
50
|
end
|
44
51
|
|
52
|
+
def can_execute_transition_from_state?(state, obj, *args)
|
53
|
+
@transitions.select { |t| t.from? state }.any? { |t| t.executable?(obj, *args) }
|
54
|
+
end
|
55
|
+
|
45
56
|
def ==(event)
|
46
57
|
if event.is_a? Symbol
|
47
58
|
name == event
|
data/lib/transitions/machine.rb
CHANGED
@@ -17,7 +17,7 @@ module Transitions
|
|
17
17
|
@initial_state = options[:initial] if options.key?(:initial)
|
18
18
|
@auto_scopes = options[:auto_scopes]
|
19
19
|
instance_eval(&block) if block
|
20
|
-
include_scopes if @auto_scopes && ::Transitions.
|
20
|
+
include_scopes if @auto_scopes && ::Transitions.active_model_descendant?(klass)
|
21
21
|
self
|
22
22
|
end
|
23
23
|
|
@@ -26,15 +26,18 @@ module Transitions
|
|
26
26
|
handle_state_exit_callback record
|
27
27
|
if new_state = transition_to_new_state(record, event, *args)
|
28
28
|
handle_state_enter_callback record, new_state
|
29
|
-
|
29
|
+
handle_event_fired_callback record, new_state, event
|
30
30
|
record.update_current_state(new_state, persist)
|
31
31
|
handle_event_success_callback record, event
|
32
|
+
return true
|
32
33
|
else
|
33
34
|
handle_event_failed_callback record, event
|
35
|
+
return false
|
34
36
|
end
|
35
37
|
rescue => e
|
36
38
|
if record.respond_to?(:event_failed)
|
37
39
|
record.send(:event_failed, event)
|
40
|
+
return false
|
38
41
|
else
|
39
42
|
raise e
|
40
43
|
end
|
@@ -64,7 +67,7 @@ module Transitions
|
|
64
67
|
state_index[new_state].call_action(:enter, record)
|
65
68
|
end
|
66
69
|
|
67
|
-
def
|
70
|
+
def handle_event_fired_callback(record, new_state, event)
|
68
71
|
if record.respond_to?(:event_fired, true)
|
69
72
|
record.send(:event_fired, record.current_state, new_state, event)
|
70
73
|
end
|
data/lib/transitions/version.rb
CHANGED
data/lib/transitions.rb
CHANGED
@@ -44,7 +44,8 @@ module Transitions
|
|
44
44
|
def update_current_state(new_state, persist = false)
|
45
45
|
sm = self.class.get_state_machine
|
46
46
|
ivar = sm.current_state_variable
|
47
|
-
|
47
|
+
|
48
|
+
if Transitions.active_model_descendant?(self.class)
|
48
49
|
write_state(new_state) if persist
|
49
50
|
write_state_without_persistence(new_state) # TODO This seems like a duplicate, `write_new` already calls `write_state_without_persistence`.
|
50
51
|
end
|
@@ -73,14 +74,14 @@ module Transitions
|
|
73
74
|
value = instance_variable_get(ivar)
|
74
75
|
return value if value
|
75
76
|
|
76
|
-
if
|
77
|
+
if Transitions.active_model_descendant?(self.class)
|
77
78
|
value = instance_variable_set(ivar, read_state)
|
78
79
|
end
|
79
80
|
|
80
81
|
!(value.nil? || value.to_s.empty?) ? value : sm.initial_state
|
81
82
|
end
|
82
83
|
|
83
|
-
def self.
|
84
|
-
defined?(
|
84
|
+
def self.active_model_descendant?(klazz)
|
85
|
+
defined?(ActiveModel) && klazz.included_modules.include?(ActiveModel::Dirty) # Checking directly for "ActiveModel" wouldn't work so we use some arbitrary module close to it.
|
85
86
|
end
|
86
87
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class MachineTestSubject
|
2
|
+
include Transitions
|
3
|
+
|
4
|
+
state_machine :initial => :open do
|
5
|
+
state :open
|
6
|
+
state :closed
|
7
|
+
|
8
|
+
event :shutdown do
|
9
|
+
transitions :from => :open, :to => :closed
|
10
|
+
end
|
11
|
+
|
12
|
+
event :timeout do
|
13
|
+
transitions :from => :open, :to => :closed
|
14
|
+
end
|
15
|
+
|
16
|
+
event :restart do
|
17
|
+
transitions :from => :closed, to: :open, guard: :restart_allowed?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def restart_allowed?(allowed = true)
|
22
|
+
allowed
|
23
|
+
end
|
24
|
+
|
25
|
+
def event_failed(*)
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "helper"
|
2
|
+
require_relative "./machine_template"
|
3
|
+
|
4
|
+
class TestFireEventMachine < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@record = MachineTestSubject.new
|
7
|
+
@machine = MachineTestSubject.get_state_machine
|
8
|
+
@event = @machine.events_for(@record.current_state).first
|
9
|
+
assert_not_nil @event
|
10
|
+
end
|
11
|
+
|
12
|
+
test "fire_event returns true if state transition was successful" do
|
13
|
+
@machine.stubs(:transition_to_new_state).returns(:closed)
|
14
|
+
|
15
|
+
assert_equal true, @machine.fire_event(@event, @record, false)
|
16
|
+
end
|
17
|
+
|
18
|
+
test "fire_event returns false if state transition was unsuccessful" do
|
19
|
+
@machine.stubs(:transition_to_new_state).returns(false)
|
20
|
+
|
21
|
+
assert_equal false, @machine.fire_event(@event, @record, false)
|
22
|
+
end
|
23
|
+
|
24
|
+
test "fire_event returns false if state transition raises" do
|
25
|
+
@machine.stubs(:transition_to_new_state).raises(StandardError)
|
26
|
+
|
27
|
+
assert_equal false, @machine.fire_event(@event, @record, false)
|
28
|
+
end
|
29
|
+
end
|
@@ -16,9 +16,13 @@ class MachineTestSubject
|
|
16
16
|
end
|
17
17
|
|
18
18
|
event :restart do
|
19
|
-
transitions :from => :closed, to: :open
|
19
|
+
transitions :from => :closed, to: :open, guard: :restart_allowed?
|
20
20
|
end
|
21
21
|
end
|
22
|
+
|
23
|
+
def restart_allowed?(allowed = true)
|
24
|
+
allowed
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
class TransitionsMachineTest < Test::Unit::TestCase
|
@@ -54,7 +58,9 @@ class TransitionsMachineTest < Test::Unit::TestCase
|
|
54
58
|
assert machine.cant_transition?(:shutdown)
|
55
59
|
end
|
56
60
|
|
57
|
-
test "
|
58
|
-
|
61
|
+
test "knows that it can't transition to a state denied by a guard" do
|
62
|
+
machine = MachineTestSubject.new
|
63
|
+
assert machine.can_execute_restart? true
|
64
|
+
refute machine.can_execute_restart? false
|
59
65
|
end
|
60
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transitions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakub Kuzma
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-12-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -153,7 +153,9 @@ files:
|
|
153
153
|
- test/event/test_event_being_fired.rb
|
154
154
|
- test/event/test_event_checks.rb
|
155
155
|
- test/helper.rb
|
156
|
+
- test/machine/machine_template.rb
|
156
157
|
- test/machine/test_available_states_listing.rb
|
158
|
+
- test/machine/test_fire_event_machine.rb
|
157
159
|
- test/machine/test_machine.rb
|
158
160
|
- test/state/test_state.rb
|
159
161
|
- test/state/test_state_predicate_method.rb
|