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 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.
@@ -27,7 +27,7 @@ module Transitions
27
27
  def initialize(name, options = {})
28
28
  @name = name
29
29
  if machine = options.delete(:machine)
30
- machine.klass.define_state_query_method(name)
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
@@ -1,3 +1,3 @@
1
1
  module Transitions
2
- VERSION = "0.0.17"
2
+ VERSION = "0.0.18"
3
3
  end
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
@@ -5,6 +5,9 @@ class CreateDb < ActiveRecord::Migration
5
5
  t.string :state
6
6
  t.string :name
7
7
  end
8
+ create_table(:bunnies, :force => true) do |t|
9
+ t.string :state
10
+ end
8
11
 
9
12
  create_table(:orders, :force => true) do |t|
10
13
  t.string :state
data/test/helper.rb CHANGED
@@ -7,6 +7,7 @@ require "db/create_db"
7
7
 
8
8
  require "transitions"
9
9
  require "active_model/transitions"
10
+ require 'random_data'
10
11
 
11
12
  def create_database
12
13
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
@@ -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
- test "scope returns correct object" do
193
- @light = TrafficLight.create!
194
- assert_respond_to TrafficLight, :off
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 TrafficLight, :off
201
- assert_respond_to TrafficLight, :red
202
- assert_respond_to TrafficLight, :green
203
- assert_respond_to TrafficLight, :yellow
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 Light < ActiveRecord::Base
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 = StateTestSubject.state_machine
14
- @options = { :crazy_custom_key => "key", :machine => @machine }
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 new_state(options={})
18
- Transitions::State.new(@state_name, @options.merge(options))
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, new_state.name
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", new_state.display_name
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", new_state(:display => "A State").display_name
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
- assert_equal @options, new_state.options
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 new_state, :astate
39
+ assert_equal @state, :astate
40
40
  end
41
41
 
42
42
  test "equals a State of the same name" do
43
- assert_equal new_state, new_state
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 = new_state(:entering => :foo)
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 = new_state(:entering => "foo")
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 = new_state(:entering => Proc.new {|r| r.foobar})
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.17
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-02 00:00:00.000000000Z
13
+ date: 2012-05-18 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: bundler
17
- requirement: &80694140 !ruby/object:Gem::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: *80694140
25
+ version_requirements: *76418870
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: test-unit
28
- requirement: &80692960 !ruby/object:Gem::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: *80692960
36
+ version_requirements: *76418470
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: mocha
39
- requirement: &80692570 !ruby/object:Gem::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: *80692570
47
+ version_requirements: *76418120
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: rake
50
- requirement: &80682540 !ruby/object:Gem::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: *80682540
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: &80681530 !ruby/object:Gem::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: *80681530
80
+ version_requirements: *76416820
70
81
  - !ruby/object:Gem::Dependency
71
82
  name: activerecord
72
- requirement: &80680830 !ruby/object:Gem::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: *80680830
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: -1021171215
143
+ hash: -1015670387
133
144
  required_rubygems_version: !ruby/object:Gem::Requirement
134
145
  none: false
135
146
  requirements: