aasm 4.11.0 → 4.12.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -17
  3. data/Appraisals +44 -0
  4. data/CHANGELOG.md +24 -1
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +4 -21
  7. data/README.md +81 -34
  8. data/Rakefile +6 -1
  9. data/TESTING.md +25 -0
  10. data/aasm.gemspec +5 -2
  11. data/gemfiles/rails_3.2.gemfile +13 -0
  12. data/gemfiles/rails_4.0.gemfile +8 -9
  13. data/gemfiles/rails_4.2.gemfile +9 -9
  14. data/gemfiles/rails_4.2_mongoid_5.gemfile +5 -9
  15. data/gemfiles/rails_5.0.gemfile +7 -16
  16. data/lib/aasm/aasm.rb +9 -3
  17. data/lib/aasm/base.rb +3 -1
  18. data/lib/aasm/configuration.rb +4 -0
  19. data/lib/aasm/core/event.rb +19 -9
  20. data/lib/aasm/core/state.rb +7 -0
  21. data/lib/aasm/core/transition.rb +9 -0
  22. data/lib/aasm/instance_base.rb +8 -8
  23. data/lib/aasm/persistence/active_record_persistence.rb +1 -1
  24. data/lib/aasm/persistence/base.rb +3 -3
  25. data/lib/aasm/persistence/mongoid_persistence.rb +48 -9
  26. data/lib/aasm/persistence.rb +0 -3
  27. data/lib/aasm/state_machine.rb +4 -2
  28. data/lib/aasm/state_machine_store.rb +5 -2
  29. data/lib/aasm/version.rb +1 -1
  30. data/lib/generators/active_record/aasm_generator.rb +1 -1
  31. data/lib/motion-aasm.rb +0 -1
  32. data/spec/en.yml +3 -0
  33. data/spec/generators/active_record_generator_spec.rb +42 -34
  34. data/spec/generators/mongoid_generator_spec.rb +4 -6
  35. data/spec/models/{invalid_persistor.rb → active_record/invalid_persistor.rb} +0 -2
  36. data/spec/models/{silent_persistor.rb → active_record/silent_persistor.rb} +0 -2
  37. data/spec/models/active_record/simple_new_dsl.rb +2 -2
  38. data/spec/models/{transactor.rb → active_record/transactor.rb} +0 -2
  39. data/spec/models/{validator.rb → active_record/validator.rb} +6 -3
  40. data/spec/models/callbacks/basic.rb +5 -2
  41. data/spec/models/guard_with_params.rb +24 -0
  42. data/spec/models/guard_with_params_multiple.rb +18 -0
  43. data/spec/models/mongoid/invalid_persistor_mongoid.rb +39 -0
  44. data/spec/models/mongoid/silent_persistor_mongoid.rb +39 -0
  45. data/spec/models/mongoid/simple_mongoid.rb +2 -2
  46. data/spec/models/mongoid/validator_mongoid.rb +100 -0
  47. data/spec/models/multi_transitioner.rb +10 -0
  48. data/spec/models/multiple_transitions_that_differ_only_by_guard.rb +31 -0
  49. data/spec/models/parametrised_event.rb +7 -0
  50. data/spec/models/simple_multiple_example.rb +12 -0
  51. data/spec/models/sub_class.rb +34 -0
  52. data/spec/spec_helper.rb +0 -33
  53. data/spec/spec_helpers/active_record.rb +7 -0
  54. data/spec/spec_helpers/dynamoid.rb +33 -0
  55. data/spec/spec_helpers/mongoid.rb +7 -0
  56. data/spec/spec_helpers/redis.rb +7 -0
  57. data/spec/spec_helpers/remove_warnings.rb +1 -0
  58. data/spec/spec_helpers/sequel.rb +7 -0
  59. data/spec/unit/api_spec.rb +76 -73
  60. data/spec/unit/callbacks_spec.rb +5 -0
  61. data/spec/unit/event_spec.rb +12 -0
  62. data/spec/unit/guard_with_params_multiple_spec.rb +10 -0
  63. data/spec/unit/guard_with_params_spec.rb +14 -0
  64. data/spec/unit/inspection_spec.rb +5 -0
  65. data/spec/unit/localizer_spec.rb +55 -53
  66. data/spec/unit/multiple_transitions_that_differ_only_by_guard_spec.rb +14 -0
  67. data/spec/unit/override_warning_spec.rb +8 -0
  68. data/spec/unit/persistence/active_record_persistence_multiple_spec.rb +452 -445
  69. data/spec/unit/persistence/active_record_persistence_spec.rb +523 -490
  70. data/spec/unit/persistence/dynamoid_persistence_multiple_spec.rb +4 -9
  71. data/spec/unit/persistence/dynamoid_persistence_spec.rb +4 -9
  72. data/spec/unit/persistence/mongoid_persistence_multiple_spec.rb +87 -10
  73. data/spec/unit/persistence/mongoid_persistence_spec.rb +89 -10
  74. data/spec/unit/persistence/redis_persistence_spec.rb +3 -7
  75. data/spec/unit/persistence/sequel_persistence_multiple_spec.rb +4 -9
  76. data/spec/unit/persistence/sequel_persistence_spec.rb +4 -9
  77. data/spec/unit/simple_multiple_example_spec.rb +28 -0
  78. data/spec/unit/subclassing_multiple_spec.rb +37 -2
  79. data/spec/unit/subclassing_spec.rb +17 -2
  80. metadata +77 -32
  81. data/gemfiles/rails_3.2_stable.gemfile +0 -15
  82. data/gemfiles/rails_4.0_mongo_mapper.gemfile +0 -17
  83. data/gemfiles/rails_4.2_mongo_mapper.gemfile +0 -18
  84. data/lib/aasm/persistence/mongo_mapper_persistence.rb +0 -163
  85. data/spec/models/mongo_mapper/complex_mongo_mapper_example.rb +0 -37
  86. data/spec/models/mongo_mapper/no_scope_mongo_mapper.rb +0 -21
  87. data/spec/models/mongo_mapper/simple_mongo_mapper.rb +0 -23
  88. data/spec/models/mongo_mapper/simple_new_dsl_mongo_mapper.rb +0 -25
  89. data/spec/unit/persistence/mongo_mapper_persistence_multiple_spec.rb +0 -146
  90. data/spec/unit/persistence/mongo_mapper_persistence_spec.rb +0 -93
  91. /data/spec/models/{worker.rb → active_record/worker.rb} +0 -0
