state_machines-mongoid 0.0.0 → 0.1.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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +20 -0
  4. data/Appraisals +8 -0
  5. data/Gemfile +0 -2
  6. data/LICENSE.txt +1 -0
  7. data/README.md +43 -4
  8. data/Rakefile +8 -1
  9. data/gemfiles/active_model_4.1.gemfile +7 -0
  10. data/gemfiles/active_model_4.2.gemfile +7 -0
  11. data/lib/state_machines-mongoid.rb +1 -0
  12. data/lib/state_machines/integrations/mongoid.rb +401 -0
  13. data/lib/state_machines/integrations/mongoid/locale.rb +11 -0
  14. data/lib/state_machines/integrations/mongoid/version.rb +7 -0
  15. data/lib/state_machines/state_machines-mongoid.rb +1 -0
  16. data/state_machines-mongoid.gemspec +18 -12
  17. data/test/files/en.yml +5 -0
  18. data/test/integration_test.rb +23 -0
  19. data/test/machine_by_default_test.rb +16 -0
  20. data/test/machine_errors_test.rb +20 -0
  21. data/test/machine_multiple_test.rb +17 -0
  22. data/test/machine_nested_action_test.rb +39 -0
  23. data/test/machine_with_aliased_attribute_test.rb +22 -0
  24. data/test/machine_with_aliased_field_test.rb +22 -0
  25. data/test/machine_with_callbacks_test.rb +167 -0
  26. data/test/machine_with_column_state_attribute_test.rb +44 -0
  27. data/test/machine_with_complex_pluralization_scopes_test.rb +16 -0
  28. data/test/machine_with_conflicting_predicate_test.rb +27 -0
  29. data/test/machine_with_conflicting_state_name_test.rb +29 -0
  30. data/test/machine_with_custom_attribute_test.rb +21 -0
  31. data/test/machine_with_default_scope_test.rb +14 -0
  32. data/test/machine_with_different_column_default_test.rb +26 -0
  33. data/test/machine_with_different_integer_column_default_test.rb +27 -0
  34. data/test/machine_with_different_same_default_test.rb +26 -0
  35. data/test/machine_with_dirty_attribute_and_custom_attributes_during_loopback_test.rb +24 -0
  36. data/test/machine_with_dirty_attribute_and_state_events_test.rb +20 -0
  37. data/test/machine_with_dirty_attributes_and_custom_attribute_test.rb +32 -0
  38. data/test/machine_with_dirty_attributes_during_loopback_test.rb +22 -0
  39. data/test/machine_with_dirty_attributes_test.rb +35 -0
  40. data/test/machine_with_dynamic_initial_state_test.rb +99 -0
  41. data/test/machine_with_event_attributes_on_autosave_test.rb +50 -0
  42. data/test/machine_with_event_attributes_on_custom_action_test.rb +40 -0
  43. data/test/machine_with_event_attributes_on_save_bang_test.rb +82 -0
  44. data/test/machine_with_event_attributes_on_save_test.rb +146 -0
  45. data/test/machine_with_event_attributes_on_validation_test.rb +115 -0
  46. data/test/machine_with_events_test.rb +13 -0
  47. data/test/machine_with_failed_action_test.rb +39 -0
  48. data/test/machine_with_failed_after_callbacks_test.rb +35 -0
  49. data/test/machine_with_failed_before_callbacks_test.rb +36 -0
  50. data/test/machine_with_field_test.rb +16 -0
  51. data/test/machine_with_initialized_state_test.rb +35 -0
  52. data/test/machine_with_internationalization_test.rb +175 -0
  53. data/test/machine_with_loopback_test.rb +26 -0
  54. data/test/machine_with_non_column_state_attribute_defined_test.rb +35 -0
  55. data/test/machine_with_non_column_state_attribute_undefined_test.rb +33 -0
  56. data/test/machine_with_scopes_and_owner_subclass_test.rb +42 -0
  57. data/test/machine_with_scopes_test.rb +69 -0
  58. data/test/machine_with_state_driven_validations_test.rb +33 -0
  59. data/test/machine_with_state_test.rb +13 -0
  60. data/test/machine_with_static_initial_state_test.rb +162 -0
  61. data/test/machine_with_validations_and_custom_attribute_test.rb +21 -0
  62. data/test/machine_with_validations_test.rb +46 -0
  63. data/test/machine_without_field_test.rb +14 -0
  64. data/test/test_helper.rb +90 -0
  65. metadata +170 -9
  66. data/lib/state_machines/mongoid.rb +0 -7
  67. data/lib/state_machines/mongoid/version.rb +0 -5
