transitions 0.0.12 → 0.0.13
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/Gemfile.lock +18 -3
- data/README.rdoc +45 -42
- data/lib/transitions/event.rb +10 -2
- data/lib/transitions/machine.rb +18 -12
- data/lib/transitions/version.rb +1 -1
- data/lib/transitions.rb +4 -0
- data/test/helper.rb +1 -0
- data/test/test_active_record.rb +73 -1
- data/test/test_available_states_listing.rb +27 -0
- data/test/test_event.rb +24 -5
- data/test/test_state_transition_success_callback.rb +60 -0
- data/transitions.gemspec +2 -1
- metadata +27 -15
- data/test/test_scopes.rb +0 -104
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
transitions (0.0.
|
4
|
+
transitions (0.0.13)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: http://rubygems.org/
|
@@ -16,15 +16,29 @@ GEM
|
|
16
16
|
arel (~> 1.0.0)
|
17
17
|
tzinfo (~> 0.3.23)
|
18
18
|
activesupport (3.0.0)
|
19
|
+
archive-tar-minitar (0.5.2)
|
19
20
|
arel (1.0.1)
|
20
21
|
activesupport (~> 3.0.0)
|
21
22
|
builder (2.1.2)
|
23
|
+
columnize (0.3.4)
|
22
24
|
i18n (0.4.1)
|
25
|
+
linecache19 (0.5.12)
|
26
|
+
ruby_core_source (>= 0.1.4)
|
23
27
|
mocha (0.9.8)
|
24
28
|
rake
|
25
29
|
rake (0.8.7)
|
30
|
+
ruby-debug-base19 (0.11.25)
|
31
|
+
columnize (>= 0.3.1)
|
32
|
+
linecache19 (>= 0.5.11)
|
33
|
+
ruby_core_source (>= 0.1.4)
|
34
|
+
ruby-debug19 (0.11.6)
|
35
|
+
columnize (>= 0.3.1)
|
36
|
+
linecache19 (>= 0.5.11)
|
37
|
+
ruby-debug-base19 (>= 0.11.19)
|
38
|
+
ruby_core_source (0.1.5)
|
39
|
+
archive-tar-minitar (>= 0.5.2)
|
26
40
|
sqlite3-ruby (1.3.1)
|
27
|
-
test-unit (2.
|
41
|
+
test-unit (2.4.1)
|
28
42
|
tzinfo (0.3.23)
|
29
43
|
|
30
44
|
PLATFORMS
|
@@ -34,6 +48,7 @@ DEPENDENCIES
|
|
34
48
|
activerecord (~> 3)
|
35
49
|
bundler (~> 1)
|
36
50
|
mocha
|
51
|
+
ruby-debug19
|
37
52
|
sqlite3-ruby
|
38
|
-
test-unit (~> 2)
|
53
|
+
test-unit (~> 2.2)
|
39
54
|
transitions!
|
data/README.rdoc
CHANGED
@@ -1,12 +1,28 @@
|
|
1
|
-
|
1
|
+
= Travis Build Status
|
2
2
|
|
3
|
-
=
|
3
|
+
{<img src="https://secure.travis-ci.org/troessner/transitions.png"/>}[http://travis-ci.org/troessner/transitions]
|
4
4
|
|
5
|
-
|
6
|
-
ActiveModel::StateMachine. It was extracted from ActiveModel and turned
|
7
|
-
into a gem when it got the axe in commit {db49c706b}[http://github.com/rails/rails/commit/db49c706b62e7ea2ab93f05399dbfddf5087ee0c].
|
5
|
+
= Synopsis
|
8
6
|
|
9
|
-
|
7
|
+
`transitions` is a ruby state machine implementation.
|
8
|
+
|
9
|
+
= Installation
|
10
|
+
|
11
|
+
== Rails
|
12
|
+
|
13
|
+
This goes into your Gemfile:
|
14
|
+
|
15
|
+
gem "transitions", :require => ["transitions", "active_record/transitions"]
|
16
|
+
|
17
|
+
… and this into your AR model:
|
18
|
+
|
19
|
+
include ActiveRecord::Transitions
|
20
|
+
|
21
|
+
== Standalone
|
22
|
+
|
23
|
+
gem install transitions
|
24
|
+
|
25
|
+
= Using transitions
|
10
26
|
|
11
27
|
require 'transitions'
|
12
28
|
|
@@ -30,6 +46,15 @@ into a gem when it got the axe in commit {db49c706b}[http://github.com/rails/rai
|
|
30
46
|
end
|
31
47
|
end
|
32
48
|
|
49
|
+
= Features
|
50
|
+
|
51
|
+
== Events
|
52
|
+
|
53
|
+
When you declare an event, say <tt>discontinue</tt>, two methods are declared for
|
54
|
+
you: <tt>discontinue</tt> and <tt>discontinue!</tt>. Both events will call
|
55
|
+
<tt>write_state_without_persistence</tt> on successful transition, but only the
|
56
|
+
bang(!)-version will call <tt>write_state</tt>.
|
57
|
+
|
33
58
|
== Automatic scope generation
|
34
59
|
|
35
60
|
`transitions` will automatically generate scopes for you if you are using ActiveRecord and tell it to do so via the `auto_scopes` option:
|
@@ -70,6 +95,12 @@ In case you need to trigger a method call after a successful transition you can
|
|
70
95
|
transitions :to => :discontinued, :from => [:available, :out_of_stock]
|
71
96
|
end
|
72
97
|
|
98
|
+
In addition to just specify the method name on the record as a symbol you can pass a lambda to
|
99
|
+
perfom some more complex success callbacks:
|
100
|
+
|
101
|
+
event :discontinue, :success => lambda { |order) AdminNotifier.notify_about_discontinued_order(order) } do
|
102
|
+
transitions :to => :discontinued, :from => [:available, :out_of_stock]
|
103
|
+
end
|
73
104
|
|
74
105
|
== Timestamps
|
75
106
|
|
@@ -89,52 +120,24 @@ the name of the timestamp column.
|
|
89
120
|
transiions :from => :exploded, :to => :rebuilt
|
90
121
|
end
|
91
122
|
|
123
|
+
== Listing all the available states
|
92
124
|
|
93
|
-
|
94
|
-
|
95
|
-
This goes into your Gemfile:
|
96
|
-
|
97
|
-
gem "transitions", :require => ["transitions", "active_record/transitions"]
|
98
|
-
|
99
|
-
… and this into your AR model:
|
100
|
-
|
101
|
-
include ActiveRecord::Transitions
|
102
|
-
|
103
|
-
=== A note about persistence
|
104
|
-
The property used to persist the models’ state is named <tt>state</tt> (really!),
|
105
|
-
which should be a string column wide enough to fit your longest state name.
|
106
|
-
It should also be mentioned that <tt>#save!</tt> is called after every successful event.
|
107
|
-
|
108
|
-
== Event execution flow
|
125
|
+
You can easily get a listing of all available states:
|
109
126
|
|
110
|
-
|
111
|
-
|
127
|
+
Order.available_states # Uses the `default` state machine
|
128
|
+
# => [:pick_line_items, :picking_line_items]
|
112
129
|
|
113
|
-
|
114
|
-
2. call <tt>:exit</tt> handler of <tt>:available</tt> state
|
115
|
-
3. call <tt>:guard</tt> of <tt>:available to :discontinue</tt> transition within <tt>#discontinue</tt> event
|
116
|
-
4. call <tt>#event_failed(:event)</tt> and abort unless <tt>3.</tt> returned <tt>true</tt>
|
117
|
-
5. call <tt>:on_transition(:reason => :pirates)</tt> of <tt>:available to :discontinue</tt> transition within <tt>#discontinue</tt> event
|
118
|
-
6. call <tt>:enter</tt> handler of <tt>:discontinue</tt>
|
119
|
-
7. call <tt>#event_fired(:available, :discontinue)</tt>
|
120
|
-
8. call <tt>#write_state(machine, :discontinue)</tt>
|
121
|
-
9. call <tt>#write_state_without_persistence(machine, :discontinue)</tt>
|
122
|
-
10. call <tt>baby_ninja#:success</tt> handler method of <tt>#discontinue</tt> event
|
130
|
+
In case you have multiple state machines you can also pass the state machine name:
|
123
131
|
|
124
|
-
|
125
|
-
|
126
|
-
When you declare an event <tt>discontinue</tt>, two methods are declared for
|
127
|
-
you: <tt>discontinue</tt> and <tt>discontinue!</tt>. Both events will call
|
128
|
-
<tt>write_state_without_persistence</tt> on successful transition, but only the
|
129
|
-
bang(!)-version will call <tt>write_state</tt>.
|
132
|
+
Order.available_states(:your_machine)
|
130
133
|
|
131
|
-
|
134
|
+
= Documentation, Guides & Examples
|
132
135
|
|
133
136
|
- {Online API Documentation}[http://rdoc.info/github/troessner/transitions/master/Transitions]
|
134
137
|
- Krzysiek Heród (aka {Netizer}[http://github.com/netizer]) wrote a nice
|
135
138
|
{blog post}[http://dev.netizer.pl/transitions-state-machine-for-rails-3.html]
|
136
139
|
about using Transitions in ActiveRecord.
|
137
140
|
|
138
|
-
|
141
|
+
= Copyright
|
139
142
|
|
140
143
|
Copyright (c) 2010 Jakub Kuźma, Timo Rößner. See LICENSE for details.
|
data/lib/transitions/event.rb
CHANGED
@@ -74,7 +74,7 @@ module Transitions
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def update(options = {}, &block)
|
77
|
-
@success = options[:success] if options.key?(:success)
|
77
|
+
@success = build_sucess_callback(options[:success]) if options.key?(:success)
|
78
78
|
self.timestamp = options[:timestamp] if options[:timestamp]
|
79
79
|
instance_eval(&block) if block
|
80
80
|
self
|
@@ -118,12 +118,20 @@ module Transitions
|
|
118
118
|
Please define #{at_name} or #{on_name} in #{obj.class}"
|
119
119
|
end
|
120
120
|
end
|
121
|
-
|
122
121
|
|
123
122
|
def transitions(trans_opts)
|
124
123
|
Array(trans_opts[:from]).each do |s|
|
125
124
|
@transitions << StateTransition.new(trans_opts.merge({:from => s.to_sym}))
|
126
125
|
end
|
127
126
|
end
|
127
|
+
|
128
|
+
def build_sucess_callback(callback_symbol_or_proc)
|
129
|
+
case callback_symbol_or_proc
|
130
|
+
when Proc
|
131
|
+
callback_symbol_or_proc
|
132
|
+
when Symbol
|
133
|
+
lambda { |record| record.send(callback_symbol_or_proc) }
|
134
|
+
end
|
135
|
+
end
|
128
136
|
end
|
129
137
|
end
|
data/lib/transitions/machine.rb
CHANGED
@@ -45,22 +45,28 @@ module Transitions
|
|
45
45
|
|
46
46
|
def fire_event(event, record, persist, *args)
|
47
47
|
state_index[record.current_state(@name)].call_action(:exit, record)
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
record.
|
48
|
+
begin
|
49
|
+
if new_state = @events[event].fire(record, nil, *args)
|
50
|
+
state_index[new_state].call_action(:enter, record)
|
51
|
+
|
52
|
+
if record.respond_to?(event_fired_callback)
|
53
|
+
record.send(event_fired_callback, record.current_state, new_state, event)
|
54
|
+
end
|
55
|
+
|
56
|
+
record.current_state(@name, new_state, persist)
|
57
|
+
@events[event].success.call(record) if @events[event].success
|
58
|
+
return true
|
59
|
+
else
|
60
|
+
record.send(event_fired_callback, event) if record.respond_to?(event_failed_callback)
|
61
|
+
return false
|
53
62
|
end
|
54
|
-
|
55
|
-
record.current_state(@name, new_state, persist)
|
56
|
-
record.send(@events[event].success) if @events[event].success
|
57
|
-
true
|
58
|
-
else
|
63
|
+
rescue => e
|
59
64
|
if record.respond_to?(event_failed_callback)
|
60
65
|
record.send(event_failed_callback, event)
|
66
|
+
return false
|
67
|
+
else
|
68
|
+
raise e
|
61
69
|
end
|
62
|
-
|
63
|
-
false
|
64
70
|
end
|
65
71
|
end
|
66
72
|
|
data/lib/transitions/version.rb
CHANGED
data/lib/transitions.rb
CHANGED
@@ -54,6 +54,10 @@ module Transitions
|
|
54
54
|
block ? state_machines[name].update(options, &block) : state_machines[name]
|
55
55
|
end
|
56
56
|
|
57
|
+
def available_states name = :default
|
58
|
+
state_machines[name].states.map(&:name).sort
|
59
|
+
end
|
60
|
+
|
57
61
|
def define_state_query_method(state_name)
|
58
62
|
name = "#{state_name}?"
|
59
63
|
undef_method(name) if method_defined?(name)
|
data/test/helper.rb
CHANGED
data/test/test_active_record.rb
CHANGED
@@ -3,10 +3,39 @@ require 'active_support/core_ext/module/aliasing'
|
|
3
3
|
|
4
4
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
5
5
|
|
6
|
+
class CreateTrafficLights < ActiveRecord::Migration
|
7
|
+
def self.up
|
8
|
+
create_table(:traffic_lights) do |t|
|
9
|
+
t.string :state
|
10
|
+
t.string :name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class CreateLightBulbs < ActiveRecord::Migration
|
16
|
+
def self.up
|
17
|
+
create_table(:light_bulbs) do |t|
|
18
|
+
t.string :state
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class CreateLights < ActiveRecord::Migration
|
24
|
+
def self.up
|
25
|
+
create_table(:lights) do |t|
|
26
|
+
t.string :state
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
CreateTrafficLights.migrate(:up)
|
32
|
+
CreateLightBulbs.migrate(:up)
|
33
|
+
CreateLights.migrate(:up)
|
34
|
+
|
6
35
|
class TrafficLight < ActiveRecord::Base
|
7
36
|
include ActiveRecord::Transitions
|
8
37
|
|
9
|
-
state_machine do
|
38
|
+
state_machine :auto_scopes => true do
|
10
39
|
state :off
|
11
40
|
|
12
41
|
state :red
|
@@ -43,6 +72,15 @@ class ConditionalValidatingTrafficLight < TrafficLight
|
|
43
72
|
validates(:name, :presence => true, :if => :red?)
|
44
73
|
end
|
45
74
|
|
75
|
+
class LightBulb < ActiveRecord::Base
|
76
|
+
include ActiveRecord::Transitions
|
77
|
+
|
78
|
+
state_machine do
|
79
|
+
state :off
|
80
|
+
state :on
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
46
84
|
class TestActiveRecord < Test::Unit::TestCase
|
47
85
|
def setup
|
48
86
|
create_database
|
@@ -141,3 +179,37 @@ class TestNewActiveRecord < TestActiveRecord
|
|
141
179
|
end
|
142
180
|
|
143
181
|
end
|
182
|
+
|
183
|
+
class TestScopes < Test::Unit::TestCase
|
184
|
+
test "scope returns correct object" do
|
185
|
+
@light = TrafficLight.create!
|
186
|
+
assert_respond_to TrafficLight, :off
|
187
|
+
assert_equal TrafficLight.off.first, @light
|
188
|
+
assert TrafficLight.red.empty?
|
189
|
+
end
|
190
|
+
|
191
|
+
test "scopes exist" do
|
192
|
+
assert_respond_to TrafficLight, :off
|
193
|
+
assert_respond_to TrafficLight, :red
|
194
|
+
assert_respond_to TrafficLight, :green
|
195
|
+
assert_respond_to TrafficLight, :yellow
|
196
|
+
end
|
197
|
+
|
198
|
+
test 'scopes are only generated if we explicitly say so' do
|
199
|
+
assert_not_respond_to LightBulb, :off
|
200
|
+
assert_not_respond_to LightBulb, :on
|
201
|
+
end
|
202
|
+
|
203
|
+
test 'scope generation raises an exception if we try to overwrite an existing method' do
|
204
|
+
assert_raise(Transitions::InvalidMethodOverride) {
|
205
|
+
class Light < ActiveRecord::Base
|
206
|
+
include ActiveRecord::Transitions
|
207
|
+
|
208
|
+
state_machine :auto_scopes => true do
|
209
|
+
state :new
|
210
|
+
state :broken
|
211
|
+
end
|
212
|
+
end
|
213
|
+
}
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class Bender
|
4
|
+
include Transitions
|
5
|
+
|
6
|
+
state_machine :default do
|
7
|
+
state :drinking
|
8
|
+
state :smoking
|
9
|
+
state :gambling
|
10
|
+
end
|
11
|
+
|
12
|
+
state_machine :maintenance do
|
13
|
+
state :wip
|
14
|
+
state :finished
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class TestAvailableStatesListing < Test::Unit::TestCase
|
19
|
+
test 'available_states should return the states for the default state machine if no state machine is specified' do
|
20
|
+
assert_equal [:drinking, :gambling, :smoking], Bender.available_states
|
21
|
+
end
|
22
|
+
|
23
|
+
test 'available_states should return the states for a given state' do
|
24
|
+
assert_equal [:finished, :wip], Bender.available_states(:maintenance)
|
25
|
+
assert_equal [:drinking, :gambling, :smoking], Bender.available_states(:default)
|
26
|
+
end
|
27
|
+
end
|
data/test/test_event.rb
CHANGED
@@ -3,11 +3,19 @@ require "helper"
|
|
3
3
|
class TestEvent < Test::Unit::TestCase
|
4
4
|
def setup
|
5
5
|
@state_name = :close_order
|
6
|
-
@
|
6
|
+
@success_as_symbol = :success_callback
|
7
|
+
@success_as_lambda = lambda { |record| record.success_callback }
|
7
8
|
end
|
8
9
|
|
9
|
-
def
|
10
|
-
@event = Transitions::Event.new(nil, @state_name, {:success => @
|
10
|
+
def event_with_symbol_success_callback
|
11
|
+
@event = Transitions::Event.new(nil, @state_name, {:success => @success_as_symbol}) do
|
12
|
+
transitions :to => :closed, :from => [:open, :received]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
alias_method :new_event, :event_with_symbol_success_callback
|
16
|
+
|
17
|
+
def event_with_lambda_success_callback
|
18
|
+
@event = Transitions::Event.new(nil, @state_name, {:success => @success_as_lambda}) do
|
11
19
|
transitions :to => :closed, :from => [:open, :received]
|
12
20
|
end
|
13
21
|
end
|
@@ -16,8 +24,19 @@ class TestEvent < Test::Unit::TestCase
|
|
16
24
|
assert_equal @state_name, new_event.name
|
17
25
|
end
|
18
26
|
|
19
|
-
test "should set the success
|
20
|
-
|
27
|
+
test "should set the success callback with a symbol and return a block" do
|
28
|
+
assert_respond_to event_with_symbol_success_callback.success, :call
|
29
|
+
end
|
30
|
+
|
31
|
+
test "should build a block which calls the given success_callback symbol on the passed record instance" do
|
32
|
+
record = mock("SomeRecordToGetCalled")
|
33
|
+
record.expects(:success_callback)
|
34
|
+
|
35
|
+
event_with_symbol_success_callback.success.call(record)
|
36
|
+
end
|
37
|
+
|
38
|
+
test "should set the success callback with a lambda" do
|
39
|
+
assert_respond_to event_with_lambda_success_callback.success, :call
|
21
40
|
end
|
22
41
|
|
23
42
|
test "should create StateTransitions" do
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class DrivingInstructor
|
4
|
+
def self.applause!
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class DrivingSchoolCar
|
9
|
+
include Transitions
|
10
|
+
|
11
|
+
state_machine do
|
12
|
+
state :parked
|
13
|
+
state :running
|
14
|
+
state :driving
|
15
|
+
state :switched_off
|
16
|
+
|
17
|
+
event :start_driving, :success => lambda { |car| DrivingInstructor.applause! } do
|
18
|
+
transitions :from => :parked, :to => :driving, :on_transition => [:start_engine, :loosen_handbrake, :push_gas_pedal]
|
19
|
+
end
|
20
|
+
|
21
|
+
event :switch_off_engine do
|
22
|
+
transitions :from => :parked, :to => :switched_off
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
%w!start_engine loosen_handbrake push_gas_pedal!.each do |m|
|
27
|
+
define_method(m){}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TestStateTransitionSuccessCallback < Test::Unit::TestCase
|
32
|
+
def setup
|
33
|
+
@car = DrivingSchoolCar.new
|
34
|
+
end
|
35
|
+
|
36
|
+
test "should execute the success callback after successfull event execution" do
|
37
|
+
DrivingInstructor.expects(:applause!)
|
38
|
+
|
39
|
+
@car.start_driving!
|
40
|
+
end
|
41
|
+
|
42
|
+
test "should not execute the success callback after event execution failed" do
|
43
|
+
DrivingInstructor.expects(:applause!).never
|
44
|
+
|
45
|
+
@car.stubs(:event_failed)
|
46
|
+
@car.expects(:loosen_handbrake).raises("Drive with handbrake fail!")
|
47
|
+
@car.start_driving!
|
48
|
+
end
|
49
|
+
|
50
|
+
test "should execute the event_failed_callback and don't raise error if callback is defined" do
|
51
|
+
@car.start_driving
|
52
|
+
@car.expects(:event_failed).with(:switch_off_engine)
|
53
|
+
@car.switch_off_engine
|
54
|
+
end
|
55
|
+
|
56
|
+
test "should just re-raise any error on transition if the event_failed_callback isn't defined" do
|
57
|
+
@car.start_driving
|
58
|
+
assert_raise(Transitions::InvalidTransition) { @car.switch_off_engine }
|
59
|
+
end
|
60
|
+
end
|
data/transitions.gemspec
CHANGED
@@ -15,10 +15,11 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "transitions"
|
16
16
|
|
17
17
|
s.add_development_dependency "bundler", "~> 1"
|
18
|
-
s.add_development_dependency "test-unit", "~> 2"
|
18
|
+
s.add_development_dependency "test-unit", "~> 2.2"
|
19
19
|
s.add_development_dependency "mocha"
|
20
20
|
s.add_development_dependency "sqlite3-ruby"
|
21
21
|
s.add_development_dependency "activerecord", "~> 3"
|
22
|
+
s.add_development_dependency "ruby-debug19"
|
22
23
|
|
23
24
|
s.files = `git ls-files`.split("\n")
|
24
25
|
s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
|
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.0.
|
4
|
+
version: 0.0.13
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-12-20 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
17
|
-
requirement: &
|
17
|
+
requirement: &77702010 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,21 +22,21 @@ dependencies:
|
|
22
22
|
version: '1'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *77702010
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: test-unit
|
28
|
-
requirement: &
|
28
|
+
requirement: &77701310 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '2'
|
33
|
+
version: '2.2'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *77701310
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: mocha
|
39
|
-
requirement: &
|
39
|
+
requirement: &77700870 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ! '>='
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
version: '0'
|
45
45
|
type: :development
|
46
46
|
prerelease: false
|
47
|
-
version_requirements: *
|
47
|
+
version_requirements: *77700870
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: sqlite3-ruby
|
50
|
-
requirement: &
|
50
|
+
requirement: &77700370 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,10 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *77700370
|
59
59
|
- !ruby/object:Gem::Dependency
|
60
60
|
name: activerecord
|
61
|
-
requirement: &
|
61
|
+
requirement: &77699800 !ruby/object:Gem::Requirement
|
62
62
|
none: false
|
63
63
|
requirements:
|
64
64
|
- - ~>
|
@@ -66,7 +66,18 @@ dependencies:
|
|
66
66
|
version: '3'
|
67
67
|
type: :development
|
68
68
|
prerelease: false
|
69
|
-
version_requirements: *
|
69
|
+
version_requirements: *77699800
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: ruby-debug19
|
72
|
+
requirement: &77698980 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *77698980
|
70
81
|
description: Lightweight state machine extracted from ActiveModel
|
71
82
|
email: timo.roessner@googlemail.com
|
72
83
|
executables: []
|
@@ -92,15 +103,16 @@ files:
|
|
92
103
|
- test/helper.rb
|
93
104
|
- test/test_active_record.rb
|
94
105
|
- test/test_active_record_timestamps.rb
|
106
|
+
- test/test_available_states_listing.rb
|
95
107
|
- test/test_event.rb
|
96
108
|
- test/test_event_arguments.rb
|
97
109
|
- test/test_event_being_fired.rb
|
98
110
|
- test/test_machine.rb
|
99
|
-
- test/test_scopes.rb
|
100
111
|
- test/test_state.rb
|
101
112
|
- test/test_state_transition.rb
|
102
113
|
- test/test_state_transition_callbacks.rb
|
103
114
|
- test/test_state_transition_guard_check.rb
|
115
|
+
- test/test_state_transition_success_callback.rb
|
104
116
|
- transitions.gemspec
|
105
117
|
homepage: http://github.com/troessner/transitions
|
106
118
|
licenses: []
|
@@ -116,7 +128,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
128
|
version: '0'
|
117
129
|
segments:
|
118
130
|
- 0
|
119
|
-
hash:
|
131
|
+
hash: 819396333
|
120
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
133
|
none: false
|
122
134
|
requirements:
|
data/test/test_scopes.rb
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
require "helper"
|
2
|
-
require 'active_support/core_ext/module/aliasing'
|
3
|
-
|
4
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
5
|
-
|
6
|
-
class CreateTrafficLights < ActiveRecord::Migration
|
7
|
-
def self.up
|
8
|
-
create_table(:traffic_lights) do |t|
|
9
|
-
t.string :state
|
10
|
-
t.string :name
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class CreateLightBulbs < ActiveRecord::Migration
|
16
|
-
def self.up
|
17
|
-
create_table(:light_bulbs) do |t|
|
18
|
-
t.string :state
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
class CreateLights < ActiveRecord::Migration
|
24
|
-
def self.up
|
25
|
-
create_table(:lights) do |t|
|
26
|
-
t.string :state
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
CreateTrafficLights.migrate(:up)
|
32
|
-
CreateLightBulbs.migrate(:up)
|
33
|
-
CreateLights.migrate(:up)
|
34
|
-
|
35
|
-
class TrafficLight < ActiveRecord::Base
|
36
|
-
include ActiveRecord::Transitions
|
37
|
-
|
38
|
-
state_machine :auto_scopes => true do
|
39
|
-
state :off
|
40
|
-
|
41
|
-
state :red
|
42
|
-
state :green
|
43
|
-
state :yellow
|
44
|
-
|
45
|
-
event :red_on do
|
46
|
-
transitions :to => :red, :from => [:yellow]
|
47
|
-
end
|
48
|
-
|
49
|
-
event :green_on do
|
50
|
-
transitions :to => :green, :from => [:red]
|
51
|
-
end
|
52
|
-
|
53
|
-
event :yellow_on do
|
54
|
-
transitions :to => :yellow, :from => [:green]
|
55
|
-
end
|
56
|
-
|
57
|
-
event :reset do
|
58
|
-
transitions :to => :red, :from => [:off]
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
class LightBulb < ActiveRecord::Base
|
64
|
-
include ActiveRecord::Transitions
|
65
|
-
|
66
|
-
state_machine do
|
67
|
-
state :off
|
68
|
-
state :on
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
class TestScopes < Test::Unit::TestCase
|
73
|
-
test "scope returns correct object" do
|
74
|
-
@light = TrafficLight.create!
|
75
|
-
assert TrafficLight.respond_to? :off
|
76
|
-
assert_equal TrafficLight.off.first, @light
|
77
|
-
assert TrafficLight.red.empty?
|
78
|
-
end
|
79
|
-
|
80
|
-
test "scopes exist" do
|
81
|
-
assert TrafficLight.respond_to? :off
|
82
|
-
assert TrafficLight.respond_to? :red
|
83
|
-
assert TrafficLight.respond_to? :green
|
84
|
-
assert TrafficLight.respond_to? :yellow
|
85
|
-
end
|
86
|
-
|
87
|
-
test 'scopes are only generated if we explicitly say so' do
|
88
|
-
assert !LightBulb.respond_to?(:off)
|
89
|
-
assert !LightBulb.respond_to?(:on)
|
90
|
-
end
|
91
|
-
|
92
|
-
test 'scope generation raises an exception if we try to overwrite an existing method' do
|
93
|
-
assert_raise(Transitions::InvalidMethodOverride) {
|
94
|
-
class Light < ActiveRecord::Base
|
95
|
-
include ActiveRecord::Transitions
|
96
|
-
|
97
|
-
state_machine :auto_scopes => true do
|
98
|
-
state :new
|
99
|
-
state :broken
|
100
|
-
end
|
101
|
-
end
|
102
|
-
}
|
103
|
-
end
|
104
|
-
end
|