transitions 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -1
  3. data/.travis.yml +5 -0
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +7 -6
  6. data/LICENSE.txt +21 -0
  7. data/README.md +9 -4
  8. data/Rakefile +9 -4
  9. data/bin/console +7 -0
  10. data/lib/active_model/transitions.rb +19 -12
  11. data/lib/transitions.rb +15 -15
  12. data/lib/transitions/event.rb +19 -15
  13. data/lib/transitions/machine.rb +23 -22
  14. data/lib/transitions/presenter.rb +2 -6
  15. data/lib/transitions/state.rb +10 -7
  16. data/lib/transitions/state_transition.rb +37 -6
  17. data/lib/transitions/version.rb +1 -1
  18. data/transitions.gemspec +23 -24
  19. metadata +39 -45
  20. data/.ruby-gemset +0 -1
  21. data/MIT-LICENSE.txt +0 -21
  22. data/test/active_record/test_active_record.rb +0 -326
  23. data/test/active_record/test_active_record_scopes.rb +0 -64
  24. data/test/active_record/test_active_record_timestamps.rb +0 -132
  25. data/test/active_record/test_custom_select.rb +0 -33
  26. data/test/event/test_event.rb +0 -72
  27. data/test/event/test_event_arguments.rb +0 -29
  28. data/test/event/test_event_being_fired.rb +0 -26
  29. data/test/event/test_event_checks.rb +0 -33
  30. data/test/helper.rb +0 -18
  31. data/test/machine/machine_template.rb +0 -27
  32. data/test/machine/test_available_states_listing.rb +0 -24
  33. data/test/machine/test_fire_event_machine.rb +0 -29
  34. data/test/machine/test_machine.rb +0 -66
  35. data/test/state/test_state.rb +0 -71
  36. data/test/state/test_state_predicate_method.rb +0 -32
  37. data/test/state_transition/test_state_transition.rb +0 -45
  38. data/test/state_transition/test_state_transition_event_failed_callback.rb +0 -36
  39. data/test/state_transition/test_state_transition_event_fired_callback.rb +0 -44
  40. data/test/state_transition/test_state_transition_guard_check.rb +0 -66
  41. data/test/state_transition/test_state_transition_on_transition_callback.rb +0 -48
  42. data/test/state_transition/test_state_transition_success_callback.rb +0 -49
@@ -1,15 +1,11 @@
1
1
  module Transitions
2
2
  module Presenter
3
3
  def available_states
4
- @state_machine.states.map(&:name).sort_by(&:to_s)
4
+ get_state_machine.states.map(&:name).sort_by(&:to_s)
5
5
  end
6
6
 
7
7
  def available_events
8
- @state_machine.events.keys.sort
9
- end
10
-
11
- def available_transitions
12
- @state_machine.events_for(current_state)
8
+ get_state_machine.events.keys.sort
13
9
  end
14
10
  end
15
11
  end
@@ -10,11 +10,11 @@ module Transitions
10
10
  update(options)
11
11
  end
12
12
 
13
- def ==(state)
14
- if state.is_a? Symbol
15
- name == state
13
+ def ==(other)
14
+ if other.is_a? Symbol
15
+ name == other
16
16
  else
17
- name == state.name
17
+ name == other.name
18
18
  end
19
19
  end
20
20
 
@@ -29,7 +29,7 @@ module Transitions
29
29
  end
30
30
 
31
31
  def display_name
32
- @display_name ||= name.to_s.gsub(/_/, ' ').capitalize
32
+ @display_name ||= name.to_s.tr('_', ' ').capitalize
33
33
  end
34
34
 
35
35
  def for_select
@@ -45,9 +45,12 @@ module Transitions
45
45
  private
46
46
 
47
47
  def define_state_query_method(machine)
48
- method_name, state_name = "#{@name}?", @name # Instance vars are out of scope when calling define_method below, so we use local variables.
48
+ method_name = "#{@name}?"
49
+ state_name = @name # Instance vars are out of scope when calling define_method below, so we use local variables.
49
50
  if machine.klass.method_defined?(method_name.to_sym)
50
- fail InvalidMethodOverride, "Transitions: Can not define method `#{method_name}` because it is already defined - either rename the existing method or the state."
51
+ fail InvalidMethodOverride,
52
+ "Transitions: Can not define method `#{method_name}` because it is already"\
53
+ 'defined - either rename the existing method or the state.'
51
54
  end
