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 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