-
Notifications
You must be signed in to change notification settings - Fork 629
/
active_record_persistence_spec.rb
206 lines (162 loc) · 5.79 KB
/
active_record_persistence_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
require 'active_record'
require 'logger'
require 'spec_helper'
load_schema
# if you want to see the statements while running the spec enable the following line
# ActiveRecord::Base.logger = Logger.new(STDERR)
shared_examples_for "aasm model" do
it "should include persistence mixins" do
klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence)
klass.included_modules.should be_include(AASM::Persistence::ActiveRecordPersistence::InstanceMethods)
end
end
describe "instance methods" do
let(:gate) {Gate.new}
it "should respond to aasm persistence methods" do
gate.should respond_to(:aasm_read_state)
gate.should respond_to(:aasm_write_state)
gate.should respond_to(:aasm_write_state_without_persistence)
end
it "should return the initial state when new and the aasm field is nil" do
gate.aasm_current_state.should == :opened
end
it "should return the aasm column when new and the aasm field is not nil" do
gate.aasm_state = "closed"
gate.aasm_current_state.should == :closed
end
it "should return the aasm column when not new and the aasm_column is not nil" do
gate.stub!(:new_record?).and_return(false)
gate.aasm_state = "state"
gate.aasm_current_state.should == :state
end
it "should allow a nil state" do
gate.stub!(:new_record?).and_return(false)
gate.aasm_state = nil
gate.aasm_current_state.should be_nil
end
it "should call aasm_ensure_initial_state on validation before create" do
gate.should_receive(:aasm_ensure_initial_state).and_return(true)
gate.valid?
end
it "should not call aasm_ensure_initial_state on validation before update" do
gate.stub!(:new_record?).and_return(false)
gate.should_not_receive(:aasm_ensure_initial_state)
gate.valid?
end
end
describe 'subclasses' do
it "should have the same states as its parent class" do
Derivate.aasm_states.should == Simple.aasm_states
end
it "should have the same events as its parent class" do
Derivate.aasm_events.should == Simple.aasm_events
end
it "should have the same column as its parent class" do
Derivate.aasm_column.should == :status
end
it "should have the same column as its parent even for the new dsl" do
SimpleNewDsl.aasm_column.should == :status
DerivateNewDsl.aasm_column.should == :status
end
end
describe "named scopes with the old DSL" do
context "Does not already respond_to? the scope name" do
it "should add a scope" do
Simple.should respond_to(:unknown_scope)
SimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation).should be_true
end
end
context "Already respond_to? the scope name" do
it "should not add a scope" do
Simple.should respond_to(:new)
Simple.new.class.should == Simple
end
end
end
describe "named scopes with the new DSL" do
context "Does not already respond_to? the scope name" do
it "should add a scope" do
SimpleNewDsl.should respond_to(:unknown_scope)
SimpleNewDsl.unknown_scope.is_a?(ActiveRecord::Relation).should be_true
end
end
context "Already respond_to? the scope name" do
it "should not add a scope" do
SimpleNewDsl.should respond_to(:new)
SimpleNewDsl.new.class.should == SimpleNewDsl
end
end
it "does not create scopes if requested" do
NoScope.should_not respond_to(:ignored_scope)
end
end
describe 'initial states' do
it 'should support conditions' do
Thief.new(:skilled => true).aasm_current_state.should == :rich
Thief.new(:skilled => false).aasm_current_state.should == :jailed
end
end
describe 'transitions with persistence' do
it "should work for valid models" do
valid_object = Validator.create(:name => 'name')
valid_object.should be_sleeping
valid_object.status = :running
valid_object.should be_running
end
it 'should not store states for invalid models' do
validator = Validator.create(:name => 'name')
validator.should be_valid
validator.should be_sleeping
validator.name = nil
validator.should_not be_valid
validator.run!.should be_false
validator.should be_sleeping
validator.reload
validator.should_not be_running
validator.should be_sleeping
validator.name = 'another name'
validator.should be_valid
validator.run!.should be_true
validator.should be_running
validator.reload
validator.should be_running
validator.should_not be_sleeping
end
it 'should store states for invalid models if configured' do
persistor = InvalidPersistor.create(:name => 'name')
persistor.should be_valid
persistor.should be_sleeping
persistor.name = nil
persistor.should_not be_valid
persistor.run!.should be_true
persistor.should be_running
persistor = InvalidPersistor.find(persistor.id)
persistor.valid?
persistor.should be_valid
persistor.should be_running
persistor.should_not be_sleeping
persistor.reload
persistor.should be_running
persistor.should_not be_sleeping
end
describe 'transactions' do
let(:worker) { Worker.create!(:name => 'worker', :status => 'sleeping') }
let(:transactor) { Transactor.create!(:name => 'transactor', :worker => worker) }
it 'should rollback all changes' do
transactor.should be_sleeping
worker.status.should == 'sleeping'
lambda {transactor.run!}.should raise_error(StandardError, 'failed on purpose')
transactor.should be_running
worker.reload.status.should == 'sleeping'
end
it "should rollback all changes in nested transaction" do
transactor.should be_sleeping
worker.status.should == 'sleeping'
Worker.transaction do
lambda { transactor.run! }.should raise_error(StandardError, 'failed on purpose')
end
transactor.should be_running
worker.reload.status.should == 'sleeping'
end
end
end