52
55
  machine.klass.send :define_method, method_name do
53
56
  current_state.to_s == state_name.to_s
@@ -1,16 +1,45 @@
1
1
  module Transitions
2
2
  class StateTransition
3
- attr_reader :from, :to, :options
3
+ attr_reader :from, :to, :guard, :on_transition
4
+ # TODO: `from` and `to` should be private as well
5
+ private :guard, :on_transition
4
6
 
5
7
  def initialize(opts)
6
- @from, @to, @guard, @on_transition = opts[:from], opts[:to], opts[:guard], opts[:on_transition]
8
+ @from = opts[:from]
9
+ @to = opts[:to]
10
+ @guard = opts[:guard]
11
+ @on_transition = opts[:on_transition]
7
12
  @options = opts
8
13
  end
9
14
 
15
+ #
16
+ # @param obj [Any] - the subject
17
+ # @param args [Array<Symbol>] - any arguments passed into the transition method
18
+ # E.g. something like
19
+ # car.drive!(:fast, :now)
20
+ # with `car` being the subject and `drive` the transition method would result
21
+ # in `args` looking like this:
22
+ # [:fast, :now]
23
+ #
24
+ # @return [Bool]
25
+ #
10
26
  def executable?(obj, *args)
11
27
  [@guard].flatten.all? { |g| perform_guard(obj, g, *args) }
12
28
  end
13
29
 
30
+ #
31
+ # @param obj [Any] - the subject
32
+ # @param args [Array<Symbol>] - any arguments passed into the transition method
33
+ # E.g. something like
34
+ # car.drive!(:fast, :now)
35
+ # with `car` being the subject and `drive` the transition method would result
36
+ # in `args` looking like this:
37
+ # [:fast, :now]
38
+ #
39
+ # @return [void]
40
+ #
41
+ # rubocop:disable Metrics/MethodLength
42
+ #
14
43
  def execute(obj, *args)
15
44
  case @on_transition
16
45
  when Symbol, String
@@ -24,13 +53,15 @@ module Transitions
24
53
  obj.send(callback, *args)
25
54
  end
26
55
  else
27
- # TODO We probably should check for this in the constructor and not that late.
28
- fail ArgumentError, "You can only pass a Symbol, a String, a Proc or an Array to 'on_transition' - got #{@on_transition.class}." unless @on_transition.nil?
56
+ # TODO: We probably should check for this in the constructor and not that late.
57
+ fail ArgumentError,
58
+ "You can only pass a Symbol, a String, a Proc or an Array to 'on_transition'"\
59
+ " - got #{@on_transition.class}." unless @on_transition.nil?
29
60
  end
30
61
  end
31
62
 
32
- def ==(obj)
33
- @from == obj.from && @to == obj.to
63
+ def ==(other)
64
+ @from == other.from && @to == other.to
34
65
  end
35
66
 
36
67
  def from?(value)
@@ -1,3 +1,3 @@
1
1
  module Transitions
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'.freeze
3
3
  end
data/transitions.gemspec CHANGED
@@ -1,29 +1,28 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/transitions/version', __FILE__)
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'transitions/version'
3
5
 
4
- Gem::Specification.new do |s|
5
- s.name = 'transitions'
6
- s.version = Transitions::VERSION
7
- s.platform = Gem::Platform::RUBY
8
- s.authors = ['Jakub Kuzma', 'Timo Roessner']
9
- s.email = 'timo.roessner@googlemail.com'
10
- s.homepage = 'http://github.com/troessner/transitions'
11
- s.summary = 'State machine extracted from ActiveModel'
12
- s.description = 'Lightweight state machine extracted from ActiveModel'
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'transitions'
8
+ spec.version = Transitions::VERSION
9
+ spec.authors = ['Timo Rößner']
10
+ spec.email = ['timo.roessner@googlemail.com']
13
11
 
14
- s.required_rubygems_version = '>= 1.3.6'
15
- s.rubyforge_project = 'transitions'
12
+ spec.summary = 'State machine extracted from ActiveModel'
13
+ spec.description = 'Lightweight state machine extracted from ActiveModel'
14
+ spec.homepage = 'http://github.com/troessner/transitions'
15
+ spec.license = 'MIT'
16
16
 
17
- s.add_development_dependency 'bundler', '~> 1'
18
- s.add_development_dependency 'test-unit', '~> 2.5'
19
- s.add_development_dependency 'mocha', '~> 0.11.0' # With mocha 0.12 we get: undefined method `run' for #<StateMachineMachineTest:0x94918b8> (NoMethodError)
20
- s.add_development_dependency 'rake'
21
- s.add_development_dependency 'random_data'
22
- s.add_development_dependency 'appraisal'
23
- s.add_development_dependency 'activerecord', ['>= 3.0', '<= 4.0']
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.require_paths = ['lib']
24
19
 
25
- s.files = `git ls-files`.split("\n")
26
- s.executables = `git ls-files`.split("\n").map { |f| f =~ /^bin\/(.*)/ ? Regexp.last_match[1] : nil }.compact
27
- s.require_path = 'lib'
28
- s.license = 'MIT'
20
+ spec.add_development_dependency 'bundler', '~> 1.0'
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'test-unit', '~> 2.5'
23
+ spec.add_development_dependency 'mocha', '~> 0.11.0' # With mocha 0.12 we get: undefined method `run' for #<StateMachineMachineTest:0x94918b8> (NoMethodError)
24
+ spec.add_development_dependency 'random_data'
25
+ spec.add_development_dependency 'appraisal'
26
+ spec.add_development_dependency 'activerecord', ['>= 3.0', '<= 4.0']
27
+ spec.add_development_dependency 'rubocop', '~> 0.36'
29
28
  end
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transitions
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
- - Jakub Kuzma
8
- - Timo Roessner
7
+ - Timo Rößner
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-12-25 00:00:00.000000000 Z
11
+ date: 2016-02-05 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
@@ -17,56 +16,56 @@ dependencies:
17
16
  requirements:
18
17
  - - "~>"
19
18
  - !ruby/object:Gem::Version
20
- version: '1'
19
+ version: '1.0'
21
20
  type: :development
22
21
  prerelease: false
23
22
  version_requirements: !ruby/object:Gem::Requirement
24
23
  requirements:
25
24
  - - "~>"
26
25
  - !ruby/object:Gem::Version
27
- version: '1'
26
+ version: '1.0'
28
27
  - !ruby/object:Gem::Dependency
29
- name: test-unit
28
+ name: rake
30
29
  requirement: !ruby/object:Gem::Requirement
31
30
  requirements:
32
- - - "~>"
31
+ - - ">="
33
32
  - !ruby/object:Gem::Version
34
- version: '2.5'
33
+ version: '0'
35
34
  type: :development
36
35
  prerelease: false
37
36
  version_requirements: !ruby/object:Gem::Requirement
38
37
  requirements:
39
- - - "~>"
38
+ - - ">="
40
39
  - !ruby/object:Gem::Version
41
- version: '2.5'
40
+ version: '0'
42
41
  - !ruby/object:Gem::Dependency
43
- name: mocha
42
+ name: test-unit
44
43
  requirement: !ruby/object:Gem::Requirement
45
44
  requirements:
46
45
  - - "~>"
47
46
  - !ruby/object:Gem::Version
48
- version: 0.11.0
47
+ version: '2.5'
49
48
  type: :development
50
49
  prerelease: false
51
50
  version_requirements: !ruby/object:Gem::Requirement
52
51
  requirements:
53
52
  - - "~>"
54
53
  - !ruby/object:Gem::Version
55
- version: 0.11.0
54
+ version: '2.5'
56
55
  - !ruby/object:Gem::Dependency
57
- name: rake
56
+ name: mocha
58
57
  requirement: !ruby/object:Gem::Requirement
59
58
  requirements:
60
- - - ">="
59
+ - - "~>"
61
60
  - !ruby/object:Gem::Version
62
- version: '0'
61
+ version: 0.11.0
63
62
  type: :development
64
63
  prerelease: false
65
64
  version_requirements: !ruby/object:Gem::Requirement
66
65
  requirements:
67
- - - ">="
66
+ - - "~>"
68
67
  - !ruby/object:Gem::Version
69
- version: '0'
68
+ version: 0.11.0
70
69
  - !ruby/object:Gem::Dependency
71
70
  name: random_data
72
71
  requirement: !ruby/object:Gem::Requirement
@@ -115,23 +114,38 @@ dependencies:
115
114
  - - "<="
116
115
  - !ruby/object:Gem::Version
117
116
  version: '4.0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rubocop
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.36'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.36'
118
131
  description: Lightweight state machine extracted from ActiveModel
119
- email: timo.roessner@googlemail.com
132
+ email:
133
+ - timo.roessner@googlemail.com
120
134
  executables: []
121
135
  extensions: []
122
136
  extra_rdoc_files: []
123
137
  files:
124
138
  - ".gitignore"
125
139
  - ".rubocop.yml"
126
- - ".ruby-gemset"
127
140
  - ".ruby-version"
128
141
  - ".travis.yml"
129
142
  - Appraisals
130
143
  - CHANGELOG.md
131
144
  - Gemfile
132
- - MIT-LICENSE.txt
145
+ - LICENSE.txt
133
146
  - README.md
134
147
  - Rakefile
148
+ - bin/console
135
149
  - gemfiles/rails_3_0.gemfile
136
150
  - gemfiles/rails_3_1.gemfile
137
151
  - gemfiles/rails_3_2.gemfile
@@ -145,27 +159,6 @@ files:
145
159
  - lib/transitions/state.rb
146
160
  - lib/transitions/state_transition.rb
147
161
  - lib/transitions/version.rb
148
- - test/active_record/test_active_record.rb
149
- - test/active_record/test_active_record_scopes.rb
150
- - test/active_record/test_active_record_timestamps.rb
151
- - test/active_record/test_custom_select.rb
152
- - test/event/test_event.rb
153
- - test/event/test_event_arguments.rb
154
- - test/event/test_event_being_fired.rb
155
- - test/event/test_event_checks.rb
156
- - test/helper.rb
157
- - test/machine/machine_template.rb
158
- - test/machine/test_available_states_listing.rb
159
- - test/machine/test_fire_event_machine.rb
160
- - test/machine/test_machine.rb
161
- - test/state/test_state.rb
162
- - test/state/test_state_predicate_method.rb
163
- - test/state_transition/test_state_transition.rb
164
- - test/state_transition/test_state_transition_event_failed_callback.rb
165
- - test/state_transition/test_state_transition_event_fired_callback.rb
166
- - test/state_transition/test_state_transition_guard_check.rb
167
- - test/state_transition/test_state_transition_on_transition_callback.rb
168
- - test/state_transition/test_state_transition_success_callback.rb
169
162
  - transitions.gemspec
170
163
  homepage: http://github.com/troessner/transitions
171
164
  licenses:
@@ -184,11 +177,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
177
  requirements:
185
178
  - - ">="
186
179
  - !ruby/object:Gem::Version
187
- version: 1.3.6
180
+ version: '0'
188
181
  requirements: []
189
- rubyforge_project: transitions
182
+ rubyforge_project:
190
183
  rubygems_version: 2.4.5.1
191
184
  signing_key:
192
185
  specification_version: 4
193
186
  summary: State machine extracted from ActiveModel
194
187
  test_files: []
