aasm 4.11.1 → 5.2.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 (194) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +27 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. data/.travis.yml +56 -23
  5. data/Appraisals +67 -0
  6. data/CHANGELOG.md +112 -0
  7. data/CONTRIBUTING.md +24 -0
  8. data/Dockerfile +44 -0
  9. data/Gemfile +3 -21
  10. data/Gemfile.lock_old +151 -0
  11. data/LICENSE +1 -1
  12. data/README.md +540 -139
  13. data/Rakefile +6 -1
  14. data/TESTING.md +25 -0
  15. data/aasm.gemspec +5 -0
  16. data/docker-compose.yml +40 -0
  17. data/gemfiles/norails.gemfile +10 -0
  18. data/gemfiles/rails_4.2.gemfile +13 -11
  19. data/gemfiles/rails_4.2_mongoid_5.gemfile +8 -11
  20. data/gemfiles/rails_4.2_nobrainer.gemfile +9 -0
  21. data/gemfiles/rails_5.0.gemfile +11 -18
  22. data/gemfiles/rails_5.0_nobrainer.gemfile +9 -0
  23. data/gemfiles/rails_5.1.gemfile +14 -0
  24. data/gemfiles/rails_5.2.gemfile +14 -0
  25. data/lib/aasm/aasm.rb +40 -29
  26. data/lib/aasm/base.rb +61 -11
  27. data/lib/aasm/configuration.rb +10 -0
  28. data/lib/aasm/core/event.rb +45 -37
  29. data/lib/aasm/core/invoker.rb +129 -0
  30. data/lib/aasm/core/invokers/base_invoker.rb +75 -0
  31. data/lib/aasm/core/invokers/class_invoker.rb +52 -0
  32. data/lib/aasm/core/invokers/literal_invoker.rb +47 -0
  33. data/lib/aasm/core/invokers/proc_invoker.rb +59 -0
  34. data/lib/aasm/core/state.rb +22 -13
  35. data/lib/aasm/core/transition.rb +17 -69
  36. data/lib/aasm/dsl_helper.rb +24 -22
  37. data/lib/aasm/errors.rb +4 -6
  38. data/lib/aasm/instance_base.rb +22 -4
  39. data/lib/aasm/localizer.rb +13 -3
  40. data/lib/aasm/minitest/allow_event.rb +13 -0
  41. data/lib/aasm/minitest/allow_transition_to.rb +13 -0
  42. data/lib/aasm/minitest/have_state.rb +13 -0
  43. data/lib/aasm/minitest/transition_from.rb +21 -0
  44. data/lib/aasm/minitest.rb +5 -0
  45. data/lib/aasm/minitest_spec.rb +15 -0
  46. data/lib/aasm/persistence/active_record_persistence.rb +49 -105
  47. data/lib/aasm/persistence/base.rb +20 -5
  48. data/lib/aasm/persistence/core_data_query_persistence.rb +2 -1
  49. data/lib/aasm/persistence/dynamoid_persistence.rb +1 -1
  50. data/lib/aasm/persistence/mongoid_persistence.rb +26 -32
  51. data/lib/aasm/persistence/no_brainer_persistence.rb +105 -0
  52. data/lib/aasm/persistence/orm.rb +154 -0
  53. data/lib/aasm/persistence/plain_persistence.rb +2 -1
  54. data/lib/aasm/persistence/redis_persistence.rb +16 -11
  55. data/lib/aasm/persistence/sequel_persistence.rb +36 -64
  56. data/lib/aasm/persistence.rb +3 -3
  57. data/lib/aasm/rspec/allow_event.rb +5 -1
  58. data/lib/aasm/rspec/allow_transition_to.rb +5 -1
  59. data/lib/aasm/rspec/transition_from.rb +5 -1
  60. data/lib/aasm/state_machine.rb +4 -2
  61. data/lib/aasm/state_machine_store.rb +5 -2
  62. data/lib/aasm/version.rb +1 -1
  63. data/lib/aasm.rb +5 -2
  64. data/lib/generators/aasm/orm_helpers.rb +6 -0
  65. data/lib/generators/active_record/aasm_generator.rb +3 -1
  66. data/lib/generators/active_record/templates/migration.rb +1 -1
  67. data/lib/generators/active_record/templates/migration_existing.rb +1 -1
  68. data/lib/generators/nobrainer/aasm_generator.rb +28 -0
  69. data/lib/motion-aasm.rb +3 -1
  70. data/spec/database.rb +20 -7
  71. data/spec/en.yml +0 -3
  72. data/spec/generators/active_record_generator_spec.rb +49 -40
  73. data/spec/generators/mongoid_generator_spec.rb +4 -6
  74. data/spec/generators/no_brainer_generator_spec.rb +29 -0
  75. data/spec/{en_deprecated_style.yml → localizer_test_model_deprecated_style.yml} +6 -3
  76. data/spec/localizer_test_model_new_style.yml +11 -0
  77. data/spec/models/active_record/active_record_callback.rb +93 -0
  78. data/spec/models/active_record/complex_active_record_example.rb +5 -1
  79. data/spec/models/active_record/instance_level_skip_validation_example.rb +19 -0
  80. data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
  81. data/spec/models/active_record/localizer_test_model.rb +11 -3
  82. data/spec/models/active_record/namespaced.rb +16 -0
  83. data/spec/models/active_record/person.rb +23 -0
  84. data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
  85. data/spec/models/active_record/simple_new_dsl.rb +15 -0
  86. data/spec/models/active_record/timestamp_example.rb +16 -0
  87. data/spec/models/{transactor.rb → active_record/transactor.rb} +25 -2
  88. data/spec/models/{validator.rb → active_record/validator.rb} +0 -2
  89. data/spec/models/active_record/work.rb +3 -0
  90. data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
  91. data/spec/models/callbacks/basic.rb +5 -2
  92. data/spec/models/callbacks/with_state_arg.rb +5 -1
  93. data/spec/models/callbacks/with_state_arg_multiple.rb +4 -1
  94. data/spec/models/default_state.rb +1 -1
  95. data/spec/models/guard_arguments_check.rb +17 -0
  96. data/spec/models/guard_with_params.rb +1 -1
  97. data/spec/models/guardian_without_from_specified.rb +18 -0
  98. data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
  99. data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
  100. data/spec/models/mongoid/timestamp_example_mongoid.rb +20 -0
  101. data/spec/models/mongoid/validator_mongoid.rb +100 -0
  102. data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
  103. data/spec/models/namespaced_multiple_example.rb +14 -0
  104. data/spec/models/nobrainer/complex_no_brainer_example.rb +36 -0
  105. data/spec/models/nobrainer/invalid_persistor_no_brainer.rb +39 -0
  106. data/spec/models/nobrainer/no_scope_no_brainer.rb +21 -0
  107. data/spec/models/nobrainer/nobrainer_relationships.rb +25 -0
  108. data/spec/models/nobrainer/silent_persistor_no_brainer.rb +39 -0
  109. data/spec/models/nobrainer/simple_new_dsl_nobrainer.rb +25 -0
  110. data/spec/models/{mongo_mapper/simple_mongo_mapper.rb → nobrainer/simple_no_brainer.rb} +8 -8
  111. data/spec/models/nobrainer/validator_no_brainer.rb +98 -0
  112. data/spec/models/parametrised_event.rb +7 -0
  113. data/spec/models/{mongo_mapper/complex_mongo_mapper_example.rb → redis/complex_redis_example.rb} +8 -5
  114. data/spec/models/redis/redis_multiple.rb +20 -0
  115. data/spec/models/redis/redis_simple.rb +20 -0
  116. data/spec/models/sequel/complex_sequel_example.rb +4 -3
  117. data/spec/models/sequel/invalid_persistor.rb +52 -0
  118. data/spec/models/sequel/sequel_multiple.rb +13 -13
  119. data/spec/models/sequel/sequel_simple.rb +13 -12
  120. data/spec/models/sequel/silent_persistor.rb +50 -0
  121. data/spec/models/sequel/transactor.rb +112 -0
  122. data/spec/models/sequel/validator.rb +93 -0
  123. data/spec/models/sequel/worker.rb +12 -0
  124. data/spec/models/simple_example.rb +8 -0
  125. data/spec/models/simple_example_with_guard_args.rb +17 -0
  126. data/spec/models/simple_multiple_example.rb +12 -0
  127. data/spec/models/sub_class.rb +34 -0
  128. data/spec/models/timestamps_example.rb +19 -0
  129. data/spec/models/timestamps_with_named_machine_example.rb +13 -0
  130. data/spec/spec_helper.rb +15 -33
  131. data/spec/spec_helpers/active_record.rb +8 -0
  132. data/spec/spec_helpers/dynamoid.rb +35 -0
  133. data/spec/spec_helpers/mongoid.rb +26 -0
  134. data/spec/spec_helpers/nobrainer.rb +15 -0
  135. data/spec/spec_helpers/redis.rb +18 -0
  136. data/spec/spec_helpers/remove_warnings.rb +1 -0
  137. data/spec/spec_helpers/sequel.rb +7 -0
  138. data/spec/unit/abstract_class_spec.rb +27 -0
  139. data/spec/unit/api_spec.rb +79 -72
  140. data/spec/unit/callback_multiple_spec.rb +7 -3
  141. data/spec/unit/callbacks_spec.rb +37 -2
  142. data/spec/unit/complex_example_spec.rb +12 -3
  143. data/spec/unit/complex_multiple_example_spec.rb +20 -4
  144. data/spec/unit/event_multiple_spec.rb +1 -1
  145. data/spec/unit/event_spec.rb +29 -4
  146. data/spec/unit/exception_spec.rb +1 -1
  147. data/spec/unit/guard_arguments_check_spec.rb +9 -0
  148. data/spec/unit/guard_spec.rb +17 -0
  149. data/spec/unit/guard_with_params_spec.rb +4 -0
  150. data/spec/unit/guard_without_from_specified_spec.rb +10 -0
  151. data/spec/unit/inspection_multiple_spec.rb +9 -5
  152. data/spec/unit/inspection_spec.rb +7 -3
  153. data/spec/unit/invoker_spec.rb +189 -0
  154. data/spec/unit/invokers/base_invoker_spec.rb +72 -0
  155. data/spec/unit/invokers/class_invoker_spec.rb +95 -0
  156. data/spec/unit/invokers/literal_invoker_spec.rb +86 -0
  157. data/spec/unit/invokers/proc_invoker_spec.rb +86 -0
  158. data/spec/unit/localizer_spec.rb +85 -52
  159. data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
  160. data/spec/unit/namespaced_multiple_example_spec.rb +22 -0
  161. data/spec/unit/override_warning_spec.rb +8 -0
  162. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +468 -447
  163. data/spec/unit/persistence/active_record_persistence_spec.rb +639 -486
  164. data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
  165. data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
  166. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +83 -13
  167. data/spec/unit/persistence/mongoid_persistence_spec.rb +97 -13
  168. data/spec/unit/persistence/no_brainer_persistence_multiple_spec.rb +198 -0
  169. data/spec/unit/persistence/no_brainer_persistence_spec.rb +158 -0
  170. data/spec/unit/persistence/redis_persistence_multiple_spec.rb +88 -0
  171. data/spec/unit/persistence/redis_persistence_spec.rb +8 -32
  172. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +6 -11
  173. data/spec/unit/persistence/sequel_persistence_spec.rb +278 -10
  174. data/spec/unit/rspec_matcher_spec.rb +9 -0
  175. data/spec/unit/simple_example_spec.rb +15 -0
  176. data/spec/unit/simple_multiple_example_spec.rb +28 -0
  177. data/spec/unit/state_spec.rb +23 -7
  178. data/spec/unit/subclassing_multiple_spec.rb +37 -2
  179. data/spec/unit/subclassing_spec.rb +17 -2
  180. data/spec/unit/timestamps_spec.rb +32 -0
  181. data/spec/unit/transition_spec.rb +1 -1
  182. data/test/minitest_helper.rb +57 -0
  183. data/test/unit/minitest_matcher_test.rb +80 -0
  184. metadata +213 -37
  185. data/callbacks.txt +0 -51
  186. data/gemfiles/rails_3.2_stable.gemfile +0 -15
  187. data/gemfiles/rails_4.0.gemfile +0 -16
  188. data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -16
  189. data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -17
  190. data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
  191. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
  192. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
  193. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -149
  194. data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -96