@@ -1,611 +1,618 @@
1
- require 'active_record'
2
1
  require 'spec_helper'
3
- Dir[File.dirname(__FILE__) + "/../../models/active_record/*.rb"].sort.each do |f|
4
- require File.expand_path(f)
5
- end
6
-
7
- load_schema
8
-
9
- # if you want to see the statements while running the spec enable the following line
10
- # require 'logger'
11
- # ActiveRecord::Base.logger = Logger.new(STDERR)
12
2
 
13
- describe "instance methods" do
14
- let(:gate) {MultipleGate.new}
3
+ if defined?(ActiveRecord)
15
4
 
16
- it "should respond to aasm persistence methods" do
17
- expect(gate).to respond_to(:aasm_read_state)
18
- expect(gate).to respond_to(:aasm_write_state)
19
- expect(gate).to respond_to(:aasm_write_state_without_persistence)
5
+ Dir[File.dirname(__FILE__) + "/../../models/active_record/*.rb"].sort.each do |f|
6
+ require File.expand_path(f)
20
7
  end
21
8
 
22
- describe "aasm_column_looks_like_enum" do
23
- subject { lambda{ gate.send(:aasm_column_looks_like_enum, :left) } }
9
+ load_schema
24
10
 
25
- let(:column_name) { "value" }
26
- let(:columns_hash) { Hash[column_name, column] }
27
-
28
- before :each do
29
- allow(gate.class.aasm(:left)).to receive(:attribute_name).and_return(column_name.to_sym)
30
- allow(gate.class).to receive(:columns_hash).and_return(columns_hash)
31
- end
11
+ # if you want to see the statements while running the spec enable the following line
12
+ # require 'logger'
13
+ # ActiveRecord::Base.logger = Logger.new(STDERR)
32
14
 
33
- context "when AASM column has integer type" do
34
- let(:column) { double(Object, type: :integer) }
15
+ describe "instance methods" do
16
+ let(:gate) {MultipleGate.new}
35
17
 
36
- it "returns true" do
37
- expect(subject.call).to be_truthy
38
- end
18
+ it "should respond to aasm persistence methods" do
19
+ expect(gate).to respond_to(:aasm_read_state)
20
+ expect(gate).to respond_to(:aasm_write_state)
21
+ expect(gate).to respond_to(:aasm_write_state_without_persistence)
39
22
  end
40
23
 
41
- context "when AASM column has string type" do
42
- let(:column) { double(Object, type: :string) }
24
+ describe "aasm_column_looks_like_enum" do
25
+ subject { lambda{ gate.send(:aasm_column_looks_like_enum, :left) } }
43
26
 
44
- it "returns false" do
45
- expect(subject.call).to be_falsey
46
- end
47
- end
48
- end
27
+ let(:column_name) { "value" }
28
+ let(:columns_hash) { Hash[column_name, column] }
49
29
 
50
- describe "aasm_guess_enum_method" do
51
- subject { lambda{ gate.send(:aasm_guess_enum_method, :left) } }
30
+ before :each do
31
+ allow(gate.class.aasm(:left)).to receive(:attribute_name).and_return(column_name.to_sym)
32
+ allow(gate.class).to receive(:columns_hash).and_return(columns_hash)
33
+ end
52
34
 
53
- before :each do
54
- allow(gate.class.aasm(:left)).to receive(:attribute_name).and_return(:value)
55
- end
35
+ context "when AASM column has integer type" do
36
+ let(:column) { double(Object, type: :integer) }
56
37
 
57
- it "pluralizes AASM column name" do
58
- expect(subject.call).to eq :values
59
- end
60
- end
38
+ it "returns true" do
39
+ expect(subject.call).to be_truthy
40
+ end
41
+ end
61
42
 
62
- describe "aasm_enum" do
63
- context "when AASM enum setting contains an explicit enum method name" do
64
- let(:with_enum) { MultipleWithEnum.new }
43
+ context "when AASM column has string type" do
44
+ let(:column) { double(Object, type: :string) }
65
45
 
66
- it "returns whatever value was set in AASM config" do
67
- expect(with_enum.send(:aasm_enum, :left)).to eq :test
46
+ it "returns false" do
47
+ expect(subject.call).to be_falsey
48
+ end
68
49
  end
69
50
  end
70
51
 
71
- context "when AASM enum setting is simply set to true" do
72
- let(:with_true_enum) { MultipleWithTrueEnum.new }
52
+ describe "aasm_guess_enum_method" do
53
+ subject { lambda{ gate.send(:aasm_guess_enum_method, :left) } }
54
+
73
55
  before :each do
74
- allow(MultipleWithTrueEnum.aasm(:left)).to receive(:attribute_name).and_return(:value)
56
+ allow(gate.class.aasm(:left)).to receive(:attribute_name).and_return(:value)
75
57
  end
76
58
 
77
- it "infers enum method name from pluralized column name" do
78
- expect(with_true_enum.send(:aasm_enum, :left)).to eq :values
59
+ it "pluralizes AASM column name" do
60
+ expect(subject.call).to eq :values
79
61
  end
80
62
  end
81
63
 
82
- context "when AASM enum setting is explicitly disabled" do
83
- let(:with_false_enum) { MultipleWithFalseEnum.new }
64
+ describe "aasm_enum" do
65
+ context "when AASM enum setting contains an explicit enum method name" do
66
+ let(:with_enum) { MultipleWithEnum.new }
84
67
 
85
- it "returns nil" do
86
- expect(with_false_enum.send(:aasm_enum, :left)).to be_nil
87
- end
88
- end
89
-
90
- context "when AASM enum setting is not enabled" do
91
- before :each do
92
- allow(MultipleGate.aasm(:left)).to receive(:attribute_name).and_return(:value)
68
+ it "returns whatever value was set in AASM config" do
69
+ expect(with_enum.send(:aasm_enum, :left)).to eq :test
70
+ end
93
71
  end
94
72
 
95
- context "when AASM column looks like enum" do
73
+ context "when AASM enum setting is simply set to true" do
74
+ let(:with_true_enum) { MultipleWithTrueEnum.new }
96
75
  before :each do
97
- allow(gate).to receive(:aasm_column_looks_like_enum).with(:left).and_return(true)
76
+ allow(MultipleWithTrueEnum.aasm(:left)).to receive(:attribute_name).and_return(:value)
98
77
  end
99
78
 
100
79
  it "infers enum method name from pluralized column name" do
