transitions 1.0.0 → 1.0.1

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.
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