188
+ has_rdoc:
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- transitions
data/MIT-LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- Copyright 2013 jQuery Foundation and other contributors
2
- http://jquery.com/
3
-
4
- Permission is hereby granted, free of charge, to any person obtaining
5
- a copy of this software and associated documentation files (the
6
- "Software"), to deal in the Software without restriction, including
7
- without limitation the rights to use, copy, modify, merge, publish,
8
- distribute, sublicense, and/or sell copies of the Software, and to
9
- permit persons to whom the Software is furnished to do so, subject to
10
- the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be
13
- included in all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,326 +0,0 @@
1
- require 'helper'
2
-
3
- class CreateTrafficLights < ActiveRecord::Migration
4
- def self.up
5
- create_table(:traffic_lights, force: true) do |t|
6
- t.string :state
7
- t.string :name
8
- t.string :power
9
- end
10
- end
11
- end
12
-
13
- class CreateDifferentTrafficLights < ActiveRecord::Migration
14
- def self.up
15
- create_table(:different_traffic_lights) do |t|
16
- t.string :different_state
17
- t.string :name
18
- end
19
- end
20
- end
21
-
22
- class TrafficLight < ActiveRecord::Base
23
- include ActiveModel::Transitions
24
-
25
- state_machine auto_scopes: true do
26
- state :off, enter: :turn_power_on
27
-
28
- state :red
29
- state :green
30
- state :yellow
31
-
32
- event :red_on do
33
- transitions to: :red, from: [:yellow]
34
- end
35
-
36
- event :green_on do
37
- transitions to: :green, from: [:red]
38
- end
39
-
40
- event :yellow_on do
41
- transitions to: :yellow, from: [:green]
42
- end
43
-
44
- event :reset do
45
- transitions to: :red, from: [:off]
46
- end
47
- end
48
-
49
- def turn_power_on
50
- fail 'the power should not have been on already' if power == 'on'
51
- self.power = 'on'
52
- end
53
- end
54
-
55
- class ValidatingTrafficLight < TrafficLight
56
- validate { |t| errors.add(:base, 'This TrafficLight will never validate after creation') unless t.new_record? }
57
- end
58
-
59
- class ConditionalValidatingTrafficLight < TrafficLight
60
- validates(:name, presence: true, if: :red?)
61
- end
62
-
63
- class TestActiveRecord < Test::Unit::TestCase
64
- def setup
65
- set_up_db CreateTrafficLights
66
- @light = TrafficLight.create!
67
- end
68
-
69
- test 'new record has the initial state set' do
70
- @light = TrafficLight.new
71
- assert_equal 'off', @light.state
72
- end
73
-
74
- test 'new active records defaults current state to the initial state' do
75
- assert_equal :off, @light.current_state
76
- end
77
-
78
- test 'states initial state' do
79
- assert @light.off?
80
- assert_equal :off, @light.current_state
81
- end
82
-
83
- test 'calls enter when setting the initial state' do
84
- @new_light = TrafficLight.new
85
- assert_equal 'on', @new_light.power
86
- end
87
-
88
- test 'does not call enter when loading a persisted record' do
89
- assert_equal 'on', @light.power
90
- assert_nothing_raised { TrafficLight.find(@light.id) }
91
- end
92
-
93
- test 'transition to a valid state' do
94
- @light.reset
95
- assert @light.red?
96
- assert_equal :red, @light.current_state
97
-
98
- @light.green_on
99
- assert @light.green?
100
- assert_equal :green, @light.current_state
101
- end
102
-
103
- test 'transition does not persist state' do
104
- @light.reset
105
- assert_equal :red, @light.current_state
106
- @light.reload
107
- assert_equal 'off', @light.state
108
- end
109
-
110
- test 'transition does persists state' do
111
- @light.reset!
112
- assert_equal :red, @light.current_state
113
- @light.reload
114
- assert_equal 'red', @light.state
115
- end
116
-
117
- test 'transition to an invalid state' do
118
- assert_raise(Transitions::InvalidTransition) { @light.yellow_on }
119
- assert_equal :off, @light.current_state
120
- end
121
-
122
- test 'transition with wrong state will not validate' do
123
- for s in @light.class.get_state_machine.states
124
- @light.state = s.name
125
- assert @light.valid?
126
- end
127
- @light.state = 'invalid_one'
128
- assert_false @light.valid?
129
- end
130
-
131
- test 'transition raises exception when model validation fails' do
132
- validating_light = ValidatingTrafficLight.create!(name: 'Foobar')
133
- assert_raise(ActiveRecord::RecordInvalid) do
134
- validating_light.reset!
135
- end
136
- end
137
-
138
- test 'state query method used in a validation condition' do
139
- validating_light = ConditionalValidatingTrafficLight.create!
140
- assert_raise(ActiveRecord::RecordInvalid) do
141
- validating_light.reset!
142
- end
143
- assert(validating_light.off?)
144
- end
145
-
146
- test 'reloading model resets current state' do
147
- @light.reset
148
- assert @light.red?
149
- @light.update_attribute(:state, 'green')
150
- assert @light.reload.green?, 'reloaded state should come from database, not instance variable'
151
- end
152
-
153
- test 'calling non-bang event updates state attribute' do
154
- @light.reset!
155
- assert @light.red?
156
- @light.green_on
157
- assert_equal 'green', @light.state
158
- assert_equal 'red', @light.reload.state
159
- end
160
- end
161
-
162
- if ActiveRecord::VERSION::MAJOR == 3
163
-
164
- class TestMassAssignmentActiveRecord < Test::Unit::TestCase
165
- # attr_protected unfortunately invokes a db call, so this test requires that
166
- # we define the class after the table already exists.
167
- def setup
168
- set_up_db CreateTrafficLights
169
-
170
- @light_with_protected_state = Class.new(TrafficLight) do
171
- attr_protected :state
172
- end
173
- end
174
-
175
- test 'transition does persists state when state is protected' do
176
- protected_light = @light_with_protected_state.create!
177
- protected_light.reset!
178
- assert_equal :red, protected_light.current_state
179
- protected_light.reload
180
- assert_equal 'red', protected_light.state
181
- end
182
- end
183
- end
184
-
185
- class TestNewActiveRecord < TestActiveRecord
186
- def setup
187
- set_up_db CreateTrafficLights
188
- @light = TrafficLight.new
189
- end
190
-
191
- test 'new active records defaults current state to the initial state' do
192
- assert_equal :off, @light.current_state
193
- end
194
- end
195
-
196
- class TestScopes < Test::Unit::TestCase
197
- test 'scope returns correct object' do
198
- @light = TrafficLight.create!
199
- assert_respond_to TrafficLight, :off
200
- assert_equal TrafficLight.off.first, @light
201
- assert TrafficLight.red.empty?
202
- end
203
-
204
- test 'scopes exist' do
205
- assert_respond_to TrafficLight, :off
206
- assert_respond_to TrafficLight, :red
207
- assert_respond_to TrafficLight, :green
208
- assert_respond_to TrafficLight, :yellow
209
- end
210
-
211
- test 'scopes are only generated if we explicitly say so' do
212
- assert_not_respond_to LightBulb, :off
213
- assert_not_respond_to LightBulb, :on
214
- end
215
-
216
- test 'scope generation raises an exception if we try to overwrite an existing method' do
217
- assert_raise(Transitions::InvalidMethodOverride) do
218
- class Light < ActiveRecord::Base
219
- include ActiveModel::Transitions
220
-
221
- state_machine auto_scopes: true do
222
- state :new
223
- state :broken
224
- end
225
- end
226
- end
227
- end
228
- end
229
-
230
- class DifferentTrafficLight < ActiveRecord::Base
231
- include ActiveModel::Transitions
232
-
233
- state_machine attribute_name: :different_state, auto_scopes: true do
234
- state :off
235
-
236
- state :red
237
- state :green
238
- state :yellow
239
-
240
- event :red_on do
241
- transitions to: :red, from: [:yellow]
242
- end
243
-
244
- event :green_on do
245
- transitions to: :green, from: [:red]
246
- end
247
-
248
- event :yellow_on do
249
- transitions to: :yellow, from: [:green]
250
- end
251
-
252
- event :reset do
253
- transitions to: :red, from: [:off]
254
- end
255
- end
256
- end
257
-
258
- class TestActiveRecordWithDifferentColumnName < Test::Unit::TestCase
259
- def setup
260
- set_up_db CreateDifferentTrafficLights
261
- @light = DifferentTrafficLight.create!
262
- end
263
-
264
- test 'new record has the initial state set' do
265
- @light = DifferentTrafficLight.new
266
- assert_equal 'off', @light.different_state
267
- end
268
-
269
- test 'states initial state' do
270
- assert @light.off?
271
- assert_equal :off, @light.current_state
272
- end
273
-
274
- test 'transition to a valid state' do
275
- @light.reset
276
- assert @light.red?
277
- assert_equal :red, @light.current_state
278
-
279
- @light.green_on
280
- assert @light.green?
281
- assert_equal :green, @light.current_state
282
- end
283
-
284
- test 'transition does not persist state' do
285
- @light.reset
286
- assert_equal :red, @light.current_state
287
- @light.reload
288
- assert_equal 'off', @light.different_state
289
- end
290
-
291
- test 'transition does persists state' do
292
- @light.reset!
293
- assert_equal :red, @light.current_state
294
- @light.reload
295
- assert_equal 'red', @light.different_state
296
- end
297
-
298
- test 'transition to an invalid state' do
299
- assert_raise(Transitions::InvalidTransition) { @light.yellow_on }
300
- assert_equal :off, @light.current_state
301
- end
302
-
303
- test 'transition with wrong state will not validate' do
304
- for s in @light.class.state_machine.states
305
- @light.different_state = s.name
306
- assert @light.valid?
307
- end
308
- @light.different_state = 'invalid_one'
309
- assert_false @light.valid?
310
- end
311
-
312
- test 'reloading model resets current state' do
313
- @light.reset
314
- assert @light.red?
315
- @light.update_attribute(:different_state, 'green')
316
- assert @light.reload.green?, 'reloaded state should come from database, not instance variable'
317
- end
318
-
319
- test 'calling non-bang event updates state attribute' do
320
- @light.reset!
321
- assert @light.red?
322
- @light.green_on
323
- assert_equal 'green', @light.different_state
324
- assert_equal 'red', @light.reload.different_state
325
- end
326
- end