101
- expect(gate.send(:aasm_enum, :left)).to eq :values
80
+ expect(with_true_enum.send(:aasm_enum, :left)).to eq :values
102
81
  end
103
82
  end
104
83
 
105
- context "when AASM column doesn't look like enum'" do
84
+ context "when AASM enum setting is explicitly disabled" do
85
+ let(:with_false_enum) { MultipleWithFalseEnum.new }
86
+
87
+ it "returns nil" do
88
+ expect(with_false_enum.send(:aasm_enum, :left)).to be_nil
89
+ end
90
+ end
91
+
92
+ context "when AASM enum setting is not enabled" do
106
93
  before :each do
107
- allow(gate).to receive(:aasm_column_looks_like_enum)
108
- .and_return(false)
94
+ allow(MultipleGate.aasm(:left)).to receive(:attribute_name).and_return(:value)
95
+ end
96
+
97
+ context "when AASM column looks like enum" do
98
+ before :each do
99
+ allow(gate).to receive(:aasm_column_looks_like_enum).with(:left).and_return(true)
100
+ end
101
+
102
+ it "infers enum method name from pluralized column name" do
103
+ expect(gate.send(:aasm_enum, :left)).to eq :values
104
+ end
109
105
  end
110
106
 
111
- it "returns nil, as we're not using enum" do
112
- expect(gate.send(:aasm_enum, :left)).to be_nil
107
+ context "when AASM column doesn't look like enum'" do
108
+ before :each do
109
+ allow(gate).to receive(:aasm_column_looks_like_enum)
110
+ .and_return(false)
111
+ end
112
+
113
+ it "returns nil, as we're not using enum" do
114
+ expect(gate.send(:aasm_enum, :left)).to be_nil
115
+ end
113
116
  end
114
117
  end
115
- end
116
118
 
117
- if ActiveRecord::VERSION::MAJOR >= 4 && ActiveRecord::VERSION::MINOR >= 1 # won't work with Rails <= 4.1
118
- # Enum are introduced from Rails 4.1, therefore enum syntax will not work on Rails <= 4.1
119
- context "when AASM enum setting is not enabled and aasm column not present" do
119
+ if ActiveRecord::VERSION::MAJOR >= 4 && ActiveRecord::VERSION::MINOR >= 1 # won't work with Rails <= 4.1
120
+ # Enum are introduced from Rails 4.1, therefore enum syntax will not work on Rails <= 4.1
121
+ context "when AASM enum setting is not enabled and aasm column not present" do
120
122
 
121
- let(:multiple_with_enum_without_column) {MultipleWithEnumWithoutColumn.new}
123
+ let(:multiple_with_enum_without_column) {MultipleWithEnumWithoutColumn.new}
122
124
 
123
- it "should raise NoMethodError for transitions" do
124
- expect{multiple_with_enum_without_column.send(:view, :left)}.to raise_error(NoMethodError, "undefined method 'status' for MultipleWithEnumWithoutColumn")
125
+ it "should raise NoMethodError for transitions" do
126
+ expect{multiple_with_enum_without_column.send(:view, :left)}.to raise_error(NoMethodError, "undefined method 'status' for MultipleWithEnumWithoutColumn")
127
+ end
125
128
  end
129
+
126
130
  end
127
131
 
128
132
  end
129
133
 
130
- end
134
+ context "when AASM is configured to use enum" do
135
+ let(:state_sym) { :running }
136
+ let(:state_code) { 2 }
137
+ let(:enum_name) { :states }
138
+ let(:enum) { Hash[state_sym, state_code] }
131
139
 
132
- context "when AASM is configured to use enum" do
133
- let(:state_sym) { :running }
134
- let(:state_code) { 2 }
135
- let(:enum_name) { :states }
136
- let(:enum) { Hash[state_sym, state_code] }
137
-
138
- before :each do
139
- allow(gate).to receive(:aasm_enum).and_return(enum_name)
140
- allow(gate).to receive(:aasm_write_attribute)
141
- allow(gate).to receive(:write_attribute)
140
+ before :each do
141
+ allow(gate).to receive(:aasm_enum).and_return(enum_name)
142
+ allow(gate).to receive(:aasm_write_attribute)
143
+ allow(gate).to receive(:write_attribute)
142
144
 
143
- allow(MultipleGate).to receive(enum_name).and_return(enum)
144
- end
145
+ allow(MultipleGate).to receive(enum_name).and_return(enum)
146
+ end
145
147
 
146
- describe "aasm_write_state" do
147
- context "when AASM is configured to skip validations on save" do
148
- before :each do
149
- allow(gate).to receive(:aasm_skipping_validations).and_return(true)
148
+ describe "aasm_write_state" do
149
+ context "when AASM is configured to skip validations on save" do
150
+ before :each do
151
+ allow(gate).to receive(:aasm_skipping_validations).and_return(true)
152
+ end
153
+
154
+ it "passes state code instead of state symbol to update_all" do
155
+ # stub_chain does not allow us to give expectations on call
156
+ # parameters in the middle of the chain, so we need to use
157
+ # intermediate object instead.
158
+ obj = double(Object, update_all: 1)
159
+ allow(MultipleGate).to receive_message_chain(:unscoped, :where)
160
+ .and_return(obj)
161
+
162
+ gate.aasm_write_state state_sym, :left
163
+
164
+ expect(obj).to have_received(:update_all)
165
+ .with(Hash[gate.class.aasm(:left).attribute_name, state_code])
166
+ end
150
167
  end
151
168
 
152
- it "passes state code instead of state symbol to update_all" do
153
- # stub_chain does not allow us to give expectations on call
154
- # parameters in the middle of the chain, so we need to use
155
- # intermediate object instead.
156
- obj = double(Object, update_all: 1)
157
- allow(MultipleGate).to receive(:where).and_return(obj)
169
+ context "when AASM is not skipping validations" do
170
+ it "delegates state update to the helper method" do
171
+ # Let's pretend that validation is passed
172
+ allow(gate).to receive(:save).and_return(true)
158
173
 
159
- gate.aasm_write_state state_sym, :left
174
+ gate.aasm_write_state state_sym, :left
160
175
 
161
- expect(obj).to have_received(:update_all)
162
- .with(Hash[gate.class.aasm(:left).attribute_name, state_code])
176
+ expect(gate).to have_received(:aasm_write_attribute).with(state_sym, :left)
177
+ expect(gate).to_not have_received :write_attribute
178
+ end
163
179
  end
164
180
  end