@@ -0,0 +1,189 @@
1
+ require 'spec_helper'
2
+
3
+ describe AASM::Core::Invoker do
4
+ let(:target) { nil }
5
+ let(:record) { double }
6
+ let(:args) { [] }
7
+
8
+ subject { described_class.new(target, record, args) }
9
+
10
+ describe '#with_options' do
11
+ context 'when passing array as a subject' do
12
+ context 'and "guard" option is set to true' do
13
+ let(:target) { [subject_1, subject_2] }
14
+
15
+ before { subject.with_options(guard: true) }
16
+
17
+ context 'and all the subjects are truthy' do
18
+ let(:subject_1) { Proc.new { true } }
19
+ let(:subject_2) { Proc.new { true } }
20
+
21
+ it 'then returns "true" while invoking' do
22
+ expect(subject.invoke).to eq(true)
23
+ end
24
+ end
25
+
26
+ context 'and any subject is falsely' do
27
+ let(:subject_1) { Proc.new { false } }
28
+ let(:subject_2) { Proc.new { true } }
29
+
30
+ it 'then returns "false" while invoking' do
31
+ expect(subject.invoke).to eq(false)
32
+ end
33
+ end
34
+ end
35
+
36
+ context 'and "unless" option is set to true' do
37
+ let(:target) { [subject_1, subject_2] }
38
+
39
+ before { subject.with_options(unless: true) }
40
+
41
+ context 'and all the subjects are falsely' do
42
+ let(:subject_1) { Proc.new { false } }
43
+ let(:subject_2) { Proc.new { false } }
44
+
45
+ it 'then returns "true" while invoking' do
46
+ expect(subject.invoke).to eq(true)
47
+ end
48
+ end
49
+
50
+ context 'and any subject is truthy' do
51
+ let(:subject_1) { Proc.new { false } }
52
+ let(:subject_2) { Proc.new { true } }
53
+
54
+ it 'then returns "false" while invoking' do
55
+ expect(subject.invoke).to eq(false)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#with_failures' do
63
+ let(:concrete_invoker) { AASM::Core::Invokers::ProcInvoker }
64
+ let(:target) { Proc.new {} }
65
+
66
+ it 'then sets failures buffer for concrete invokers' do
67
+ expect_any_instance_of(concrete_invoker)
68
+ .to receive(:with_failures)
69
+ .and_call_original
70
+
71
+ subject.invoke
72
+ end
73
+ end
74
+
75
+ describe '#with_default_return_value' do
76
+ context 'when return value is "true"' do
77
+ before { subject.with_default_return_value(true) }
78
+
79
+ it 'then returns "true" when was not picked up by any invoker' do
80
+ expect(subject.invoke).to eq(true)
81
+ end
82
+ end
83
+
84
+ context 'when return value is "false"' do
85
+ before { subject.with_default_return_value(false) }
86
+
87
+ it 'then returns "false" when was not picked up by any invoker' do
88
+ expect(subject.invoke).to eq(false)
89
+ end
90
+ end
91
+ end
92
+
93
+ describe '#invoke' do
94
+ context 'when subject is a proc' do
95
+ let(:concrete_invoker) { AASM::Core::Invokers::ProcInvoker }
96
+ let(:target) { Proc.new {} }
97
+
98
+ it 'then calls proc invoker' do
99
+ expect_any_instance_of(concrete_invoker)
100
+ .to receive(:invoke)
101
+ .and_call_original
102
+
103
+ expect(record).to receive(:instance_exec)
104
+
105
+ subject.invoke
106
+ end
107
+ end
108
+
109
+ context 'when subject is a class' do
110
+ let(:concrete_invoker) { AASM::Core::Invokers::ClassInvoker }
111
+ let(:target) { Class.new { def call; end } }
112
+
113
+ it 'then calls proc invoker' do
114
+ expect_any_instance_of(concrete_invoker)
115
+ .to receive(:invoke)
116
+ .and_call_original
117
+
118
+ expect_any_instance_of(target).to receive(:call)
119
+
120
+ subject.invoke
121
+ end
122
+ end
123
+
124
+ context 'when subject is a literal' do
125
+ let(:concrete_invoker) { AASM::Core::Invokers::LiteralInvoker }
126
+ let(:record) { double(invoke_me: nil) }
127
+ let(:target) { :invoke_me }
128
+
129
+ it 'then calls literal invoker' do
130
+ expect_any_instance_of(concrete_invoker)
131
+ .to receive(:invoke)
132
+ .and_call_original
133
+
134
+ expect(record).to receive(:invoke_me)
135
+
136
+ subject.invoke
137
+ end
138
+ end
139
+
140
+ context 'when subject is an array of procs' do
141
+ let(:subject_1) { Proc.new {} }
142
+ let(:subject_2) { Proc.new {} }
143
+ let(:target) { [subject_1, subject_2] }
144
+
145
+ it 'then calls each proc' do
146
+ expect(record).to receive(:instance_exec).twice
147
+
148
+ subject.invoke
149
+ end
150
+ end
151
+
152
+ context 'when subject is an array of classes' do
153
+ let(:subject_1) { Class.new { def call; end } }
154
+ let(:subject_2) { Class.new { def call; end } }
155
+ let(:target) { [subject_1, subject_2] }
156
+
157
+ it 'then calls each class' do
158
+ expect_any_instance_of(subject_1).to receive(:call)
159
+
160
+ expect_any_instance_of(subject_2).to receive(:call)
161
+
162
+ subject.invoke
163
+ end
164
+ end
165
+
166
+ context 'when subject is an array of literals' do
167
+ let(:subject_1) { :method_one }
168
+ let(:subject_2) { :method_two }
169
+ let(:record) { double(method_one: nil, method_two: nil) }
170
+ let(:target) { [subject_1, subject_2] }
171
+
172
+ it 'then calls each class' do
173
+ expect(record).to receive(:method_one)
174
+
175
+ expect(record).to receive(:method_two)
176
+
177
+ subject.invoke
178
+ end
179
+ end
180
+
181
+ context 'when subject is not supported' do
182
+ let(:target) { nil }
183
+
184
+ it 'then just returns default value' do
185
+ expect(subject.invoke).to eq(described_class::DEFAULT_RETURN_VALUE)
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe AASM::Core::Invokers::BaseInvoker do
4
+ let(:target) { double }
5
+ let(:record) { double }
6
+ let(:args) { [] }
7
+
8
+ subject { described_class.new(target, record, args) }
9
+
10
+ describe '#may_invoke?' do
11
+ it 'then raises NoMethodError' do
12
+ expect { subject.may_invoke? }.to raise_error(NoMethodError)
13
+ end
14
+ end
15
+
16
+ describe '#log_failure' do
17
+ it 'then raises NoMethodError' do
18
+ expect { subject.log_failure }.to raise_error(NoMethodError)
19
+ end
20
+ end
21
+
22
+ describe '#invoke_subject' do
23
+ it 'then raises NoMethodError' do
24
+ expect { subject.log_failure }.to raise_error(NoMethodError)
25
+ end
26
+ end
27
+
28
+ describe '#with_failures' do
29
+ it 'then sets failures buffer' do
30
+ buffer = [1, 2, 3]
31
+ subject.with_failures(buffer)
32
+
33
+ expect(subject.failures).to eq(buffer)
34
+ end
35
+ end
36
+
37
+ describe '#invoke' do
38
+ context 'when #may_invoke? respond with "false"' do
39
+ before { allow(subject).to receive(:may_invoke?).and_return(false) }
40
+
41
+ it 'then returns "nil"' do
42
+ expect(subject.invoke).to eq(nil)
43
+ end
44
+ end
45
+
46
+ context 'when #invoke_subject respond with "false"' do
47
+ before do
48
+ allow(subject).to receive(:may_invoke?).and_return(true)
49
+ allow(subject).to receive(:invoke_subject).and_return(false)
50
+ end
51
+
52
+ it 'then calls #log_failure' do
53
+ expect(subject).to receive(:log_failure)
54
+
55
+ subject.invoke
56
+ end
57
+ end
58
+
59
+ context 'when #invoke_subject succeed' do
60
+ before do
61
+ allow(subject).to receive(:may_invoke?).and_return(true)
62
+ allow(subject).to receive(:invoke_subject).and_return(true)
63
+ end
64
+
65
+ it 'then returns result' do
66
+ expect(subject).to receive(:result)
67
+
68
+ subject.invoke
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,95 @@
1
+ require 'spec_helper'
2
+
3
+ describe AASM::Core::Invokers::ClassInvoker do
4
+ let(:target) { Class.new { def call; end } }
5
+ let(:record) { double }
6
+ let(:args) { [] }
7
+
8
+ subject { described_class.new(target, record, args) }
9
+
10
+ describe '#may_invoke?' do
11
+ context 'when subject is a Class and responds to #call' do
12
+ it 'then returns "true"' do
13
+ expect(subject.may_invoke?).to eq(true)
14
+ end
15
+ end
16
+
17
+ context 'when subject is not a class or not respond to #call' do
18
+ let(:target) { Class.new {} }
19
+
20
+ it 'then returns "false"' do
21
+ expect(subject.may_invoke?).to eq(false)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#log_failure' do
27
+ context 'when subject respond to #source_location' do
28
+ it 'then adds "source_location" to a failures buffer' do
29
+ subject.log_failure
30
+
31
+ expect(subject.failures)
32
+ .to eq([target.instance_method(:call).source_location.join('#')])
33
+ end
34
+ end
35
+
36
+ context 'when subject does not respond to #source_location' do
37
+ before do
38
+ Method.__send__(:alias_method, :original_source_location, :source_location)
39
+ Method.__send__(:undef_method, :source_location)
40
+ end
41
+
42
+ after do
43
+ Method.__send__(
44
+ :define_method,
45
+ :source_location,
46
+ Method.instance_method(:original_source_location)
47
+ )
48
+ end
49
+
50
+ it 'then adds the subject to a failures buffer' do
51
+ subject.log_failure
52
+
53
+ expect(subject.failures.first).to be_a(Method)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#invoke_subject' do
59
+ context 'when passing no arguments' do
60
+ let(:args) { [1, 2 ,3] }
61
+ let(:target) { Class.new { def call; end } }
62
+
63
+ it 'then correctly uses passed arguments' do
64
+ expect { subject.invoke_subject }.not_to raise_error
65
+ end
66
+ end
67
+
68
+ context 'when passing single argument' do
69
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
70
+ let(:target) { Class.new { def initialize(_a); end; def call; end } }
71
+
72
+ it 'then correctly uses passed arguments' do
73
+ expect { subject.invoke_subject }.not_to raise_error
74
+ end
75
+ end
76
+
77
+ context 'when passing variable number arguments' do
78
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
79
+ let(:target) { Class.new { def initialize(_a, _b, *_c); end; def call; end } }
80
+
81
+ it 'then correctly uses passed arguments' do
82
+ expect { subject.invoke_subject }.not_to raise_error
83
+ end
84
+ end
85
+
86
+ context 'when passing one or more arguments' do
87
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
88
+ let(:target) { Class.new { def initialize(_a, _b, _c); end; def call; end } }
89
+
90
+ it 'then correctly uses passed arguments' do
91
+ expect { subject.invoke_subject }.not_to raise_error
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe AASM::Core::Invokers::LiteralInvoker do
4
+ let(:target) { nil }
5
+ let(:record) { double }
6
+ let(:args) { [] }
7
+
8
+ subject { described_class.new(target, record, args) }
9
+
10
+ describe '#may_invoke?' do
11
+ context 'when subject is a Symbol' do
12
+ let(:target) { :i_am_symbol }
13
+
14
+ it 'then returns "true"' do
15
+ expect(subject.may_invoke?).to eq(true)
16
+ end
17
+ end
18
+
19
+ context 'when subject is a String' do
20
+ let(:target) { 'i_am_string' }
21
+
22
+ it 'then returns "true"' do
23
+ expect(subject.may_invoke?).to eq(true)
24
+ end
25
+ end
26
+
27
+ context 'when subject is neither a String nor Symbol' do
28
+ let(:target) { double }
29
+
30
+ it 'then returns "false"' do
31
+ expect(subject.may_invoke?).to eq(false)
32
+ end
33
+ end
34
+ end
35
+
36
+ describe '#log_failure' do
37
+ let(:target) { Proc.new { false } }
38
+
39
+ it 'then adds the subject to a failures buffer' do
40
+ subject.log_failure
41
+
42
+ expect(subject.failures).to eq([target])
43
+ end
44
+ end
45
+
46
+ describe '#invoke_subject' do
47
+ context 'when passing no arguments' do
48
+ let(:record) { Class.new { def my_method; end }.new }
49
+ let(:args) { [1, 2 ,3] }
50
+ let(:target) { :my_method }
51
+
52
+ it 'then correctly uses passed arguments' do
53
+ expect { subject.invoke_subject }.not_to raise_error
54
+ end
55
+ end
56
+
57
+ context 'when passing variable number arguments' do
58
+ let(:record) { Class.new { def my_method(_a, _b, *_c); end }.new }
59
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
60
+ let(:target) { :my_method }
61
+
62
+ it 'then correctly uses passed arguments' do
63
+ expect { subject.invoke_subject }.not_to raise_error
64
+ end
65
+ end
66
+
67
+ context 'when passing one or more arguments' do
68
+ let(:record) { Class.new { def my_method(_a, _b, _c); end }.new }
69
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
70
+ let(:target) { :my_method }
71
+
72
+ it 'then correctly uses passed arguments' do
73
+ expect { subject.invoke_subject }.not_to raise_error
74
+ end
75
+ end
76
+
77
+ context 'when record does not respond to subject' do
78
+ let(:record) { Class.new { }.new }
79
+ let(:target) { :my_method }
80
+
81
+ it 'then raises uses passed arguments' do
82
+ expect { subject.invoke_subject }.to raise_error(NoMethodError)
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe AASM::Core::Invokers::ProcInvoker do
4
+ let(:target) { Proc.new {} }
5
+ let(:record) { double }
6
+ let(:args) { [] }
7
+
8
+ subject { described_class.new(target, record, args) }
9
+
10
+ describe '#may_invoke?' do
11
+ context 'when subject is a Proc' do
12
+ it 'then returns "true"' do
13
+ expect(subject.may_invoke?).to eq(true)
14
+ end
15
+ end
16
+
17
+ context 'when subject is not a Proc' do
18
+ let(:target) { nil }
19
+
20
+ it 'then returns "false"' do
21
+ expect(subject.may_invoke?).to eq(false)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe '#log_failure' do
27
+ context 'when subject respond to #source_location' do
28
+ it 'then adds "source_location" to a failures buffer' do
29
+ subject.log_failure
30
+
31
+ expect(subject.failures)
32
+ .to eq([target.source_location.join('#')])
33
+ end
34
+ end
35
+
36
+ context 'when subject does not respond to #source_location' do
37
+ before do
38
+ Method.__send__(:alias_method, :original_source_location, :source_location)
39
+ Method.__send__(:undef_method, :source_location)
40
+ end
41
+
42
+ after do
43
+ Method.__send__(
44
+ :define_method,
45
+ :source_location,
46
+ Method.instance_method(:original_source_location)
47
+ )
48
+ end
49
+
50
+ it 'then adds the subject to a failures buffer' do
51
+ subject.log_failure
52
+
53
+ expect(subject.failures).to eq([target])
54
+ end
55
+ end
56
+ end
57
+
58
+ describe '#invoke_subject' do
59
+ context 'when passing no arguments' do
60
+ let(:args) { [1, 2 ,3] }
61
+ let(:target) { ->() {} }
62
+
63
+ it 'then correctly uses passed arguments' do
64
+ expect { subject.invoke_subject }.not_to raise_error
65
+ end
66
+ end
67
+
68
+ context 'when passing variable number arguments' do
69
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
70
+ let(:target) { ->(_a, _b, *_c) {} }
71
+
72
+ it 'then correctly uses passed arguments' do
73
+ expect { subject.invoke_subject }.not_to raise_error
74
+ end
75
+ end
76
+
77
+ context 'when passing one or more arguments' do
78
+ let(:args) { [1, 2 ,3, 4, 5, 6] }
79
+ let(:target) { ->(_a, _b, _c) {} }
80
+
81
+ it 'then correctly uses passed arguments' do
82
+ expect { subject.invoke_subject }.not_to raise_error
83
+ end
84
+ end
85
+ end
86
+ end
@@ -1,76 +1,109 @@
1
1
  require 'spec_helper'
