snusnu-dm-accepts_nested_attributes 0.0.1

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.
@@ -0,0 +1,454 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ describe "DataMapper::Model.accepts_nested_attributes_for" do
5
+
6
+ before(:each) do
7
+
8
+ # don't use the originally defined fixtures but provide new ones,
9
+ # this time without already calling accepts_nested_attributes_for on them.
10
+ # this helps speccing the exact behavior of this very method call
11
+
12
+ Object.send(:remove_const, 'Branch') if Object.const_defined?('Branch')
13
+ Object.send(:remove_const, 'Shop') if Object.const_defined?('Shop')
14
+ Object.send(:remove_const, 'Item') if Object.const_defined?('Item')
15
+ Object.send(:remove_const, 'Booking') if Object.const_defined?('Booking')
16
+
17
+ class Branch
18
+ include DataMapper::Resource
19
+ property :id, Serial
20
+ has 1, :shop
21
+ has n, :items
22
+ has n, :bookings, :through => :items
23
+ end
24
+
25
+ class Shop
26
+ include DataMapper::Resource
27
+ property :id, Serial
28
+ property :branch_id, Integer
29
+ belongs_to :branch
30
+ end
31
+
32
+ class Item
33
+ include DataMapper::Resource
34
+ property :id, Serial
35
+ property :branch_id, Integer
36
+ belongs_to :branch
37
+ has n, :bookings
38
+ end
39
+
40
+ class Booking
41
+ include DataMapper::Resource
42
+ property :id, Serial
43
+ property :item_id, Integer
44
+ belongs_to :item
45
+ end
46
+
47
+ DataMapper.auto_migrate!
48
+
49
+ end
50
+
51
+
52
+ describe "when called with" do
53
+
54
+ describe "no association_name" do
55
+
56
+ describe "and no options" do
57
+
58
+ it "should raise" do
59
+ lambda { Branch.accepts_nested_attributes_for }.should raise_error(ArgumentError)
60
+ end
61
+
62
+ end
63
+
64
+ describe "and empty options" do
65
+
66
+ it "should raise" do
67
+ lambda { Branch.accepts_nested_attributes_for({}) }.should raise_error(ArgumentError)
68
+ end
69
+
70
+ end
71
+
72
+ describe "and invalid options" do
73
+
74
+ it "should raise" do
75
+ lambda { Branch.accepts_nested_attributes_for({ :foo => :bar}) }.should raise_error(ArgumentError)
76
+ end
77
+
78
+ end
79
+
80
+ describe "and valid options" do
81
+
82
+ it "should raise" do
83
+ lambda { Branch.accepts_nested_attributes_for({ :allow_destroy => true}) }.should raise_error(ArgumentError)
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+ describe "nil as association_name" do
91
+
92
+ describe "and no options" do
93
+
94
+ it "should raise" do
95
+ lambda { Branch.accepts_nested_attributes_for(nil) }.should raise_error(ArgumentError)
96
+ end
97
+
98
+ end
99
+
100
+ describe "and empty options" do
101
+
102
+ it "should raise" do
103
+ lambda { Branch.accepts_nested_attributes_for(nil, {}) }.should raise_error(ArgumentError)
104
+ end
105
+
106
+ end
107
+
108
+ describe "and invalid options" do
109
+
110
+ it "should raise" do
111
+ lambda { Branch.accepts_nested_attributes_for(nil, { :foo => :bar }) }.should raise_error(ArgumentError)
112
+ end
113
+
114
+ end
115
+
116
+ describe "and valid options" do
117
+
118
+ it "should raise" do
119
+ lambda { Branch.accepts_nested_attributes_for(nil, { :allow_destroy => true }) }.should raise_error(ArgumentError)
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ describe "an invalid association_name" do
127
+
128
+ describe "and no options" do
129
+
130
+ it "should raise" do
131
+ lambda { Branch.accepts_nested_attributes_for(:foo) }.should raise_error(ArgumentError)
132
+ end
133
+
134
+ end
135
+
136
+ describe "and empty options" do
137
+
138
+ it "should raise" do
139
+ lambda { Branch.accepts_nested_attributes_for(:foo, {}) }.should raise_error(ArgumentError)
140
+ end
141
+
142
+ end
143
+
144
+ describe "and invalid options" do
145
+
146
+ it "should raise" do
147
+ lambda { Branch.accepts_nested_attributes_for(:foo, { :foo => :bar }) }.should raise_error(ArgumentError)
148
+ end
149
+
150
+ end
151
+
152
+ describe "and valid options" do
153
+
154
+ it "should raise" do
155
+ lambda { Branch.accepts_nested_attributes_for(:foo, { :allow_destroy => true }) }.should raise_error(ArgumentError)
156
+ end
157
+
158
+ end
159
+
160
+ end
161
+
162
+
163
+ describe "a valid association_name", :shared => true do
164
+
165
+
166
+ describe "and no options" do
167
+
168
+ it "should not raise" do
169
+ lambda { @model.accepts_nested_attributes_for @association }.should_not raise_error
170
+ end
171
+
172
+ it "should store the accessible association in .autosave_associations" do
173
+ @model.autosave_associations[@association].should be_nil
174
+ @model.accepts_nested_attributes_for @association
175
+ @model.autosave_associations[@association].should_not be_nil
176
+ end
177
+
178
+ it "should store the default options under the association_name in .autosave_associations" do
179
+ @model.autosave_associations[@association].should be_nil
180
+ @model.accepts_nested_attributes_for @association
181
+ @model.autosave_associations[@association].should == { :allow_destroy => false }
182
+ end
183
+
184
+ it "should create a \#{association_name}_attributes instance writer" do
185
+ p = @model.new
186
+ p.respond_to?("#{@association}_attributes=").should be_false
187
+ @model.accepts_nested_attributes_for @association
188
+ p = @model.new
189
+ p.respond_to?("#{@association}_attributes=").should be_true
190
+ end
191
+
192
+ end
193
+
194
+ describe "and empty options" do
195
+
196
+ it "should not raise" do
197
+ lambda { @model.accepts_nested_attributes_for @association, {} }.should_not raise_error
198
+ end
199
+
200
+ it "should store the accessible association in .autosave_associations" do
201
+ @model.autosave_associations[@association].should be_nil
202
+ @model.accepts_nested_attributes_for @association, {}
203
+ @model.autosave_associations[@association].should_not be_nil
204
+ end
205
+
206
+ it "should store the default options under the association_name in .autosave_associations" do
207
+ @model.autosave_associations[@association].should be_nil
208
+ @model.accepts_nested_attributes_for @association, {}
209
+ @model.autosave_associations[@association].should == { :allow_destroy => false }
210
+ end
211
+
212
+ it "should create a \#{association_name}_attributes instance writer" do
213
+ p = @model.new
214
+ p.respond_to?("#{@association}_attributes=").should be_false
215
+ @model.accepts_nested_attributes_for @association, {}
216
+ p = @model.new
217
+ p.respond_to?("#{@association}_attributes=").should be_true
218
+ end
219
+
220
+ end
221
+
222
+ describe "and invalid options" do
223
+
224
+ it "should raise" do
225
+ lambda { @model.accepts_nested_attributes_for @association, { :foo => :bar } }.should raise_error
226
+ end
227
+
228
+ it "should not store the accessible association in .autosave_associations" do
229
+ @model.autosave_associations[@association].should be_nil
230
+ lambda { @model.accepts_nested_attributes_for @association, { :foo => :bar } }.should raise_error
231
+ @model.autosave_associations[@association].should be_nil
232
+ end
233
+
234
+ it "should not create a \#{association_name}_attributes instance writer" do
235
+ p = @model.new
236
+ p.respond_to?("#{@association}_attributes=").should be_false
237
+ lambda { @model.accepts_nested_attributes_for @association, { :foo => :bar } }.should raise_error
238
+ p = @model.new
239
+ p.respond_to?("#{@association}_attributes=").should be_false
240
+ end
241
+
242
+ end
243
+
244
+ describe "and valid options" do
245
+
246
+ it "should not raise" do
247
+ lambda { @model.accepts_nested_attributes_for @association, :allow_destroy => true }.should_not raise_error
248
+ end
249
+
250
+ it "should store the accessible association in .autosave_associations" do
251
+ @model.autosave_associations[@association].should be_nil
252
+ @model.accepts_nested_attributes_for @association, :allow_destroy => true
253
+ @model.autosave_associations[@association].should_not be_nil
254
+ end
255
+
256
+ it "should accept :allow_destroy as the only option (and thus overwrite the default option)" do
257
+ @model.autosave_associations[@association].should be_nil
258
+ @model.accepts_nested_attributes_for @association, :allow_destroy => true
259
+ @model.autosave_associations[@association].should == { :allow_destroy => true }
260
+ end
261
+
262
+ it "should accept :reject_if as the only option (and add :allow_destroy => false)" do
263
+ @model.autosave_associations[@association].should be_nil
264
+ @model.accepts_nested_attributes_for @association, :reject_if => lambda { |attributes| nil }
265
+ @model.autosave_associations[@association].should_not be_nil
266
+ @model.autosave_associations[@association][:allow_destroy].should be_false
267
+ @model.autosave_associations[@association][:reject_if].should be_kind_of(Proc)
268
+ @model.reject_new_nested_attributes_proc_for(@association).should be_kind_of(Proc)
269
+ end
270
+
271
+ it "should accept both :allow_destroy and :reject_if as options" do
272
+ @model.autosave_associations[@association].should be_nil
273
+ @model.accepts_nested_attributes_for @association, :allow_destroy => true, :reject_if => lambda { |attributes| nil }
274
+ @model.autosave_associations[@association].should_not be_nil
275
+ @model.autosave_associations[@association][:allow_destroy].should be_true
276
+ @model.autosave_associations[@association][:reject_if].should be_kind_of(Proc)
277
+ @model.reject_new_nested_attributes_proc_for(@association).should be_kind_of(Proc)
278
+ end
279
+
280
+ it "should create a \#{association_name}_attributes instance writer" do
281
+ p = @model.new
282
+ p.respond_to?("#{@association}_attributes=").should be_false
283
+ @model.accepts_nested_attributes_for @association, :allow_destroy => true
284
+ p = @model.new
285
+ p.respond_to?("#{@association}_attributes=").should be_true
286
+ end
287
+
288
+ end
289
+
290
+ end
291
+
292
+ describe "a valid association_name pointing to a single resource", :shared => true do
293
+
294
+ describe "and no options" do
295
+
296
+ it "should create a get_\#{association_name} instance reader" do
297
+ p = @model.new
298
+ p.respond_to?("get_#{@association}").should be_false
299
+ @model.accepts_nested_attributes_for @association
300
+ p = @model.new
301
+ p.respond_to?("get_#{@association}").should be_true
302
+ p.send("get_#{@association}").should_not be_nil
303
+ end
304
+
305
+ end
306
+
307
+ describe "and empty options" do
308
+
309
+ it "should create a get_\#{association_name} instance reader" do
310
+ p = @model.new
311
+ p.respond_to?("get_#{@association}").should be_false
312
+ @model.accepts_nested_attributes_for @association, {}
313
+ p = @model.new
314
+ p.respond_to?("get_#{@association}").should be_true
315
+ p.send("get_#{@association}").should_not be_nil
316
+ end
317
+
318
+ end
319
+
320
+ describe "and invalid options" do
321
+
322
+ it "should not create a get_\#{association_name} instance reader" do
323
+ p = @model.new
324
+ p.respond_to?("get_#{@association}").should be_false
325
+ lambda { @model.accepts_nested_attributes_for @association, { :foo => :bar } }.should raise_error
326
+ p = @model.new
327
+ p.respond_to?("get_#{@association}").should be_false
328
+ end
329
+
330
+ end
331
+
332
+ describe "and valid options" do
333
+
334
+ it "should create a get_\#{association_name} instance reader" do
335
+ p = @model.new
336
+ p.respond_to?("get_#{@association}").should be_false
337
+ @model.accepts_nested_attributes_for @association, :allow_destroy => true
338
+ p = @model.new
339
+ p.respond_to?("get_#{@association}").should be_true
340
+ p.send("get_#{@association}").should_not be_nil
341
+ end
342
+
343
+ end
344
+
345
+ end
346
+
347
+ describe "a valid association_name pointing to multiple resources", :shared => true do
348
+
349
+ describe "and no options" do
350
+
351
+ it "should not create a get_\#{association_name} instance reader" do
352
+ p = @model.new
353
+ p.respond_to?("get_#{@association}").should be_false
354
+ lambda { @model.accepts_nested_attributes_for @association }.should_not raise_error
355
+ p = @model.new
356
+ p.respond_to?("get_#{@association}").should be_false
357
+ end
358
+
359
+ end
360
+
361
+ describe "and empty options" do
362
+
363
+ it "should not create a get_\#{association_name} instance reader" do
364
+ p = @model.new
365
+ p.respond_to?("get_#{@association}").should be_false
366
+ lambda { @model.accepts_nested_attributes_for @association, {} }.should_not raise_error
367
+ p = @model.new
368
+ p.respond_to?("get_#{@association}").should be_false
369
+ end
370
+
371
+ end
372
+
373
+ describe "and invalid options" do
374
+
375
+ it "should not create a get_\#{association_name} instance reader" do
376
+ p = @model.new
377
+ p.respond_to?("get_#{@association}").should be_false
378
+ lambda { @model.accepts_nested_attributes_for @association, { :foo => :bar } }.should raise_error
379
+ p = @model.new
380
+ p.respond_to?("get_#{@association}").should be_false
381
+ end
382
+
383
+ end
384
+
385
+ describe "and valid options" do
386
+
387
+ it "should not create a get_\#{association_name} instance reader" do
388
+ p = @model.new
389
+ p.respond_to?("get_#{@association}").should be_false
390
+ lambda { @model.accepts_nested_attributes_for @association, { :allow_destroy => :true } }.should_not raise_error
391
+ p = @model.new
392
+ p.respond_to?("get_#{@association}").should be_false
393
+ end
394
+
395
+ end
396
+
397
+ end
398
+
399
+ # ----------------------------------------------------------------------------------------
400
+ # ----------------------------------------------------------------------------------------
401
+ # ----------------------------------------------------------------------------------------
402
+
403
+
404
+ describe "a valid belongs_to association_name" do
405
+
406
+ before(:each) do
407
+ @model = Item
408
+ @association = :branch
409
+ end
410
+
411
+ it_should_behave_like "a valid association_name"
412
+ it_should_behave_like "a valid association_name pointing to a single resource"
413
+
414
+ end
415
+
416
+ describe "a valid has(1) association_name" do
417
+
418
+ before(:each) do
419
+ @model = Branch
420
+ @association = :shop
421
+ end
422
+
423
+ it_should_behave_like "a valid association_name"
424
+ it_should_behave_like "a valid association_name pointing to a single resource"
425
+
426
+ end
427
+
428
+ describe "a valid has(n) association_name" do
429
+
430
+ before(:each) do
431
+ @model = Branch
432
+ @association = :items
433
+ end
434
+
435
+ it_should_behave_like "a valid association_name"
436
+ it_should_behave_like "a valid association_name pointing to multiple resources"
437
+
438
+ end
439
+
440
+ describe "a valid has(n, :through) association_name" do
441
+
442
+ before(:each) do
443
+ @model = Branch
444
+ @association = :bookings
445
+ end
446
+
447
+ it_should_behave_like "a valid association_name"
448
+ it_should_behave_like "a valid association_name pointing to multiple resources"
449
+
450
+ end
451
+
452
+ end
453
+
454
+ end