165
181
 
166
- context "when AASM is not skipping validations" do
182
+ describe "aasm_write_state_without_persistence" do
167
183
  it "delegates state update to the helper method" do
168
- # Let's pretend that validation is passed
169
- allow(gate).to receive(:save).and_return(true)
170
-
171
- gate.aasm_write_state state_sym, :left
184
+ gate.aasm_write_state_without_persistence state_sym, :left
172
185
 
173
186
  expect(gate).to have_received(:aasm_write_attribute).with(state_sym, :left)
174
187
  expect(gate).to_not have_received :write_attribute
175
188
  end
176
189
  end
190
+
191
+ describe "aasm_raw_attribute_value" do
192
+ it "converts state symbol to state code" do
193
+ expect(gate.send(:aasm_raw_attribute_value, state_sym))
194
+ .to eq state_code
195
+ end
196
+ end
177
197
  end
178
198
 
179
- describe "aasm_write_state_without_persistence" do
180
- it "delegates state update to the helper method" do
181
- gate.aasm_write_state_without_persistence state_sym, :left
199
+ context "when AASM is configured to use string field" do
200
+ let(:state_sym) { :running }
182
201
 
183
- expect(gate).to have_received(:aasm_write_attribute).with(state_sym, :left)
184
- expect(gate).to_not have_received :write_attribute
202
+ before :each do
203
+ allow(gate).to receive(:aasm_enum).and_return(nil)
185
204
  end
186
- end
187
205
 
188
- describe "aasm_raw_attribute_value" do
189
- it "converts state symbol to state code" do
190
- expect(gate.send(:aasm_raw_attribute_value, state_sym))
191
- .to eq state_code
206
+ describe "aasm_raw_attribute_value" do
207
+ it "converts state symbol to string" do
208
+ expect(gate.send(:aasm_raw_attribute_value, state_sym))
209
+ .to eq state_sym.to_s
210
+ end
192
211
  end
193
212
  end
194
- end
195
213
 
196
- context "when AASM is configured to use string field" do
197
- let(:state_sym) { :running }
214
+ describe "aasm_write_attribute helper method" do
215
+ let(:sym) { :sym }
216
+ let(:value) { 42 }
198
217
 
199
- before :each do
200
- allow(gate).to receive(:aasm_enum).and_return(nil)
201
- end
218
+ before :each do
219
+ allow(gate).to receive(:write_attribute)
220
+ allow(gate).to receive(:aasm_raw_attribute_value).and_return(value)
202
221
 
203
- describe "aasm_raw_attribute_value" do
204
- it "converts state symbol to string" do
205
- expect(gate.send(:aasm_raw_attribute_value, state_sym))
206
- .to eq state_sym.to_s
222
+ gate.send(:aasm_write_attribute, sym, :left)
207
223
  end
208
- end
209
- end
210
224
 
211
- describe "aasm_write_attribute helper method" do
212
- let(:sym) { :sym }
213
- let(:value) { 42 }
214
-
215
- before :each do
216
- allow(gate).to receive(:write_attribute)
217
- allow(gate).to receive(:aasm_raw_attribute_value).and_return(value)
225
+ it "generates attribute value using a helper method" do
226
+ expect(gate).to have_received(:aasm_raw_attribute_value).with(sym, :left)
227
+ end
218
228
 
219
- gate.send(:aasm_write_attribute, sym, :left)
229
+ it "writes attribute to the model" do
230
+ expect(gate).to have_received(:write_attribute).with(:aasm_state, value)
231
+ end
220
232
  end
221
233
 
222
- it "generates attribute value using a helper method" do
223
- expect(gate).to have_received(:aasm_raw_attribute_value).with(sym, :left)
234
+ it "should return the initial state when new and the aasm field is nil" do
235
+ expect(gate.aasm(:left).current_state).to eq(:opened)
224
236
  end
225
237
 
226
- it "writes attribute to the model" do
227
- expect(gate).to have_received(:write_attribute).with(:aasm_state, value)
238
+ it "should return the aasm column when new and the aasm field is not nil" do
239
+ gate.aasm_state = "closed"
240
+ expect(gate.aasm(:left).current_state).to eq(:closed)
228
241
  end
229
- end
230
-
231
- it "should return the initial state when new and the aasm field is nil" do
232
- expect(gate.aasm(:left).current_state).to eq(:opened)
233
- end
234
-
235
- it "should return the aasm column when new and the aasm field is not nil" do
236
- gate.aasm_state = "closed"
237
- expect(gate.aasm(:left).current_state).to eq(:closed)
238
- end
239
242
 
240
- it "should return the aasm column when not new and the aasm.attribute_name is not nil" do
241
- allow(gate).to receive(:new_record?).and_return(false)
242
- gate.aasm_state = "state"
243
- expect(gate.aasm(:left).current_state).to eq(:state)
244
- end
245
-
246
- it "should allow a nil state" do
247
- allow(gate).to receive(:new_record?).and_return(false)
248
- gate.aasm_state = nil
249
- expect(gate.aasm(:left).current_state).to be_nil
250
- end
243
+ it "should return the aasm column when not new and the aasm.attribute_name is not nil" do
244
+ allow(gate).to receive(:new_record?).and_return(false)
245
+ gate.aasm_state = "state"
246
+ expect(gate.aasm(:left).current_state).to eq(:state)
247
+ end
251
248
 
252
- context 'on initialization' do
253
- it "should initialize the aasm state" do
254
- expect(MultipleGate.new.aasm_state).to eql 'opened'
255
- expect(MultipleGate.new.aasm(:left).current_state).to eql :opened
249
+ it "should allow a nil state" do
250
+ allow(gate).to receive(:new_record?).and_return(false)
251
+ gate.aasm_state = nil
252
+ expect(gate.aasm(:left).current_state).to be_nil
256
253
  end
257
254
 
258
- it "should not initialize the aasm state if it has not been loaded" do
259
- # we have to create a gate in the database, for which we only want to
260
- # load the id, and not the state
261
- gate = MultipleGate.create!
255
+ context 'on initialization' do
256
+ it "should initialize the aasm state" do
257
+ expect(MultipleGate.new.aasm_state).to eql 'opened'
258
+ expect(MultipleGate.new.aasm(:left).current_state).to eql :opened
259
+ end
262
260
 
263
- # then we just load the gate ids
264
- MultipleGate.select(:id).where(id: gate.id).first
265
- end
266
- end
261
+ it "should not initialize the aasm state if it has not been loaded" do
262
+ # we have to create a gate in the database, for which we only want to
263
+ # load the id, and not the state
264
+ gate = MultipleGate.create!
267
265
 