2
- require 'active_record'
3
- require 'i18n'
4
2
 
5
- I18n.enforce_available_locales = false
6
- load_schema
3
+ if defined?(ActiveRecord)
4
+ require 'models/active_record/localizer_test_model'
5
+ load_schema
7
6
 
8
- describe AASM::Localizer, "new style" do
9
- before(:all) do
10
- I18n.load_path << 'spec/en.yml'
11
- I18n.default_locale = :en
12
- I18n.reload!
13
- end
7
+ describe AASM::Localizer, "new style" do
8
+ before(:all) do
9
+ I18n.load_path << 'spec/localizer_test_model_new_style.yml'
10
+ I18n.reload!
11
+ end
14
12
 
15
- after(:all) do
16
- I18n.load_path.clear
17
- end
13
+ after(:all) do
14
+ I18n.load_path.delete('spec/localizer_test_model_new_style.yml')
15
+ I18n.backend.load_translations
16
+ end
17
+
18
+ let (:foo_opened) { LocalizerTestModel.new }
19
+ let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
18
20
 
19
- let (:foo_opened) { LocalizerTestModel.new }
20
- let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
21
+ context 'aasm.human_state' do
22
+ it 'should return translated state value' do
23
+ expect(foo_opened.aasm.human_state).to eq("It's open now!")
24
+ end
21
25
 
