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,7 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activemodel", :github => "rails/rails"
6
-
7
- gemspec :path => "../"
@@ -1,62 +0,0 @@
1
- GIT
2
- remote: git://github.com/rails/rails.git
3
- revision: 595326647405282e9edc6754019945896b1f2fc5
4
- specs:
5
- activemodel (4.2.0.alpha)
6
- activesupport (= 4.2.0.alpha)
7
- builder (~> 3.1)
8
- activesupport (4.2.0.alpha)
9
- i18n (~> 0.6, >= 0.6.9)
10
- json (~> 1.7, >= 1.7.7)
11
- minitest (~> 5.1)
12
- thread_safe (~> 0.1)
13
- tzinfo (~> 1.1)
14
-
15
- PATH
16
- remote: ../
17
- specs:
18
- state_machines-activemodel (0.0.2)
19
- activemodel (>= 3.2)
20
- state_machines
21
-
22
- GEM
23
- remote: https://rubygems.org/
24
- specs:
25
- appraisal (1.0.0)
26
- bundler
27
- rake
28
- thor (>= 0.14.0)
29
- builder (3.2.2)
30
- diff-lcs (1.2.5)
31
- i18n (0.6.9)
32
- json (1.8.1)
33
- minitest (5.3.3)
34
- rake (10.3.1)
35
- rspec (3.0.0.beta2)
36
- rspec-core (= 3.0.0.beta2)
37
- rspec-expectations (= 3.0.0.beta2)
38
- rspec-mocks (= 3.0.0.beta2)
39
- rspec-core (3.0.0.beta2)
40
- rspec-support (= 3.0.0.beta2)
41
- rspec-expectations (3.0.0.beta2)
42
- diff-lcs (>= 1.2.0, < 2.0)
43
- rspec-support (= 3.0.0.beta2)
44
- rspec-mocks (3.0.0.beta2)
45
- rspec-support (= 3.0.0.beta2)
46
- rspec-support (3.0.0.beta2)
47
- state_machines (0.0.2)
48
- thor (0.19.1)
49
- thread_safe (0.3.3)
50
- tzinfo (1.1.0)
51
- thread_safe (~> 0.1)
52
-
53
- PLATFORMS
54
- ruby
55
-
56
- DEPENDENCIES
57
- activemodel!
58
- appraisal (>= 1)
59
- bundler (>= 1.6)
60
- rake (>= 10)
61
- rspec (= 3.0.0.beta2)
62
- state_machines-activemodel!
@@ -1,801 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe StateMachines::Integrations::ActiveModel do
4
- context 'ByDefault' do
5
- let(:model) { new_model }
6
- let!(:machine) { StateMachines::Machine.new(model, :integration => :active_model) }
7
-
8
- it 'should_not_have_action' do
9
- expect(machine.action).to be_nil
10
- end
11
-
12
- it 'should_use_transactions' do
13
- expect(machine.use_transactions).to be_truthy
14
- end
15
-
16
- it 'should_not_have_any_before_callbacks' do
17
- expect(machine.callbacks[:before].size).to eq(0)
18
- end
19
-
20
- it 'should_not_have_any_after_callbacks' do
21
- expect(machine.callbacks[:after].size).to eq(0)
22
- end
23
- end
24
-
25
- context 'WithStates' do
26
- before(:each) do
27
- @model = new_model
28
- @machine = StateMachines::Machine.new(@model)
29
- @machine.state :first_gear
30
- end
31
-
32
- it 'should_humanize_name' do
33
- expect(@machine.state(:first_gear).human_name).to eq('first gear')
34
- end
35
- end
36
-
37
- context 'WithStaticInitialState' do
38
- before(:each) do
39
- @model = new_model
40
- @machine = StateMachines::Machine.new(@model, :initial => :parked, :integration => :active_model)
41
- end
42
-
43
- it 'should_set_initial_state_on_created_object' do
44
- record = @model.new
45
- expect(record.state).to eq('parked')
46
- end
47
- end
48
-
49
- context 'WithDynamicInitialState' do
50
- before(:each) do
51
- @model = new_model
52
- @machine = StateMachines::Machine.new(@model, :initial => lambda { |object| :parked }, :integration => :active_model)
53
- @machine.state :parked
54
- end
55
-
56
- it 'should_set_initial_state_on_created_object' do
57
- record = @model.new
58
- assert_equal 'parked', record.state
59
- end
60
- end
61
-
62
- context 'WithEvents' do
63
- before(:each) do
64
- @model = new_model
65
- @machine = StateMachines::Machine.new(@model)
66
- @machine.event :shift_up
67
- end
68
-
69
- it 'should_humanize_name' do
70
- assert_equal 'shift up', @machine.event(:shift_up).human_name
71
- end
72
- end
73
-
74
- context 'WithModelStateAttribute' do
75
- before(:each) do
76
- @model = new_model
77
- @machine = StateMachines::Machine.new(@model, :initial => :parked, :integration => :active_model)
78
- @machine.other_states(:idling)
79
-
80
- @record = @model.new
81
- end
82
-
83
- it 'should_have_an_attribute_predicate' do
84
- assert @record.respond_to?(:state?)
85
- end
86
-
87
- it 'should_raise_exception_for_predicate_without_parameters' do
88
- assert_raise(ArgumentError) { @record.state? }
89
- end
90
-
91
- it 'should_return_false_for_predicate_if_does_not_match_current_value' do
92
- assert !@record.state?(:idling)
93
- end
94
-
95
- it 'should_return_true_for_predicate_if_matches_current_value' do
96
- assert @record.state?(:parked)
97
- end
98
-
99
- it 'should_raise_exception_for_predicate_if_invalid_state_specified' do
100
- assert_raise(IndexError) { @record.state?(:invalid) }
101
- end
102
- end
103
-
104
- context 'WithNonModelStateAttributeUndefined' do
105
- before(:each) do
106
- @model = new_model do
107
- def initialize
108
- end
109
- end
110
-
111
- @machine = StateMachines::Machine.new(@model, :status, :initial => :parked, :integration => :active_model)
112
- @machine.other_states(:idling)
113
- @record = @model.new
114
- end
115
-
116
- it 'should_not_define_a_reader_attribute_for_the_attribute' do
117
- assert !@record.respond_to?(:status)
118
- end
119
-
120
- it 'should_not_define_a_writer_attribute_for_the_attribute' do
121
- assert !@record.respond_to?(:status=)
122
- end
123
-
124
- it 'should_define_an_attribute_predicate' do
125
- assert @record.respond_to?(:status?)
126
- end
127
- end
128
-
129
- context 'WithInitializedState' do
130
- before(:each) do
131
- @model = new_model
132
- @machine = StateMachines::Machine.new(@model, :initial => :parked, :integration => :active_model)
133
- @machine.state :idling
134
- end
135
-
136
- it 'should_allow_nil_initial_state_when_static' do
137
- @machine.state nil
138
-
139
- record = @model.new(:state => nil)
140
- assert_nil record.state
141
- end
142
-
143
- it 'should_allow_nil_initial_state_when_dynamic' do
144
- @machine.state nil
145
-
146
- @machine.initial_state = lambda { :parked }
147
- record = @model.new(:state => nil)
148
- assert_nil record.state
149
- end
150
-
151
- it 'should_allow_different_initial_state_when_static' do
152
- record = @model.new(:state => 'idling')
153
- assert_equal 'idling', record.state
154
- end
155
-
156
- it 'should_allow_different_initial_state_when_dynamic' do
157
- @machine.initial_state = lambda { :parked }
158
- record = @model.new(:state => 'idling')
159
- assert_equal 'idling', record.state
160
- end
161
-
162
- it 'should_use_default_state_if_protected' do
163
- if defined?(ActiveModel::MassAssignmentSecurity)
164
- @model.class_eval do
165
- include ActiveModel::MassAssignmentSecurity
166
- attr_protected :state
167
-
168
- def initialize(attrs = {})
169
- initialize_state_machines do
170
- sanitize_for_mass_assignment(attrs).each { |attr, value| send("#{attr}=", value) } if attrs
171
- @changed_attributes = {}
172
- end
173
- end
174
- end
175
-
176
- record = @model.new(:state => 'idling')
177
- assert_equal 'parked', record.state
178
-
179
- record = @model.new(nil)
180
- assert_equal 'parked', record.state
181
- end
182
- end
183
- end
184
-
185
- context 'Multiple' do
186
- before(:each) do
187
- @model = new_model do
188
- model_attribute :status
189
- end
190
-
191
- @state_machine = StateMachines::Machine.new(@model, :initial => :parked, :integration => :active_model)
192
- @status_machine = StateMachines::Machine.new(@model, :status, :initial => :idling, :integration => :active_model)
193
- end
194
-
195
- it 'should_should_initialize_each_state' do
196
- record = @model.new
197
- assert_equal 'parked', record.state
198
- assert_equal 'idling', record.status
199
- end
200
- end
201
-
202
- context 'WithDirtyAttributes' do
203
- before(:each) do
204
- @model = new_model do
205
- include ActiveModel::Dirty
206
- define_attribute_methods [:state]
207
- end
208
- @machine = StateMachines::Machine.new(@model, :initial => :parked)
209
- @machine.event :ignite
210
- @machine.state :idling
211
-
212
- @record = @model.create
213
-
214
- @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
215
- @transition.perform
216
- end
217
-
218
- it 'should_include_state_in_changed_attributes' do
219
- assert_equal %w(state), @record.changed
220
- end
221
-
222
- it 'should_track_attribute_change' do
223
- assert_equal %w(parked idling), @record.changes['state']
224
- end
225
-
226
- it 'should_not_reset_changes_on_multiple_transitions' do
227
- transition = StateMachines::Transition.new(@record, @machine, :ignite, :idling, :idling)
228
- transition.perform
229
-
230
- assert_equal %w(parked idling), @record.changes['state']
231
- end
232
- end
233
-
234
- context 'WithDirtyAttributesDuringLoopback' do
235
- before(:each) do
236
- @model = new_model do
237
- include ActiveModel::Dirty
238
- define_attribute_methods [:state]
239
- end
240
- @machine = StateMachines::Machine.new(@model, :initial => :parked)
241
- @machine.event :park
242
-
243
- @record = @model.create
244
-
245
- @transition = StateMachines::Transition.new(@record, @machine, :park, :parked, :parked)
246
- @transition.perform
247
- end
248
-
249
- it 'should_not_include_state_in_changed_attributes' do
250
- assert_equal [], @record.changed
251
- end
252
-
253
- it 'should_not_track_attribute_changes' do
254
- assert_equal nil, @record.changes['state']
255
- end
256
- end
257
-
258
- context 'WithDirtyAttributesAndCustomAttribute' do
259
- before(:each) do
260
- @model = new_model do
261
- include ActiveModel::Dirty
262
- model_attribute :status
263
- define_attribute_methods [:status]
264
- end
265
- @machine = StateMachines::Machine.new(@model, :status, :initial => :parked)
266
- @machine.event :ignite
267
- @machine.state :idling
268
-
269
- @record = @model.create
270
-
271
- @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
272
- @transition.perform
273
- end
274
-
275
- it 'should_include_state_in_changed_attributes' do
276
- assert_equal %w(status), @record.changed
277
- end
278
-
279
- it 'should_track_attribute_change' do
280
- assert_equal %w(parked idling), @record.changes['status']
281
- end
282
-
283
- it 'should_not_reset_changes_on_multiple_transitions' do
284
- transition = StateMachines::Transition.new(@record, @machine, :ignite, :idling, :idling)
285
- transition.perform
286
-
287
- assert_equal %w(parked idling), @record.changes['status']
288
- end
289
- end
290
-
291
- context 'WithDirtyAttributeAndCustomAttributesDuringLoopback' do
292
- before(:each) do
293
- @model = new_model do
294
- include ActiveModel::Dirty
295
- model_attribute :status
296
- define_attribute_methods [:status]
297
- end
298
- @machine = StateMachines::Machine.new(@model, :status, :initial => :parked)
299
- @machine.event :park
300
-
301
- @record = @model.create
302
-
303
- @transition = StateMachines::Transition.new(@record, @machine, :park, :parked, :parked)
304
- @transition.perform
305
- end
306
-
307
- it 'should_not_include_state_in_changed_attributes' do
308
- assert_equal [], @record.changed
309
- end
310
-
311
- it 'should_not_track_attribute_changes' do
312
- assert_equal nil, @record.changes['status']
313
- end
314
- end
315
-
316
- context 'WithDirtyAttributeAndStateEvents' do
317
- before(:each) do
318
- @model = new_model do
319
- include ActiveModel::Dirty
320
- define_attribute_methods [:state]
321
- end
322
- @machine = StateMachines::Machine.new(@model, :action => :save, :initial => :parked)
323
- @machine.event :ignite
324
-
325
- @record = @model.create
326
- @record.state_event = 'ignite'
327
- end
328
-
329
- it 'should_not_include_state_in_changed_attributes' do
330
- assert_equal [], @record.changed
331
- end
332
-
333
- it 'should_not_track_attribute_change' do
334
- assert_equal nil, @record.changes['state']
335
- end
336
- end
337
-
338
- context 'WithCallbacks' do
339
- before(:each) do
340
- @model = new_model
341
- @machine = StateMachines::Machine.new(@model, :initial => :parked, :integration => :active_model)
342
- @machine.other_states :idling
343
- @machine.event :ignite
344
-
345
- @record = @model.new(:state => 'parked')
346
- @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
347
- end
348
-
349
- it 'should_run_before_callbacks' do
350
- called = false
351
- @machine.before_transition {called = true}
352
-
353
- @transition.perform
354
- assert called
355
- end
356
-
357
- it 'should_pass_record_to_before_callbacks_with_one_argument' do
358
- record = nil
359
- @machine.before_transition {|arg| record = arg}
360
-
361
- @transition.perform
362
- assert_equal @record, record
363
- end
364
-
365
- it 'should_pass_record_and_transition_to_before_callbacks_with_multiple_arguments' do
366
- callback_args = nil
367
- @machine.before_transition {|*args| callback_args = args}
368
-
369
- @transition.perform
370
- assert_equal [@record, @transition], callback_args
371
- end
372
-
373
- it 'should_run_before_callbacks_outside_the_context_of_the_record' do
374
- context = nil
375
- @machine.before_transition {context = self}
376
-
377
- @transition.perform
378
- assert_equal self, context
379
- end
380
-
381
- it 'should_run_after_callbacks' do
382
- called = false
383
- @machine.after_transition {called = true}
384
-
385
- @transition.perform
386
- assert called
387
- end
388
-
389
- it 'should_pass_record_to_after_callbacks_with_one_argument' do
390
- record = nil
391
- @machine.after_transition {|arg| record = arg}
392
-
393
- @transition.perform
394
- assert_equal @record, record
395
- end
396
-
397
- it 'should_pass_record_and_transition_to_after_callbacks_with_multiple_arguments' do
398
- callback_args = nil
399
- @machine.after_transition {|*args| callback_args = args}
400
-
401
- @transition.perform
402
- assert_equal [@record, @transition], callback_args
403
- end
404
-
405
- it 'should_run_after_callbacks_outside_the_context_of_the_record' do
406
- context = nil
407
- @machine.after_transition {context = self}
408
-
409
- @transition.perform
410
- assert_equal self, context
411
- end
412
-
413
- it 'should_run_around_callbacks' do
414
- before_called = false
415
- after_called = false
416
- ensure_called = 0
417
- @machine.around_transition do |block|
418
- before_called = true
419
- begin
420
- block.call
421
- ensure
422
- ensure_called += 1
423
- end
424
- after_called = true
425
- end
426
-
427
- @transition.perform
428
- assert before_called
429
- assert after_called
430
- assert_equal ensure_called, 1
431
- end
432
-
433
- it 'should_include_transition_states_in_known_states' do
434
- @machine.before_transition :to => :first_gear, :do => lambda {}
435
-
436
- assert_equal [:parked, :idling, :first_gear], @machine.states.map {|state| state.name}
437
- end
438
-
439
- it 'should_allow_symbolic_callbacks' do
440
- callback_args = nil
441
-
442
- klass = class << @record; self; end
443
- klass.send(:define_method, :after_ignite) do |*args|
444
- callback_args = args
445
- end
446
-
447
- @machine.before_transition(:after_ignite)
448
-
449
- @transition.perform
450
- assert_equal [@transition], callback_args
451
- end
452
-
453
- it 'should_allow_string_callbacks' do
454
- class << @record
455
- attr_reader :callback_result
456
- end
457
-
458
- @machine.before_transition('@callback_result = [1, 2, 3]')
459
- @transition.perform
460
-
461
- assert_equal [1, 2, 3], @record.callback_result
462
- end
463
- end
464
-
465
- context 'WithFailedBeforeCallbacks' do
466
- before(:each) do
467
- @callbacks = []
468
-
469
- @model = new_model
470
- @machine = StateMachines::Machine.new(@model, :integration => :active_model)
471
- @machine.state :parked, :idling
472
- @machine.event :ignite
473
- @machine.before_transition {@callbacks << :before_1; false}
474
- @machine.before_transition {@callbacks << :before_2}
475
- @machine.after_transition {@callbacks << :after}
476
- @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
477
-
478
- @record = @model.new(:state => 'parked')
479
- @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
480
- @result = @transition.perform
481
- end
482
-
483
- it 'should_not_be_successful' do
484
- assert !@result
485
- end
486
-
487
- it 'should_not_change_current_state' do
488
- assert_equal 'parked', @record.state
489
- end
490
-
491
- it 'should_not_run_further_callbacks' do
492
- assert_equal [:before_1], @callbacks
493
- end
494
- end
495
-
496
- context 'WithFailedAfterCallbacks' do
497
- before(:each) do
498
- @callbacks = []
499
-
500
- @model = new_model
501
- @machine = StateMachines::Machine.new(@model, :integration => :active_model)
502
- @machine.state :parked, :idling
503
- @machine.event :ignite
504
- @machine.after_transition {@callbacks << :after_1; false}
505
- @machine.after_transition {@callbacks << :after_2}
506
- @machine.around_transition {|block| @callbacks << :around_before; block.call; @callbacks << :around_after}
507
-
508
- @record = @model.new(:state => 'parked')
509
- @transition = StateMachines::Transition.new(@record, @machine, :ignite, :parked, :idling)
510
- @result = @transition.perform
511
- end
512
-
513
- it 'should_be_successful' do
514
- assert @result
515
- end
516
-
517
- it 'should_change_current_state' do
518
- assert_equal 'idling', @record.state
519
- end
520
-
521
- it 'should_not_run_further_after_callbacks' do
522
- assert_equal [:around_before, :around_after, :after_1], @callbacks
523
- end
524
- end
525
-
526
- context 'WithValidations' do
527
- before(:each) do
528
- @model = new_model { include ActiveModel::Validations }
529
- @machine = StateMachines::Machine.new(@model, :action => :save)
530
- @machine.state :parked
531
-
532
- @record = @model.new
533
- end
534
-
535
- it 'should_invalidate_using_errors' do
536
- I18n.backend = I18n::Backend::Simple.new if Object.const_defined?(:I18n)
537
- @record.state = 'parked'
538
-
539
- @machine.invalidate(@record, :state, :invalid_transition, [[:event, 'park']])
540
- assert_equal ['State cannot transition via "park"'], @record.errors.full_messages
541
- end
542
-
543
- it 'should_auto_prefix_custom_attributes_on_invalidation' do
544
- @machine.invalidate(@record, :event, :invalid)
545
-
546
- assert_equal ['State event is invalid'], @record.errors.full_messages
547
- end
548
-
549
- it 'should_clear_errors_on_reset' do
550
- @record.state = 'parked'
551
- @record.errors.add(:state, 'is invalid')
552
-
553
- @machine.reset(@record)
554
- assert_equal [], @record.errors.full_messages
555
- end
556
-
557
- it 'should_be_valid_if_state_is_known' do
558
- @record.state = 'parked'
559
-
560
- assert @record.valid?
561
- end
562
-
563
- it 'should_not_be_valid_if_state_is_unknown' do
564
- @record.state = 'invalid'
565
-
566
- assert !@record.valid?
567
- assert_equal ['State is invalid'], @record.errors.full_messages
568
- end
569
- end
570
-
571
- context 'WithValidationsAndCustomAttribute' do
572
- before(:each) do
573
- @model = new_model { include ActiveModel::Validations }
574
-
575
- @machine = StateMachines::Machine.new(@model, :status, :attribute => :state)
576
- @machine.state :parked
577
-
578
- @record = @model.new
579
- end
580
-
581
- it 'should_add_validation_errors_to_custom_attribute' do
582
- @record.state = 'invalid'
583
-
584
- assert !@record.valid?
585
- assert_equal ['State is invalid'], @record.errors.full_messages
586
-
587
- @record.state = 'parked'
588
- assert @record.valid?
589
- end
590
- end
591
-
592
- context 'Errors' do
593
- before(:each) do
594
- @model = new_model { include ActiveModel::Validations }
595
- @machine = StateMachines::Machine.new(@model)
596
- @record = @model.new
597
- end
598
-
599
- it 'should_be_able_to_describe_current_errors' do
600
- @record.errors.add(:id, 'cannot be blank')
601
- @record.errors.add(:state, 'is invalid')
602
- assert_equal ['Id cannot be blank', 'State is invalid'], @machine.errors_for(@record).split(', ').sort
603
- end
604
-
605
- it 'should_describe_as_halted_with_no_errors' do
606
- assert_equal 'Transition halted', @machine.errors_for(@record)
607
- end
608
- end
609
-
610
- context 'WithStateDrivenValidations' do
611
- before(:each) do
612
- @model = new_model do
613
- include ActiveModel::Validations
614
- attr_accessor :seatbelt
615
- end
616
-
617
- @machine = StateMachines::Machine.new(@model)
618
- @machine.state :first_gear, :second_gear do
619
- validates_presence_of :seatbelt
620
- end
621
- @machine.other_states :parked
622
- end
623
-
624
- it 'should_be_valid_if_validation_fails_outside_state_scope' do
625
- record = @model.new(:state => 'parked', :seatbelt => nil)
626
- assert record.valid?
627
- end
628
-
629
- it 'should_be_invalid_if_validation_fails_within_state_scope' do
630
- record = @model.new(:state => 'first_gear', :seatbelt => nil)
631
- assert !record.valid?
632
- end
633
-
634
- it 'should_be_valid_if_validation_succeeds_within_state_scope' do
635
- record = @model.new(:state => 'second_gear', :seatbelt => true)
636
- assert record.valid?
637
- end
638
- end
639
-
640
-
641
-
642
- context 'WithInternationalization' do
643
- before(:each) do
644
- I18n.backend = I18n::Backend::Simple.new
645
-
646
- # Initialize the backend
647
- I18n.backend.translate(:en, 'activemodel.errors.messages.invalid_transition', :event => 'ignite', :value => 'idling')
648
-
649
- @model = new_model { include ActiveModel::Validations }
650
- end
651
-
652
- it 'should_use_defaults' do
653
- I18n.backend.store_translations(:en, {
654
- :activemodel => {:errors => {:messages => {:invalid_transition => 'cannot %{event}'}}}
655
- })
656
-
657
- machine = StateMachines::Machine.new(@model, :action => :save)
658
- machine.state :parked, :idling
659
- machine.event :ignite
660
-
661
- record = @model.new(:state => 'idling')
662
-
663
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
664
- assert_equal ['State cannot ignite'], record.errors.full_messages
665
- end
666
-
667
- it 'should_allow_customized_error_key' do
668
- I18n.backend.store_translations(:en, {
669
- :activemodel => {:errors => {:messages => {:bad_transition => 'cannot %{event}'}}}
670
- })
671
-
672
- machine = StateMachines::Machine.new(@model, :action => :save, :messages => {:invalid_transition => :bad_transition})
673
- machine.state :parked, :idling
674
-
675
- record = @model.new
676
- record.state = 'idling'
677
-
678
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
679
- assert_equal ['State cannot ignite'], record.errors.full_messages
680
- end
681
-
682
- it 'should_allow_customized_error_string' do
683
- machine = StateMachines::Machine.new(@model, :action => :save, :messages => {:invalid_transition => 'cannot %{event}'})
684
- machine.state :parked, :idling
685
-
686
- record = @model.new(:state => 'idling')
687
-
688
- machine.invalidate(record, :state, :invalid_transition, [[:event, 'ignite']])
689
- assert_equal ['State cannot ignite'], record.errors.full_messages
690
- end
691
-
692
- it 'should_allow_customized_state_key_scoped_to_class_and_machine' do
693
- I18n.backend.store_translations(:en, {
694
- :activemodel => {:state_machines => {:'bar/foo' => {:state => {:states => {:parked => 'shutdown'}}}}}
695
- })
696
-
697
- machine = StateMachines::Machine.new(@model)
698
- machine.state :parked
699
-
700
- assert_equal 'shutdown', machine.state(:parked).human_name
701
- end
702
-
703
- it 'should_allow_customized_state_key_scoped_to_class' do
704
- I18n.backend.store_translations(:en, {
705
- :activemodel => {:state_machines => {:'bar/foo' => {:states => {:parked => 'shutdown'}}}}
706
- })
707
-
708
- machine = StateMachines::Machine.new(@model)
709
- machine.state :parked
710
-
711
- assert_equal 'shutdown', machine.state(:parked).human_name
712
- end
713
-
714
- it 'should_allow_customized_state_key_scoped_to_machine' do
715
- I18n.backend.store_translations(:en, {
716
- :activemodel => {:state_machines => {:state => {:states => {:parked => 'shutdown'}}}}
717
- })
718
-
719
- machine = StateMachines::Machine.new(@model)
720
- machine.state :parked
721
-
722
- assert_equal 'shutdown', machine.state(:parked).human_name
723
- end
724
-
725
- it 'should_allow_customized_state_key_unscoped' do
726
- I18n.backend.store_translations(:en, {
727
- :activemodel => {:state_machines => {:states => {:parked => 'shutdown'}}}
728
- })
729
-
730
- machine = StateMachines::Machine.new(@model)
731
- machine.state :parked
732
-
733
- assert_equal 'shutdown', machine.state(:parked).human_name
734
- end
735
-
736
- it 'should_support_nil_state_key' do
737
- I18n.backend.store_translations(:en, {
738
- :activemodel => {:state_machines => {:states => {:nil => 'empty'}}}
739
- })
740
-
741
- machine = StateMachines::Machine.new(@model)
742
-
743
- assert_equal 'empty', machine.state(nil).human_name
744
- end
745
-
746
- it 'should_allow_customized_event_key_scoped_to_class_and_machine' do
747
- I18n.backend.store_translations(:en, {
748
- :activemodel => {:state_machines => {:'bar/foo' => {:state => {:events => {:park => 'stop'}}}}}
749
- })
750
-
751
- machine = StateMachines::Machine.new(@model)
752
- machine.event :park
753
-
754
- assert_equal 'stop', machine.event(:park).human_name
755
- end
756
-
757
- it 'should_allow_customized_event_key_scoped_to_class' do
758
- I18n.backend.store_translations(:en, {
759
- :activemodel => {:state_machines => {:'bar/foo' => {:events => {:park => 'stop'}}}}
760
- })
761
-
762
- machine = StateMachines::Machine.new(@model)
763
- machine.event :park
764
-
765
- assert_equal 'stop', machine.event(:park).human_name
766
- end
767
-
768
- it 'should_allow_customized_event_key_scoped_to_machine' do
769
- I18n.backend.store_translations(:en, {
770
- :activemodel => {:state_machines => {:state => {:events => {:park => 'stop'}}}}
771
- })
772
-
773
- machine = StateMachines::Machine.new(@model)
774
- machine.event :park
775
-
776
- assert_equal 'stop', machine.event(:park).human_name
777
- end
778
-
779
- it 'should_allow_customized_event_key_unscoped' do
780
- I18n.backend.store_translations(:en, {
781
- :activemodel => {:state_machines => {:events => {:park => 'stop'}}}
782
- })
783
-
784
- machine = StateMachines::Machine.new(@model)
785
- machine.event :park
786
-
787
- assert_equal 'stop', machine.event(:park).human_name
788
- end
789
-
790
- it 'should_only_add_locale_once_in_load_path' do
791
- assert_equal 1, I18n.load_path.select { |path| path =~ %r{active_model/locale\.rb$} }.length
792
-
793
- # Create another ActiveModel model that will triger the i18n feature
794
- new_model
795
-
796
- assert_equal 1, I18n.load_path.select { |path| path =~ %r{active_model/locale\.rb$} }.length
797
- end
798
-
799
- end
800
-
801
- end