sam-dm-core 0.9.6

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