rpbertp13-dm-core 0.9.11.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.
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 +52 -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 +32 -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 +138 -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 +221 -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 +252 -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 +60 -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 +469 -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