state_machines-activemodel 0.0.2 → 0.0.3

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +14 -10
  4. data/Appraisals +4 -15
  5. data/Gemfile +3 -0
  6. data/LICENSE.txt +1 -1
  7. data/README.md +9 -6
  8. data/Rakefile +5 -6
  9. data/gemfiles/active_model_4.1.gemfile +5 -1
  10. data/gemfiles/active_model_4.2.gemfile +11 -0
  11. data/lib/state_machines/integrations/active_model.rb +105 -108
  12. data/lib/state_machines/integrations/active_model/locale.rb +8 -8
  13. data/lib/state_machines/integrations/{version.rb → active_model/version.rb} +1 -1
  14. data/state_machines-activemodel.gemspec +10 -9
  15. data/{spec/support → test/files}/en.yml +1 -1
  16. data/test/integration_test.rb +23 -0
  17. data/test/machine_by_default_test.rb +24 -0
  18. data/test/machine_errors_test.rb +19 -0
  19. data/test/machine_multiple_test.rb +18 -0
  20. data/test/machine_with_callbacks_test.rb +130 -0
  21. data/test/machine_with_dirty_attribute_and_custom_attributes_during_loopback_test.rb +26 -0
  22. data/test/machine_with_dirty_attribute_and_state_events_test.rb +23 -0
  23. data/test/machine_with_dirty_attributes_and_custom_attribute_test.rb +34 -0
  24. data/test/machine_with_dirty_attributes_during_loopback_test.rb +49 -0
  25. data/test/machine_with_dirty_attributes_test.rb +33 -0
  26. data/test/machine_with_dynamic_initial_state_test.rb +14 -0
  27. data/test/machine_with_events_test.rb +13 -0
  28. data/test/machine_with_failed_after_callbacks_test.rb +31 -0
  29. data/test/machine_with_failed_before_callbacks_test.rb +32 -0
  30. data/test/machine_with_initialized_state_test.rb +35 -0
  31. data/test/machine_with_internationalization_test.rb +190 -0
  32. data/test/machine_with_model_state_attribute_test.rb +31 -0
  33. data/test/machine_with_non_model_state_attribute_undefined_test.rb +26 -0
  34. data/test/machine_with_state_driven_validations_test.rb +31 -0
  35. data/test/machine_with_states_test.rb +13 -0
  36. data/test/machine_with_static_initial_state_test.rb +13 -0
  37. data/test/machine_with_validations_and_custom_attribute_test.rb +22 -0
  38. data/test/machine_with_validations_test.rb +46 -0
  39. data/test/test_helper.rb +58 -0
  40. metadata +83 -36
  41. data/gemfiles/active_model_3.2.gemfile +0 -7
  42. data/gemfiles/active_model_3.2.gemfile.lock +0 -50
  43. data/gemfiles/active_model_4.0.gemfile +0 -7
  44. data/gemfiles/active_model_4.0.gemfile.lock +0 -56
  45. data/gemfiles/active_model_4.1.gemfile.lock +0 -57
  46. data/gemfiles/active_model_edge.gemfile +0 -7
  47. data/gemfiles/active_model_edge.gemfile.lock +0 -62
  48. data/spec/active_model_spec.rb +0 -801
  49. data/spec/integration_spec.rb +0 -26
  50. data/spec/spec_helper.rb +0 -8
  51. data/spec/support/helpers.rb +0 -48
  52. data/spec/support/migration_helpers.rb +0 -43