268
- end
266
+ # then we just load the gate ids
267
+ MultipleGate.select(:id).where(id: gate.id).first
268
+ end
269
+ end
269
270
 
270
- if ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2 # won't work with Rails >= 4.2
271
- describe "direct state column access" do
272
- it "accepts false states" do
273
- f = MultipleFalseState.create!
274
- expect(f.aasm_state).to eql false
275
- expect {
276
- f.aasm(:left).events.map(&:name)
277
- }.to_not raise_error
278
271
  end
279
- end
280
- end
281
272
 
282
- describe 'subclasses' do
283
- it "should have the same states as its parent class" do
284
- expect(MultipleDerivateNewDsl.aasm(:left).states).to eq(MultipleSimpleNewDsl.aasm(:left).states)
273
+ if ActiveRecord::VERSION::MAJOR < 4 && ActiveRecord::VERSION::MINOR < 2 # won't work with Rails >= 4.2
274
+ describe "direct state column access" do
275
+ it "accepts false states" do
276
+ f = MultipleFalseState.create!
277
+ expect(f.aasm_state).to eql false
278
+ expect {
279
+ f.aasm(:left).events.map(&:name)
280
+ }.to_not raise_error
281
+ end
285
282
  end
286
-
287
- it "should have the same events as its parent class" do
288
- expect(MultipleDerivateNewDsl.aasm(:left).events).to eq(MultipleSimpleNewDsl.aasm(:left).events)
289
283
  end
290
284
 
291
- it "should have the same column as its parent even for the new dsl" do
292
- expect(MultipleSimpleNewDsl.aasm(:left).attribute_name).to eq(:status)
293
- expect(MultipleDerivateNewDsl.aasm(:left).attribute_name).to eq(:status)
294
- end
295
- end
285
+ describe 'subclasses' do
286
+ it "should have the same states as its parent class" do
287
+ expect(MultipleDerivateNewDsl.aasm(:left).states).to eq(MultipleSimpleNewDsl.aasm(:left).states)
288
+ end
296
289
 
297
- describe "named scopes with the new DSL" do
298
- context "Does not already respond_to? the scope name" do
299
- it "should add a scope" do
300
- expect(MultipleSimpleNewDsl).to respond_to(:unknown_scope)
301
- expect(MultipleSimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation)).to be_truthy
290
+ it "should have the same events as its parent class" do
291
+ expect(MultipleDerivateNewDsl.aasm(:left).events).to eq(MultipleSimpleNewDsl.aasm(:left).events)
302
292
  end
303
- end
304
293
 
305
- context "Already respond_to? the scope name" do
306
- it "should not add a scope" do
307
- expect(MultipleSimpleNewDsl).to respond_to(:new)
308
- expect(MultipleSimpleNewDsl.new.class).to eq(MultipleSimpleNewDsl)
294
+ it "should have the same column as its parent even for the new dsl" do
295
+ expect(MultipleSimpleNewDsl.aasm(:left).attribute_name).to eq(:status)
296
+ expect(MultipleDerivateNewDsl.aasm(:left).attribute_name).to eq(:status)
309
297
  end
310
298
  end
311
299
 
312
- it "does not create scopes if requested" do
313
- expect(MultipleNoScope).not_to respond_to(:pending)
314
- end
300
+ describe "named scopes with the new DSL" do
301
+ context "Does not already respond_to? the scope name" do
302
+ it "should add a scope for each state" do
303
+ expect(MultipleSimpleNewDsl).to respond_to(:unknown_scope)
304
+ expect(MultipleSimpleNewDsl).to respond_to(:another_unknown_scope)
315
305
 
316
- context "result of scope" do
317
- let!(:dsl1) { MultipleSimpleNewDsl.create!(status: :new) }
318
- let!(:dsl2) { MultipleSimpleNewDsl.create!(status: :unknown_scope) }
306
+ expect(MultipleSimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation)).to be_truthy
307
+ expect(MultipleSimpleNewDsl.another_unknown_scope.is_a?(ActiveRecord::Relation)).to be_truthy
308
+ end
309
+ end
319
310
 
320
- after do
321
- MultipleSimpleNewDsl.destroy_all
311
+ context "Already respond_to? the scope name" do
312
+ it "should not add a scope" do
313
+ expect(MultipleSimpleNewDsl).to respond_to(:new)
314
+ expect(MultipleSimpleNewDsl.new.class).to eq(MultipleSimpleNewDsl)
315
+ end
322
316
  end
323
317
 
324
- it "created scope works as where(name: :scope_name)" do
325
- expect(MultipleSimpleNewDsl.unknown_scope).to contain_exactly(dsl2)
318
+ it "does not create scopes if requested" do
319
+ expect(MultipleNoScope).not_to respond_to(:pending)
326
320
  end
327
- end
328
- end # scopes
329
321
 
330
- describe "direct assignment" do
331
- it "is allowed by default" do
332
- obj = MultipleNoScope.create
333
- expect(obj.aasm_state.to_sym).to eql :pending
322
+ context "result of scope" do
323
+ let!(:dsl1) { MultipleSimpleNewDsl.create!(status: :new) }
324
+ let!(:dsl2) { MultipleSimpleNewDsl.create!(status: :unknown_scope) }
334
325
 
335
- obj.aasm_state = :running
336
- expect(obj.aasm_state.to_sym).to eql :running
337
- end
326
+ after do
327
+ MultipleSimpleNewDsl.destroy_all
328
+ end
338
329
 
339
- it "is forbidden if configured" do
340
- obj = MultipleNoDirectAssignment.create
341
- expect(obj.aasm_state.to_sym).to eql :pending
330
+ it "created scope works as where(name: :scope_name)" do
331
+ expect(MultipleSimpleNewDsl.unknown_scope).to contain_exactly(dsl2)
332
+ end
333
+ end
334
+ end # scopes
342
335
 
343
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
344
- expect(obj.aasm_state.to_sym).to eql :pending
345
- end
336
+ describe "direct assignment" do
337
+ it "is allowed by default" do
338
+ obj = MultipleNoScope.create
339
+ expect(obj.aasm_state.to_sym).to eql :pending
346
340
 