@@ -0,0 +1,11 @@
1
+ { en: {
2
+ mongoid: {
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
+ }
9
+ }
10
+ }
11
+ } }
@@ -0,0 +1,7 @@
1
+ module StateMachines
2
+ module Integrations
3
+ module Mongoid
4
+ VERSION = '0.1.0'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'state_machines/integrations/mongoid'
@@ -1,23 +1,29 @@
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/mongoid/version'
4
+ require 'state_machines/integrations/mongoid/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "state_machines-mongoid"
8
- spec.version = StateMachines::Mongoid::VERSION
9
- spec.authors = ["Abdelkader Boudih"]
10
- spec.email = ["terminale@gmail.com"]
11
- spec.summary = %q{Mongoid integration for state machines}
12
- spec.description = %q{Mongoid integration for state machines gem}
13
- spec.homepage = ""
14
- spec.license = "MIT"
7
+ spec.name = 'state_machines-mongoid'
8
+ spec.version = StateMachines::Integrations::Mongoid::VERSION
9
+ spec.authors = ['Abdelkader Boudih', 'Aaron Pfeifer']
10
+ spec.email = %w(terminale@gmail.com aaron@pluginaweek.org)
11
+ spec.summary = 'Mongoid integration for state machines'
12
+ spec.description = 'Mongoid integration for state machines gem'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.6"
22
- spec.add_development_dependency "rake"
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+ spec.add_dependency 'state_machines-activemodel' , '>= 0'
23
+ spec.add_dependency 'mongoid' , '>= 4.0.0'
24
+
25
+ spec.add_development_dependency 'bundler', '>= 1.6'
26
+ spec.add_development_dependency 'rake', '~> 10.3'
27
+ spec.add_development_dependency 'minitest', '>= 5.4.1'
28
+ spec.add_development_dependency 'minitest-reporters'
23
29
  end