22
- context 'aasm.human_state' do
23
- it 'should return translated state value' do
24
- expect(foo_opened.aasm.human_state).to eq("It's open now!")
26
+ it 'should return humanized value if not localized' do
27
+ expect(foo_closed.aasm.human_state).to eq("Closed")
28
+ end
25
29
  end
26
30
 
27
- it 'should return humanized value if not localized' do
28
- expect(foo_closed.aasm.human_state).to eq("Closed")
31
+ context 'aasm.human_event_name' do
32
+ context 'with event name' do
33
+ it 'should return translated event name' do
34
+ expect(LocalizerTestModel.aasm.human_event_name(:close)).to eq("Let's close it!")
35
+ end
36
+
37
+ it 'should return humanized event name' do
38
+ expect(LocalizerTestModel.aasm.human_event_name(:open)).to eq("Open")
39
+ end
40
+ end
41
+
42
+ context 'with event object' do
43
+ it 'should return translated event name' do
44
+ event = LocalizerTestModel.aasm.events.detect { |e| e.name == :close }
45
+
46
+ expect(LocalizerTestModel.aasm.human_event_name(event)).to eq("Let's close it!")
47
+ end
48
+
49
+ it 'should return humanized event name' do
50
+ event = LocalizerTestModel.aasm.events.detect { |e| e.name == :open }
51
+
52
+ expect(LocalizerTestModel.aasm.human_event_name(event)).to eq("Open")
53
+ end
54
+ end
29
55
  end
