state_machines-activemodel 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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