transitions 0.0.17 → 0.0.18
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/CHANGELOG.md +5 -0
- data/lib/transitions/state.rb +26 -1
- data/lib/transitions/version.rb +1 -1
- data/lib/transitions.rb +3 -7
- data/test/db/create_db.rb +3 -0
- data/test/helper.rb +1 -0
- data/test/test_active_record.rb +29 -12
- data/test/test_state.rb +49 -20
- data/transitions.gemspec +1 -0
- metadata +26 -15
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# 0.0.18 (2012-05-18)
|
2
|
+
|
3
|
+
* (troessner) Remove `define_state_query_method` from public API
|
4
|
+
* (troessner) Do not override existing methods when defining state query methods but warn the user.
|
5
|
+
|
1
6
|
# 0.0.17 (2012-05-02):
|
2
7
|
|
3
8
|
* (zmillman) Add write_state_without_persistence.
|
data/lib/transitions/state.rb
CHANGED
@@ -27,7 +27,7 @@ module Transitions
|
|
27
27
|
def initialize(name, options = {})
|
28
28
|
@name = name
|
29
29
|
if machine = options.delete(:machine)
|
30
|
-
|
30
|
+
define_state_query_method(machine)
|
31
31
|
end
|
32
32
|
update(options)
|
33
33
|
end
|
@@ -63,5 +63,30 @@ module Transitions
|
|
63
63
|
@options = options
|
64
64
|
self
|
65
65
|
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def define_state_query_method(machine)
|
69
|
+
method_name, state_name = "#{@name}?", @name # Instance vars are out of scope when calling define_method below, so we use local variables.
|
70
|
+
if method_already_defined_on_recipient?(machine, method_name)
|
71
|
+
override_warning method_name
|
72
|
+
else
|
73
|
+
machine.klass.send :define_method, method_name do
|
74
|
+
current_state.to_s == state_name.to_s
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def method_already_defined_on_recipient?(machine, method_name)
|
80
|
+
machine.klass.new.respond_to?(method_name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def override_warning(method_name)
|
84
|
+
warning = "Transitions: Can not define method #{method_name} because it is already defined, please rename either the existing method or the state."
|
85
|
+
if Rails && Rails.logger
|
86
|
+
Rails.logger.warn warning
|
87
|
+
else
|
88
|
+
puts warning
|
89
|
+
end
|
90
|
+
end
|
66
91
|
end
|
67
92
|
end
|
data/lib/transitions/version.rb
CHANGED
data/lib/transitions.rb
CHANGED
@@ -32,7 +32,7 @@ module Transitions
|
|
32
32
|
|
33
33
|
module ClassMethods
|
34
34
|
def inherited(klass)
|
35
|
-
super
|
35
|
+
super # Make sure we call other callbacks possibly defined upstream the ancestor chain.
|
36
36
|
klass.state_machines = state_machines
|
37
37
|
end
|
38
38
|
|
@@ -40,6 +40,7 @@ module Transitions
|
|
40
40
|
@state_machines ||= {}
|
41
41
|
end
|
42
42
|
|
43
|
+
# The only reason we need this method is for the inherited callback.
|
43
44
|
def state_machines=(value)
|
44
45
|
@state_machines = value ? value.dup : nil
|
45
46
|
end
|
@@ -57,18 +58,13 @@ module Transitions
|
|
57
58
|
def available_states(name = :default)
|
58
59
|
state_machines[name].states.map(&:name).sort_by {|x| x.to_s}
|
59
60
|
end
|
60
|
-
|
61
|
-
def define_state_query_method(state_name)
|
62
|
-
name = "#{state_name}?"
|
63
|
-
undef_method(name) if method_defined?(name)
|
64
|
-
define_method(name) { current_state.to_s == %(#{state_name}) }
|
65
|
-
end
|
66
61
|
end
|
67
62
|
|
68
63
|
def self.included(base)
|
69
64
|
base.extend(ClassMethods)
|
70
65
|
end
|
71
66
|
|
67
|
+
# TODO Do we need this method really? Also, it's not a beauty, refactor at least.
|
72
68
|
def current_state(name = nil, new_state = nil, persist = false)
|
73
69
|
sm = self.class.state_machine(name)
|
74
70
|
ivar = sm.current_state_variable
|
data/test/db/create_db.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/test_active_record.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require "helper"
|
2
2
|
require 'active_support/core_ext/module/aliasing'
|
3
3
|
|
4
|
+
# TODO Tests here are quite messy, clean up.
|
5
|
+
|
4
6
|
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
5
7
|
|
6
8
|
class CreateTrafficLights < ActiveRecord::Migration
|
@@ -188,34 +190,49 @@ class TestNewActiveRecord < TestActiveRecord
|
|
188
190
|
|
189
191
|
end
|
190
192
|
|
193
|
+
class CreateBunnies < ActiveRecord::Migration
|
194
|
+
def self.up
|
195
|
+
create_table(:bunnies) do |t|
|
196
|
+
t.string :state
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
CreateBunnies.migrate(:up)
|
202
|
+
|
203
|
+
class Bunny < ActiveRecord::Base
|
204
|
+
include ActiveModel::Transitions
|
205
|
+
|
206
|
+
state_machine :auto_scopes => true do
|
207
|
+
state :hobbling
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
191
211
|
class TestScopes < Test::Unit::TestCase
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
assert_equal TrafficLight.off.first, @light
|
196
|
-
assert TrafficLight.red.empty?
|
212
|
+
def setup
|
213
|
+
create_database
|
214
|
+
@bunny = Bunny.create!
|
197
215
|
end
|
198
216
|
|
199
217
|
test "scopes exist" do
|
200
|
-
assert_respond_to
|
201
|
-
|
202
|
-
|
203
|
-
|
218
|
+
assert_respond_to Bunny, :hobbling
|
219
|
+
end
|
220
|
+
|
221
|
+
test "scope returns correct object" do
|
222
|
+
assert_equal Bunny.hobbling.first, @bunny
|
204
223
|
end
|
205
224
|
|
206
225
|
test 'scopes are only generated if we explicitly say so' do
|
207
226
|
assert_not_respond_to LightBulb, :off
|
208
|
-
assert_not_respond_to LightBulb, :on
|
209
227
|
end
|
210
228
|
|
211
229
|
test 'scope generation raises an exception if we try to overwrite an existing method' do
|
212
230
|
assert_raise(Transitions::InvalidMethodOverride) {
|
213
|
-
class
|
231
|
+
class TrafficLight < ActiveRecord::Base
|
214
232
|
include ActiveModel::Transitions
|
215
233
|
|
216
234
|
state_machine :auto_scopes => true do
|
217
235
|
state :new
|
218
|
-
state :broken
|
219
236
|
end
|
220
237
|
end
|
221
238
|
}
|
data/test/test_state.rb
CHANGED
@@ -1,50 +1,50 @@
|
|
1
1
|
require "helper"
|
2
2
|
|
3
|
-
class StateTestSubject
|
4
|
-
include Transitions
|
5
|
-
|
6
|
-
state_machine do
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
3
|
class TestState < Test::Unit::TestCase
|
11
4
|
def setup
|
5
|
+
@state_test_subject = Class.new do
|
6
|
+
include Transitions
|
7
|
+
state_machine do
|
8
|
+
end
|
9
|
+
end
|
12
10
|
@state_name = :astate
|
13
|
-
@machine =
|
14
|
-
@options = { :
|
11
|
+
@machine = @state_test_subject.state_machine
|
12
|
+
@options = { :machine => @machine, :custom_key => :my_key }
|
13
|
+
@state = Transitions::State.new(@state_name, @options)
|
15
14
|
end
|
16
15
|
|
17
|
-
def
|
18
|
-
|
16
|
+
def new_state_name
|
17
|
+
Random.alphanumeric(16)
|
19
18
|
end
|
20
19
|
|
21
20
|
test "sets the name" do
|
22
|
-
assert_equal :astate,
|
21
|
+
assert_equal :astate, @state.name
|
23
22
|
end
|
24
23
|
|
25
24
|
test "sets the display_name from name" do
|
26
|
-
assert_equal "Astate",
|
25
|
+
assert_equal "Astate", @state.display_name
|
27
26
|
end
|
28
27
|
|
29
28
|
test "sets the display_name from options" do
|
30
|
-
assert_equal "A State",
|
29
|
+
assert_equal "A State", Transitions::State.new(new_state_name, @options.merge(:display => "A State")).display_name
|
31
30
|
end
|
32
31
|
|
33
32
|
test "sets the options and expose them as options" do
|
34
33
|
@options.delete(:machine)
|
35
|
-
|
34
|
+
state = Transitions::State.new new_state_name, @options
|
35
|
+
assert_equal @options, state.options
|
36
36
|
end
|
37
37
|
|
38
38
|
test "equals a symbol of the same name" do
|
39
|
-
assert_equal
|
39
|
+
assert_equal @state, :astate
|
40
40
|
end
|
41
41
|
|
42
42
|
test "equals a State of the same name" do
|
43
|
-
assert_equal
|
43
|
+
assert_equal @state, @state
|
44
44
|
end
|
45
45
|
|
46
46
|
test "should send a message to the record for an action if the action is present as a symbol" do
|
47
|
-
state =
|
47
|
+
state = Transitions::State.new new_state_name, @options.merge(:entering => :foo)
|
48
48
|
|
49
49
|
record = stub
|
50
50
|
record.expects(:foo)
|
@@ -53,7 +53,7 @@ class TestState < Test::Unit::TestCase
|
|
53
53
|
end
|
54
54
|
|
55
55
|
test "should send a message to the record for an action if the action is present as a string" do
|
56
|
-
state =
|
56
|
+
state = Transitions::State.new new_state_name, @options.merge(:entering => "foo")
|
57
57
|
|
58
58
|
record = stub
|
59
59
|
record.expects(:foo)
|
@@ -62,7 +62,7 @@ class TestState < Test::Unit::TestCase
|
|
62
62
|
end
|
63
63
|
|
64
64
|
test "should call a proc, passing in the record for an action if the action is present" do
|
65
|
-
state =
|
65
|
+
state = Transitions::State.new new_state_name, @options.merge(:entering => Proc.new {|r| r.foobar})
|
66
66
|
|
67
67
|
record = stub
|
68
68
|
record.expects(:foobar)
|
@@ -70,3 +70,32 @@ class TestState < Test::Unit::TestCase
|
|
70
70
|
state.call_action(:entering, record)
|
71
71
|
end
|
72
72
|
end
|
73
|
+
|
74
|
+
class StateOverrideMethodTestSubject
|
75
|
+
include Transitions
|
76
|
+
|
77
|
+
state_machine do
|
78
|
+
end
|
79
|
+
|
80
|
+
def a_state_name?; :foo; end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
class TestStateQueryOverrideMethod < Test::Unit::TestCase
|
85
|
+
def setup
|
86
|
+
@state_name = 'a_state_name'
|
87
|
+
@machine = StateOverrideMethodTestSubject.state_machine
|
88
|
+
@options = { :machine => @machine }
|
89
|
+
end
|
90
|
+
|
91
|
+
test "warn on creation when we try to overwrite an existing method" do
|
92
|
+
# TODO
|
93
|
+
end
|
94
|
+
|
95
|
+
test "should not override an already existing method" do
|
96
|
+
Transitions::State.new :dummy, @options
|
97
|
+
expected_result = :foo
|
98
|
+
actual_result = StateOverrideMethodTestSubject.new.a_state_name?
|
99
|
+
assert_equal expected_result, actual_result
|
100
|
+
end
|
101
|
+
end
|
data/transitions.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_development_dependency "test-unit", "~> 2.2"
|
19
19
|
s.add_development_dependency "mocha"
|
20
20
|
s.add_development_dependency "rake"
|
21
|
+
s.add_development_dependency "random_data"
|
21
22
|
s.add_development_dependency "sqlite3"
|
22
23
|
s.add_development_dependency "activerecord", "~> 3"
|
23
24
|
|
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.18
|
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: 2012-05-
|
13
|
+
date: 2012-05-18 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|
17
|
-
requirement: &
|
17
|
+
requirement: &76418870 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ~>
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '1'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *76418870
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: test-unit
|
28
|
-
requirement: &
|
28
|
+
requirement: &76418470 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
@@ -33,10 +33,10 @@ dependencies:
|
|
33
33
|
version: '2.2'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *76418470
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
name: mocha
|
39
|
-
requirement: &
|
39
|
+
requirement: &76418120 !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: *76418120
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
49
|
name: rake
|
50
|
-
requirement: &
|
50
|
+
requirement: &76417650 !ruby/object:Gem::Requirement
|
51
51
|
none: false
|
52
52
|
requirements:
|
53
53
|
- - ! '>='
|
@@ -55,10 +55,21 @@ dependencies:
|
|
55
55
|
version: '0'
|
56
56
|
type: :development
|
57
57
|
prerelease: false
|
58
|
-
version_requirements: *
|
58
|
+
version_requirements: *76417650
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: random_data
|
61
|
+
requirement: &76417170 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *76417170
|
59
70
|
- !ruby/object:Gem::Dependency
|
60
71
|
name: sqlite3
|
61
|
-
requirement: &
|
72
|
+
requirement: &76416820 !ruby/object:Gem::Requirement
|
62
73
|
none: false
|
63
74
|
requirements:
|
64
75
|
- - ! '>='
|
@@ -66,10 +77,10 @@ dependencies:
|
|
66
77
|
version: '0'
|
67
78
|
type: :development
|
68
79
|
prerelease: false
|
69
|
-
version_requirements: *
|
80
|
+
version_requirements: *76416820
|
70
81
|
- !ruby/object:Gem::Dependency
|
71
82
|
name: activerecord
|
72
|
-
requirement: &
|
83
|
+
requirement: &76416030 !ruby/object:Gem::Requirement
|
73
84
|
none: false
|
74
85
|
requirements:
|
75
86
|
- - ~>
|
@@ -77,7 +88,7 @@ dependencies:
|
|
77
88
|
version: '3'
|
78
89
|
type: :development
|
79
90
|
prerelease: false
|
80
|
-
version_requirements: *
|
91
|
+
version_requirements: *76416030
|
81
92
|
description: Lightweight state machine extracted from ActiveModel
|
82
93
|
email: timo.roessner@googlemail.com
|
83
94
|
executables: []
|
@@ -129,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
140
|
version: '0'
|
130
141
|
segments:
|
131
142
|
- 0
|
132
|
-
hash: -
|
143
|
+
hash: -1015670387
|
133
144
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
145
|
none: false
|
135
146
|
requirements:
|