30
56
  end
31
57
 
32
- context 'aasm.human_event_name' do
33
- it 'should return translated event name' do
34
- expect(LocalizerTestModel.aasm.human_event_name(:close)).to eq("Let's close it!")
58
+ describe AASM::Localizer, "deprecated style" do
59
+ before(:all) do
60
+ I18n.load_path << 'spec/localizer_test_model_deprecated_style.yml'
61
+ I18n.reload!
62
+ I18n.backend.load_translations
35
63
  end
36
64
 
37
- it 'should return humanized event name' do
38
- expect(LocalizerTestModel.aasm.human_event_name(:open)).to eq("Open")
65
+ after(:all) do
66
+ I18n.load_path.delete('spec/localizer_test_model_deprecated_style.yml')
67
+ I18n.backend.load_translations
39
68
  end
40
- end
41
- end
42
69
 
43
- describe AASM::Localizer, "deprecated style" do
44
- before(:all) do
45
- I18n.load_path << 'spec/en_deprecated_style.yml'
46
- I18n.default_locale = :en
47
- I18n.reload!
48
- end
70
+ let (:foo_opened) { LocalizerTestModel.new }
71
+ let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
49
72
 
50
- after(:all) do
51
- I18n.load_path.clear
52
- end
73
+ context 'aasm.human_state' do
74
+ it 'should return translated state value' do
75
+ expect(foo_opened.aasm.human_state).to eq("It's open now!")
76
+ end
53
77
 
