transitions 0.1.13 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b87d3c72b83d64e0c80f22f8b6984fc897e75725
4
- data.tar.gz: c680875bb9ebd5b68fcf0b02943a04a07147121b
3
+ metadata.gz: 4f76fbe7e05b93bbec46f0faa6723169979ec375
4
+ data.tar.gz: d968ddb9b44da30cb3b8f34bfa5f536e33d3a6a3
5
5
  SHA512:
6
- metadata.gz: 400a2ecb0b2c08ae1a29f860607eeddb1c9d0cb4565a2530e90b9d886a88d4c292658097a604e993af2150a8fc90bfacefc030d03a2d76f9d57dede7327de239
7
- data.tar.gz: 08d83f73449b3338b4b8a4cbc8ff6f031e9ab61eaa715fdc016f4a3794722e25fb0887ac9326be8195241a76e401d1ed4d93495accdcaec80f6fce3b3145ec43
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(options = nil)
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)
@@ -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
@@ -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.active_record_descendant?(klass)
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
- handle_event_fired_calllback record, new_state, event
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 handle_event_fired_calllback(record, new_state, event)
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
@@ -1,3 +1,3 @@
1
1
  module Transitions
2
- VERSION = '0.1.13'
2
+ VERSION = '0.2.0'
3
3
  end
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
- if ::Transitions.active_record_descendant?(self.class)
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 ::Transitions.active_record_descendant?(self.class)
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.active_record_descendant?(klazz)
84
- defined?(ActiveRecord::Base) && klazz < ActiveRecord::Base
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 "test fire_event" do
58
- pend "Implement me"
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.1.13
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-10-10 00:00:00.000000000 Z
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