snusnu-dm-accepts_nested_attributes 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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