347
- it 'can be turned off and on again' do
348
- obj = MultipleNoDirectAssignment.create
349
- expect(obj.aasm_state.to_sym).to eql :pending
341
+ obj.aasm_state = :running
342
+ expect(obj.aasm_state.to_sym).to eql :running
343
+ end
350
344
 
351
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
352
- expect(obj.aasm_state.to_sym).to eql :pending
345
+ it "is forbidden if configured" do
346
+ obj = MultipleNoDirectAssignment.create
347
+ expect(obj.aasm_state.to_sym).to eql :pending
353
348
 
354
- # allow it temporarily
355
- MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = false
356
- obj.aasm_state = :pending
357
- expect(obj.aasm_state.to_sym).to eql :pending
349
+ expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
350
+ expect(obj.aasm_state.to_sym).to eql :pending
351
+ end
358
352
 
359
- # and forbid it again
360
- MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = true
361
- expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
362
- expect(obj.aasm_state.to_sym).to eql :pending
363
- end
364
- end # direct assignment
353
+ it 'can be turned off and on again' do
354
+ obj = MultipleNoDirectAssignment.create
355
+ expect(obj.aasm_state.to_sym).to eql :pending
365
356
 
366
- describe 'initial states' do
367
- it 'should support conditions' do
368
- expect(MultipleThief.new(:skilled => true).aasm(:left).current_state).to eq(:rich)
369
- expect(MultipleThief.new(:skilled => false).aasm(:left).current_state).to eq(:jailed)
370
- end
371
- end
357
+ expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
358
+ expect(obj.aasm_state.to_sym).to eql :pending
372
359
 
373
- describe 'transitions with persistence' do
360
+ # allow it temporarily
361
+ MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = false
362
+ obj.aasm_state = :pending
363
+ expect(obj.aasm_state.to_sym).to eql :pending
374
364
 
375
- it "should work for valid models" do
376
- valid_object = MultipleValidator.create(:name => 'name')
377
- expect(valid_object).to be_sleeping
378
- valid_object.status = :running
379
- expect(valid_object).to be_running
380
- end
365
+ # and forbid it again
366
+ MultipleNoDirectAssignment.aasm(:left).state_machine.config.no_direct_assignment = true
367
+ expect {obj.aasm_state = :running}.to raise_error(AASM::NoDirectAssignmentError)
368
+ expect(obj.aasm_state.to_sym).to eql :pending
369
+ end
370
+ end # direct assignment
381
371
 
382
- it 'should not store states for invalid models' do
383
- validator = MultipleValidator.create(:name => 'name')
384
- expect(validator).to be_valid
385
- expect(validator).to be_sleeping
372
+ describe 'initial states' do
373
+ it 'should support conditions' do
374
+ expect(MultipleThief.new(:skilled => true).aasm(:left).current_state).to eq(:rich)
375
+ expect(MultipleThief.new(:skilled => false).aasm(:left).current_state).to eq(:jailed)
376
+ end
377
+ end
386
378
 
387
- validator.name = nil
388
- expect(validator).not_to be_valid
389
- expect { validator.run! }.to raise_error(ActiveRecord::RecordInvalid)
390
- expect(validator).to be_sleeping
379
+ describe 'transitions with persistence' do
391
380
 
392
- validator.reload
393
- expect(validator).not_to be_running
394
- expect(validator).to be_sleeping
381
+ it "should work for valid models" do
382
+ valid_object = MultipleValidator.create(:name => 'name')
383
+ expect(valid_object).to be_sleeping
384
+ valid_object.status = :running
385
+ expect(valid_object).to be_running
386
+ end
395
387
 
396
- validator.name = 'another name'
397
- expect(validator).to be_valid
398
- expect(validator.run!).to be_truthy
399
- expect(validator).to be_running
388
+ it 'should not store states for invalid models' do
389
+ validator = MultipleValidator.create(:name => 'name')
390
+ expect(validator).to be_valid
391
+ expect(validator).to be_sleeping
400
392
 
401
- validator.reload
402
- expect(validator).to be_running
403
- expect(validator).not_to be_sleeping
404
- end
393
+ validator.name = nil
394
+ expect(validator).not_to be_valid
395
+ expect { validator.run! }.to raise_error(ActiveRecord::RecordInvalid)
396
+ expect(validator).to be_sleeping
405
397
 
406
- it 'should not store states for invalid models silently if configured' do
407
- validator = MultipleSilentPersistor.create(:name => 'name')
408
- expect(validator).to be_valid
409
- expect(validator).to be_sleeping
398
+ validator.reload
399
+ expect(validator).not_to be_running
400
+ expect(validator).to be_sleeping
410
401
 
411
- validator.name = nil
412
- expect(validator).not_to be_valid
413
- expect(validator.run!).to be_falsey
414
- expect(validator).to be_sleeping
402
+ validator.name = 'another name'
403
+ expect(validator).to be_valid
404
+ expect(validator.run!).to be_truthy
405
+ expect(validator).to be_running
415
406
 
416
- validator.reload
417
- expect(validator).not_to be_running
418
- expect(validator).to be_sleeping
407
+ validator.reload
408
+ expect(validator).to be_running
409
+ expect(validator).not_to be_sleeping
410
+ end
419
411
 
420
- validator.name = 'another name'
421
- expect(validator).to be_valid
422
- expect(validator.run!).to be_truthy
423
- expect(validator).to be_running
412
+ it 'should not store states for invalid models silently if configured' do
413
+ validator = MultipleSilentPersistor.create(:name => 'name')
414
+ expect(validator).to be_valid
415
+ expect(validator).to be_sleeping
424
416
 
425
- validator.reload
426
- expect(validator).to be_running
427
- expect(validator).not_to be_sleeping
428
- end
417
+ validator.name = nil
418
+ expect(validator).not_to be_valid
419
+ expect(validator.run!).to be_falsey
420
+ expect(validator).to be_sleeping
429
421
 
430
- it 'should store states for invalid models if configured' do
431
- persistor = MultipleInvalidPersistor.create(:name => 'name')
432
- expect(persistor).to be_valid
433
- expect(persistor).to be_sleeping
434
-
435
- persistor.name = nil
436
- expect(persistor).not_to be_valid
437
- expect(persistor.run!).to be_truthy
438
- expect(persistor).to be_running
439
-
440
- persistor = MultipleInvalidPersistor.find(persistor.id)
441
- persistor.valid?
442
- expect(persistor).to be_valid
443
- expect(persistor).to be_running
444
- expect(persistor).not_to be_sleeping
445
-
446
- persistor.reload
447
- expect(persistor).to be_running
448
- expect(persistor).not_to be_sleeping
449
- end
422
+ validator.reload
423
+ expect(validator).not_to be_running
424
+ expect(validator).to be_sleeping
450
425
 
