datamapper-dm-core 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. data/.autotest +26 -0
  2. data/.gitignore +18 -0
  3. data/CONTRIBUTING +51 -0
  4. data/FAQ +92 -0
  5. data/History.txt +41 -0
  6. data/MIT-LICENSE +22 -0
  7. data/Manifest.txt +130 -0
  8. data/QUICKLINKS +11 -0
  9. data/README.txt +143 -0
  10. data/Rakefile +30 -0
  11. data/SPECS +62 -0
  12. data/TODO +1 -0
  13. data/dm-core.gemspec +40 -0
  14. data/lib/dm-core.rb +217 -0
  15. data/lib/dm-core/adapters.rb +16 -0
  16. data/lib/dm-core/adapters/abstract_adapter.rb +209 -0
  17. data/lib/dm-core/adapters/data_objects_adapter.rb +716 -0
  18. data/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  19. data/lib/dm-core/adapters/mysql_adapter.rb +136 -0
  20. data/lib/dm-core/adapters/postgres_adapter.rb +189 -0
  21. data/lib/dm-core/adapters/sqlite3_adapter.rb +105 -0
  22. data/lib/dm-core/associations.rb +207 -0
  23. data/lib/dm-core/associations/many_to_many.rb +147 -0
  24. data/lib/dm-core/associations/many_to_one.rb +107 -0
  25. data/lib/dm-core/associations/one_to_many.rb +315 -0
  26. data/lib/dm-core/associations/one_to_one.rb +61 -0
  27. data/lib/dm-core/associations/relationship.rb +229 -0
  28. data/lib/dm-core/associations/relationship_chain.rb +81 -0
  29. data/lib/dm-core/auto_migrations.rb +105 -0
  30. data/lib/dm-core/collection.rb +670 -0
  31. data/lib/dm-core/dependency_queue.rb +32 -0
  32. data/lib/dm-core/hook.rb +11 -0
  33. data/lib/dm-core/identity_map.rb +42 -0
  34. data/lib/dm-core/is.rb +16 -0
  35. data/lib/dm-core/logger.rb +232 -0
  36. data/lib/dm-core/migrations/destructive_migrations.rb +17 -0
  37. data/lib/dm-core/migrator.rb +29 -0
  38. data/lib/dm-core/model.rb +526 -0
  39. data/lib/dm-core/naming_conventions.rb +84 -0
  40. data/lib/dm-core/property.rb +676 -0
  41. data/lib/dm-core/property_set.rb +169 -0
  42. data/lib/dm-core/query.rb +676 -0
  43. data/lib/dm-core/repository.rb +167 -0
  44. data/lib/dm-core/resource.rb +671 -0
  45. data/lib/dm-core/scope.rb +58 -0
  46. data/lib/dm-core/support.rb +7 -0
  47. data/lib/dm-core/support/array.rb +13 -0
  48. data/lib/dm-core/support/assertions.rb +8 -0
  49. data/lib/dm-core/support/errors.rb +23 -0
  50. data/lib/dm-core/support/kernel.rb +11 -0
  51. data/lib/dm-core/support/symbol.rb +41 -0
  52. data/lib/dm-core/transaction.rb +267 -0
  53. data/lib/dm-core/type.rb +160 -0
  54. data/lib/dm-core/type_map.rb +80 -0
  55. data/lib/dm-core/types.rb +19 -0
  56. data/lib/dm-core/types/boolean.rb +7 -0
  57. data/lib/dm-core/types/discriminator.rb +34 -0
  58. data/lib/dm-core/types/object.rb +24 -0
  59. data/lib/dm-core/types/paranoid_boolean.rb +34 -0
  60. data/lib/dm-core/types/paranoid_datetime.rb +33 -0
  61. data/lib/dm-core/types/serial.rb +9 -0
  62. data/lib/dm-core/types/text.rb +10 -0
  63. data/lib/dm-core/version.rb +3 -0
  64. data/script/all +4 -0
  65. data/script/performance.rb +282 -0
  66. data/script/profile.rb +87 -0
  67. data/spec/integration/association_spec.rb +1382 -0
  68. data/spec/integration/association_through_spec.rb +203 -0
  69. data/spec/integration/associations/many_to_many_spec.rb +449 -0
  70. data/spec/integration/associations/many_to_one_spec.rb +163 -0
  71. data/spec/integration/associations/one_to_many_spec.rb +188 -0
  72. data/spec/integration/auto_migrations_spec.rb +413 -0
  73. data/spec/integration/collection_spec.rb +1073 -0
  74. data/spec/integration/data_objects_adapter_spec.rb +32 -0
  75. data/spec/integration/dependency_queue_spec.rb +46 -0
  76. data/spec/integration/model_spec.rb +197 -0
  77. data/spec/integration/mysql_adapter_spec.rb +85 -0
  78. data/spec/integration/postgres_adapter_spec.rb +731 -0
  79. data/spec/integration/property_spec.rb +253 -0
  80. data/spec/integration/query_spec.rb +514 -0
  81. data/spec/integration/repository_spec.rb +61 -0
  82. data/spec/integration/resource_spec.rb +513 -0
  83. data/spec/integration/sqlite3_adapter_spec.rb +352 -0
  84. data/spec/integration/sti_spec.rb +273 -0
  85. data/spec/integration/strategic_eager_loading_spec.rb +156 -0
  86. data/spec/integration/transaction_spec.rb +75 -0
  87. data/spec/integration/type_spec.rb +275 -0
  88. data/spec/lib/logging_helper.rb +18 -0
  89. data/spec/lib/mock_adapter.rb +27 -0
  90. data/spec/lib/model_loader.rb +100 -0
  91. data/spec/lib/publicize_methods.rb +28 -0
  92. data/spec/models/content.rb +16 -0
  93. data/spec/models/vehicles.rb +34 -0
  94. data/spec/models/zoo.rb +48 -0
  95. data/spec/spec.opts +3 -0
  96. data/spec/spec_helper.rb +91 -0
  97. data/spec/unit/adapters/abstract_adapter_spec.rb +133 -0
  98. data/spec/unit/adapters/adapter_shared_spec.rb +15 -0
  99. data/spec/unit/adapters/data_objects_adapter_spec.rb +632 -0
  100. data/spec/unit/adapters/in_memory_adapter_spec.rb +98 -0
  101. data/spec/unit/adapters/postgres_adapter_spec.rb +133 -0
  102. data/spec/unit/associations/many_to_many_spec.rb +32 -0
  103. data/spec/unit/associations/many_to_one_spec.rb +159 -0
  104. data/spec/unit/associations/one_to_many_spec.rb +393 -0
  105. data/spec/unit/associations/one_to_one_spec.rb +7 -0
  106. data/spec/unit/associations/relationship_spec.rb +71 -0
  107. data/spec/unit/associations_spec.rb +242 -0
  108. data/spec/unit/auto_migrations_spec.rb +111 -0
  109. data/spec/unit/collection_spec.rb +182 -0
  110. data/spec/unit/data_mapper_spec.rb +35 -0
  111. data/spec/unit/identity_map_spec.rb +126 -0
  112. data/spec/unit/is_spec.rb +80 -0
  113. data/spec/unit/migrator_spec.rb +33 -0
  114. data/spec/unit/model_spec.rb +321 -0
  115. data/spec/unit/naming_conventions_spec.rb +36 -0
  116. data/spec/unit/property_set_spec.rb +90 -0
  117. data/spec/unit/property_spec.rb +753 -0
  118. data/spec/unit/query_spec.rb +571 -0
  119. data/spec/unit/repository_spec.rb +93 -0
  120. data/spec/unit/resource_spec.rb +649 -0
  121. data/spec/unit/scope_spec.rb +142 -0
  122. data/spec/unit/transaction_spec.rb +493 -0
  123. data/spec/unit/type_map_spec.rb +114 -0
  124. data/spec/unit/type_spec.rb +119 -0
  125. data/tasks/ci.rb +36 -0
  126. data/tasks/dm.rb +63 -0
  127. data/tasks/doc.rb +20 -0
  128. data/tasks/gemspec.rb +23 -0
  129. data/tasks/hoe.rb +46 -0
  130. data/tasks/install.rb +20 -0
  131. metadata +215 -0
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ if ADAPTER
4
+ describe DataMapper::Repository, "with #{ADAPTER}" do
5
+ before :all do
6
+ class ::SerialFinderSpec
7
+ include DataMapper::Resource
8
+
9
+ property :id, Serial
10
+ property :sample, String
11
+
12
+ auto_migrate!(ADAPTER)
13
+ end
14
+
15
+ repository(ADAPTER).create((0...100).map { SerialFinderSpec.new(:sample => rand.to_s) })
16
+ end
17
+
18
+ before do
19
+ @repository = repository(ADAPTER)
20
+ @model = SerialFinderSpec
21
+ @query = DataMapper::Query.new(@repository, @model)
22
+ end
23
+
24
+ it 'should be serializable with Marshal' do
25
+ Marshal.load(Marshal.dump(@repository)).should == @repository
26
+ end
27
+
28
+ it "should throw an exception if the named repository is unknown" do
29
+ r = DataMapper::Repository.new(:completely_bogus)
30
+ lambda { r.adapter }.should raise_error(ArgumentError)
31
+ end
32
+
33
+ it "should return all available rows" do
34
+ @repository.read_many(@query).should have(100).entries
35
+ end
36
+
37
+ it "should allow limit and offset" do
38
+ @repository.read_many(@query.merge(:limit => 50)).should have(50).entries
39
+
40
+ collection = @repository.read_many(@query.merge(:limit => 20, :offset => 40))
41
+ collection.should have(20).entries
42
+ collection.map { |entry| entry.id }.should == @repository.read_many(@query)[40...60].map { |entry| entry.id }
43
+ end
44
+
45
+ it "should lazy-load missing attributes" do
46
+ sfs = @repository.read_one(@query.merge(:fields => [ :id ], :limit => 1))
47
+ sfs.should be_a_kind_of(@model)
48
+ sfs.should_not be_a_new_record
49
+
50
+ sfs.attribute_loaded?(:sample).should be_false
51
+ sfs.sample.should_not be_nil
52
+ end
53
+
54
+ it "should translate an Array to an IN clause" do
55
+ ids = @repository.read_many(@query.merge(:fields => [ :id ], :limit => 10)).map { |entry| entry.id }
56
+ results = @repository.read_many(@query.merge(:id => ids))
57
+
58
+ results.map { |entry| entry.id }.should == ids
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,513 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ # ------------------------------------------------------------
4
+ # ----- Read SPECS for information about how to read -----
5
+ # ----- and contribute to the DataMapper specs. -----
6
+ # ------------------------------------------------------------
7
+
8
+ if ADAPTER
9
+ describe "DataMapper::Resource with #{ADAPTER}" do
10
+
11
+ load_models_for_metaphor :zoo
12
+ load_models_for_metaphor :content
13
+
14
+ before(:each) do
15
+ DataMapper.auto_migrate!(ADAPTER)
16
+ @zoo = Zoo.new(:name => "San Francisco")
17
+ repository(ADAPTER) { @zoo.save }
18
+ end
19
+
20
+ it 'should be serializable with Marshal' do
21
+ Marshal.load(Marshal.dump(@zoo)).should == @zoo
22
+ end
23
+
24
+ # --- Move somewhere ----
25
+ it "should be able to destroy objects" do
26
+ lambda { @zoo.destroy.should be_true }.should_not raise_error
27
+ end
28
+
29
+ it 'should not overwrite attributes when lazy loading' do
30
+ zoo = Zoo.first
31
+ zoo.name = 'San Diego'
32
+ lambda { zoo.description }.should_not change(zoo, :name)
33
+ end
34
+
35
+ describe '#attribute_get' do
36
+ it 'should provide #attribute_get' do
37
+ Zoo.new.should respond_to(:attribute_get)
38
+ end
39
+
40
+ it 'should delegate to Property#get' do
41
+ Zoo.properties[:name].should_receive(:get).with(zoo = Zoo.new)
42
+ zoo.name
43
+ end
44
+
45
+ it "should return Property#get's return value" do
46
+ Zoo.properties[:name].should_receive(:get).and_return("San Francisco")
47
+ Zoo.new.name.should == "San Francisco"
48
+ end
49
+ end
50
+
51
+ describe '#attribute_set' do
52
+ it "should provide #attribute_set" do
53
+ Zoo.new.should respond_to(:attribute_set)
54
+ end
55
+
56
+ it 'should delegate to Property#set' do
57
+ Zoo.properties[:name].should_receive(:set).with(zoo = Zoo.new, "San Francisco")
58
+ zoo.name = "San Francisco"
59
+ end
60
+ end
61
+
62
+ describe '#eql?' do
63
+
64
+ it "should return true if the objects are the same instances" do
65
+ z = Zoo.first
66
+ z2 = z
67
+ z.should be_eql(z2)
68
+ end
69
+
70
+ it "should return false if the other object is not an instance of the same model" do
71
+ z = Zoo.first
72
+ z2 = Zoo.create(:name => 'New York')
73
+ z.should_not be_eql(z2)
74
+ end
75
+
76
+ it "should return false if the other object is a different class" do
77
+ z = Zoo.first
78
+ o = Content::Dialect.first
79
+ z.should_not be_eql(o)
80
+ end
81
+
82
+ it "should return true if the repositories are the same and the primary key is the same"
83
+ it "should return false if the repository is not the same and the primary key is the same"
84
+
85
+ it "should return true if all the properties are the same" do
86
+ z = Zoo.first
87
+ z2 = Zoo.new(z.attributes.delete_if{|key, value| key == :mission})
88
+ z.should be_eql(z2)
89
+ end
90
+
91
+ it "should return false if any of the properties are different" do
92
+ z = Zoo.first
93
+ z2 = Zoo.new(z.attributes.delete_if{|key, value| key == :mission}.merge(:description => 'impressive'))
94
+ z.should_not be_eql(z2)
95
+ end
96
+ end
97
+
98
+ describe '#hash' do
99
+ it "should return the same hash values for unsaved objects that are equal" do
100
+ e1 = Employee.new(:name => "John")
101
+ e2 = Employee.new(:name => "John")
102
+ e1.hash.should == e2.hash
103
+ end
104
+
105
+ it "should return the same hash values for saved objects that are equal" do
106
+ # Make sure that the object_id's are not the same
107
+ e1 = e2 = nil
108
+ repository(ADAPTER) do
109
+ e1 = Employee.create(:name => "John")
110
+ end
111
+ repository(ADAPTER) do
112
+ e2 = Employee.get("John")
113
+ end
114
+ e1.hash.should == e2.hash
115
+ end
116
+
117
+ it "should return a different hash value for different objects of the same type" do
118
+ repository(ADAPTER) do
119
+ e1 = Employee.create(:name => "John")
120
+ e2 = Employee.create(:name => "Dan")
121
+ e1.hash.should_not == e2.hash
122
+ end
123
+ end
124
+
125
+ it "should return a different hash value for different types of objects with the same key"
126
+ end
127
+
128
+ describe '#id' do
129
+ it "should be awesome"
130
+ end
131
+
132
+ describe '#inspect' do
133
+ it "should return a string representing the object"
134
+ end
135
+
136
+ describe '#key' do
137
+ describe "original_value[:key]" do
138
+ it "should be used when an existing resource's key changes" do
139
+ repository(ADAPTER) do
140
+ employee = Employee.create(:name => "John")
141
+ employee.name = "Jon"
142
+ employee.key.should == ["John"]
143
+ end
144
+ end
145
+
146
+ it "should be used when saving an existing resource" do
147
+ repository(ADAPTER) do
148
+ employee = Employee.create(:name => "John")
149
+ employee.name = "Jon"
150
+ employee.save.should == true
151
+ Employee.get("Jon").should == employee
152
+ end
153
+ end
154
+
155
+ it "should not be used when a new resource's key changes" do
156
+ employee = Employee.new(:name => "John")
157
+ employee.name = "Jon"
158
+ employee.key.should == ["Jon"]
159
+ end
160
+ end
161
+ end
162
+
163
+ describe '#pretty_print' do
164
+ it "should display a pretty version of inspect"
165
+ end
166
+
167
+ describe '#save' do
168
+
169
+ describe 'with a new resource' do
170
+ it 'should set defaults before create'
171
+ it 'should create when dirty'
172
+ it 'should create when non-dirty, and it has a serial key'
173
+ end
174
+
175
+ describe 'with an existing resource' do
176
+ it 'should update'
177
+ end
178
+
179
+ end
180
+
181
+ describe '#repository' do
182
+ it "should return the repository associated with the object if there is one"
183
+ it "should return the repository associated with the model if the object doesn't have one"
184
+ end
185
+ end
186
+ end
187
+
188
+
189
+
190
+
191
+ # ---------- Old specs... BOOOOOOOOOO ---------------
192
+ if ADAPTER
193
+ describe "DataMapper::Resource with #{ADAPTER}" do
194
+ before :all do
195
+ class ::Orange
196
+ include DataMapper::Resource
197
+
198
+ def self.default_repository_name
199
+ ADAPTER
200
+ end
201
+
202
+ property :name, String, :key => true
203
+ property :color, String
204
+ end
205
+
206
+ class ::Apple
207
+ include DataMapper::Resource
208
+
209
+ def self.default_repository_name
210
+ ADAPTER
211
+ end
212
+
213
+ property :id, Serial
214
+ property :color, String, :default => 'green', :nullable => true
215
+ end
216
+
217
+ class ::FortunePig
218
+ include DataMapper::Resource
219
+
220
+ def self.default_repository_name
221
+ ADAPTER
222
+ end
223
+
224
+ property :id, Serial
225
+ property :name, String
226
+
227
+ def to_s
228
+ name
229
+ end
230
+
231
+ after :create do
232
+ @created_id = self.id
233
+ end
234
+
235
+ after :save do
236
+ @save_id = self.id
237
+ end
238
+ end
239
+
240
+ class ::Car
241
+ include DataMapper::Resource
242
+
243
+ def self.default_repository_name
244
+ ADAPTER
245
+ end
246
+
247
+ property :brand, String, :key => true
248
+ property :color, String
249
+ property :created_on, Date
250
+ property :touched_on, Date
251
+ property :updated_on, Date
252
+
253
+ before :save do
254
+ self.touched_on = Date.today
255
+ end
256
+
257
+ before :create do
258
+ self.created_on = Date.today
259
+ end
260
+
261
+ before :update do
262
+ self.updated_on = Date.today
263
+ end
264
+ end
265
+
266
+ class ::Male
267
+ include DataMapper::Resource
268
+
269
+ def self.default_repository_name
270
+ ADAPTER
271
+ end
272
+
273
+ property :id, Serial
274
+ property :name, String
275
+ property :iq, Integer, :default => 100
276
+ property :type, Discriminator
277
+ property :data, Object
278
+
279
+ def iq=(i)
280
+ attribute_set(:iq, i - 1)
281
+ end
282
+ end
283
+
284
+ class ::Bully < Male; end
285
+
286
+ class ::Mugger < Bully; end
287
+
288
+ class ::Maniac < Bully; end
289
+
290
+ class ::Psycho < Maniac; end
291
+
292
+ class ::Geek < Male
293
+ property :awkward, Boolean, :default => true
294
+
295
+ def iq=(i)
296
+ attribute_set(:iq, i + 30)
297
+ end
298
+ end
299
+
300
+ class ::Flanimal
301
+ include DataMapper::Resource
302
+
303
+ def self.default_repository_name
304
+ ADAPTER
305
+ end
306
+
307
+ property :id, Serial
308
+ property :type, Discriminator
309
+ property :name, String
310
+ end
311
+
312
+ class ::Sprog < Flanimal; end
313
+
314
+ Orange.auto_migrate!(ADAPTER)
315
+ Apple.auto_migrate!(ADAPTER)
316
+ FortunePig.auto_migrate!(ADAPTER)
317
+
318
+ orange = Orange.new(:color => 'orange')
319
+ orange.name = 'Bob' # Keys are protected from mass-assignment by default.
320
+ repository(ADAPTER) { orange.save }
321
+ end
322
+
323
+ it "should be able to overwrite Resource#to_s" do
324
+ repository(ADAPTER) do
325
+ ted = FortunePig.create(:name => "Ted")
326
+ FortunePig.get!(ted.id).to_s.should == 'Ted'
327
+ end
328
+ end
329
+
330
+ it "should be able to destroy objects" do
331
+ apple = Apple.create(:color => 'Green')
332
+ lambda do
333
+ apple.destroy.should be_true
334
+ end.should_not raise_error
335
+ end
336
+
337
+ it 'should return false to #destroy if the resource is new' do
338
+ Apple.new.destroy.should be_false
339
+ end
340
+
341
+ it "should be able to reload objects" do
342
+ orange = repository(ADAPTER) { Orange.get!('Bob') }
343
+ orange.color.should == 'orange'
344
+ orange.color = 'blue'
345
+ orange.color.should == 'blue'
346
+ orange.reload
347
+ orange.color.should == 'orange'
348
+ end
349
+
350
+ it "should be able to reload new objects" do
351
+ repository(ADAPTER) do
352
+ Orange.create(:name => 'Tom').reload
353
+ end
354
+ end
355
+
356
+ it "should be able to find first or create objects" do
357
+ repository(ADAPTER) do
358
+ orange = Orange.create(:name => 'Naval')
359
+
360
+ Orange.first_or_create(:name => 'Naval').should == orange
361
+
362
+ purple = Orange.first_or_create(:name => 'Purple', :color => 'Fuschia')
363
+ oranges = Orange.all(:name => 'Purple')
364
+ oranges.size.should == 1
365
+ oranges.first.should == purple
366
+ end
367
+ end
368
+
369
+ it "should be able to override a default with a nil" do
370
+ repository(ADAPTER) do
371
+ apple = Apple.new
372
+ apple.color = nil
373
+ apple.save
374
+ apple.color.should be_nil
375
+
376
+ apple = Apple.create(:color => nil)
377
+ apple.color.should be_nil
378
+ end
379
+ end
380
+
381
+ it "should be able to respond to create hooks" do
382
+ bob = repository(ADAPTER) { FortunePig.create(:name => 'Bob') }
383
+ bob.id.should_not be_nil
384
+ bob.instance_variable_get("@created_id").should == bob.id
385
+
386
+ fred = FortunePig.new(:name => 'Fred')
387
+ repository(ADAPTER) { fred.save }
388
+ fred.id.should_not be_nil
389
+ fred.instance_variable_get("@save_id").should == fred.id
390
+ end
391
+
392
+ it "should be dirty when Object properties are changed" do
393
+ # pending "Awaiting Property#track implementation"
394
+ repository(ADAPTER) do
395
+ Male.auto_migrate!
396
+ end
397
+ repository(ADAPTER) do
398
+ bob = Male.create(:name => "Bob", :data => {})
399
+ bob.dirty?.should be_false
400
+ bob.data.merge!(:name => "Bob")
401
+ bob.dirty?.should be_true
402
+ bob = Male.first
403
+ bob.data[:name] = "Bob"
404
+ bob.dirty?.should be_true
405
+ end
406
+ end
407
+
408
+ describe "hooking" do
409
+ before :all do
410
+ Car.auto_migrate!(ADAPTER)
411
+ end
412
+
413
+ it "should execute hooks before creating/updating objects" do
414
+ repository(ADAPTER) do
415
+ c1 = Car.new(:brand => 'BMW', :color => 'white')
416
+
417
+ c1.new_record?.should == true
418
+ c1.created_on.should == nil
419
+
420
+ c1.save
421
+
422
+ c1.new_record?.should == false
423
+ c1.touched_on.should == Date.today
424
+ c1.created_on.should == Date.today
425
+ c1.updated_on.should == nil
426
+
427
+ c1.color = 'black'
428
+ c1.save
429
+
430
+ c1.updated_on.should == Date.today
431
+ end
432
+
433
+ end
434
+
435
+ end
436
+
437
+ describe "inheritance" do
438
+ before :all do
439
+ Geek.auto_migrate!(ADAPTER)
440
+
441
+ repository(ADAPTER) do
442
+ Male.create(:name => 'John Dorian')
443
+ Bully.create(:name => 'Bob', :iq => 69)
444
+ Geek.create(:name => 'Steve', :awkward => false, :iq => 132)
445
+ Geek.create(:name => 'Bill', :iq => 150)
446
+ Bully.create(:name => 'Johnson')
447
+ Mugger.create(:name => 'Frank')
448
+ Maniac.create(:name => 'William')
449
+ Psycho.create(:name => 'Norman')
450
+ end
451
+
452
+ Flanimal.auto_migrate!(ADAPTER)
453
+
454
+ end
455
+
456
+ it "should test bug ticket #302" do
457
+ repository(ADAPTER) do
458
+ Sprog.create(:name => 'Marty')
459
+ Sprog.first(:name => 'Marty').should_not be_nil
460
+ end
461
+ end
462
+
463
+ it "should select appropriate types" do
464
+ repository(ADAPTER) do
465
+ males = Male.all
466
+ males.should have(8).entries
467
+
468
+ males.each do |male|
469
+ male.class.name.should == male.type.name
470
+ end
471
+
472
+ Male.first(:name => 'Steve').should be_a_kind_of(Geek)
473
+ Bully.first(:name => 'Bob').should be_a_kind_of(Bully)
474
+ Geek.first(:name => 'Steve').should be_a_kind_of(Geek)
475
+ Geek.first(:name => 'Bill').should be_a_kind_of(Geek)
476
+ Bully.first(:name => 'Johnson').should be_a_kind_of(Bully)
477
+ Male.first(:name => 'John Dorian').should be_a_kind_of(Male)
478
+ end
479
+ end
480
+
481
+ it "should not select parent type" do
482
+ repository(ADAPTER) do
483
+ Male.first(:name => 'John Dorian').should be_a_kind_of(Male)
484
+ Geek.first(:name => 'John Dorian').should be_nil
485
+ Geek.first.iq.should > Bully.first.iq
486
+ end
487
+ end
488
+
489
+ it "should select objects of all inheriting classes" do
490
+ repository(ADAPTER) do
491
+ Male.all.should have(8).entries
492
+ Geek.all.should have(2).entries
493
+ Bully.all.should have(5).entries
494
+ Mugger.all.should have(1).entries
495
+ Maniac.all.should have(2).entries
496
+ Psycho.all.should have(1).entries
497
+ end
498
+ end
499
+
500
+ it "should inherit setter method from parent" do
501
+ repository(ADAPTER) do
502
+ Bully.first(:name => "Bob").iq.should == 68
503
+ end
504
+ end
505
+
506
+ it "should be able to overwrite a setter in a child class" do
507
+ repository(ADAPTER) do
508
+ Geek.first(:name => "Bill").iq.should == 180
509
+ end
510
+ end
511
+ end
512
+ end
513
+ end