tastebook-acts_as_state_machine 3.0.2 → 3.0.3
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/Rakefile +1 -1
- data/acts_as_state_machine.gemspec +3 -3
- data/lib/acts_as_state_machine.rb +17 -2
- data/test/test_acts_as_state_machine.rb +33 -28
- metadata +5 -4
data/Rakefile
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = 'tastebook-acts_as_state_machine'
|
|
3
|
-
s.version = '3.0.
|
|
4
|
-
s.date = '2013-
|
|
3
|
+
s.version = '3.0.3'
|
|
4
|
+
s.date = '2013-07-30'
|
|
5
5
|
|
|
6
6
|
s.summary = "Allows ActiveRecord models to define states and transition actions between them"
|
|
7
7
|
s.description = "This act gives an Active Record model the ability to act as a finite state machine (FSM)."
|
|
8
8
|
|
|
9
|
-
s.authors = ['RailsJedi', 'Scott Barron']
|
|
9
|
+
s.authors = ['RailsJedi', 'Scott Barron', 'Surendra Singhi']
|
|
10
10
|
s.email = 'ssinghi@kreeti.com'
|
|
11
11
|
s.homepage = 'http://github.com/tastebook/acts_as_state_machine'
|
|
12
12
|
|
|
@@ -62,6 +62,8 @@ module ScottBarron #:nodoc:
|
|
|
62
62
|
|
|
63
63
|
record.update_attribute(record.class.state_column, next_state.value)
|
|
64
64
|
|
|
65
|
+
record.send(:run_state_change_action, record.class.state_change_success_hook, next_state, event)
|
|
66
|
+
|
|
65
67
|
next_state.entered(record, event, *args) unless loopback
|
|
66
68
|
old_state.exited(record, event, *args) unless loopback
|
|
67
69
|
true
|
|
@@ -92,9 +94,11 @@ module ScottBarron #:nodoc:
|
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
def fire(record, *args)
|
|
95
|
-
next_states(record).
|
|
96
|
-
|
|
97
|
+
transitioned = next_states(record).any? {|transition| transition.perform(record, *args) }
|
|
98
|
+
unless transitioned
|
|
99
|
+
record.send(:run_state_change_action, record.class.state_change_failure_hook, record.class._states[record.current_state.to_s], self)
|
|
97
100
|
end
|
|
101
|
+
transitioned
|
|
98
102
|
end
|
|
99
103
|
|
|
100
104
|
def transitions(trans_opts)
|
|
@@ -132,6 +136,12 @@ module ScottBarron #:nodoc:
|
|
|
132
136
|
class_attribute :state_column
|
|
133
137
|
self.state_column = options[:column] || 'state'
|
|
134
138
|
|
|
139
|
+
class_attribute :state_change_success_hook
|
|
140
|
+
self.state_change_success_hook = options[:success]
|
|
141
|
+
|
|
142
|
+
class_attribute :state_change_failure_hook
|
|
143
|
+
self.state_change_failure_hook = options[:failure]
|
|
144
|
+
|
|
135
145
|
before_create :set_initial_state
|
|
136
146
|
after_create :run_initial_state_actions
|
|
137
147
|
end
|
|
@@ -146,6 +156,7 @@ module ScottBarron #:nodoc:
|
|
|
146
156
|
def run_initial_state_actions
|
|
147
157
|
initial = self.class._states[self.class.initial_state.to_s]
|
|
148
158
|
initial.entering(self, nil)
|
|
159
|
+
run_state_change_action(self.class.state_change_success_hook, initial, nil)
|
|
149
160
|
initial.entered(self, nil)
|
|
150
161
|
end
|
|
151
162
|
|
|
@@ -174,6 +185,10 @@ module ScottBarron #:nodoc:
|
|
|
174
185
|
def run_transition_action(action, event, *args)
|
|
175
186
|
Symbol === action ? self.method(action).call(event, *args) : action.call(self, event, *args) if action
|
|
176
187
|
end
|
|
188
|
+
|
|
189
|
+
def run_state_change_action(action, state, event, *args)
|
|
190
|
+
Symbol === action ? self.method(action).call(state, event, *args) : action.call(self, state, event, *args) if action
|
|
191
|
+
end
|
|
177
192
|
end
|
|
178
193
|
|
|
179
194
|
module ClassMethods
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
require "test/unit"
|
|
2
2
|
|
|
3
3
|
require "rubygems"
|
|
4
|
-
require "test/unit"
|
|
5
4
|
require "active_record"
|
|
6
5
|
require "active_record/fixtures"
|
|
6
|
+
require "sqlite3"
|
|
7
7
|
|
|
8
8
|
$:.unshift File.dirname(__FILE__) + "/../lib"
|
|
9
|
-
|
|
9
|
+
$:.unshift File.dirname(__FILE__) + "/../"
|
|
10
|
+
require "#{File.dirname(__FILE__)}/../init"
|
|
10
11
|
|
|
11
12
|
# Log everything to a global StringIO object instead of a file.
|
|
12
13
|
require "stringio"
|
|
@@ -15,13 +16,9 @@ $LOGGER = Logger.new($LOG)
|
|
|
15
16
|
ActiveRecord::Base.logger = $LOGGER
|
|
16
17
|
|
|
17
18
|
ActiveRecord::Base.configurations = {
|
|
18
|
-
"sqlite" => {
|
|
19
|
-
:adapter => "sqlite",
|
|
20
|
-
:dbfile => "state_machine.sqlite.db"
|
|
21
|
-
},
|
|
22
|
-
|
|
23
19
|
"sqlite3" => {
|
|
24
20
|
:adapter => "sqlite3",
|
|
21
|
+
:database => "state_machine_test",
|
|
25
22
|
:dbfile => "state_machine.sqlite3.db"
|
|
26
23
|
},
|
|
27
24
|
|
|
@@ -43,7 +40,7 @@ ActiveRecord::Base.configurations = {
|
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
# Connect to the database.
|
|
46
|
-
ActiveRecord::Base.establish_connection(ENV["DB"] || "
|
|
43
|
+
ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3")
|
|
47
44
|
|
|
48
45
|
# Create table for conversations.
|
|
49
46
|
ActiveRecord::Migration.verbose = false
|
|
@@ -55,14 +52,18 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
|
55
52
|
end
|
|
56
53
|
end
|
|
57
54
|
|
|
58
|
-
class
|
|
59
|
-
|
|
60
|
-
self.use_transactional_fixtures = true
|
|
61
|
-
self.use_instantiated_fixtures = false
|
|
55
|
+
#class ActiveSupport::TestCase
|
|
56
|
+
# self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
|
|
57
|
+
# self.use_transactional_fixtures = true
|
|
58
|
+
# self.use_instantiated_fixtures = false
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
# def create_fixtures(*table_names, &block)
|
|
61
|
+
# ActiveRecord::TestFixtures.create_fixtures(Test::Unit::TestCase.fixture_path, table_names, &block)
|
|
62
|
+
# end
|
|
63
|
+
#end
|
|
64
|
+
|
|
65
|
+
ActiveRecord::Base.class_eval do
|
|
66
|
+
include ScottBarron::Acts::StateMachine
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
class Conversation < ActiveRecord::Base
|
|
@@ -81,34 +82,38 @@ class Conversation < ActiveRecord::Base
|
|
|
81
82
|
!!@can_close
|
|
82
83
|
end
|
|
83
84
|
|
|
84
|
-
def read_enter_action
|
|
85
|
+
def read_enter_action(event)
|
|
85
86
|
self.read_enter = true
|
|
86
87
|
end
|
|
87
88
|
|
|
88
|
-
def read_after_first_action
|
|
89
|
+
def read_after_first_action(event)
|
|
89
90
|
self.read_after_first = true
|
|
90
91
|
end
|
|
91
92
|
|
|
92
|
-
def read_after_second_action
|
|
93
|
+
def read_after_second_action(event)
|
|
93
94
|
self.read_after_second = true
|
|
94
95
|
end
|
|
95
96
|
|
|
96
|
-
def closed_after_action
|
|
97
|
+
def closed_after_action(event)
|
|
97
98
|
self.closed_after = true
|
|
98
99
|
end
|
|
99
100
|
end
|
|
100
101
|
|
|
101
102
|
class ActsAsStateMachineTest < Test::Unit::TestCase
|
|
102
103
|
include ScottBarron::Acts::StateMachine
|
|
103
|
-
fixtures :conversations
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
#include ActiveRecord::TestFixtures
|
|
106
|
+
#fixtures :conversations
|
|
107
|
+
|
|
108
|
+
def teardown1 #throws error
|
|
106
109
|
Conversation.class_eval do
|
|
107
110
|
self._states = {}
|
|
108
|
-
self.
|
|
111
|
+
self.initial_state = nil
|
|
109
112
|
self.transition_table = {}
|
|
110
113
|
self.event_table = {}
|
|
111
114
|
self.state_column = "state"
|
|
115
|
+
self.state_change_success_hook = nil
|
|
116
|
+
self.state_change_failure_hook = nil
|
|
112
117
|
|
|
113
118
|
# Clear out any callbacks that were set by acts_as_state_machine.
|
|
114
119
|
reset_callbacks :before_create
|
|
@@ -369,7 +374,7 @@ class ActsAsStateMachineTest < Test::Unit::TestCase
|
|
|
369
374
|
state :needs_attention
|
|
370
375
|
state :closed, :after => :closed_after_action
|
|
371
376
|
state :read, :enter => :read_enter_action,
|
|
372
|
-
:exit => Proc.new { |o| o.read_exit = true },
|
|
377
|
+
:exit => Proc.new { |o, args| o.read_exit = true },
|
|
373
378
|
:after => [:read_after_first_action, :read_after_second_action]
|
|
374
379
|
|
|
375
380
|
event :view do
|
|
@@ -438,7 +443,7 @@ class ActsAsStateMachineTest < Test::Unit::TestCase
|
|
|
438
443
|
acts_as_state_machine :initial => :needs_attention
|
|
439
444
|
state :junk
|
|
440
445
|
state :needs_attention
|
|
441
|
-
state :read, :exit => lambda { |o| o.read_exit = true }
|
|
446
|
+
state :read, :exit => lambda { |o, args| o.read_exit = true }
|
|
442
447
|
|
|
443
448
|
event :view do
|
|
444
449
|
transitions :to => :read, :from => :needs_attention
|
|
@@ -460,7 +465,7 @@ class ActsAsStateMachineTest < Test::Unit::TestCase
|
|
|
460
465
|
Conversation.class_eval do
|
|
461
466
|
acts_as_state_machine :initial => :needs_attention
|
|
462
467
|
state :needs_attention
|
|
463
|
-
state :read, :exit => lambda { |o| o.read_exit = true }
|
|
468
|
+
state :read, :exit => lambda { |o, args| o.read_exit = true }
|
|
464
469
|
|
|
465
470
|
event :view do
|
|
466
471
|
transitions :to => :read, :from => [:needs_attention, :read]
|
|
@@ -479,8 +484,8 @@ class ActsAsStateMachineTest < Test::Unit::TestCase
|
|
|
479
484
|
def test_entry_and_after_actions_called_for_initial_state
|
|
480
485
|
Conversation.class_eval do
|
|
481
486
|
acts_as_state_machine :initial => :needs_attention
|
|
482
|
-
state :needs_attention, :enter => lambda { |o| o.needs_attention_enter = true },
|
|
483
|
-
:after => lambda { |o| o.needs_attention_after = true }
|
|
487
|
+
state :needs_attention, :enter => lambda { |o, args| o.needs_attention_enter = true },
|
|
488
|
+
:after => lambda { |o, args| o.needs_attention_after = true }
|
|
484
489
|
end
|
|
485
490
|
|
|
486
491
|
c = Conversation.create!
|
metadata
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tastebook-acts_as_state_machine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.3
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- RailsJedi
|
|
9
9
|
- Scott Barron
|
|
10
|
+
- Surendra Singhi
|
|
10
11
|
autorequire:
|
|
11
12
|
bindir: bin
|
|
12
13
|
cert_chain: []
|
|
13
|
-
date: 2013-
|
|
14
|
+
date: 2013-07-30 00:00:00.000000000 Z
|
|
14
15
|
dependencies:
|
|
15
16
|
- !ruby/object:Gem::Dependency
|
|
16
17
|
name: activerecord
|
|
17
|
-
requirement: &
|
|
18
|
+
requirement: &2153031500 !ruby/object:Gem::Requirement
|
|
18
19
|
none: false
|
|
19
20
|
requirements:
|
|
20
21
|
- - ! '>='
|
|
@@ -22,7 +23,7 @@ dependencies:
|
|
|
22
23
|
version: '3.1'
|
|
23
24
|
type: :runtime
|
|
24
25
|
prerelease: false
|
|
25
|
-
version_requirements: *
|
|
26
|
+
version_requirements: *2153031500
|
|
26
27
|
description: This act gives an Active Record model the ability to act as a finite
|
|
27
28
|
state machine (FSM).
|
|
28
29
|
email: ssinghi@kreeti.com
|