state_machines-activerecord 0.10.0 → 0.40.0

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -1
  3. data/lib/state_machines/integrations/active_record/locale.rb +10 -9
  4. data/lib/state_machines/integrations/active_record/version.rb +1 -1
  5. data/lib/state_machines/integrations/active_record.rb +52 -31
  6. metadata +35 -138
  7. data/test/files/en.yml +0 -5
  8. data/test/files/models/post.rb +0 -13
  9. data/test/integration_test.rb +0 -27
  10. data/test/machine_by_default_test.rb +0 -18
  11. data/test/machine_errors_test.rb +0 -21
  12. data/test/machine_multiple_test.rb +0 -19
  13. data/test/machine_nested_action_test.rb +0 -40
  14. data/test/machine_unmigrated_test.rb +0 -16
  15. data/test/machine_with_aliased_attribute_test.rb +0 -25
  16. data/test/machine_with_callbacks_test.rb +0 -174
  17. data/test/machine_with_column_state_attribute_test.rb +0 -46
  18. data/test/machine_with_complex_pluralization_scopes_test.rb +0 -18
  19. data/test/machine_with_conflicting_predicate_test.rb +0 -20
  20. data/test/machine_with_conflicting_state_name_test.rb +0 -31
  21. data/test/machine_with_custom_attribute_test.rb +0 -23
  22. data/test/machine_with_default_scope_test.rb +0 -20
  23. data/test/machine_with_different_column_default_test.rb +0 -29
  24. data/test/machine_with_different_integer_column_default_test.rb +0 -31
  25. data/test/machine_with_dirty_attribute_and_custom_attributes_during_loopback_test.rb +0 -26
  26. data/test/machine_with_dirty_attribute_and_state_events_test.rb +0 -22
  27. data/test/machine_with_dirty_attributes_and_custom_attribute_test.rb +0 -34
  28. data/test/machine_with_dirty_attributes_during_loopback_test.rb +0 -24
  29. data/test/machine_with_dirty_attributes_test.rb +0 -37
  30. data/test/machine_with_dynamic_initial_state_test.rb +0 -101
  31. data/test/machine_with_event_attributes_on_autosave_test.rb +0 -50
  32. data/test/machine_with_event_attributes_on_custom_action_test.rb +0 -43
  33. data/test/machine_with_event_attributes_on_save_bang_test.rb +0 -84
  34. data/test/machine_with_event_attributes_on_save_test.rb +0 -246
  35. data/test/machine_with_event_attributes_on_validation_test.rb +0 -145
  36. data/test/machine_with_events_test.rb +0 -15
  37. data/test/machine_with_failed_action_test.rb +0 -42
  38. data/test/machine_with_failed_after_callbacks_test.rb +0 -37
  39. data/test/machine_with_failed_before_callbacks_test.rb +0 -38
  40. data/test/machine_with_initialized_state_test.rb +0 -43
  41. data/test/machine_with_internationalization_test.rb +0 -182
  42. data/test/machine_with_loopback_test.rb +0 -24
  43. data/test/machine_with_non_column_state_attribute_defined_test.rb +0 -31
  44. data/test/machine_with_same_column_default_test.rb +0 -28
  45. data/test/machine_with_same_integer_column_default_test.rb +0 -32
  46. data/test/machine_with_scopes_and_joins_test.rb +0 -40
  47. data/test/machine_with_scopes_and_owner_subclass_test.rb +0 -29
  48. data/test/machine_with_scopes_test.rb +0 -72
  49. data/test/machine_with_state_driven_validations_test.rb +0 -32
  50. data/test/machine_with_states_test.rb +0 -15
  51. data/test/machine_with_static_initial_state_test.rb +0 -169
  52. data/test/machine_with_transactions_test.rb +0 -28
  53. data/test/machine_with_validations_and_custom_attribute_test.rb +0 -23
  54. data/test/machine_with_validations_test.rb +0 -49
  55. data/test/machine_without_database_test.rb +0 -22
  56. data/test/machine_without_transactions_test.rb +0 -28
  57. data/test/model_test.rb +0 -14
  58. data/test/test_helper.rb +0 -57
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithInitializedStateTest < BaseTestCase
6
- def setup
7
- @model = new_model
8
- @machine = StateMachines::Machine.new(@model, :initial => :parked)
9
- @machine.state :idling
10
- end
11
-
12
- def test_should_allow_nil_initial_state_when_static
13
- @machine.state nil
14
-
15
- record = @model.new(:state => nil)
16
- assert_nil record.state
17
- end
18
-
19
- def test_should_allow_nil_initial_state_when_dynamic
20
- @machine.state nil
21
-
22
- @machine.initial_state = lambda { :parked }
23
- record = @model.new(:state => nil)
24
- assert_nil record.state
25
- end
26
-
27
- def test_should_allow_different_initial_state_when_static
28
- record = @model.new(:state => 'idling')
29
- assert_equal 'idling', record.state
30
- end
31
-
32
- def test_should_allow_different_initial_state_when_using_create_with
33
- record = @model.create_with(state: 'idling').new
34
-
35
- assert_equal 'idling', record.state
36
- end
37
-
38
- def test_should_allow_different_initial_state_when_dynamic
39
- @machine.initial_state = lambda { :parked }
40
- record = @model.new(:state => 'idling')
41
- assert_equal 'idling', record.state
42
- end
43
- end
@@ -1,182 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithInternationalizationTest < BaseTestCase
6
- def setup
7
- I18n.backend = I18n::Backend::Simple.new
8
-
9
- # Initialize the backend
10
- StateMachines::Machine.new(new_model)
11
-
12
- @model = new_model
13
- end
14
-
15
- def test_should_use_defaults
16
- I18n.backend.store_translations(:en, {
17
- :activerecord => {:errors => {:messages => {:invalid_transition => "cannot #{interpolation_key('event')}"}}}
18
- })
19
-
20
- machine = StateMachines::Machine.new(@model)
21
- machine.state :parked, :idling
22
- machine.event :ignite
23
-
24
- record = @model.new(:state => 'idling')
25
-
26
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
27
- assert_equal ['State cannot transition via "ignite"'], record.errors.full_messages
28
- end
29
-
30
- def test_should_allow_customized_error_key
31
- I18n.backend.store_translations(:en, {
32
- :activerecord => {:errors => {:messages => {:bad_transition => "cannot #{interpolation_key('event')}"}}}
33
- })
34
-
35
- machine = StateMachines::Machine.new(@model, :messages => {:invalid_transition => :bad_transition})
36
- machine.state :parked, :idling
37
-
38
- record = @model.new(:state => 'idling')
39
-
40
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
41
- assert_equal ['State cannot ignite'], record.errors.full_messages
42
- end
43
-
44
- def test_should_allow_customized_error_string
45
- machine = StateMachines::Machine.new(@model, :messages => {:invalid_transition => "cannot #{interpolation_key('event')}"})
46
- machine.state :parked, :idling
47
-
48
- record = @model.new(:state => 'idling')
49
-
50
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
51
- assert_equal ['State cannot ignite'], record.errors.full_messages
52
- end
53
-
54
- def test_should_allow_customized_state_key_scoped_to_class_and_machine
55
- I18n.backend.store_translations(:en, {
56
- :activerecord => {:state_machines => {:'foo' => {:state => {:states => {:parked => 'shutdown'}}}}}
57
- })
58
-
59
- machine = StateMachines::Machine.new(@model)
60
- machine.state :parked
61
-
62
- assert_equal 'shutdown', machine.state(:parked).human_name
63
- end
64
-
65
- def test_should_allow_customized_state_key_scoped_to_class
66
- I18n.backend.store_translations(:en, {
67
- :activerecord => {:state_machines => {:'foo' => {:states => {:parked => 'shutdown'}}}}
68
- })
69
-
70
- machine = StateMachines::Machine.new(@model)
71
- machine.state :parked
72
-
73
- assert_equal 'shutdown', machine.state(:parked).human_name
74
- end
75
-
76
- def test_should_allow_customized_state_key_scoped_to_machine
77
- I18n.backend.store_translations(:en, {
78
- :activerecord => {:state_machines => {:state => {:states => {:parked => 'shutdown'}}}}
79
- })
80
-
81
- machine = StateMachines::Machine.new(@model)
82
- machine.state :parked
83
-
84
- assert_equal 'shutdown', machine.state(:parked).human_name
85
- end
86
-
87
- def test_should_allow_customized_state_key_unscoped
88
- I18n.backend.store_translations(:en, {
89
- :activerecord => {:state_machines => {:states => {:parked => 'shutdown'}}}
90
- })
91
-
92
- machine = StateMachines::Machine.new(@model)
93
- machine.state :parked
94
-
95
- assert_equal 'shutdown', machine.state(:parked).human_name
96
- end
97
-
98
- def test_should_support_nil_state_key
99
- I18n.backend.store_translations(:en, {
100
- :activerecord => {:state_machines => {:states => {:nil => 'empty'}}}
101
- })
102
-
103
- machine = StateMachines::Machine.new(@model)
104
-
105
- assert_equal 'empty', machine.state(nil).human_name
106
- end
107
-
108
- def test_should_allow_customized_event_key_scoped_to_class_and_machine
109
- I18n.backend.store_translations(:en, {
110
- :activerecord => {:state_machines => {:'foo' => {:state => {:events => {:park => 'stop'}}}}}
111
- })
112
-
113
- machine = StateMachines::Machine.new(@model)
114
- machine.event :park
115
-
116
- assert_equal 'stop', machine.event(:park).human_name
117
- end
118
-
119
- def test_should_allow_customized_event_key_scoped_to_class
120
- I18n.backend.store_translations(:en, {
121
- :activerecord => {:state_machines => {:'foo' => {:events => {:park => 'stop'}}}}
122
- })
123
-
124
- machine = StateMachines::Machine.new(@model)
125
- machine.event :park
126
-
127
- assert_equal 'stop', machine.event(:park).human_name
128
- end
129
-
130
- def test_should_allow_customized_event_key_scoped_to_machine
131
- I18n.backend.store_translations(:en, {
132
- :activerecord => {:state_machines => {:state => {:events => {:park => 'stop'}}}}
133
- })
134
-
135
- machine = StateMachines::Machine.new(@model)
136
- machine.event :park
137
-
138
- assert_equal 'stop', machine.event(:park).human_name
139
- end
140
-
141
- def test_should_allow_customized_event_key_unscoped
142
- I18n.backend.store_translations(:en, {
143
- :activerecord => {:state_machines => {:events => {:park => 'stop'}}}
144
- })
145
-
146
- machine = StateMachines::Machine.new(@model)
147
- machine.event :park
148
-
149
- assert_equal 'stop', machine.event(:park).human_name
150
- end
151
-
152
- def test_should_only_add_locale_once_in_load_path
153
- assert_equal 1, I18n.load_path.select { |path| path =~ %r{active_record/locale\.rb$} }.length
154
-
155
- # Create another ActiveRecord model that will trigger the i18n feature
156
- new_model
157
-
158
- assert_equal 1, I18n.load_path.select { |path| path =~ %r{active_record/locale\.rb$} }.length
159
- end
160
-
161
- def test_should_prefer_other_locales_first
162
- @original_load_path = I18n.load_path
163
- I18n.backend = I18n::Backend::Simple.new
164
- I18n.load_path = [File.dirname(__FILE__) + '/files/en.yml']
165
-
166
- machine = StateMachines::Machine.new(@model)
167
- machine.state :parked, :idling
168
- machine.event :ignite
169
-
170
- record = @model.new(:state => 'idling')
171
-
172
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
173
- assert_equal ['State cannot transition'], record.errors.full_messages
174
- ensure
175
- I18n.load_path = @original_load_path
176
- end
177
-
178
- private
179
- def interpolation_key(key)
180
- "%{#{key}}"
181
- end
182
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithLoopbackTest < BaseTestCase
6
- def setup
7
- @model = new_model do
8
- connection.add_column table_name, :updated_at, :datetime
9
- end
10
-
11
- @machine = StateMachines::Machine.new(@model, :initial => :parked)
12
- @machine.event :park
13
-
14
- @record = @model.create(:updated_at => Time.now - 1)
15
- @transition = StateMachines::Transition.new(@record, @machine, :park, :parked, :parked)
16
-
17
- @timestamp = @record.updated_at
18
- @transition.perform
19
- end
20
-
21
- def test_should_not_update_record
22
- assert_equal @timestamp, @record.updated_at
23
- end
24
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithNonColumnStateAttributeDefinedTest < BaseTestCase
6
- def setup
7
- @model = new_model do
8
- attr_accessor :status
9
- end
10
-
11
- @machine = StateMachines::Machine.new(@model, :status, :initial => :parked)
12
- @machine.other_states(:idling)
13
- @record = @model.new
14
- end
15
-
16
- def test_should_return_false_for_predicate_if_does_not_match_current_value
17
- refute @record.status?(:idling)
18
- end
19
-
20
- def test_should_return_true_for_predicate_if_matches_current_value
21
- assert @record.status?(:parked)
22
- end
23
-
24
- def test_should_raise_exception_for_predicate_if_invalid_state_specified
25
- assert_raise(IndexError) { @record.status?(:invalid) }
26
- end
27
-
28
- def test_should_set_initial_state_on_created_object
29
- assert_equal 'parked', @record.status
30
- end
31
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithSameColumnDefaultTest < BaseTestCase
6
- def setup
7
- @original_stderr, $stderr = $stderr, StringIO.new
8
-
9
- @model = new_model do
10
- connection.add_column table_name, :status, :string, :default => 'parked'
11
- end
12
- @machine = StateMachines::Machine.new(@model, :status, :initial => :parked)
13
- @record = @model.new
14
- end
15
-
16
- def test_should_use_machine_default
17
- assert_equal 'parked', @record.status
18
- end
19
-
20
- def test_should_not_generate_a_warning
21
- assert_no_match(/have defined a different default/, $stderr.string)
22
- end
23
-
24
- def teardown
25
- $stderr = @original_stderr
26
- super
27
- end
28
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
- require 'stringio'
5
-
6
- class MachineWithSameIntegerColumnDefaultTest < BaseTestCase
7
- def setup
8
- @original_stderr, $stderr = $stderr, StringIO.new
9
-
10
- @model = new_model do
11
- connection.add_column table_name, :status, :integer, :default => 1
12
- end
13
- @machine = StateMachines::Machine.new(@model, :status, :initial => :parked) do
14
- state :parked, :value => 1
15
- end
16
- @record = @model.new
17
- end
18
-
19
- def test_should_use_machine_default
20
- assert_equal 1, @record.status
21
- end
22
-
23
- def test_should_not_generate_a_warning
24
- assert_no_match(/have defined a different default/, $stderr.string)
25
- end
26
-
27
- def teardown
28
- $stderr = @original_stderr
29
- super
30
- end
31
- end
32
-
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithScopesAndJoinsTest < BaseTestCase
6
- def setup
7
- @company = new_model(:company)
8
- MachineWithScopesAndJoinsTest.const_set('Company', @company)
9
-
10
- @vehicle = new_model(:vehicle) do
11
- connection.add_column table_name, :company_id, :integer
12
- belongs_to :company, :class_name => 'MachineWithScopesAndJoinsTest::Company'
13
- end
14
- MachineWithScopesAndJoinsTest.const_set('Vehicle', @vehicle)
15
-
16
- @company_machine = StateMachines::Machine.new(@company, :initial => :active)
17
- @vehicle_machine = StateMachines::Machine.new(@vehicle, :initial => :parked)
18
- @vehicle_machine.state :idling
19
-
20
- @ford = @company.create
21
- @mustang = @vehicle.create(:company => @ford)
22
- end
23
-
24
- def test_should_find_records_in_with_scope
25
- assert_equal [@mustang], @vehicle.with_states(:parked).joins(:company).where("#{@company.table_name}.state = \"active\"")
26
- end
27
-
28
- def test_should_find_records_in_without_scope
29
- assert_equal [@mustang], @vehicle.without_states(:idling).joins(:company).where("#{@company.table_name}.state = \"active\"")
30
- end
31
-
32
- def teardown
33
- MachineWithScopesAndJoinsTest.class_eval do
34
- remove_const('Vehicle')
35
- remove_const('Company')
36
- end
37
-
38
- clear_active_support_dependencies
39
- end
40
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithScopesAndOwnerSubclassTest < BaseTestCase
6
- def setup
7
- @model = new_model
8
- @machine = StateMachines::Machine.new(@model, :state)
9
-
10
- @subclass = Class.new(@model)
11
- @subclass_machine = @subclass.state_machine(:state) {}
12
- @subclass_machine.state :parked, :idling, :first_gear
13
- end
14
-
15
- def test_should_only_include_records_with_subclass_states_in_with_scope
16
- parked = @subclass.create :state => 'parked'
17
- idling = @subclass.create :state => 'idling'
18
-
19
- assert_equal [parked, idling], @subclass.with_states(:parked, :idling).all
20
- end
21
-
22
- def test_should_only_include_records_without_subclass_states_in_without_scope
23
- parked = @subclass.create :state => 'parked'
24
- idling = @subclass.create :state => 'idling'
25
- @subclass.create :state => 'first_gear'
26
-
27
- assert_equal [parked, idling], @subclass.without_states(:first_gear).all
28
- end
29
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithScopesTest < BaseTestCase
6
- def setup
7
- @model = new_model
8
- @machine = StateMachines::Machine.new(@model)
9
- @machine.state :parked, :first_gear
10
- @machine.state :idling, :value => -> { 'idling' }
11
- end
12
-
13
- def test_should_create_singular_with_scope
14
- assert @model.respond_to?(:with_state)
15
- end
16
-
17
- def test_should_only_include_records_with_state_in_singular_with_scope
18
- parked = @model.create :state => 'parked'
19
- @model.create :state => 'idling'
20
-
21
- assert_equal [parked], @model.with_state(:parked).all
22
- end
23
-
24
- def test_should_create_plural_with_scope
25
- assert @model.respond_to?(:with_states)
26
- end
27
-
28
- def test_should_only_include_records_with_states_in_plural_with_scope
29
- parked = @model.create :state => 'parked'
30
- idling = @model.create :state => 'idling'
31
-
32
- assert_equal [parked, idling], @model.with_states(:parked, :idling).all
33
- end
34
-
35
- def test_should_allow_lookup_by_string_name
36
- parked = @model.create :state => 'parked'
37
- idling = @model.create :state => 'idling'
38
-
39
- assert_equal [parked, idling], @model.with_states('parked', 'idling').all
40
- end
41
-
42
- def test_should_create_singular_without_scope
43
- assert @model.respond_to?(:without_state)
44
- end
45
-
46
- def test_should_only_include_records_without_state_in_singular_without_scope
47
- parked = @model.create :state => 'parked'
48
- @model.create :state => 'idling'
49
-
50
- assert_equal [parked], @model.without_state(:idling).all
51
- end
52
-
53
- def test_should_create_plural_without_scope
54
- assert @model.respond_to?(:without_states)
55
- end
56
-
57
- def test_should_only_include_records_without_states_in_plural_without_scope
58
- parked = @model.create :state => 'parked'
59
- idling = @model.create :state => 'idling'
60
- @model.create :state => 'first_gear'
61
-
62
- assert_equal [parked, idling], @model.without_states(:first_gear).all
63
- end
64
-
65
- def test_should_allow_chaining_scopes
66
- @model.create :state => 'parked'
67
- idling = @model.create :state => 'idling'
68
-
69
- assert_equal [idling], @model.without_state(:parked).with_state(:idling).all
70
- end
71
- end
72
-
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithStateDrivenValidationsTest < BaseTestCase
6
- def setup
7
- @model = new_model do
8
- attr_accessor :seatbelt
9
- end
10
-
11
- @machine = StateMachines::Machine.new(@model)
12
- @machine.state :first_gear, :second_gear do
13
- validates :seatbelt, presence: true
14
- end
15
- @machine.other_states :parked
16
- end
17
-
18
- def test_should_be_valid_if_validation_fails_outside_state_scope
19
- record = @model.new(:state => 'parked', :seatbelt => nil)
20
- assert record.valid?
21
- end
22
-
23
- def test_should_be_invalid_if_validation_fails_within_state_scope
24
- record = @model.new(:state => 'first_gear', :seatbelt => nil)
25
- refute record.valid?
26
- end
27
-
28
- def test_should_be_valid_if_validation_succeeds_within_state_scope
29
- record = @model.new(:state => 'second_gear', :seatbelt => true)
30
- assert record.valid?
31
- end
32
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'test_helper'
4
-
5
- class MachineWithStatesTest < BaseTestCase
6
- def setup
7
- @model = new_model
8
- @machine = StateMachines::Machine.new(@model)
9
- @machine.state :first_gear
10
- end
11
-
12
- def test_should_humanize_name
13
- assert_equal 'first gear', @machine.state(:first_gear).human_name
14
- end
15
- end