embedson 1.0.2 → 1.0.3
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.
- checksums.yaml +13 -5
- data/LICENSE.txt +1 -1
- data/README.md +3 -0
- data/TODO.md +5 -0
- data/lib/embedson/exceptions.rb +8 -7
- data/lib/embedson/model/embedded_builder.rb +73 -50
- data/lib/embedson/model/embeds_builder.rb +33 -28
- data/lib/embedson/model/method_builder.rb +8 -23
- data/lib/embedson/model.rb +44 -0
- data/lib/embedson/version.rb +1 -1
- data/spec/embedson/exceptions_spec.rb +25 -0
- data/spec/embedson/model/embedded_builder_spec.rb +485 -0
- data/spec/embedson/model_spec.rb +70 -64
- metadata +28 -23
@@ -0,0 +1,485 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Embedson::Model::EmbeddedBuilder do
|
4
|
+
|
5
|
+
with_model :Parent do
|
6
|
+
table do |t|
|
7
|
+
t.json :son_col
|
8
|
+
t.json :emb_col
|
9
|
+
end
|
10
|
+
|
11
|
+
model do
|
12
|
+
embeds_one :son, column_name: :son_col
|
13
|
+
embeds_one :emb, class_name: Son, inverse_of: :parenta, column_name: :emb_col
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
with_model :ParentTwo do
|
18
|
+
table do |t|
|
19
|
+
t.json :son_col
|
20
|
+
end
|
21
|
+
|
22
|
+
model do
|
23
|
+
embeds_one :son, column_name: :son_col
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Son
|
28
|
+
extend Embedson::Model
|
29
|
+
|
30
|
+
def initialize(hash = nil)
|
31
|
+
@table = {}
|
32
|
+
return unless hash
|
33
|
+
hash.each do |k,v|
|
34
|
+
@table[k.to_sym] = v
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def change=(arg)
|
39
|
+
@table['change'] = arg
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_h
|
43
|
+
@table
|
44
|
+
end
|
45
|
+
|
46
|
+
embedded_in :parent
|
47
|
+
embedded_in :parenta, class_name: 'Parent', inverse_of: :emb
|
48
|
+
embedded_in :parent_two
|
49
|
+
end
|
50
|
+
|
51
|
+
let(:different) { { 'different' => 'true' } }
|
52
|
+
let(:parent) { Parent.new(son_col: different, emb_col: different) }
|
53
|
+
let(:parent_two) { ParentTwo.new(son_col: different) }
|
54
|
+
let(:son) { Son.new(something: { 'to' => 'write' }, parent: parent, parenta: parent) }
|
55
|
+
|
56
|
+
describe 'defined .parent_send_to_related' do
|
57
|
+
context 'when parent responds to son' do
|
58
|
+
context 'and to_h is different than parents son.to_h' do
|
59
|
+
before do
|
60
|
+
son
|
61
|
+
parent.send(:write_attribute, :son_col, different)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'changes parents son_col to son.to_h' do
|
65
|
+
expect{
|
66
|
+
son.send(:parent_send_to_related, son)
|
67
|
+
}.to change { parent.son_col }.from('different' => 'true').to(son.to_h.stringify_keys)
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'and to_h is equal parents embeded.to_h' do
|
73
|
+
before do
|
74
|
+
son
|
75
|
+
parent.send(:write_attribute, :son_col, { something: { to: 'write' } } )
|
76
|
+
parent.save!
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does not register change on parent' do
|
80
|
+
expect {
|
81
|
+
son.send(:parent_send_to_related, son)
|
82
|
+
}.to_not change { parent.changes }
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when parent do not respond to son=' do
|
89
|
+
before do
|
90
|
+
allow(parent).to receive(:respond_to?).and_return(false)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'raises Embedson::NoRelationDefinedError' do
|
94
|
+
expect {
|
95
|
+
son.send(:parent_send_to_related, son)
|
96
|
+
}.to raise_error(Embedson::NoRelationDefinedError)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'defined .parenta_send_to_related' do
|
102
|
+
context 'when parent responds to emb' do
|
103
|
+
context 'and to_h is different than parents emb_col' do
|
104
|
+
before do
|
105
|
+
son
|
106
|
+
parent.send(:write_attribute, :emb_col, different)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'changes parents emb_col to son.to_h' do
|
110
|
+
expect{
|
111
|
+
son.send(:parenta_send_to_related, son)
|
112
|
+
}.to change { parent.emb_col }.from('different' => 'true').to(son.to_h.stringify_keys)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'and to_h is equal parents emb_col' do
|
118
|
+
before do
|
119
|
+
son
|
120
|
+
parent.send(:write_attribute, :son_col, { something: { to: 'write' } } )
|
121
|
+
parent.save!
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'does not register change on parent' do
|
125
|
+
expect {
|
126
|
+
son.send(:parenta_send_to_related, son)
|
127
|
+
}.to_not change { parent.changes }
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context 'when parent do not respond to emb=' do
|
134
|
+
before do
|
135
|
+
allow(parent).to receive(:respond_to?).and_return(false)
|
136
|
+
end
|
137
|
+
|
138
|
+
it 'raises Embedson::NoRelationDefinedError' do
|
139
|
+
expect {
|
140
|
+
son.send(:parenta_send_to_related, son)
|
141
|
+
}.to raise_error(Embedson::NoRelationDefinedError)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe 'defined .save' do
|
147
|
+
let(:parent) { Parent.new() }
|
148
|
+
|
149
|
+
context 'when there is no parent' do
|
150
|
+
let(:son) { Son.new }
|
151
|
+
|
152
|
+
it 'returns false' do
|
153
|
+
expect(son.save).to eq(false)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when there are parents' do
|
158
|
+
let(:son) { Son.new(parent: parent, parent_two: parent_two, something: different) }
|
159
|
+
|
160
|
+
context 'and save on all returns true' do
|
161
|
+
it 'returns true' do
|
162
|
+
expect(son.save).to eq(true)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'and save on one of them fails' do
|
167
|
+
before do
|
168
|
+
allow(parent_two).to receive(:save).and_return(false)
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'returns false' do
|
172
|
+
expect(son.save).to be_falsy
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'does not change any of parents' do
|
176
|
+
parent.save!
|
177
|
+
parent_two.save!
|
178
|
+
expect{ son.save }.to_not change{ parent.reload.son_col }
|
179
|
+
expect(parent_two.reload.son_col).to eq different
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'and parent is new record' do
|
184
|
+
it 'saves all parents' do
|
185
|
+
parent
|
186
|
+
parent_two
|
187
|
+
expect(parent).to receive(:save).and_return(true)
|
188
|
+
expect(parent_two).to receive(:save).and_return(true)
|
189
|
+
son.save
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'saves son to parent' do
|
193
|
+
parent
|
194
|
+
parent_two
|
195
|
+
son.save
|
196
|
+
parent.reload
|
197
|
+
parent_two.reload
|
198
|
+
expect(parent.son).to eq son
|
199
|
+
expect(parent.emb).to be_nil
|
200
|
+
expect(parent_two.son).to eq son
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'and parent is persisted' do
|
205
|
+
let(:son) { Son.new(something: different, parent: parent, parent_two: parent_two) }
|
206
|
+
|
207
|
+
before do
|
208
|
+
parent.save!
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'changes column values' do
|
212
|
+
son.save
|
213
|
+
expect(parent.son_col).to eq('something' => different)
|
214
|
+
expect(parent.emb_col).to be_nil
|
215
|
+
expect(parent_two.son_col).to eq('something' => different)
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'and son is changed' do
|
219
|
+
it 'saves changes in parent' do
|
220
|
+
son.save!
|
221
|
+
expect {
|
222
|
+
son.change = 'new value'
|
223
|
+
son.save
|
224
|
+
}.to change { parent.reload.son_col }
|
225
|
+
.from('something' => different)
|
226
|
+
.to('something' => different, 'change' => 'new value')
|
227
|
+
expect(parent_two.son_col).to eq('something' => different, 'change' => 'new value')
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'and parent is one from many defined' do
|
233
|
+
let(:son) { Son.new(parent: parent) }
|
234
|
+
|
235
|
+
context 'and is new record' do
|
236
|
+
it 'calls save on parent once' do
|
237
|
+
parent
|
238
|
+
expect(parent).to receive(:save).once.and_return(true)
|
239
|
+
expect(son.save).to be_truthy
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'saves son to parent' do
|
243
|
+
parent
|
244
|
+
expect(son.save).to be_truthy
|
245
|
+
parent.reload
|
246
|
+
expect(parent.son).to eq son
|
247
|
+
expect(parent.emb).to be_nil
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context 'and is persisted' do
|
252
|
+
let(:son) { Son.new(something: different, parent: parent) }
|
253
|
+
|
254
|
+
before do
|
255
|
+
parent.save!
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'changes column values' do
|
259
|
+
expect(son.save).to be_truthy
|
260
|
+
expect(parent.son_col).to eq('something' => different)
|
261
|
+
expect(parent.emb_col).to be_nil
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe 'defined .save!' do
|
269
|
+
let(:parent) { Parent.new() }
|
270
|
+
|
271
|
+
context 'when there is no parent' do
|
272
|
+
let(:son) { Son.new }
|
273
|
+
|
274
|
+
it 'raises error' do
|
275
|
+
expect{ son.save! }.to raise_error(Embedson::NoParentError)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context 'when there are parents' do
|
280
|
+
let(:son) { Son.new(parent: parent, parent_two: parent_two) }
|
281
|
+
|
282
|
+
context 'and save on all returns true' do
|
283
|
+
it 'returns true' do
|
284
|
+
expect(son.save!).to eq(true)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'and save on one of them fails' do
|
289
|
+
before do
|
290
|
+
parent_two.save!
|
291
|
+
allow(parent_two).to receive(:save!).and_return(false)
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'returns false' do
|
295
|
+
expect(son.save!).to be_falsy
|
296
|
+
end
|
297
|
+
|
298
|
+
it 'does not change any of parents' do
|
299
|
+
parent.save!
|
300
|
+
expect{ son.save! }.to_not change{ parent.reload.son_col }
|
301
|
+
expect(parent_two.reload.son_col).to eq different
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context 'and parent is new record' do
|
306
|
+
it 'calls save! on all parents' do
|
307
|
+
parent
|
308
|
+
expect(parent).to receive(:save!).and_return(true)
|
309
|
+
expect(parent_two).to receive(:save!).and_return(true)
|
310
|
+
expect(son.save!).to be_truthy
|
311
|
+
end
|
312
|
+
|
313
|
+
it 'saves son to parent' do
|
314
|
+
parent
|
315
|
+
expect(son.save!).to be_truthy
|
316
|
+
parent.reload
|
317
|
+
expect(parent.son).to eq son
|
318
|
+
expect(parent.emb).to be_nil
|
319
|
+
expect(parent_two.reload.son).to eq son
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'and parent is persisted' do
|
324
|
+
let(:son) { Son.new(something: different, parent: parent, parent_two: parent_two) }
|
325
|
+
|
326
|
+
before do
|
327
|
+
parent.save!
|
328
|
+
parent_two.save!
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'changes column values' do
|
332
|
+
expect(son.save!).to be_truthy
|
333
|
+
parent.reload
|
334
|
+
expect(parent.son_col).to eq('something' => different)
|
335
|
+
expect(parent.emb_col).to be_nil
|
336
|
+
expect(parent_two.reload.son_col).to eq('something' => different)
|
337
|
+
end
|
338
|
+
|
339
|
+
context 'and son is changed' do
|
340
|
+
it 'saves changes in both relations' do
|
341
|
+
son.save!
|
342
|
+
expect {
|
343
|
+
son.change = 'new value'
|
344
|
+
son.save!
|
345
|
+
}.to change { parent.reload.son_col }
|
346
|
+
.from('something' => different)
|
347
|
+
.to('something' => different, 'change' => 'new value')
|
348
|
+
expect(parent_two.son_col).to eq('something' => different, 'change' => 'new value')
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context 'and parent is one from many defined' do
|
354
|
+
let(:son) { Son.new(parent: parent) }
|
355
|
+
|
356
|
+
context 'and is new record' do
|
357
|
+
it 'calls save! on parent once' do
|
358
|
+
parent
|
359
|
+
expect(parent).to receive(:save!).once.and_return(true)
|
360
|
+
expect(son.save!).to be_truthy
|
361
|
+
end
|
362
|
+
|
363
|
+
it 'saves son to parent' do
|
364
|
+
parent
|
365
|
+
expect(son.save!).to be_truthy
|
366
|
+
parent.reload
|
367
|
+
expect(parent.son).to eq son
|
368
|
+
expect(parent.emb).to be_nil
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
context 'and is persisted' do
|
373
|
+
let(:son) { Son.new(something: different, parent: parent) }
|
374
|
+
|
375
|
+
before do
|
376
|
+
parent.save!
|
377
|
+
end
|
378
|
+
|
379
|
+
it 'changes column values' do
|
380
|
+
expect(son.save!).to be_truthy
|
381
|
+
expect(parent.son_col).to eq('something' => different)
|
382
|
+
expect(parent.emb_col).to be_nil
|
383
|
+
end
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
describe 'defined .destroy' do
|
390
|
+
context 'when there is parent' do
|
391
|
+
let(:son) { Son.new(parent: parent, parent_two: parent_two) }
|
392
|
+
|
393
|
+
context 'and destroy on all returns true' do
|
394
|
+
it 'returns true' do
|
395
|
+
expect(son.destroy).to eq(true)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
context 'and save! on one of them fails' do
|
400
|
+
before do
|
401
|
+
parent_two.save!
|
402
|
+
allow(parent_two).to receive(:save!).and_return(false)
|
403
|
+
end
|
404
|
+
|
405
|
+
it 'returns false' do
|
406
|
+
expect(son.destroy).to be_falsy
|
407
|
+
end
|
408
|
+
|
409
|
+
it 'does not change any of parents' do
|
410
|
+
parent.save!
|
411
|
+
expect{ son.destroy }.to_not change{ parent.reload.son_col }
|
412
|
+
expect(parent_two.reload.son_col).to eq different
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context 'and is new record' do
|
417
|
+
|
418
|
+
it 'calls save! on all parents' do
|
419
|
+
parent
|
420
|
+
expect(parent).to receive(:save!).and_return(true)
|
421
|
+
expect(parent_two).to receive(:save!).and_return(true)
|
422
|
+
expect(son.destroy).to be_truthy
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'saves nil to all relations' do
|
426
|
+
parent
|
427
|
+
expect(son.destroy).to be_truthy
|
428
|
+
parent.reload
|
429
|
+
expect(parent.son).to be_nil
|
430
|
+
expect(parent.reload.son).to be_nil
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
context 'and is persisted' do
|
435
|
+
let(:son) { Son.new(something: different, parent: parent, parent_two: parent_two) }
|
436
|
+
|
437
|
+
before do
|
438
|
+
parent.save!
|
439
|
+
parent_two.save!
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'changes column values' do
|
443
|
+
expect(son.destroy).to be_truthy
|
444
|
+
expect(parent.reload.son_col).to be_nil
|
445
|
+
expect(parent_two.reload.son_col).to be_nil
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
context 'and parent is one from many defined' do
|
450
|
+
let(:son) { Son.new(parent: parent) }
|
451
|
+
|
452
|
+
context 'and is new record' do
|
453
|
+
it 'calls save! on parent once' do
|
454
|
+
parent
|
455
|
+
expect(parent).to receive(:save!).once.and_return(true)
|
456
|
+
expect(son.save!).to be_truthy
|
457
|
+
end
|
458
|
+
|
459
|
+
it 'saves nil to parent' do
|
460
|
+
parent
|
461
|
+
expect(son.destroy).to be_truthy
|
462
|
+
parent.reload
|
463
|
+
expect(parent.son).to be_nil
|
464
|
+
expect(parent.emb_col).to eq different
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
context 'and is persisted' do
|
469
|
+
let(:son) { Son.new(something: different, parent: parent) }
|
470
|
+
|
471
|
+
before do
|
472
|
+
parent.save!
|
473
|
+
end
|
474
|
+
|
475
|
+
it 'changes column values' do
|
476
|
+
expect(son.destroy).to be_truthy
|
477
|
+
parent.reload
|
478
|
+
expect(parent.son_col).to be_nil
|
479
|
+
expect(parent.emb_col).to eq different
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|