dm-core 0.9.2 → 0.9.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.
- data/.autotest +26 -0
- data/{CHANGELOG → History.txt} +78 -77
- data/Manifest.txt +123 -0
- data/{README → README.txt} +0 -0
- data/Rakefile +29 -0
- data/SPECS +63 -0
- data/TODO +1 -0
- data/lib/dm-core.rb +6 -1
- data/lib/dm-core/adapters/data_objects_adapter.rb +29 -32
- data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
- data/lib/dm-core/adapters/postgres_adapter.rb +1 -1
- data/lib/dm-core/adapters/sqlite3_adapter.rb +2 -2
- data/lib/dm-core/associations.rb +26 -0
- data/lib/dm-core/associations/many_to_many.rb +34 -25
- data/lib/dm-core/associations/many_to_one.rb +4 -4
- data/lib/dm-core/associations/one_to_many.rb +48 -13
- data/lib/dm-core/associations/one_to_one.rb +4 -4
- data/lib/dm-core/associations/relationship.rb +144 -42
- data/lib/dm-core/associations/relationship_chain.rb +31 -24
- data/lib/dm-core/auto_migrations.rb +0 -4
- data/lib/dm-core/collection.rb +40 -7
- data/lib/dm-core/dependency_queue.rb +31 -0
- data/lib/dm-core/hook.rb +2 -2
- data/lib/dm-core/is.rb +2 -2
- data/lib/dm-core/logger.rb +10 -10
- data/lib/dm-core/model.rb +94 -41
- data/lib/dm-core/property.rb +72 -41
- data/lib/dm-core/property_set.rb +8 -14
- data/lib/dm-core/query.rb +34 -9
- data/lib/dm-core/repository.rb +0 -0
- data/lib/dm-core/resource.rb +13 -13
- data/lib/dm-core/scope.rb +25 -2
- data/lib/dm-core/type.rb +3 -3
- data/lib/dm-core/types/discriminator.rb +10 -8
- data/lib/dm-core/types/object.rb +4 -0
- data/lib/dm-core/types/paranoid_boolean.rb +15 -4
- data/lib/dm-core/types/paranoid_datetime.rb +15 -4
- data/lib/dm-core/version.rb +3 -0
- data/script/all +5 -0
- data/script/performance.rb +191 -0
- data/script/profile.rb +86 -0
- data/spec/integration/association_spec.rb +288 -204
- data/spec/integration/association_through_spec.rb +9 -3
- data/spec/integration/associations/many_to_many_spec.rb +97 -31
- data/spec/integration/associations/many_to_one_spec.rb +41 -6
- data/spec/integration/associations/one_to_many_spec.rb +18 -2
- data/spec/integration/auto_migrations_spec.rb +0 -0
- data/spec/integration/collection_spec.rb +89 -42
- data/spec/integration/dependency_queue_spec.rb +58 -0
- data/spec/integration/model_spec.rb +67 -8
- data/spec/integration/postgres_adapter_spec.rb +19 -20
- data/spec/integration/property_spec.rb +17 -8
- data/spec/integration/query_spec.rb +273 -191
- data/spec/integration/resource_spec.rb +108 -10
- data/spec/integration/strategic_eager_loading_spec.rb +138 -0
- data/spec/integration/transaction_spec.rb +3 -3
- data/spec/integration/type_spec.rb +121 -0
- data/spec/lib/logging_helper.rb +18 -0
- data/spec/lib/model_loader.rb +91 -0
- data/spec/lib/publicize_methods.rb +28 -0
- data/spec/models/vehicles.rb +34 -0
- data/spec/models/zoo.rb +48 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +25 -62
- data/spec/unit/adapters/data_objects_adapter_spec.rb +1 -0
- data/spec/unit/associations/many_to_many_spec.rb +3 -0
- data/spec/unit/associations/many_to_one_spec.rb +9 -1
- data/spec/unit/associations/one_to_many_spec.rb +12 -4
- data/spec/unit/associations/relationship_spec.rb +19 -15
- data/spec/unit/associations_spec.rb +37 -0
- data/spec/unit/collection_spec.rb +8 -0
- data/spec/unit/data_mapper_spec.rb +14 -0
- data/spec/unit/model_spec.rb +2 -2
- data/spec/unit/property_set_spec.rb +0 -13
- data/spec/unit/property_spec.rb +92 -21
- data/spec/unit/query_spec.rb +49 -4
- data/spec/unit/resource_spec.rb +122 -60
- data/spec/unit/scope_spec.rb +11 -0
- data/tasks/ci.rb +68 -0
- data/tasks/dm.rb +63 -0
- data/tasks/doc.rb +20 -0
- data/tasks/hoe.rb +38 -0
- data/tasks/install.rb +20 -0
- metadata +63 -22
@@ -1,8 +1,76 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
+
if HAS_SQLITE3
|
4
|
+
describe DataMapper::Associations do
|
5
|
+
before :all do
|
6
|
+
db1 = File.expand_path(File.join(File.dirname(__FILE__), "custom_db1_sqlite3.db"))
|
7
|
+
db2 = File.expand_path(File.join(File.dirname(__FILE__), "custom_db2_sqlite3.db"))
|
8
|
+
FileUtils.touch(db1)
|
9
|
+
FileUtils.touch(db2)
|
10
|
+
DataMapper.setup(:custom_db1, "sqlite3://#{db1}")
|
11
|
+
DataMapper.setup(:custom_db2, "sqlite3://#{db2}")
|
12
|
+
class CustomParent
|
13
|
+
include DataMapper::Resource
|
14
|
+
def self.default_repository_name
|
15
|
+
:custom_db1
|
16
|
+
end
|
17
|
+
property :id, Serial
|
18
|
+
property :name, String
|
19
|
+
repository(:custom_db2) do
|
20
|
+
has n, :custom_childs
|
21
|
+
end
|
22
|
+
end
|
23
|
+
class CustomChild
|
24
|
+
include DataMapper::Resource
|
25
|
+
def self.default_repository_name
|
26
|
+
:custom_db2
|
27
|
+
end
|
28
|
+
property :id, Serial
|
29
|
+
property :name, String
|
30
|
+
repository(:custom_db1) do
|
31
|
+
belongs_to :custom_parent
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
before :each do
|
37
|
+
[ CustomChild, CustomParent ].each { |m| m.auto_migrate! }
|
38
|
+
|
39
|
+
parent = CustomParent.create(:name => "mother")
|
40
|
+
child1 = parent.custom_childs.create(:name => "son")
|
41
|
+
child2 = parent.custom_childs.create(:name => "daughter")
|
42
|
+
|
43
|
+
@parent = CustomParent.first(:name => "mother")
|
44
|
+
@child1 = CustomChild.first(:name => "son")
|
45
|
+
@child2 = CustomChild.first(:name => "daughter")
|
46
|
+
end
|
47
|
+
it "should be able to handle has_many relationships to other repositories" do
|
48
|
+
@parent.custom_childs.size.should == 2
|
49
|
+
@parent.custom_childs.include?(@child1).should == true
|
50
|
+
@parent.custom_childs.include?(@child2).should == true
|
51
|
+
@parent.custom_childs.delete(@child1)
|
52
|
+
@parent.custom_childs.save
|
53
|
+
@parent.reload
|
54
|
+
@parent.custom_childs.size.should == 1
|
55
|
+
@parent.custom_childs.include?(@child2).should == true
|
56
|
+
end
|
57
|
+
it "should be able to handle belongs_to relationships to other repositories" do
|
58
|
+
@child1.custom_parent.should == @parent
|
59
|
+
@child2.custom_parent.should == @parent
|
60
|
+
@child1.custom_parent = nil
|
61
|
+
@child1.save
|
62
|
+
@child1.reload
|
63
|
+
@child1.custom_parent.should == nil
|
64
|
+
@parent.reload
|
65
|
+
@parent.custom_childs.size.should == 1
|
66
|
+
@parent.custom_childs.include?(@child2).should == true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
3
71
|
if ADAPTER
|
4
72
|
repository(ADAPTER) do
|
5
|
-
class
|
73
|
+
class Machine
|
6
74
|
include DataMapper::Resource
|
7
75
|
|
8
76
|
def self.default_repository_name
|
@@ -12,11 +80,11 @@ if ADAPTER
|
|
12
80
|
property :id, Serial
|
13
81
|
property :name, String
|
14
82
|
|
15
|
-
has n, :
|
16
|
-
has n, :
|
83
|
+
has n, :areas
|
84
|
+
has n, :fussy_areas, :class_name => 'Area', :rating.gte => 3, :type => 'particular'
|
17
85
|
end
|
18
86
|
|
19
|
-
class
|
87
|
+
class Area
|
20
88
|
include DataMapper::Resource
|
21
89
|
|
22
90
|
def self.default_repository_name
|
@@ -28,7 +96,7 @@ if ADAPTER
|
|
28
96
|
property :rating, Integer
|
29
97
|
property :type, String
|
30
98
|
|
31
|
-
belongs_to :
|
99
|
+
belongs_to :machine
|
32
100
|
end
|
33
101
|
|
34
102
|
class Pie
|
@@ -57,7 +125,7 @@ if ADAPTER
|
|
57
125
|
has 1, :pie
|
58
126
|
end
|
59
127
|
|
60
|
-
class
|
128
|
+
class Ultrahost
|
61
129
|
include DataMapper::Resource
|
62
130
|
|
63
131
|
def self.default_repository_name
|
@@ -67,10 +135,10 @@ if ADAPTER
|
|
67
135
|
property :id, Serial
|
68
136
|
property :name, String
|
69
137
|
|
70
|
-
has n, :
|
138
|
+
has n, :ultraslices, :order => [:id.desc]
|
71
139
|
end
|
72
140
|
|
73
|
-
class
|
141
|
+
class Ultraslice
|
74
142
|
include DataMapper::Resource
|
75
143
|
|
76
144
|
def self.default_repository_name
|
@@ -80,7 +148,7 @@ if ADAPTER
|
|
80
148
|
property :id, Serial
|
81
149
|
property :name, String
|
82
150
|
|
83
|
-
belongs_to :
|
151
|
+
belongs_to :ultrahost
|
84
152
|
end
|
85
153
|
|
86
154
|
class Node
|
@@ -108,8 +176,8 @@ if ADAPTER
|
|
108
176
|
property :title, String, :length => 255, :key => true
|
109
177
|
property :summary, DataMapper::Types::Text
|
110
178
|
|
111
|
-
has n, :tasks
|
112
|
-
has 1, :goal
|
179
|
+
has n, :tasks
|
180
|
+
has 1, :goal
|
113
181
|
end
|
114
182
|
|
115
183
|
class Goal
|
@@ -122,7 +190,7 @@ if ADAPTER
|
|
122
190
|
property :title, String, :length => 255, :key => true
|
123
191
|
property :summary, DataMapper::Types::Text
|
124
192
|
|
125
|
-
belongs_to :project
|
193
|
+
belongs_to :project
|
126
194
|
end
|
127
195
|
|
128
196
|
class Task
|
@@ -135,7 +203,7 @@ if ADAPTER
|
|
135
203
|
property :title, String, :length => 255, :key => true
|
136
204
|
property :description, DataMapper::Types::Text
|
137
205
|
|
138
|
-
belongs_to :project
|
206
|
+
belongs_to :project
|
139
207
|
end
|
140
208
|
end
|
141
209
|
|
@@ -187,8 +255,8 @@ if ADAPTER
|
|
187
255
|
end
|
188
256
|
|
189
257
|
it 'should allow namespaced classes in parent and child for one <=> one' do
|
190
|
-
g = Models::Goal.new(:title => "g2", :
|
191
|
-
p = Models::Project.create
|
258
|
+
g = Models::Goal.new(:title => "g2", :summary => "desc 2")
|
259
|
+
p = Models::Project.create(:title => "p2", :summary => "sum 2", :goal => g)
|
192
260
|
|
193
261
|
pp = Models::Project.first(:title => 'p2')
|
194
262
|
pp.goal.title.should == "g2"
|
@@ -204,30 +272,38 @@ if ADAPTER
|
|
204
272
|
|
205
273
|
describe 'many to one associations' do
|
206
274
|
before do
|
207
|
-
|
208
|
-
|
275
|
+
Machine.auto_migrate!(ADAPTER)
|
276
|
+
Area.auto_migrate!(ADAPTER)
|
209
277
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
278
|
+
machine1 = Machine.create(:name => 'machine1')
|
279
|
+
machine2 = Machine.create(:name => 'machine2')
|
280
|
+
area1 = Area.create(:name => 'area1', :machine => machine1)
|
281
|
+
area2 = Area.create(:name => 'area2')
|
214
282
|
end
|
215
283
|
|
216
284
|
it '#belongs_to' do
|
217
|
-
|
218
|
-
|
219
|
-
|
285
|
+
area = Area.new
|
286
|
+
area.should respond_to(:machine)
|
287
|
+
area.should respond_to(:machine=)
|
220
288
|
end
|
221
289
|
|
222
290
|
it 'should load without the parent'
|
223
291
|
|
224
292
|
it 'should allow substituting the parent' do
|
225
|
-
|
226
|
-
|
293
|
+
area1 = Area.first(:name => 'area1')
|
294
|
+
machine2 = Machine.first(:name => 'machine2')
|
227
295
|
|
228
|
-
|
229
|
-
|
230
|
-
|
296
|
+
area1.machine = machine2
|
297
|
+
area1.save
|
298
|
+
Area.first(:name => 'area1').machine.should == machine2
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'should save both the object and parent if both are new' do
|
302
|
+
pending "This is fixed"
|
303
|
+
area1 = Area.new(:name => 'area1')
|
304
|
+
area1.machine = Machine.new(:name => 'machine1')
|
305
|
+
area1.machine.save
|
306
|
+
area1.machine_id.should == area1.machine.id
|
231
307
|
end
|
232
308
|
|
233
309
|
it '#belongs_to with namespaced models' do
|
@@ -246,42 +322,42 @@ if ADAPTER
|
|
246
322
|
end
|
247
323
|
|
248
324
|
it 'should load the associated instance' do
|
249
|
-
|
250
|
-
|
325
|
+
machine1 = Machine.first(:name => 'machine1')
|
326
|
+
Area.first(:name => 'area1').machine.should == machine1
|
251
327
|
end
|
252
328
|
|
253
329
|
it 'should save the association key in the child' do
|
254
|
-
|
330
|
+
machine2 = Machine.first(:name => 'machine2')
|
255
331
|
|
256
|
-
|
257
|
-
|
332
|
+
Area.create(:name => 'area3', :machine => machine2)
|
333
|
+
Area.first(:name => 'area3').machine.should == machine2
|
258
334
|
end
|
259
335
|
|
260
336
|
it 'should set the association key immediately' do
|
261
|
-
|
262
|
-
|
337
|
+
machine = Machine.first(:name => 'machine1')
|
338
|
+
Area.new(:machine => machine).machine_id.should == machine.id
|
263
339
|
end
|
264
340
|
|
265
341
|
it 'should save the parent upon saving of child' do
|
266
|
-
e =
|
267
|
-
y =
|
342
|
+
e = Machine.new(:name => 'machine10')
|
343
|
+
y = Area.create(:name => 'area10', :machine => e)
|
268
344
|
|
269
|
-
y.
|
270
|
-
|
345
|
+
y.machine.name.should == 'machine10'
|
346
|
+
Machine.first(:name => 'machine10').should_not be_nil
|
271
347
|
end
|
272
348
|
|
273
349
|
it 'should convert NULL parent ids into nils' do
|
274
|
-
|
350
|
+
Area.first(:name => 'area2').machine.should be_nil
|
275
351
|
end
|
276
352
|
|
277
353
|
it 'should save nil parents as NULL ids' do
|
278
|
-
y1 =
|
279
|
-
y2 =
|
354
|
+
y1 = Area.create(:id => 20, :name => 'area20')
|
355
|
+
y2 = Area.create(:id => 30, :name => 'area30', :machine => nil)
|
280
356
|
|
281
357
|
y1.id.should == 20
|
282
|
-
y1.
|
358
|
+
y1.machine.should be_nil
|
283
359
|
y2.id.should == 30
|
284
|
-
y2.
|
360
|
+
y2.machine.should be_nil
|
285
361
|
end
|
286
362
|
|
287
363
|
it 'should respect length on foreign keys' do
|
@@ -296,10 +372,10 @@ if ADAPTER
|
|
296
372
|
end
|
297
373
|
|
298
374
|
it 'should be reloaded when calling Resource#reload' do
|
299
|
-
e =
|
300
|
-
y =
|
375
|
+
e = Machine.new(:name => 'machine40')
|
376
|
+
y = Area.create(:name => 'area40', :machine => e)
|
301
377
|
|
302
|
-
y.send(:
|
378
|
+
y.send(:machine_association).should_receive(:reload).once
|
303
379
|
|
304
380
|
lambda { y.reload }.should_not raise_error
|
305
381
|
end
|
@@ -310,9 +386,9 @@ if ADAPTER
|
|
310
386
|
Sky.auto_migrate!(ADAPTER)
|
311
387
|
Pie.auto_migrate!(ADAPTER)
|
312
388
|
|
313
|
-
pie1 = Pie.create
|
314
|
-
pie2 = Pie.create
|
315
|
-
sky1 = Sky.create
|
389
|
+
pie1 = Pie.create(:name => 'pie1')
|
390
|
+
pie2 = Pie.create(:name => 'pie2')
|
391
|
+
sky1 = Sky.create(:name => 'sky1', :pie => pie1)
|
316
392
|
end
|
317
393
|
|
318
394
|
it '#has 1' do
|
@@ -346,13 +422,13 @@ if ADAPTER
|
|
346
422
|
it 'should save the association key in the child' do
|
347
423
|
pie2 = Pie.first(:name => 'pie2')
|
348
424
|
|
349
|
-
sky2 = Sky.create
|
425
|
+
sky2 = Sky.create(:id => 2, :name => 'sky2', :pie => pie2)
|
350
426
|
pie2.sky.should == sky2
|
351
427
|
end
|
352
428
|
|
353
429
|
it 'should save the children upon saving of parent' do
|
354
430
|
p = Pie.new(:id => 10, :name => 'pie10')
|
355
|
-
s = Sky.create
|
431
|
+
s = Sky.create(:id => 10, :name => 'sky10', :pie => p)
|
356
432
|
|
357
433
|
p.sky.should == s
|
358
434
|
|
@@ -360,8 +436,8 @@ if ADAPTER
|
|
360
436
|
end
|
361
437
|
|
362
438
|
it 'should save nil parents as NULL ids' do
|
363
|
-
p1 = Pie.create
|
364
|
-
p2 = Pie.create
|
439
|
+
p1 = Pie.create(:id => 20, :name => 'pie20')
|
440
|
+
p2 = Pie.create(:id => 30, :name => 'pie30', :sky => nil)
|
365
441
|
|
366
442
|
p1.id.should == 20
|
367
443
|
p1.sky.should be_nil
|
@@ -378,154 +454,162 @@ if ADAPTER
|
|
378
454
|
|
379
455
|
describe 'one to many associations' do
|
380
456
|
before do
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
457
|
+
Ultrahost.auto_migrate!(ADAPTER)
|
458
|
+
Ultraslice.auto_migrate!(ADAPTER)
|
459
|
+
Machine.auto_migrate!(ADAPTER)
|
460
|
+
Area.auto_migrate!(ADAPTER)
|
385
461
|
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
462
|
+
ultrahost1 = Ultrahost.create(:name => 'ultrahost1')
|
463
|
+
ultrahost2 = Ultrahost.create(:name => 'ultrahost2')
|
464
|
+
ultraslice1 = Ultraslice.create(:name => 'ultraslice1', :ultrahost => ultrahost1)
|
465
|
+
ultraslice2 = Ultraslice.create(:name => 'ultraslice2', :ultrahost => ultrahost1)
|
466
|
+
ultraslice3 = Ultraslice.create(:name => 'ultraslice3')
|
391
467
|
end
|
392
468
|
|
393
469
|
it '#has n' do
|
394
|
-
h =
|
395
|
-
h.should respond_to(:
|
470
|
+
h = Ultrahost.new
|
471
|
+
h.should respond_to(:ultraslices)
|
396
472
|
end
|
397
473
|
|
398
474
|
it 'should allow removal of a child through a loaded association' do
|
399
|
-
|
400
|
-
|
475
|
+
ultrahost1 = Ultrahost.first(:name => 'ultrahost1')
|
476
|
+
ultraslice2 = ultrahost1.ultraslices.first
|
401
477
|
|
402
|
-
|
403
|
-
|
404
|
-
|
478
|
+
ultrahost1.ultraslices.size.should == 2
|
479
|
+
ultrahost1.ultraslices.delete(ultraslice2)
|
480
|
+
ultrahost1.ultraslices.size.should == 1
|
405
481
|
|
406
|
-
|
407
|
-
|
482
|
+
ultraslice2 = Ultraslice.first(:name => 'ultraslice2')
|
483
|
+
ultraslice2.ultrahost.should_not be_nil
|
408
484
|
|
409
|
-
|
485
|
+
ultrahost1.save
|
410
486
|
|
411
|
-
|
487
|
+
ultraslice2.reload.ultrahost.should be_nil
|
412
488
|
end
|
413
489
|
|
414
490
|
it 'should use the IdentityMap correctly' do
|
415
491
|
repository(ADAPTER) do
|
416
|
-
|
492
|
+
ultrahost1 = Ultrahost.first(:name => 'ultrahost1')
|
417
493
|
|
418
|
-
|
419
|
-
|
420
|
-
|
494
|
+
ultraslice = ultrahost1.ultraslices.first
|
495
|
+
ultraslice2 = ultrahost1.ultraslices(:order => [:id]).last # should be the same as 1
|
496
|
+
ultraslice3 = Ultraslice.get(2) # should be the same as 1
|
421
497
|
|
422
|
-
|
423
|
-
|
498
|
+
ultraslice.object_id.should == ultraslice2.object_id
|
499
|
+
ultraslice.object_id.should == ultraslice3.object_id
|
424
500
|
end
|
425
501
|
end
|
426
502
|
|
427
503
|
it '#<< should add exactly the parameters' do
|
428
|
-
|
504
|
+
machine = Machine.new(:name => 'my machine')
|
429
505
|
4.times do |i|
|
430
|
-
|
506
|
+
machine.areas << Area.new(:name => "area nr #{i}")
|
431
507
|
end
|
432
|
-
|
433
|
-
|
508
|
+
machine.save
|
509
|
+
machine.areas.size.should == 4
|
434
510
|
4.times do |i|
|
435
|
-
|
436
|
-
|
511
|
+
machine.areas.any? do |area|
|
512
|
+
area.name == "area nr #{i}"
|
437
513
|
end.should == true
|
438
514
|
end
|
439
|
-
|
440
|
-
|
515
|
+
machine = Machine.get!(machine.id)
|
516
|
+
machine.areas.size.should == 4
|
441
517
|
4.times do |i|
|
442
|
-
|
443
|
-
|
518
|
+
machine.areas.any? do |area|
|
519
|
+
area.name == "area nr #{i}"
|
444
520
|
end.should == true
|
445
521
|
end
|
446
522
|
end
|
447
523
|
|
524
|
+
it "#<< should add the correct number of elements if they are created" do
|
525
|
+
machine = Machine.create(:name => 'my machine')
|
526
|
+
4.times do |i|
|
527
|
+
machine.areas << Area.create(:name => "area nr #{i}", :machine => machine)
|
528
|
+
end
|
529
|
+
machine.areas.size.should == 4
|
530
|
+
end
|
531
|
+
|
448
532
|
it '#<< should add default values for relationships that have conditions' do
|
449
533
|
# it should add default values
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
534
|
+
machine = Machine.new(:name => 'my machine')
|
535
|
+
machine.fussy_areas << Area.new(:name => 'area 1', :rating => 4 )
|
536
|
+
machine.save
|
537
|
+
Area.first(:name => 'area 1').type.should == 'particular'
|
454
538
|
# it should not add default values if the condition's property already has a value
|
455
|
-
|
456
|
-
|
457
|
-
|
539
|
+
machine.fussy_areas << Area.new(:name => 'area 2', :rating => 4, :type => 'not particular')
|
540
|
+
machine.save
|
541
|
+
Area.first(:name => 'area 2').type.should == 'not particular'
|
458
542
|
# it should ignore non :eql conditions
|
459
|
-
|
460
|
-
|
461
|
-
|
543
|
+
machine.fussy_areas << Area.new(:name => 'area 3')
|
544
|
+
machine.save
|
545
|
+
Area.first(:name => 'area 3').rating.should == nil
|
462
546
|
end
|
463
547
|
|
464
548
|
it 'should load the associated instances, in the correct order' do
|
465
|
-
|
549
|
+
ultrahost1 = Ultrahost.first(:name => 'ultrahost1')
|
466
550
|
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
551
|
+
ultrahost1.ultraslices.should_not be_nil
|
552
|
+
ultrahost1.ultraslices.size.should == 2
|
553
|
+
ultrahost1.ultraslices.first.name.should == 'ultraslice2' # ordered by [:id.desc]
|
554
|
+
ultrahost1.ultraslices.last.name.should == 'ultraslice1'
|
471
555
|
|
472
|
-
|
556
|
+
ultraslice3 = Ultraslice.first(:name => 'ultraslice3')
|
473
557
|
|
474
|
-
|
558
|
+
ultraslice3.ultrahost.should be_nil
|
475
559
|
end
|
476
560
|
|
477
561
|
it 'should add and save the associated instance' do
|
478
|
-
|
479
|
-
|
480
|
-
|
562
|
+
ultrahost1 = Ultrahost.first(:name => 'ultrahost1')
|
563
|
+
ultrahost1.ultraslices << Ultraslice.new(:id => 4, :name => 'ultraslice4')
|
564
|
+
ultrahost1.save
|
481
565
|
|
482
|
-
|
566
|
+
Ultraslice.first(:name => 'ultraslice4').ultrahost.should == ultrahost1
|
483
567
|
end
|
484
568
|
|
485
569
|
it 'should not save the associated instance if the parent is not saved' do
|
486
|
-
h =
|
487
|
-
h.
|
570
|
+
h = Ultrahost.new(:id => 10, :name => 'ultrahost10')
|
571
|
+
h.ultraslices << Ultraslice.new(:id => 10, :name => 'ultraslice10')
|
488
572
|
|
489
|
-
|
573
|
+
Ultraslice.first(:name => 'ultraslice10').should be_nil
|
490
574
|
end
|
491
575
|
|
492
576
|
it 'should save the associated instance upon saving of parent' do
|
493
|
-
h =
|
494
|
-
h.
|
577
|
+
h = Ultrahost.new(:id => 10, :name => 'ultrahost10')
|
578
|
+
h.ultraslices << Ultraslice.new(:id => 10, :name => 'ultraslice10')
|
495
579
|
h.save
|
496
580
|
|
497
|
-
s =
|
581
|
+
s = Ultraslice.first(:name => 'ultraslice10')
|
498
582
|
|
499
583
|
s.should_not be_nil
|
500
|
-
s.
|
584
|
+
s.ultrahost.should == h
|
501
585
|
end
|
502
586
|
|
503
587
|
it 'should save the associated instances upon saving of parent when mass-assigned' do
|
504
|
-
h =
|
588
|
+
h = Ultrahost.create(:id => 10, :name => 'ultrahost10', :ultraslices => [ Ultraslice.new(:id => 10, :name => 'ultraslice10') ])
|
505
589
|
|
506
|
-
s =
|
590
|
+
s = Ultraslice.first(:name => 'ultraslice10')
|
507
591
|
|
508
592
|
s.should_not be_nil
|
509
|
-
s.
|
593
|
+
s.ultrahost.should == h
|
510
594
|
end
|
511
595
|
|
512
596
|
it 'should have finder-functionality' do
|
513
|
-
h =
|
597
|
+
h = Ultrahost.first(:name => 'ultrahost1')
|
514
598
|
|
515
|
-
h.
|
599
|
+
h.ultraslices.should have(2).entries
|
516
600
|
|
517
|
-
s = h.
|
601
|
+
s = h.ultraslices.all(:name => 'ultraslice2')
|
518
602
|
|
519
603
|
s.should have(1).entries
|
520
604
|
s.first.id.should == 2
|
521
605
|
|
522
|
-
h.
|
606
|
+
h.ultraslices.first(:name => 'ultraslice2').should == s.first
|
523
607
|
end
|
524
608
|
|
525
609
|
it 'should be reloaded when calling Resource#reload' do
|
526
|
-
|
527
|
-
|
528
|
-
lambda {
|
610
|
+
ultrahost = Ultrahost.first(:name => 'ultrahost1')
|
611
|
+
ultrahost.send(:ultraslices_association).should_receive(:reload).once
|
612
|
+
lambda { ultrahost.reload }.should_not raise_error
|
529
613
|
end
|
530
614
|
end
|
531
615
|
|
@@ -533,12 +617,12 @@ if ADAPTER
|
|
533
617
|
before do
|
534
618
|
Node.auto_migrate!(ADAPTER)
|
535
619
|
|
536
|
-
Node.create
|
537
|
-
Node.create
|
538
|
-
Node.create
|
539
|
-
Node.create
|
540
|
-
Node.create
|
541
|
-
Node.create
|
620
|
+
Node.create(:name => 'r1')
|
621
|
+
Node.create(:name => 'r2')
|
622
|
+
Node.create(:name => 'r1c1', :parent_id => 1)
|
623
|
+
Node.create(:name => 'r1c2', :parent_id => 1)
|
624
|
+
Node.create(:name => 'r1c3', :parent_id => 1)
|
625
|
+
Node.create(:name => 'r1c1c1', :parent_id => 3)
|
542
626
|
end
|
543
627
|
|
544
628
|
it 'should properly set #parent' do
|
@@ -562,7 +646,7 @@ if ADAPTER
|
|
562
646
|
end
|
563
647
|
|
564
648
|
it 'should allow to create root nodes' do
|
565
|
-
r = Node.create
|
649
|
+
r = Node.create(:name => 'newroot')
|
566
650
|
r.parent.should be_nil
|
567
651
|
r.children.size.should == 0
|
568
652
|
end
|
@@ -589,21 +673,21 @@ if ADAPTER
|
|
589
673
|
end
|
590
674
|
property :id, Serial
|
591
675
|
property :name, String
|
592
|
-
has n, :cakes
|
593
|
-
has n, :recipes, :through => :cakes
|
594
|
-
has n, :ingredients, :through => :cakes
|
595
|
-
has n, :creators, :through => :cakes
|
596
|
-
has n, :
|
597
|
-
has n, :bites, :through => :cakes
|
598
|
-
has n, :shapes, :through => :cakes
|
599
|
-
has n, :customers, :through => :cakes
|
600
|
-
has 1, :shop_owner
|
601
|
-
has 1, :wife, :through => :shop_owner
|
602
|
-
has 1, :ring, :through => :shop_owner
|
603
|
-
has n, :coats, :through => :shop_owner
|
604
|
-
has n, :children, :through => :shop_owner
|
605
|
-
has n, :toys, :through => :shop_owner
|
606
|
-
has n, :boogers, :through => :shop_owner
|
676
|
+
has n, :cakes # has n
|
677
|
+
has n, :recipes, :through => :cakes # has n => has 1
|
678
|
+
has n, :ingredients, :through => :cakes # has n => has 1 => has n
|
679
|
+
has n, :creators, :through => :cakes # has n => has 1 => has 1
|
680
|
+
has n, :ultraslices, :through => :cakes # has n => has n
|
681
|
+
has n, :bites, :through => :cakes # has n => has n => has n
|
682
|
+
has n, :shapes, :through => :cakes # has n => has n => has 1
|
683
|
+
has n, :customers, :through => :cakes # has n => belongs_to (pending)
|
684
|
+
has 1, :shop_owner # has 1
|
685
|
+
has 1, :wife, :through => :shop_owner # has 1 => has 1
|
686
|
+
has 1, :ring, :through => :shop_owner # has 1 => has 1 => has 1
|
687
|
+
has n, :coats, :through => :shop_owner # has 1 => has 1 => has n
|
688
|
+
has n, :children, :through => :shop_owner # has 1 => has n
|
689
|
+
has n, :toys, :through => :shop_owner # has 1 => has n => has n
|
690
|
+
has n, :boogers, :through => :shop_owner # has 1 => has n => has 1
|
607
691
|
end
|
608
692
|
|
609
693
|
class ShopOwner
|
@@ -614,13 +698,13 @@ if ADAPTER
|
|
614
698
|
property :id, Serial
|
615
699
|
property :name, String
|
616
700
|
belongs_to :shop, :class_name => 'Sweets::Shop'
|
617
|
-
has 1, :wife
|
618
|
-
has n, :children
|
619
|
-
has n, :toys, :through => :children
|
620
|
-
has n, :boogers, :through => :children
|
621
|
-
has n, :coats, :through => :wife
|
622
|
-
has 1, :ring, :through => :wife
|
623
|
-
has n, :schools, :through => :children
|
701
|
+
has 1, :wife
|
702
|
+
has n, :children
|
703
|
+
has n, :toys, :through => :children
|
704
|
+
has n, :boogers, :through => :children
|
705
|
+
has n, :coats, :through => :wife
|
706
|
+
has 1, :ring, :through => :wife
|
707
|
+
has n, :schools, :through => :children
|
624
708
|
end
|
625
709
|
|
626
710
|
class Wife
|
@@ -630,9 +714,9 @@ if ADAPTER
|
|
630
714
|
end
|
631
715
|
property :id, Serial
|
632
716
|
property :name, String
|
633
|
-
belongs_to :shop_owner
|
634
|
-
has 1, :ring
|
635
|
-
has n, :coats
|
717
|
+
belongs_to :shop_owner
|
718
|
+
has 1, :ring
|
719
|
+
has n, :coats
|
636
720
|
end
|
637
721
|
|
638
722
|
class Coat
|
@@ -642,7 +726,7 @@ if ADAPTER
|
|
642
726
|
end
|
643
727
|
property :id, Serial
|
644
728
|
property :name, String
|
645
|
-
belongs_to :wife
|
729
|
+
belongs_to :wife
|
646
730
|
end
|
647
731
|
|
648
732
|
class Ring
|
@@ -652,7 +736,7 @@ if ADAPTER
|
|
652
736
|
end
|
653
737
|
property :id, Serial
|
654
738
|
property :name, String
|
655
|
-
belongs_to :wife
|
739
|
+
belongs_to :wife
|
656
740
|
end
|
657
741
|
|
658
742
|
class Child
|
@@ -662,9 +746,9 @@ if ADAPTER
|
|
662
746
|
end
|
663
747
|
property :id, Serial
|
664
748
|
property :name, String
|
665
|
-
belongs_to :shop_owner
|
666
|
-
has n, :toys
|
667
|
-
has 1, :booger
|
749
|
+
belongs_to :shop_owner
|
750
|
+
has n, :toys
|
751
|
+
has 1, :booger
|
668
752
|
end
|
669
753
|
|
670
754
|
class Booger
|
@@ -674,7 +758,7 @@ if ADAPTER
|
|
674
758
|
end
|
675
759
|
property :id, Serial
|
676
760
|
property :name, String
|
677
|
-
belongs_to :child
|
761
|
+
belongs_to :child
|
678
762
|
end
|
679
763
|
|
680
764
|
class Toy
|
@@ -684,7 +768,7 @@ if ADAPTER
|
|
684
768
|
end
|
685
769
|
property :id, Serial
|
686
770
|
property :name, String
|
687
|
-
belongs_to :child
|
771
|
+
belongs_to :child
|
688
772
|
end
|
689
773
|
|
690
774
|
class Cake
|
@@ -694,14 +778,14 @@ if ADAPTER
|
|
694
778
|
end
|
695
779
|
property :id, Serial
|
696
780
|
property :name, String
|
697
|
-
belongs_to :shop
|
698
|
-
belongs_to :customer
|
699
|
-
has n, :
|
700
|
-
has n, :bites, :through => :
|
701
|
-
has 1, :recipe
|
702
|
-
has n, :ingredients, :through => :recipe
|
703
|
-
has 1, :creator, :through => :recipe
|
704
|
-
has n, :shapes, :through => :
|
781
|
+
belongs_to :shop
|
782
|
+
belongs_to :customer
|
783
|
+
has n, :ultraslices
|
784
|
+
has n, :bites, :through => :ultraslices
|
785
|
+
has 1, :recipe
|
786
|
+
has n, :ingredients, :through => :recipe
|
787
|
+
has 1, :creator, :through => :recipe
|
788
|
+
has n, :shapes, :through => :ultraslices
|
705
789
|
end
|
706
790
|
|
707
791
|
class Recipe
|
@@ -711,9 +795,9 @@ if ADAPTER
|
|
711
795
|
end
|
712
796
|
property :id, Serial
|
713
797
|
property :name, String
|
714
|
-
belongs_to :cake
|
715
|
-
has n, :ingredients
|
716
|
-
has 1, :creator
|
798
|
+
belongs_to :cake
|
799
|
+
has n, :ingredients
|
800
|
+
has 1, :creator
|
717
801
|
end
|
718
802
|
|
719
803
|
class Customer
|
@@ -723,7 +807,7 @@ if ADAPTER
|
|
723
807
|
end
|
724
808
|
property :id, Serial
|
725
809
|
property :name, String
|
726
|
-
has n, :cakes
|
810
|
+
has n, :cakes
|
727
811
|
end
|
728
812
|
|
729
813
|
class Creator
|
@@ -733,7 +817,7 @@ if ADAPTER
|
|
733
817
|
end
|
734
818
|
property :id, Serial
|
735
819
|
property :name, String
|
736
|
-
belongs_to :recipe
|
820
|
+
belongs_to :recipe
|
737
821
|
end
|
738
822
|
|
739
823
|
class Ingredient
|
@@ -743,19 +827,19 @@ if ADAPTER
|
|
743
827
|
end
|
744
828
|
property :id, Serial
|
745
829
|
property :name, String
|
746
|
-
belongs_to :recipe
|
830
|
+
belongs_to :recipe
|
747
831
|
end
|
748
832
|
|
749
|
-
class
|
833
|
+
class Ultraslice
|
750
834
|
include DataMapper::Resource
|
751
835
|
def self.default_repository_name
|
752
836
|
ADAPTER
|
753
837
|
end
|
754
838
|
property :id, Serial
|
755
839
|
property :size, Integer
|
756
|
-
belongs_to :cake
|
757
|
-
has n, :bites
|
758
|
-
has 1, :shape
|
840
|
+
belongs_to :cake
|
841
|
+
has n, :bites
|
842
|
+
has 1, :shape
|
759
843
|
end
|
760
844
|
|
761
845
|
class Shape
|
@@ -765,7 +849,7 @@ if ADAPTER
|
|
765
849
|
end
|
766
850
|
property :id, Serial
|
767
851
|
property :name, String
|
768
|
-
belongs_to :
|
852
|
+
belongs_to :ultraslice
|
769
853
|
end
|
770
854
|
|
771
855
|
class Bite
|
@@ -775,7 +859,7 @@ if ADAPTER
|
|
775
859
|
end
|
776
860
|
property :id, Serial
|
777
861
|
property :name, String
|
778
|
-
belongs_to :
|
862
|
+
belongs_to :ultraslice
|
779
863
|
end
|
780
864
|
|
781
865
|
DataMapper::Resource.descendants.each do |descendant|
|
@@ -832,31 +916,31 @@ if ADAPTER
|
|
832
916
|
|
833
917
|
# has n => has n
|
834
918
|
|
835
|
-
10.times do |i| german_chocolate.
|
836
|
-
5.times do |i| short_cake.
|
837
|
-
german_chocolate.
|
919
|
+
10.times do |i| german_chocolate.ultraslices << Ultraslice.new(:size => i) end
|
920
|
+
5.times do |i| short_cake.ultraslices << Ultraslice.new(:size => i) end
|
921
|
+
german_chocolate.ultraslices.size.should == 10
|
838
922
|
# has n => has n => has 1
|
839
923
|
|
840
|
-
german_chocolate.
|
924
|
+
german_chocolate.ultraslices.each do |ultraslice|
|
841
925
|
shape = Shape.new(:name => 'square')
|
842
|
-
|
926
|
+
ultraslice.shape = shape
|
843
927
|
shape.save
|
844
928
|
end
|
845
|
-
short_cake.
|
929
|
+
short_cake.ultraslices.each do |ultraslice|
|
846
930
|
shape = Shape.new(:name => 'round')
|
847
|
-
|
931
|
+
ultraslice.shape = shape
|
848
932
|
shape.save
|
849
933
|
end
|
850
934
|
|
851
935
|
# has n => has n => has n
|
852
|
-
german_chocolate.
|
936
|
+
german_chocolate.ultraslices.each do |ultraslice|
|
853
937
|
6.times do |i|
|
854
|
-
|
938
|
+
ultraslice.bites << Bite.new(:name => "Big bite nr #{i}")
|
855
939
|
end
|
856
940
|
end
|
857
|
-
short_cake.
|
941
|
+
short_cake.ultraslices.each do |ultraslice|
|
858
942
|
3.times do |i|
|
859
|
-
|
943
|
+
ultraslice.bites << Bite.new(:name => "Small bite nr #{i}")
|
860
944
|
end
|
861
945
|
end
|
862
946
|
|
@@ -919,10 +1003,10 @@ if ADAPTER
|
|
919
1003
|
#
|
920
1004
|
|
921
1005
|
it 'should return the right children for has n => has n relationships' do
|
922
|
-
Sweets::Shop.first.
|
1006
|
+
Sweets::Shop.first.ultraslices.size.should == 15
|
923
1007
|
10.times do |i|
|
924
|
-
Sweets::Shop.first.
|
925
|
-
|
1008
|
+
Sweets::Shop.first.ultraslices.select do |ultraslice|
|
1009
|
+
ultraslice.cake == Sweets::Cake.first(:name => 'German Chocolate') && ultraslice.size == i
|
926
1010
|
end
|
927
1011
|
end
|
928
1012
|
end
|
@@ -940,10 +1024,10 @@ if ADAPTER
|
|
940
1024
|
it 'should return the right children for has n => has n => has n' do
|
941
1025
|
Sweets::Shop.first.bites.size.should == 75
|
942
1026
|
Sweets::Shop.first.bites.select do |bite|
|
943
|
-
bite.
|
1027
|
+
bite.ultraslice.cake == Sweets::Cake.first(:name => 'German Chocolate')
|
944
1028
|
end.size.should == 60
|
945
1029
|
Sweets::Shop.first.bites.select do |bite|
|
946
|
-
bite.
|
1030
|
+
bite.ultraslice.cake == Sweets::Cake.first(:name => 'Short Cake')
|
947
1031
|
end.size.should == 15
|
948
1032
|
end
|
949
1033
|
|