data/test/files/en.yml ADDED
@@ -0,0 +1,5 @@
1
+ en:
2
+ mongoid:
3
+ errors:
4
+ messages:
5
+ invalid_transition: "cannot transition"
@@ -0,0 +1,23 @@
1
+ require_relative 'test_helper'
2
+
3
+ class IntegrationTest < BaseTestCase
4
+ def test_should_have_an_integration_name
5
+ assert_equal :mongoid, StateMachines::Integrations::Mongoid.integration_name
6
+ end
7
+
8
+ def test_should_match_if_class_includes_mongoid
9
+ assert StateMachines::Integrations::Mongoid.matches?(new_model)
10
+ end
11
+
12
+ def test_should_not_match_if_class_does_not_include_mongoid
13
+ assert !StateMachines::Integrations::Mongoid.matches?(Class.new)
14
+ end
15
+
16
+ def test_should_have_defaults
17
+ assert_equal({:action => :save}, StateMachines::Integrations::Mongoid.defaults)
18
+ end
19
+
20
+ def test_should_have_a_locale_path
21
+ refute_nil StateMachines::Integrations::Mongoid.locale_path
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineByDefaultTest < BaseTestCase
4
+ def setup
5
+ @model = new_model
6
+ @machine = StateMachines::Machine.new(@model)
7
+ end
8
+
9
+ def test_should_use_save_as_action
10
+ assert_equal :save, @machine.action
11
+ end
12
+
13
+ def test_should_not_use_transactions
14
+ assert_equal false, @machine.use_transactions
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineErrorsTest < BaseTestCase
4
+ def setup
5
+ @model = new_model
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
+
14
+ assert_equal ['Id cannot be blank', 'State is invalid'], @machine.errors_for(@record).split(', ').sort
15
+ end
16
+
17
+ def test_should_describe_as_halted_with_no_errors
18
+ assert_equal 'Transition halted', @machine.errors_for(@record)
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineMultipleTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ field :status, :type => String
7
+ end
8
+ @state_machine = StateMachines::Machine.new(@model, :initial => :parked)
9
+ @status_machine = StateMachines::Machine.new(@model, :status, :initial => :idling)
10
+ end
11
+
12
+ def test_should_should_initialize_each_state
13
+ record = @model.new
14
+ assert_equal 'parked', record.state
15
+ assert_equal 'idling', record.status
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineNestedActionTest < BaseTestCase
4
+ def setup
5
+ @callbacks = []
6
+
7
+ @model = new_model
8
+ @machine = StateMachines::Machine.new(@model)
9
+ @machine.event :ignite do
10
+ transition :parked => :idling
11
+ end
12
+
13
+ @record = @model.new(:state => 'parked')
14
+ end
15
+
16
+ def test_should_allow_transition_prior_to_creation_if_skipping_action
17
+ record = @record
18
+ @model.before_create { record.ignite(false) }
19
+ result = @record.save
20
+
21
+ assert_equal true, result
22
+ assert_equal "idling", @record.state
23
+ @record.reload
24
+ assert_equal "idling", @record.state
25
+ end
26
+
27
+ if Mongoid::VERSION !~ /^2\.1\./
28
+ def test_should_allow_transition_after_creation
29
+ record = @record
30
+ @model.after_create { record.ignite }
31
+ result = @record.save
32
+
33
+ assert_equal true, result
34
+ assert_equal "idling", @record.state
35
+ @record.reload
36
+ assert_equal "idling", @record.state
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithAliasedAttributeTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ alias_attribute :vehicle_status, :state
7
+ end
8
+
9
+ @machine = StateMachines::Machine.new(@model, :status, :attribute => :vehicle_status)
10
+ @machine.state :parked
11
+
12
+ @record = @model.new
13
+ end
14
+
15
+ def test_should_check_custom_attribute_for_predicate
16
+ @record.vehicle_status = nil
17
+ assert !@record.status?(:parked)
18
+
19
+ @record.vehicle_status = 'parked'
20
+ assert @record.status?(:parked)
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithAliasedFieldTest < BaseTestCase
4
+ def setup
5
+ @model = new_model do
6
+ field :status, :as => :vehicle_status
7
+ end
8
+
9
+ @machine = StateMachines::Machine.new(@model, :vehicle_status)
10
+ @machine.state :parked
11
+
12
+ @record = @model.new
13
+ end
14
+
15
+ def test_should_check_custom_attribute_for_predicate
16
+ @record.vehicle_status = nil
17
+ assert !@record.vehicle_status?(:parked)
18
+
19
+ @record.vehicle_status = 'parked'
20
+ assert @record.vehicle_status?(:parked)
21
+ end
22
+ end
@@ -0,0 +1,167 @@
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)
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_after_callbacks_if_model_callback_added_prior_to_state_machine_definition
79
+ model = new_model do
80
+ after_save { nil }
81
+ end
82
+ machine = StateMachines::Machine.new(model, :initial => :parked)
83
+ machine.other_states :idling
84
+ machine.event :ignite
85
+ after_called = false
86
+ machine.after_transition {after_called = true}
87
+
88
+ record = model.new(:state => 'parked')
89
+ transition = StateMachines::Transition.new(record, machine, :ignite, :parked, :idling)
90
+ transition.perform
91
+ assert_equal true, after_called
92
+ end
93
+
94
+ def test_should_run_around_callbacks
95
+ before_called = false
96
+ after_called = false
97
+ ensure_called = 0
98
+ @machine.around_transition do |block|
99
+ before_called = true
100
+ begin
101
+ block.call
102
+ ensure
103
+ ensure_called += 1
104
+ end
105
+ after_called = true
106
+ end
107
+
108
+ @transition.perform
109
+ assert before_called
110
+ assert after_called
111
+ assert_equal ensure_called, 1
112
+ end
113
+
114
+ def test_should_include_transition_states_in_known_states
115
+ @machine.before_transition :to => :first_gear, :do => lambda {}
116
+
117
+ assert_equal [:parked, :idling, :first_gear], @machine.states.map {|state| state.name}
118
+ end
119
+
120
+ def test_should_allow_symbolic_callbacks
121
+ callback_args = nil
122
+
123
+ klass = class << @record; self; end
124
+ klass.send(:define_method, :after_ignite) do |*args|
125
+ callback_args = args
126
+ end
127
+
128
+ @machine.before_transition(:after_ignite)
129
+
130
+ @transition.perform
131
+ assert_equal [@transition], callback_args
132
+ end
133
+
134
+ def test_should_allow_string_callbacks
135
+ class << @record
136
+ attr_reader :callback_result
137
+ end
138
+
139
+ @machine.before_transition('@callback_result = [1, 2, 3]')
140
+ @transition.perform
141
+
142
+ assert_equal [1, 2, 3], @record.callback_result
143
+ end
144
+
145
+ def test_should_run_in_expected_order
146
+ expected = [
147
+ :before_transition, :before_validation, :after_validation,
148
+ :before_save, :before_create, :after_create, :after_save,
149
+ :after_transition
150
+ ]
151
+
152
+ callbacks = []
153
+ @model.before_validation { callbacks << :before_validation }
154
+ @model.after_validation { callbacks << :after_validation }
155
+ @model.before_save { callbacks << :before_save }
156
+ @model.before_create { callbacks << :before_create }
157
+ @model.after_create { callbacks << :after_create }
158
+ @model.after_save { callbacks << :after_save }
159
+
160
+ @machine.before_transition { callbacks << :before_transition }
161
+ @machine.after_transition { callbacks << :after_transition }
162
+
163
+ @transition.perform
164
+
165
+ assert_equal expected, callbacks
166
+ end
167
+ end
@@ -0,0 +1,44 @@
1
+ require_relative 'test_helper'
2
+
3
+ class MachineWithColumnStateAttributeTest < BaseTestCase
4
+ def setup
5
+ @model = new_model
6
+ @machine = StateMachines::Machine.new(@model, :initial => :parked)
7
+ @machine.other_states(:idling)
8
+
9
+ @record = @model.new
10
+ end
11
+
12
+ def test_should_not_override_the_column_reader
13
+ @record[:state] = 'parked'
14
+ assert_equal 'parked', @record.state
15
+ end
16
+
17
+ def test_should_not_override_the_column_writer
18
+ @record.state = 'parked'
19
+ assert_equal 'parked', @record[:state]
20
+ end
21
+
22
+ def test_should_have_an_attribute_predicate
23
+ assert @record.respond_to?(:state?)
24
+ end
25
+
26
+ def test_should_test_for_existence_on_predicate_without_parameters
27
+ assert @record.state?
28
+
29
+ @record.state = nil
30
+ assert !@record.state?
31
+ end
32
+
33
+ def test_should_return_false_for_predicate_if_does_not_match_current_value
34
+ assert !@record.state?(:idling)
35
+ end
36
+
37
+ def test_should_return_true_for_predicate_if_matches_current_value
38
+ assert @record.state?(:parked)
39
+ end
40
+
41
+ def test_should_raise_exception_for_predicate_if_invalid_state_specified
42
+ assert_raises(IndexError) { @record.state?(:invalid) }
43
+ end
44
+ end