54
- let (:foo_opened) { LocalizerTestModel.new }
55
- let (:foo_closed) { LocalizerTestModel.new.tap { |x| x.aasm_state = :closed } }
56
-
57
- context 'aasm.human_state' do
58
- it 'should return translated state value' do
59
- expect(foo_opened.aasm.human_state).to eq("It's open now!")
78
+ it 'should return humanized value if not localized' do
79
+ expect(foo_closed.aasm.human_state).to eq("Closed")
80
+ end
60
81
  end
61
82
 
62
- it 'should return humanized value if not localized' do
63
- expect(foo_closed.aasm.human_state).to eq("Closed")
64
- end
65
- end
83
+ context 'aasm.human_event_name' do
84
+ context 'with event name' do
85
+ it 'should return translated event name' do
86
+ expect(LocalizerTestModel.aasm.human_event_name(:close)).to eq("Let's close it!")
87
+ end
66
88
 
67
- context 'aasm.human_event_name' do
68
- it 'should return translated event name' do
69
- expect(LocalizerTestModel.aasm.human_event_name(:close)).to eq("Let's close it!")
70
- end
89
+ it 'should return humanized event name' do
90
+ expect(LocalizerTestModel.aasm.human_event_name(:open)).to eq("Open")
91
+ end
92
+ end
93
+
94
+ context 'with event object' do
95
+ it 'should return translated event name' do
96
+ event = LocalizerTestModel.aasm.events.detect { |e| e.name == :close }
97
+
98
+ expect(LocalizerTestModel.aasm.human_event_name(event)).to eq("Let's close it!")
99
+ end
100
+
101
+ it 'should return humanized event name' do
102
+ event = LocalizerTestModel.aasm.events.detect { |e| e.name == :open }
71
103
 
72
- it 'should return humanized event name' do
73
- expect(LocalizerTestModel.aasm.human_event_name(:open)).to eq("Open")
104
+ expect(LocalizerTestModel.aasm.human_event_name(event)).to eq("Open")
105
+ end
106
+ end
74
107
  end
75
108
  end
76
109
  end