451
- describe 'transactions' do
452
- let(:worker) { Worker.create!(:name => 'worker', :status => 'sleeping') }
453
- let(:transactor) { MultipleTransactor.create!(:name => 'transactor', :worker => worker) }
426
+ validator.name = 'another name'
427
+ expect(validator).to be_valid
428
+ expect(validator.run!).to be_truthy
429
+ expect(validator).to be_running
454
430
 
455
- it 'should rollback all changes' do
456
- expect(transactor).to be_sleeping
457
- expect(worker.status).to eq('sleeping')
431
+ validator.reload
432
+ expect(validator).to be_running
433
+ expect(validator).not_to be_sleeping
434
+ end
458
435
 
459
- expect {transactor.run!}.to raise_error(StandardError, 'failed on purpose')
460
- expect(transactor).to be_running
461
- expect(worker.reload.status).to eq('sleeping')
436
+ it 'should store states for invalid models if configured' do
437
+ persistor = MultipleInvalidPersistor.create(:name => 'name')
438
+ expect(persistor).to be_valid
439
+ expect(persistor).to be_sleeping
440
+
441
+ persistor.name = nil
442
+ expect(persistor).not_to be_valid
443
+ expect(persistor.run!).to be_truthy
444
+ expect(persistor).to be_running
445
+
446
+ persistor = MultipleInvalidPersistor.find(persistor.id)
447
+ persistor.valid?
448
+ expect(persistor).to be_valid
449
+ expect(persistor).to be_running
450
+ expect(persistor).not_to be_sleeping
451
+
452
+ persistor.reload
453
+ expect(persistor).to be_running
454
+ expect(persistor).not_to be_sleeping
462
455
  end
463
456
 
464
- context "nested transactions" do
465
- it "should rollback all changes in nested transaction" do
457
+ describe 'transactions' do
458
+ let(:worker) { Worker.create!(:name => 'worker', :status => 'sleeping') }
459
+ let(:transactor) { MultipleTransactor.create!(:name => 'transactor', :worker => worker) }
460
+
461
+ it 'should rollback all changes' do
466
462
  expect(transactor).to be_sleeping
467
463
  expect(worker.status).to eq('sleeping')
468
464
 
469
- Worker.transaction do
470
- expect { transactor.run! }.to raise_error(StandardError, 'failed on purpose')
471
- end
472
-
465
+ expect {transactor.run!}.to raise_error(StandardError, 'failed on purpose')
473
466
  expect(transactor).to be_running
474
467
  expect(worker.reload.status).to eq('sleeping')
475
468
  end
476
469
 
477
- it "should only rollback changes in the main transaction not the nested one" do
478
- # change configuration to not require new transaction
479
- AASM::StateMachineStore[MultipleTransactor][:left].config.requires_new_transaction = false
470
+ context "nested transactions" do
471
+ it "should rollback all changes in nested transaction" do
472
+ expect(transactor).to be_sleeping
473
+ expect(worker.status).to eq('sleeping')
480
474
 
481
- expect(transactor).to be_sleeping
482
- expect(worker.status).to eq('sleeping')
475
+ Worker.transaction do
476
+ expect { transactor.run! }.to raise_error(StandardError, 'failed on purpose')
477
+ end
483
478
 
484
- Worker.transaction do
485
- expect { transactor.run! }.to raise_error(StandardError, 'failed on purpose')
479
+ expect(transactor).to be_running
480
+ expect(worker.reload.status).to eq('sleeping')
486
481
  end
487
482
 
488
- expect(transactor).to be_running
489
- expect(worker.reload.status).to eq('running')
490
- end
491
- end
483
+ it "should only rollback changes in the main transaction not the nested one" do
484
+ # change configuration to not require new transaction
485
+ AASM::StateMachineStore[MultipleTransactor][:left].config.requires_new_transaction = false
492
486
 
493
- describe "after_commit callback" do
494
- it "should fire :after_commit if transaction was successful" do
495
- validator = MultipleValidator.create(:name => 'name')
496
- expect(validator).to be_sleeping
487
+ expect(transactor).to be_sleeping
488
+ expect(worker.status).to eq('sleeping')
497
489
 
498
- validator.run!
499
- expect(validator).to be_running
500
- expect(validator.name).to eq("name changed")
490
+ Worker.transaction do
491
+ expect { transactor.run! }.to raise_error(StandardError, 'failed on purpose')
492
+ end
501
493
 
502
- validator.sleep!("sleeper")
503
- expect(validator).to be_sleeping
504
- expect(validator.name).to eq("sleeper")
494
+ expect(transactor).to be_running
495
+ expect(worker.reload.status).to eq('running')
496
+ end
505
497
  end
506
498
 
507
- it "should not fire :after_commit if transaction failed" do
508
- validator = MultipleValidator.create(:name => 'name')
509
- expect { validator.fail! }.to raise_error(StandardError, 'failed on purpose')
510
- expect(validator.name).to eq("name")
511
- end
499
+ describe "after_commit callback" do
500
+ it "should fire :after_commit if transaction was successful" do
501
+ validator = MultipleValidator.create(:name => 'name')
502
+ expect(validator).to be_sleeping
512
503
 
513
- it "should not fire if not saving" do
514
- validator = MultipleValidator.create(:name => 'name')
515
- expect(validator).to be_sleeping
516
- validator.run
517
- expect(validator).to be_running
518
- expect(validator.name).to eq("name")
519
- end
504
+ validator.run!
505
+ expect(validator).to be_running
506
+ expect(validator.name).to eq("name changed")
520
507
 
521
- end
508
+ validator.sleep!("sleeper")
509
+ expect(validator).to be_sleeping
510
+ expect(validator.name).to eq("sleeper")
511
+ end
522
512
 
523
- context "when not persisting" do
524
- it 'should not rollback all changes' do
525
- expect(transactor).to be_sleeping
526
- expect(worker.status).to eq('sleeping')
513
+ it "should not fire :after_commit if transaction failed" do
514
+ validator = MultipleValidator.create(:name => 'name')
515
+ expect { validator.fail! }.to raise_error(StandardError, 'failed on purpose')
516
+ expect(validator.name).to eq("name")
517
+ end
518
+
519
+ it "should not fire if not saving" do
520
+ validator = MultipleValidator.create(:name => 'name')
521
+ expect(validator).to be_sleeping
522
+ validator.run
523
+ expect(validator).to be_running
524
+ expect(validator.name).to eq("name")
525
+ end
527
526
 