@@ -1,11 +1,11 @@
1
- {:en => {
2
- :activemodel => {
3
- :errors => {
4
- :messages => {
5
- :invalid => StateMachines::Machine.default_messages[:invalid],
6
- :invalid_event => StateMachines::Machine.default_messages[:invalid_event] % ['%{state}'],
7
- :invalid_transition => StateMachines::Machine.default_messages[:invalid_transition] % ['%{event}']
1
+ { en: {
2
+ activemodel: {
3
+ errors: {
4
+ messages: {
5
+ invalid: StateMachines::Machine.default_messages[:invalid],
6
+ invalid_event: StateMachines::Machine.default_messages[:invalid_event] % ['%{state}'],
7
+ invalid_transition: StateMachines::Machine.default_messages[:invalid_transition] % ['%{event}']
8
8
  }
9
9
  }
10
10
  }
11
- }}
11
+ } }
@@ -1,7 +1,7 @@
1
1
  module StateMachines
2
2
  module Integrations
3
3
  module ActiveModel
4
- VERSION = '0.0.2'
4
+ VERSION = '0.0.3'
5
5
  end
6
6
  end
7
7
  end
@@ -1,27 +1,28 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'state_machines/integrations/version'
4
+ require 'state_machines/integrations/active_model/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'state_machines-activemodel'
8
8
  spec.version = StateMachines::Integrations::ActiveModel::VERSION
9
9
  spec.authors = ['Abdelkader Boudih', 'Aaron Pfeifer']
10
- spec.email = ['terminale@gmail.com']
11
- spec.summary = %q(ActiveModel integration for State Machines)
12
- spec.description = %q(Adds support for creating state machines for attributes on ActiveModel)
13
- spec.homepage = 'https://github.com/seuros/state_machines-activemodel'
10
+ spec.email = %w(terminale@gmail.com aaron@pluginaweek.org)
11
+ spec.summary = 'ActiveModel integration for State Machines'
12
+ spec.description = 'Adds support for creating state machines for attributes on ActiveModel'
13
+ spec.homepage = 'https://github.com/state-machines/state_machines-activemodel'
14
14
  spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
- spec.test_files = spec.files.grep(/^spec\//)
17
+ spec.test_files = spec.files.grep(/^test\//)
18
18
  spec.require_paths = ['lib']
19
19
  spec.required_ruby_version = '>= 1.9.3'
20
- spec.add_dependency 'state_machines' , '>= 0'
21
- spec.add_dependency 'activemodel' , '>= 3.2'
20
+ spec.add_dependency 'state_machines', '~> 0.1.0'
21
+ spec.add_dependency 'activemodel', '~> 4.1'
22
22
 
23
23
  spec.add_development_dependency 'bundler', '>= 1.6'
24
24
  spec.add_development_dependency 'rake', '>= 10'
25
25
  spec.add_development_dependency 'appraisal', '>= 1'
26
- spec.add_development_dependency 'rspec' , '3.0.0.beta2'
26
+ spec.add_development_dependency 'minitest', '~> 5.4'
27
+ spec.add_development_dependency 'minitest-reporters'
27
28
  end
@@ -2,4 +2,4 @@ en:
2
2
  activemodel:
3
3
  errors:
4
4
  messages:
5
- invalid_transition: "cannot %{event}"
5
+ invalid_transition: "cannot %{event}"
@@ -0,0 +1,23 @@
1
+ require_relative 'test_helper'
2
+
3
+ class IntegrationTest < BaseTestCase
4
+ def test_should_be_registred
5
+ assert_includes StateMachines::Integrations.list, StateMachines::Integrations::ActiveModel
6
+ end
7
+
8
+ def test_should_have_an_integration_name
9
+ assert_equal :active_model, StateMachines::Integrations::ActiveModel.integration_name
10
+ end
11
+
12
+ def test_should_match_if_class_includes_validations_feature
13
+ assert StateMachines::Integrations::ActiveModel.matches?(new_model { include ActiveModel::Validations })
14
+ end
15
+
16
+ def test_should_not_match_if_class_does_not_include_active_model_features
17
+ refute StateMachines::Integrations::ActiveModel.matches?(new_model)
18
+ end
19
+
20
+ def test_should_have_no_defaults
21
+ assert_equal({}, StateMachines::Integrations::ActiveModel.defaults)
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineByDefaultTest < BaseTestCase
4
+ def setup
5
+ @model = new_model
6
+ @machine = StateMachines::Machine.new(@model, integration: :active_model)
7
+ end
8
+
9
+ def test_should_not_have_action
10
+ assert_nil @machine.action
11
+ end
12
+
13
+ def test_should_use_transactions
14
+ assert_equal true, @machine.use_transactions
15
+ end
16
+
17
+ def test_should_not_have_any_before_callbacks
18
+ assert_equal 0, @machine.callbacks[:before].size
19
+ end
20
+
21
+ def test_should_not_have_any_after_callbacks
22
+ assert_equal 0, @machine.callbacks[:after].size
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineErrorsTest < BaseTestCase
4
+ def setup
5
+ @model = new_model { include ActiveModel::Validations }
6
+ @machine = StateMachines::Machine.new(@model)
7
+ @record = @model.new
8
+ end
9
+
10
+ def test_should_be_able_to_describe_current_errors
11
+ @record.errors.add(:id, 'cannot be blank')
12
+ @record.errors.add(:state, 'is invalid')
13
+ assert_equal ['Id cannot be blank', 'State is invalid'], @machine.errors_for(@record).split(', ').sort
14
+ end
15
+
16
+ def test_should_describe_as_halted_with_no_errors
17
+ assert_equal 'Transition halted', @machine.errors_for(@record)
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineMultipleTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ model_attribute :status
7
+ end
8
+
9
+ @state_machine = StateMachines::Machine.new(@model, initial: :parked, integration: :active_model)
10
+ @status_machine = StateMachines::Machine.new(@model, :status, initial: :idling, integration: :active_model)
11
+ end
12
+
13
+ def test_should_should_initialize_each_state
14
+ record = @model.new
15
+ assert_equal 'parked', record.state
16
+ assert_equal 'idling', record.status
17
+ end
18
+ end
@@ -0,0 +1,130 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithCallbacksTest < BaseTestCase
4
+ def setup
5
+ @model = new_model
6
+ @machine = StateMachines::Machine.new(@model, initial: :parked, integration: :active_model)
7
+ @machine.other_states :idling
8
+ @machine.event :ignite
9
+
10
+ @record = @model.new(state: 'parked')
11
+ @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
12
+ end
13
+
14
+ def test_should_run_before_callbacks
15
+ called = false
16
+ @machine.before_transition { called = true }
17
+
18
+ @transition.perform
19
+ assert called
20
+ end
21
+
22
+ def test_should_pass_record_to_before_callbacks_with_one_argument
23
+ record = nil
24
+ @machine.before_transition { |arg| record = arg }
25
+
26
+ @transition.perform
27
+ assert_equal @record, record
28
+ end
29
+
30
+ def test_should_pass_record_and_transition_to_before_callbacks_with_multiple_arguments
31
+ callback_args = nil
32
+ @machine.before_transition { |*args| callback_args = args }
33
+
34
+ @transition.perform
35
+ assert_equal [@record, @transition], callback_args
36
+ end
37
+
38
+ def test_should_run_before_callbacks_outside_the_context_of_the_record
39
+ context = nil
40
+ @machine.before_transition { context = self }
41
+
42
+ @transition.perform
43
+ assert_equal self, context
44
+ end
45
+
46
+ def test_should_run_after_callbacks
47
+ called = false
48
+ @machine.after_transition { called = true }
49
+
50
+ @transition.perform
51
+ assert called
52
+ end
53
+
54
+ def test_should_pass_record_to_after_callbacks_with_one_argument
55
+ record = nil
56
+ @machine.after_transition { |arg| record = arg }
57
+
58
+ @transition.perform
59
+ assert_equal @record, record
60
+ end
61
+
62
+ def test_should_pass_record_and_transition_to_after_callbacks_with_multiple_arguments
63
+ callback_args = nil
64
+ @machine.after_transition { |*args| callback_args = args }
65
+
66
+ @transition.perform
67
+ assert_equal [@record, @transition], callback_args
68
+ end
69
+
70
+ def test_should_run_after_callbacks_outside_the_context_of_the_record
71
+ context = nil
72
+ @machine.after_transition { context = self }
73
+
74
+ @transition.perform
75
+ assert_equal self, context
76
+ end
77
+
78
+ def test_should_run_around_callbacks
79
+ before_called = false
80
+ after_called = false
81
+ ensure_called = 0
82
+ @machine.around_transition do |block|
83
+ before_called = true
84
+ begin
85
+ block.call
86
+ ensure
87
+ ensure_called += 1
88
+ end
89
+ after_called = true
90
+ end
91
+
92
+ @transition.perform
93
+ assert before_called
94
+ assert after_called
95
+ assert_equal ensure_called, 1
96
+ end
97
+
98
+ def test_should_include_transition_states_in_known_states
99
+ @machine.before_transition to: :first_gear, do: lambda {}
100
+
101
+ assert_equal [:parked, :idling, :first_gear], @machine.states.map { |state| state.name }
102
+ end
103
+
104
+ def test_should_allow_symbolic_callbacks
105
+ callback_args = nil
106
+
107
+ klass = class << @record
108
+ self
109
+ end
110
+ klass.send(:define_method, :after_ignite) do |*args|
111
+ callback_args = args
112
+ end
113
+
114
+ @machine.before_transition(:after_ignite)
115
+
116
+ @transition.perform
117
+ assert_equal [@transition], callback_args
118
+ end
119
+
120
+ def test_should_allow_string_callbacks
121
+ class << @record
122
+ attr_reader :callback_result
123
+ end
124
+
125
+ @machine.before_transition('@callback_result = [1, 2, 3]')
126
+ @transition.perform
127
+
128
+ assert_equal [1, 2, 3], @record.callback_result
129
+ end
130
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithDirtyAttributeAndCustomAttributesDuringLoopbackTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ include ActiveModel::Dirty
7
+ model_attribute :status
8
+ define_attribute_methods [:status]
9
+ end
10
+ @machine = StateMachines::Machine.new(@model, :status, initial: :parked)
11
+ @machine.event :park
12
+
13
+ @record = @model.create
14
+
15
+ @transition = StateMachines::Transition.new(@record, @machine, :park, :parked, :parked)
16
+ @transition.perform
17
+ end
18
+
19
+ def test_should_not_include_state_in_changed_attributes
20
+ assert_equal [], @record.changed
21
+ end
22
+
23
+ def test_should_not_track_attribute_changes
24
+ assert_equal nil, @record.changes['status']
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithDirtyAttributeAndStateEventsTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ include ActiveModel::Dirty
7
+ define_attribute_methods [:state]
8
+ end
9
+ @machine = StateMachines::Machine.new(@model, action: :save, initial: :parked)
10
+ @machine.event :ignite
11
+
12
+ @record = @model.create
13
+ @record.state_event = 'ignite'
14
+ end
15
+
16
+ def test_should_not_include_state_in_changed_attributes
17
+ assert_equal [], @record.changed
18
+ end
19
+
20
+ def test_should_not_track_attribute_change
21
+ assert_equal nil, @record.changes['state']
22
+ end
23
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithDirtyAttributesAndCustomAttributeTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ include ActiveModel::Dirty
7
+ model_attribute :status
8
+ define_attribute_methods [:status]
9
+ end
10
+ @machine = StateMachines::Machine.new(@model, :status, initial: :parked)
11
+ @machine.event :ignite
12
+ @machine.state :idling
13
+
14
+ @record = @model.create
15
+
16
+ @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
17
+ @transition.perform
18
+ end
19
+
20
+ def test_should_include_state_in_changed_attributes
21
+ assert_equal %w(status), @record.changed
22
+ end
23
+
24
+ def test_should_track_attribute_change
25
+ assert_equal %w(parked idling), @record.changes['status']
26
+ end
27
+
28
+ def test_should_not_reset_changes_on_multiple_transitions
29
+ transition = StateMachines::Transition.new(@record, @machine, :ignite, :idling, :idling)
30
+ transition.perform
31
+
32
+ assert_equal %w(parked idling), @record.changes['status']
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithDirtyAttributesDuringLoopbackTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ include ActiveModel::Dirty
7
+ define_attribute_methods [:state]
8
+ end
9
+ @machine = StateMachines::Machine.new(@model, initial: :parked)
10
+ @machine.event :park
11
+
12
+ @record = @model.create
13
+
14
+ @transition = StateMachines::Transition.new(@record, @machine, :park, :parked, :parked)
15
+ @transition.perform
16
+ end
17
+
18
+ def test_should_not_include_state_in_changed_attributes
19
+ assert_equal [], @record.changed
20
+ end
21
+
22
+ def test_should_not_track_attribute_changes
23
+ assert_equal nil, @record.changes['state']
24
+ end
25
+ end
26
+ class MachineWithDirtyAttributeAndCustomAttributesDuringLoopbackTest < BaseTestCase
27
+ def setup
28
+ @model = new_model do
29
+ include ActiveModel::Dirty
30
+ model_attribute :status
31
+ define_attribute_methods [:status]
32
+ end
33
+ @machine = StateMachines::Machine.new(@model, :status, initial: :parked)
34
+ @machine.event :park
35
+
36
+ @record = @model.create
37
+
38
+ @transition = StateMachines::Transition.new(@record, @machine, :park, :parked, :parked)
39
+ @transition.perform
40
+ end
41
+
42
+ def test_should_not_include_state_in_changed_attributes
43
+ assert_equal [], @record.changed
44
+ end
45
+
46
+ def test_should_not_track_attribute_changes
47
+ assert_equal nil, @record.changes['status']
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithDirtyAttributesTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ include ActiveModel::Dirty
7
+ define_attribute_methods [:state]
8
+ end
9
+ @machine = StateMachines::Machine.new(@model, initial: :parked)
10
+ @machine.event :ignite
11
+ @machine.state :idling
12
+
13
+ @record = @model.create
14
+
15
+ @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
16
+ @transition.perform
17
+ end
18
+
19
+ def test_should_include_state_in_changed_attributes
20
+ assert_equal %w(state), @record.changed
21
+ end
22
+
23
+ def test_should_track_attribute_change
24
+ assert_equal %w(parked idling), @record.changes['state']
25
+ end
26
+
27
+ def test_should_not_reset_changes_on_multiple_transitions
28
+ transition = StateMachines::Transition.new(@record, @machine, :ignite, :idling, :idling)
29
+ transition.perform
30
+
31
+ assert_equal %w(parked idling), @record.changes['state']
32
+ end
33
+ end