528
- # Notice here we're calling "run" and not "run!" with a bang.
529
- expect {transactor.run}.to raise_error(StandardError, 'failed on purpose')
530
- expect(transactor).to be_running
531
- expect(worker.reload.status).to eq('running')
532
527
  end
533
528
 
534
- it 'should not create a database transaction' do
535
- expect(transactor.class).not_to receive(:transaction)
536
- expect {transactor.run}.to raise_error(StandardError, 'failed on purpose')
529
+ context "when not persisting" do
530
+ it 'should not rollback all changes' do
531
+ expect(transactor).to be_sleeping
532
+ expect(worker.status).to eq('sleeping')
533
+
534
+ # Notice here we're calling "run" and not "run!" with a bang.
535
+ expect {transactor.run}.to raise_error(StandardError, 'failed on purpose')
536
+ expect(transactor).to be_running
537
+ expect(worker.reload.status).to eq('running')
538
+ end
539
+
540
+ it 'should not create a database transaction' do
541
+ expect(transactor.class).not_to receive(:transaction)
542
+ expect {transactor.run}.to raise_error(StandardError, 'failed on purpose')
543
+ end
537
544
  end
538
545
  end
539
546
  end
540
- end
541
547
 
542
- describe "invalid states with persistence" do
543
- it "should not store states" do
544
- validator = MultipleValidator.create(:name => 'name')
545
- validator.status = 'invalid_state'
546
- expect(validator.save).to be_falsey
547
- expect {validator.save!}.to raise_error(ActiveRecord::RecordInvalid)
548
+ describe "invalid states with persistence" do
549
+ it "should not store states" do
550
+ validator = MultipleValidator.create(:name => 'name')
551
+ validator.status = 'invalid_state'
552
+ expect(validator.save).to be_falsey
553
+ expect {validator.save!}.to raise_error(ActiveRecord::RecordInvalid)
548
554
 
549
- validator.reload
550
- expect(validator).to be_sleeping
551
- end
555
+ validator.reload
556
+ expect(validator).to be_sleeping
557
+ end
552
558
 
553
- it "should store invalid states if configured" do
554
- persistor = MultipleInvalidPersistor.create(:name => 'name')
555
- persistor.status = 'invalid_state'
556
- expect(persistor.save).to be_truthy
559
+ it "should store invalid states if configured" do
560
+ persistor = MultipleInvalidPersistor.create(:name => 'name')
561
+ persistor.status = 'invalid_state'
562
+ expect(persistor.save).to be_truthy
557
563
 
558
- persistor.reload
559
- expect(persistor.status).to eq('invalid_state')
564
+ persistor.reload
565
+ expect(persistor.status).to eq('invalid_state')
566
+ end
560
567
  end
561
- end
562
568
 
563
- describe "complex example" do
564
- it "works" do
565
- record = ComplexActiveRecordExample.new
566
- expect_aasm_states record, :one, :alpha
567
-
568
- record.save!
569
- expect_aasm_states record, :one, :alpha
570
- record.reload
571
- expect_aasm_states record, :one, :alpha
572
-
573
- record.increment!
574
- expect_aasm_states record, :two, :alpha
575
- record.reload
576
- expect_aasm_states record, :two, :alpha
577
-
578
- record.level_up!
579
- expect_aasm_states record, :two, :beta
580
- record.reload
581
- expect_aasm_states record, :two, :beta
582
-
583
- record.increment!
584
- expect { record.increment! }.to raise_error(AASM::InvalidTransition)
585
- expect_aasm_states record, :three, :beta
586
- record.reload
587
- expect_aasm_states record, :three, :beta
588
-
589
- record.level_up!
590
- expect_aasm_states record, :three, :gamma
591
- record.reload
592
- expect_aasm_states record, :three, :gamma
593
-
594
- record.level_down # without saving
595
- expect_aasm_states record, :three, :beta
596
- record.reload
597
- expect_aasm_states record, :three, :gamma
598
-
599
- record.level_down # without saving
600
- expect_aasm_states record, :three, :beta
601
- record.reset!
602
- expect_aasm_states record, :one, :beta
603
- end
569
+ describe "complex example" do
570
+ it "works" do
571
+ record = ComplexActiveRecordExample.new
572
+ expect_aasm_states record, :one, :alpha
573
+
574
+ record.save!
575
+ expect_aasm_states record, :one, :alpha
576
+ record.reload
577
+ expect_aasm_states record, :one, :alpha
578
+
579
+ record.increment!
580
+ expect_aasm_states record, :two, :alpha
581
+ record.reload
582
+ expect_aasm_states record, :two, :alpha
583
+
584
+ record.level_up!
585
+ expect_aasm_states record, :two, :beta
586
+ record.reload
587
+ expect_aasm_states record, :two, :beta
588
+
589
+ record.increment!
590
+ expect { record.increment! }.to raise_error(AASM::InvalidTransition)
591
+ expect_aasm_states record, :three, :beta
592
+ record.reload
593
+ expect_aasm_states record, :three, :beta
594
+
595
+ record.level_up!
596
+ expect_aasm_states record, :three, :gamma
597
+ record.reload
598
+ expect_aasm_states record, :three, :gamma
599
+
600
+ record.level_down # without saving
601
+ expect_aasm_states record, :three, :beta
602
+ record.reload
603
+ expect_aasm_states record, :three, :gamma
604
+
605
+ record.level_down # without saving
606
+ expect_aasm_states record, :three, :beta
607
+ record.reset!
608
+ expect_aasm_states record, :one, :beta
609
+ end
604
610
 
605
- def expect_aasm_states(record, left_state, right_state)
606
- expect(record.aasm(:left).current_state).to eql left_state.to_sym
607
- expect(record.left).to eql left_state.to_s
608
- expect(record.aasm(:right).current_state).to eql right_state.to_sym
609
- expect(record.right).to eql right_state.to_s
611
+ def expect_aasm_states(record, left_state, right_state)
612
+ expect(record.aasm(:left).current_state).to eql left_state.to_sym
613
+ expect(record.left).to eql left_state.to_s
614
+ expect(record.aasm(:right).current_state).to eql right_state.to_sym
615
+ expect(record.right).to eql right_state.to_s
616
+ end
610
617
  end
611
618
  end