dm-core 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/Manifest.txt +3 -0
  2. data/lib/dm-core.rb +14 -20
  3. data/lib/dm-core/adapters.rb +18 -0
  4. data/lib/dm-core/adapters/abstract_adapter.rb +17 -10
  5. data/lib/dm-core/adapters/data_objects_adapter.rb +17 -22
  6. data/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
  7. data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
  8. data/lib/dm-core/adapters/postgres_adapter.rb +2 -2
  9. data/lib/dm-core/adapters/sqlite3_adapter.rb +1 -1
  10. data/lib/dm-core/associations.rb +3 -2
  11. data/lib/dm-core/associations/many_to_many.rb +3 -3
  12. data/lib/dm-core/associations/one_to_many.rb +10 -2
  13. data/lib/dm-core/associations/relationship.rb +20 -16
  14. data/lib/dm-core/auto_migrations.rb +5 -4
  15. data/lib/dm-core/collection.rb +10 -6
  16. data/lib/dm-core/dependency_queue.rb +2 -1
  17. data/lib/dm-core/identity_map.rb +3 -6
  18. data/lib/dm-core/model.rb +48 -27
  19. data/lib/dm-core/property.rb +57 -37
  20. data/lib/dm-core/property_set.rb +29 -22
  21. data/lib/dm-core/query.rb +57 -49
  22. data/lib/dm-core/repository.rb +3 -3
  23. data/lib/dm-core/resource.rb +17 -15
  24. data/lib/dm-core/scope.rb +7 -7
  25. data/lib/dm-core/support/kernel.rb +6 -2
  26. data/lib/dm-core/transaction.rb +7 -7
  27. data/lib/dm-core/version.rb +1 -1
  28. data/script/performance.rb +114 -22
  29. data/spec/integration/association_spec.rb +31 -2
  30. data/spec/integration/association_through_spec.rb +2 -0
  31. data/spec/integration/associations/many_to_many_spec.rb +152 -0
  32. data/spec/integration/associations/one_to_many_spec.rb +40 -3
  33. data/spec/integration/dependency_queue_spec.rb +0 -12
  34. data/spec/integration/postgres_adapter_spec.rb +1 -1
  35. data/spec/integration/property_spec.rb +3 -3
  36. data/spec/integration/query_spec.rb +39 -8
  37. data/spec/integration/resource_spec.rb +10 -6
  38. data/spec/integration/sti_spec.rb +22 -0
  39. data/spec/integration/strategic_eager_loading_spec.rb +21 -6
  40. data/spec/integration/type_spec.rb +1 -0
  41. data/spec/lib/model_loader.rb +10 -1
  42. data/spec/models/content.rb +16 -0
  43. data/spec/spec_helper.rb +4 -1
  44. data/spec/unit/adapters/data_objects_adapter_spec.rb +11 -11
  45. data/spec/unit/adapters/in_memory_adapter_spec.rb +98 -0
  46. data/spec/unit/associations/many_to_many_spec.rb +16 -1
  47. data/spec/unit/model_spec.rb +0 -16
  48. data/spec/unit/property_set_spec.rb +8 -1
  49. data/spec/unit/property_spec.rb +476 -240
  50. data/spec/unit/query_spec.rb +41 -0
  51. data/spec/unit/resource_spec.rb +75 -56
  52. data/tasks/ci.rb +4 -36
  53. data/tasks/dm.rb +3 -3
  54. metadata +5 -2
@@ -0,0 +1,98 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', "..", 'spec_helper'))
2
+
3
+ describe DataMapper::Adapters::InMemoryAdapter do
4
+ before do
5
+ DataMapper.setup(:inmem, :adapter => 'in_memory')
6
+
7
+ class Heffalump
8
+ include DataMapper::Resource
9
+
10
+ def self.default_repository_name
11
+ :inmem
12
+ end
13
+
14
+ property :color, String, :key => true # TODO: Drop the 'must have a key' limitation
15
+ property :num_spots, Integer
16
+ property :striped, Boolean
17
+ end
18
+
19
+ @heff1 = Heffalump.create(:color => 'Black', :num_spots => 0, :striped => true)
20
+ @heff2 = Heffalump.create(:color => 'Brown', :num_spots => 25, :striped => false)
21
+ @heff3 = Heffalump.create(:color => 'Blue', :num_spots => nil, :striped => false)
22
+ end
23
+
24
+ it 'should successfully save an object' do
25
+ @heff1.new_record?.should be_false
26
+ end
27
+
28
+ it 'should be able to get the object' do
29
+ Heffalump.get('Black').should == @heff1
30
+ end
31
+
32
+ it 'should be able to get all the objects' do
33
+ Heffalump.all.should == [@heff1, @heff2, @heff3]
34
+ end
35
+
36
+ it 'should be able to search for objects with equal value' do
37
+ Heffalump.all(:striped => true).should == [@heff1]
38
+ end
39
+
40
+ it 'should be able to search for objects included in an array of values' do
41
+ Heffalump.all(:num_spots => [ 25, 50, 75, 100 ]).should == [@heff2]
42
+ end
43
+
44
+ it 'should be able to search for objects included in a range of values' do
45
+ Heffalump.all(:num_spots => 25..100).should == [@heff2]
46
+ end
47
+
48
+ it 'should be able to search for objects with nil value' do
49
+ Heffalump.all(:num_spots => nil).should == [@heff3]
50
+ end
51
+
52
+ it 'should be able to search for objects with not equal value' do
53
+ Heffalump.all(:striped.not => true).should == [@heff2, @heff3]
54
+ end
55
+
56
+ it 'should be able to search for objects not included in an array of values' do
57
+ Heffalump.all(:num_spots.not => [ 25, 50, 75, 100 ]).should == [@heff1, @heff3]
58
+ end
59
+
60
+ it 'should be able to search for objects not included in a range of values' do
61
+ Heffalump.all(:num_spots.not => 25..100).should == [@heff1, @heff3]
62
+ end
63
+
64
+ it 'should be able to search for objects with not nil value' do
65
+ Heffalump.all(:num_spots.not => nil).should == [@heff1, @heff2]
66
+ end
67
+
68
+ it 'should be able to search for objects that match value' do
69
+ Heffalump.all(:color.like => 'Bl').should == [@heff1, @heff3]
70
+ end
71
+
72
+ it 'should be able to search for objects with value greater than' do
73
+ Heffalump.all(:num_spots.gt => 0).should == [@heff2]
74
+ end
75
+
76
+ it 'should be able to search for objects with value greater than or equal to' do
77
+ Heffalump.all(:num_spots.gte => 0).should == [@heff1, @heff2]
78
+ end
79
+
80
+ it 'should be able to search for objects with value less than' do
81
+ Heffalump.all(:num_spots.lt => 1).should == [@heff1]
82
+ end
83
+
84
+ it 'should be able to search for objects with value less than or equal to' do
85
+ Heffalump.all(:num_spots.lte => 0).should == [@heff1]
86
+ end
87
+
88
+ it 'should be able to update an object' do
89
+ @heff1.num_spots = 10
90
+ @heff1.save
91
+ Heffalump.get('Black').num_spots.should == 10
92
+ end
93
+
94
+ it 'should be able to destroy an object' do
95
+ @heff1.destroy
96
+ Heffalump.all.size.should == 2
97
+ end
98
+ end
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'spec_hel
2
2
 
3
3
  describe DataMapper::Associations::ManyToMany do
4
4
 
5
- load_models_for_metaphor :vehicles
5
+ load_models_for_metaphor :vehicles, :content
6
6
 
7
7
  it 'should allow a declaration' do
8
8
  lambda do
@@ -11,6 +11,21 @@ describe DataMapper::Associations::ManyToMany do
11
11
  end
12
12
  end.should_not raise_error
13
13
  end
14
+
15
+ it 'should handle models inside modules' do
16
+ lambda do
17
+ module Content
18
+ class Dialect
19
+ has n, :locales, :through => Resource, :class_name => "Language::Locale"
20
+ end
21
+
22
+ class Locale
23
+ has n, :dialects, :through => Resource, :class_name => "Language::Dialect"
24
+ end
25
+ end
26
+ end.should_not raise_error
27
+ end
28
+
14
29
  end
15
30
 
16
31
  describe DataMapper::Associations::ManyToMany::Proxy do
@@ -147,22 +147,6 @@ describe 'DataMapper::Model' do
147
147
  end
148
148
  end
149
149
 
150
- it 'should provide #inheritance_property' do
151
- ModelSpec::Resource.should respond_to(:inheritance_property)
152
- end
153
-
154
- describe '#inheritance_property' do
155
- it 'should return a Property object' do
156
- ModelSpec::Resource.inheritance_property(:legacy).should be_kind_of(DataMapper::Property)
157
- ModelSpec::Resource.inheritance_property(:legacy).name.should == :type
158
- ModelSpec::Resource.inheritance_property(:legacy).type.should == DM::Discriminator
159
- end
160
-
161
- it 'should use default repository when not passed any arguments' do
162
- ModelSpec::Resource.inheritance_property.object_id.should == ModelSpec::Resource.inheritance_property(:default).object_id
163
- end
164
- end
165
-
166
150
  it 'should provide #get' do
167
151
  ModelSpec::Resource.should respond_to(:get)
168
152
  end
@@ -24,7 +24,7 @@ end
24
24
 
25
25
  describe DataMapper::PropertySet do
26
26
  before :each do
27
- @properties = Icon.properties(:default)
27
+ @properties = Icon.properties(:default).dup
28
28
  end
29
29
 
30
30
  it "#slice should find properties" do
@@ -35,6 +35,13 @@ describe DataMapper::PropertySet do
35
35
  @properties.select { |property| property.primitive == Integer }.should have(3).entries
36
36
  end
37
37
 
38
+ it "#clear should clear out set" do
39
+ @properties.clear
40
+ @properties.key.should == []
41
+ @properties.defaults.should == []
42
+ @properties.length.should == 0
43
+ end
44
+
38
45
  it "#[] should find properties by name (Symbol or String)" do
39
46
  default_properties = [ :id, 'name', :width, 'height' ]
40
47
  @properties.each_with_index do |property,i|
@@ -1,221 +1,405 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
2
 
3
3
  describe DataMapper::Property do
4
- before :all do
4
+ before :each do
5
+ Object.send(:remove_const, :Zoo) if defined?(Zoo)
5
6
  class Zoo
6
7
  include DataMapper::Resource
8
+
9
+ property :id, DataMapper::Types::Serial
7
10
  end
8
11
 
12
+ Object.send(:remove_const, :Name) if defined?(Name)
9
13
  class Name < DataMapper::Type
10
14
  primitive String
11
- size 100
15
+ track :hash
16
+
17
+ def self.load(value, property)
18
+ value.split(", ").reverse
19
+ end
20
+
21
+ def self.dump(value, property)
22
+ value && value.reverse.join(", ")
23
+ end
24
+
25
+ def self.typecast(value, property)
26
+ value
27
+ end
12
28
  end
13
29
 
30
+ Object.send(:remove_const, :Tomato) if defined?(Tomato)
14
31
  class Tomato
15
32
  include DataMapper::Resource
16
33
  end
17
34
  end
18
35
 
19
- before do
20
- @property = DataMapper::Property.new(Zoo, :name, String, :default => 'San Diego')
21
- end
22
-
23
- it 'should provide .new' do
24
- DataMapper::Property.should respond_to(:new)
25
- end
26
-
27
36
  describe '.new' do
28
37
  [ Float, BigDecimal ].each do |primitive|
29
38
  describe "with a #{primitive} primitive" do
30
- it 'should raise an ArgumentError if precision is equal to or less than 0' do
31
- lambda{
32
- DataMapper::Property.new(Zoo, :test, primitive, :precision => 0)
39
+ it 'should raise an ArgumentError if precision is 0' do
40
+ lambda {
41
+ Zoo.class_eval <<-RUBY
42
+ property :test, #{primitive}, :precision => 0
43
+ RUBY
33
44
  }.should raise_error(ArgumentError)
45
+ end
34
46
 
35
- lambda{
36
- DataMapper::Property.new(Zoo, :test, primitive, :precision => -1)
47
+ it "raises an ArgumentError if precision is less than 0" do
48
+ lambda {
49
+ Zoo.class_eval <<-RUBY
50
+ property :test, #{primitive}, :precision => -1
51
+ RUBY
37
52
  }.should raise_error(ArgumentError)
38
53
  end
39
54
 
40
55
  it 'should raise an ArgumentError if scale is less than 0' do
41
- lambda{
42
- DataMapper::Property.new(Zoo, :test, primitive, :scale => -1)
56
+ lambda {
57
+ Zoo.class_eval <<-RUBY
58
+ property :test, #{primitive}, :scale => -1
59
+ RUBY
43
60
  }.should raise_error(ArgumentError)
44
61
  end
45
62
 
46
63
  it 'should raise an ArgumentError if precision is less than scale' do
47
- lambda{
48
- DataMapper::Property.new(Zoo, :test, primitive, :precision => 1, :scale => 2)
64
+ lambda {
65
+ Zoo.class_eval <<-RUBY
66
+ property :test, #{primitive}, :precision => 1, :scale => 2
67
+ RUBY
49
68
  }.should raise_error(ArgumentError)
50
69
  end
51
70
  end
52
71
  end
53
72
  end
54
73
 
55
- it 'should provide #field' do
56
- @property.should respond_to(:field)
57
- end
58
-
59
74
  describe '#field' do
60
- it 'should accept a custom field' do
61
- property = DataMapper::Property.new(Zoo, :location, String, :field => 'City')
62
- property.field.should == 'City'
63
- end
75
+ before(:each) do
76
+ Zoo.class_eval do
77
+ property :location, String, :field => "City"
64
78
 
65
- it 'should use repository name if passed in' do
66
- @property.field(:default).should == 'name'
79
+ repository(:mock) do
80
+ property :location, String, :field => "MockCity"
81
+ end
82
+ end
67
83
  end
68
84
 
69
- it 'should return default field if no repository name passed in' do
70
- @property.field.should == 'name'
85
+ it 'should accept a custom field' do
86
+ Zoo.properties[:location].field.should == 'City'
71
87
  end
72
- end
73
88
 
74
- it 'should provide #get' do
75
- @property.should respond_to(:get)
89
+ # How is this supposed to work?
90
+ it 'should use repository name if passed in' do
91
+ pending
92
+ Zoo.properties[:location].field(:mock).should == 'MockCity'
93
+ end
76
94
  end
77
95
 
78
96
  describe '#get' do
79
97
  before do
80
- @original_values = {}
81
- @resource = mock('resource', :kind_of? => true, :new_record? => true, :original_values => @original_values)
98
+ Zoo.class_eval do
99
+ property :name, String, :default => "San Diego"
100
+ property :address, String
101
+ end
102
+ @resource = Zoo.new
82
103
  end
83
104
 
84
105
  describe 'when setting the default on initial access' do
85
- before do
86
- # make sure there was no original value
87
- @original_values.should_not have_key(:name)
106
+ it 'should set the ivar to the default' do
107
+ @resource.name.should == 'San Diego'
108
+ end
88
109
 
89
- # force the default to be set
90
- @resource.should_receive(:instance_variable_get).with('@name').twice.and_return(nil)
91
- @resource.should_receive(:attribute_loaded?).with(:name).and_return(false)
110
+ it 'should set the original value to nil' do
111
+ @resource.original_values[:name].should == nil
92
112
  end
113
+ end
93
114
 
94
- it 'should set the ivar to the default' do
95
- @resource.should_receive(:instance_variable_set).with('@name', 'San Diego')
115
+ it "should not reload the default if you set the property to nil" do
116
+ @resource.name = nil
117
+ @resource.name.should == nil
118
+ end
119
+ end
120
+
121
+ describe '#get, when tracking via :hash' do
122
+ before do
123
+ Zoo.class_eval do
124
+ property :name, String, :lazy => true, :track => :hash
125
+ end
126
+ Zoo.auto_migrate!
127
+ @resource = Zoo.create(:name => "San Diego")
128
+ end
96
129
 
97
- @property.get(@resource).should == 'San Diego'
130
+ describe 'when setting the default on initial access' do
131
+ it 'should set the ivar to the default' do
132
+ @resource.name.should == "San Diego"
98
133
  end
99
134
 
100
135
  it 'should set the original value to nil' do
101
- @property.get(@resource).should == 'San Diego'
136
+ @resource.name
137
+ @resource.original_values[:name].should == "San Diego".hash
138
+ end
102
139
 
103
- @original_values.should == { :name => nil }
140
+ it "should know it's dirty if a change was made to the object" do
141
+ @resource.name.upcase!
142
+ @resource.should be_dirty
104
143
  end
105
144
  end
106
145
  end
107
146
 
108
- it 'should provide #get!' do
109
- @property.should respond_to(:get!)
147
+ describe '#get, when tracking via :get' do
148
+ before do
149
+ Zoo.class_eval do
150
+ property :name, String
151
+ end
152
+ Zoo.auto_migrate!
153
+ @resource = Zoo.create(:name => "San Diego")
154
+ end
155
+
156
+ describe 'when setting the default on initial access' do
157
+ it 'should set the ivar to the default' do
158
+ @resource.name.should == "San Diego"
159
+ end
160
+
161
+ it 'should set the original value to "San Diego"' do
162
+ @resource.name
163
+ @resource.original_values[:name].should == "San Diego"
164
+ end
165
+ end
166
+
167
+ it "should know it's dirty if a change was made to the object" do
168
+ @resource.name.upcase!
169
+ @resource.name
170
+ @resource.should be_dirty
171
+ @resource.original_values[:name].should == "San Diego"
172
+ end
110
173
  end
111
174
 
112
- describe '#get!' do
113
- it 'should get the resource instance variable' do
114
- resource = mock('resource', :kind_of? => true)
115
- resource.should_receive(:instance_variable_get).with('@name').and_return('Portland Zoo')
116
- @property.get!(resource).should == 'Portland Zoo'
175
+ describe 'with Proc defaults' do
176
+ it "calls the proc" do
177
+ Zoo.class_eval do
178
+ property :name, String, :default => proc {|r,p| "San Diego"}
179
+ property :address, String
180
+ end
181
+
182
+ Zoo.new.name.should == "San Diego"
183
+ end
184
+
185
+ it "provides the resource to the proc" do
186
+ Zoo.class_eval do
187
+ property :name, String, :default => proc {|r,p| r.address}
188
+ property :address, String
189
+ end
190
+
191
+ zoo = Zoo.new
192
+ zoo.address = "San Diego"
193
+ zoo.name.should == "San Diego"
194
+ end
195
+
196
+ it "provides the property to the proc" do
197
+ Zoo.class_eval do
198
+ property :name, String, :default => proc {|r,p| p.name.to_s}
199
+ end
200
+
201
+ zoo = Zoo.new
202
+ zoo.name.should == "name"
117
203
  end
118
204
  end
119
205
 
120
- it 'should provide #set' do
121
- @property.should respond_to(:set)
206
+
207
+ describe '#get!' do
208
+ it 'should get the resource' do
209
+ Zoo.class_eval do
210
+ property :name, String
211
+ end
212
+
213
+ resource = Zoo.new(:name => "Portland Zoo")
214
+ resource.name.should == "Portland Zoo"
215
+ end
122
216
  end
123
217
 
124
218
  describe '#set' do
125
- before do
126
- @original_values = {}
127
- @resource = mock('resource', :kind_of? => true, :original_values => @original_values, :new_record? => true)
219
+ before(:each) do
220
+ Zoo.class_eval do
221
+ property :name, String
222
+ property :age, Integer
223
+ property :description, String, :lazy => true
224
+ end
225
+ Zoo.auto_migrate!
226
+ Zoo.create(:name => "San Diego Zoo", :age => 888,
227
+ :description => "Great Zoo")
228
+ @resource = Zoo.new
128
229
  end
129
230
 
130
231
  it 'should typecast the value' do
131
- @property.should_receive(:typecast).with(888)
132
- @property.set(@resource, 888)
232
+ @resource.age = "888"
233
+ @resource.age.should == 888
234
+ end
235
+
236
+ it "should lazy load itself first" do
237
+ resource = Zoo.first
238
+ resource.description = "Still a Great Zoo"
239
+ resource.original_values[:description].should == "Great Zoo"
133
240
  end
134
- end
135
241
 
136
- it 'should provide #set!' do
137
- @property.should respond_to(:set!)
242
+ it "should only set original_values once" do
243
+ resource = Zoo.first
244
+ resource.description = "Still a Great Zoo"
245
+ resource.description = "What can I say. This is one great Zoo"
246
+ resource.original_values[:description].should == "Great Zoo"
247
+ end
138
248
  end
139
249
 
140
250
  describe '#set!' do
141
- it 'should set the resource instance variable' do
142
- resource = mock('resource', :kind_of? => true)
143
- resource.should_receive(:instance_variable_set).with('@name', 'Seattle Zoo').and_return(resource)
144
- @property.set!(resource, 'Seattle Zoo').object_id.should == resource.object_id
251
+ before do
252
+ Zoo.class_eval do
253
+ property :name, String
254
+ property :age, Integer
255
+ end
145
256
  end
146
- end
147
257
 
148
- it "should evaluate two similar properties as equal" do
149
- p1 = DataMapper::Property.new(Zoo, :name, String, { :size => 30 })
150
- p2 = DataMapper::Property.new(Zoo, :name, String, { :size => 30 })
151
- p3 = DataMapper::Property.new(Zoo, :title, String, { :size => 30 })
152
- p1.eql?(p2).should == true
153
- p1.hash.should == p2.hash
154
- p1.eql?(p3).should == false
155
- p1.hash.should_not == p3.hash
258
+ it 'should set the resource' do
259
+ resource = Zoo.new
260
+ resource.name = "Seattle Zoo"
261
+ resource.name.should == "Seattle Zoo"
262
+ end
156
263
  end
157
264
 
265
+ # What is this for?
266
+ # ---
267
+ # it "should evaluate two similar properties as equal" do
268
+ # p1 = DataMapper::Property.new(Zoo, :name, String, { :size => 30 })
269
+ # p2 = DataMapper::Property.new(Zoo, :name, String, { :size => 30 })
270
+ # p3 = DataMapper::Property.new(Zoo, :title, String, { :size => 30 })
271
+ # p1.eql?(p2).should == true
272
+ # p1.hash.should == p2.hash
273
+ # p1.eql?(p3).should == false
274
+ # p1.hash.should_not == p3.hash
275
+ # end
276
+
158
277
  it "should create a String property" do
159
- property = DataMapper::Property.new(Zoo, :name, String, { :size => 30 })
278
+ Zoo.class_eval do
279
+ property :name, String, :size => 30
280
+ end
160
281
 
161
- property.primitive.should == String
282
+ resource = Zoo.new
283
+ resource.name = 100
284
+ resource.name.should == "100"
162
285
  end
163
286
 
164
287
  it "should not have key that is lazy" do
165
- property = DataMapper::Property.new(Zoo, :id, DataMapper::Types::Text, { :key => true })
166
- property.lazy?.should == false
288
+ Zoo.class_eval do
289
+ property :id, DataMapper::Types::Text, :key => true
290
+ property :name, String, :lazy => true
291
+ end
292
+ Zoo.auto_migrate!
293
+
294
+ Zoo.create(:id => "100", :name => "San Diego Zoo")
295
+ zoo = Zoo.first
296
+
297
+ # Do we mean for attribute_loaded? to be public?
298
+ zoo.attribute_loaded?(:id).should == true
299
+ end
300
+
301
+ it "should lazily load other non-loaded, non-lazy fields" do
302
+ # This somewhat contorted setup is to successfully test that
303
+ # the list of eager properties to be loaded when it's initially
304
+ # missing is, in fact, repository-scoped
305
+ Zoo.class_eval do
306
+ property :id, DataMapper::Types::Serial
307
+ property :name, String, :lazy => true
308
+ property :address, String, :lazy => true
309
+
310
+ repository(:default2) do
311
+ property :name, String
312
+ property :address, String
313
+ end
314
+ end
315
+
316
+ repository(:default2) do
317
+ Zoo.auto_migrate!
318
+ Zoo.create(:name => "San Diego Zoo", :address => "San Diego")
319
+ end
320
+ repository(:default2) do
321
+ zoo = Zoo.first(:fields => [:id])
322
+
323
+ zoo.attribute_loaded?(:name).should == false
324
+ zoo.attribute_loaded?(:address).should == false
325
+ zoo.name
326
+ zoo.attribute_loaded?(:name).should == true
327
+ zoo.attribute_loaded?(:address).should == true
328
+ end
167
329
  end
168
330
 
169
331
  it "should use a custom type Name property" do
170
- class Name < DataMapper::Type
171
- primitive String
332
+ Zoo.class_eval do
333
+ property :name, Name
172
334
  end
173
335
 
174
- property = DataMapper::Property.new(Zoo, :name, Name, {})
336
+ Zoo.auto_migrate!
175
337
 
176
- property.primitive.should == String
177
- property.type.should == Name
178
- property.primitive.should == property.type.primitive
338
+ zoo = Zoo.create(:name => %w(Zoo San\ Diego))
339
+ Zoo.first.name.should == %w(Zoo San\ Diego)
179
340
  end
180
341
 
181
342
  it "should override type options with property options" do
182
- property = DataMapper::Property.new(Zoo, :name, Name, { :size => 50 })
183
- options = property.instance_variable_get(:@options)
343
+ Zoo.class_eval do
344
+ property :name, Name, :track => :get
345
+ end
184
346
 
185
- options[:size].should == 50
186
- end
347
+ Zoo.auto_migrate!
187
348
 
188
- it "should determine nullness" do
189
- DataMapper::Property.new(Tomato,:botanical_name,String,{:nullable => true}).options[:nullable].should == true
190
- end
349
+ Zoo.create(:name => %w(Awesome Person\ Dude))
350
+ zoo = Zoo.first
351
+ zoo.name = %w(Awesome Person\ Dude)
191
352
 
192
- it "should determine its name" do
193
- DataMapper::Property.new(Tomato,:botanical_name,String,{}).name.should == :botanical_name
353
+ # If we were tracking by hash, this would cause zoo to be dirty,
354
+ # as its hash would not match the original. Since we've overridden
355
+ # and are tracking by :get, it won't be dirty
356
+ zoo.name.stub!(:hash).and_return(1)
357
+ zoo.should_not be_dirty
194
358
  end
195
359
 
196
- it "should determine laziness" do
197
- DataMapper::Property.new(Tomato,:botanical_name,String,{:lazy => true}).lazy?.should == true
198
- DataMapper::Property.new(Tomato,:seedless,TrueClass,{}).lazy?.should == false
199
- end
360
+ describe "public details" do
361
+ before do
362
+ Zoo.class_eval do
363
+ property :botanical_name, String, :nullable => true, :lazy => true
364
+ property :colloquial_name, DataMapper::Types::Text, :default => "Tomato"
365
+ end
366
+ Zoo.auto_migrate!
367
+ end
200
368
 
201
- it "should automatically set laziness to true on text fields?" do
202
- DataMapper::Property.new(Tomato,:botanical_name,DataMapper::Types::Text,{}).lazy?.should == true
203
- end
369
+ it "should determine nullness" do
370
+ Zoo.properties[:botanical_name].options[:nullable].should be_true
371
+ end
204
372
 
205
- it "should determine whether it is a key" do
206
- DataMapper::Property.new(Tomato,:id,Integer,{:key => true}).key?.should == true
207
- DataMapper::Property.new(Tomato,:botanical_name,String,{}).key?.should == false
208
- end
373
+ it "should determine its name" do
374
+ Zoo.properties[:botanical_name].name.should == :botanical_name
375
+ end
209
376
 
210
- it "should determine whether it is serial" do
211
- DataMapper::Property.new(Tomato,:id,Integer,{:serial => true}).serial?.should == true
212
- DataMapper::Property.new(Tomato,:botanical_name,String,{}).serial?.should == false
213
- end
377
+ # lazy? is not exposed to or used by the adapters, so it should be tested indirectly
378
+ it "should determine laziness" do
379
+ Zoo.create(:botanical_name => "Calystegia sepium")
380
+ Zoo.first.attribute_loaded?(:botanical_name).should be_false
381
+ end
382
+
383
+ it "should automatically set laziness to true on text fields" do
384
+ Zoo.create(:colloquial_name => "American hedge bindweed")
385
+ Zoo.first.attribute_loaded?(:colloquial_name).should be_false
386
+ end
387
+
388
+ it "should determine whether it is a key" do
389
+ zoo = Zoo.create(:botanical_name => "Calystegia sepium")
390
+ id = zoo.id
391
+ Zoo.first.id.should == id
392
+ end
393
+
394
+ it "should determine whether it is serial" do
395
+ zoo = Zoo.create(:botanical_name => "Calystegia sepium")
396
+ zoo.id.should_not be_nil
397
+ end
214
398
 
215
- it "should determine a default value" do
216
- resource = mock('resource')
217
- property = DataMapper::Property.new(Tomato, :botanical_name, String, :default => 'Tomato')
218
- property.default_for(resource).should == 'Tomato'
399
+ it "should determine a default value" do
400
+ zoo = Zoo.new
401
+ zoo.colloquial_name.should == "Tomato"
402
+ end
219
403
  end
220
404
 
221
405
  describe "reader and writer visibility" do
@@ -242,9 +426,11 @@ describe DataMapper::Property do
242
426
  { :reader => :private, :writer => :private } => [:private, :private],
243
427
  }.each do |input, output|
244
428
  it "#{input.inspect} should make reader #{output[0]} and writer #{output[1]}" do
245
- property = DataMapper::Property.new(Tomato, :botanical_name, String, input)
246
- property.reader_visibility.should == output[0]
247
- property.writer_visibility.should == output[1]
429
+ Tomato.class_eval <<-RUBY
430
+ property :botanical_name, String, #{input.inspect}
431
+ RUBY
432
+ Tomato.send("#{output[0]}_instance_methods").should include("botanical_name")
433
+ Tomato.send("#{output[1]}_instance_methods").should include("botanical_name=")
248
434
  end
249
435
  end
250
436
 
@@ -264,16 +450,20 @@ describe DataMapper::Property do
264
450
  ].each do |input|
265
451
  it "#{input.inspect} should raise ArgumentError" do
266
452
  lambda {
267
- property = DataMapper::Property.new(Tomato, :family, String, input)
453
+ Tomato.class_eval <<-RUBY
454
+ property :family, String, #{input.inspect}
455
+ RUBY
268
456
  }.should raise_error(ArgumentError)
269
457
  end
270
458
  end
271
459
  end
272
460
 
273
- it "should return an instance variable name" do
274
- DataMapper::Property.new(Tomato, :flavor, String, {}).instance_variable_name.should == '@flavor'
275
- DataMapper::Property.new(Tomato, :ripe, TrueClass, {}).instance_variable_name.should == '@ripe' #not @ripe?
276
- end
461
+ # This is handled by get!
462
+ # ---
463
+ # it "should return an instance variable name" do
464
+ # DataMapper::Property.new(Tomato, :flavor, String, {}).instance_variable_name.should == '@flavor'
465
+ # DataMapper::Property.new(Tomato, :ripe, TrueClass, {}).instance_variable_name.should == '@ripe' #not @ripe?
466
+ # end
277
467
 
278
468
  it "should append ? to TrueClass property reader methods" do
279
469
  class Potato
@@ -283,60 +473,61 @@ describe DataMapper::Property do
283
473
  property :public, TrueClass
284
474
  end
285
475
 
286
- Potato.new().should respond_to(:fresh)
287
- Potato.new().should respond_to(:fresh?)
288
-
289
476
  Potato.new(:fresh => true).should be_fresh
290
-
291
- Potato.new().should respond_to(:public)
292
- Potato.new().should respond_to(:public?)
293
477
  end
294
478
 
295
479
  it "should move unknown options into Property#extra_options" do
296
- d = DataMapper::Property.new(Tomato,:botanical_name,String,{:foo=>:bar})
297
- d.extra_options.should == {:foo => :bar}
480
+ Tomato.class_eval do
481
+ property :botanical_name, String, :foo => :bar
482
+ end
483
+ Tomato.properties[:botanical_name].extra_options.should == {:foo => :bar}
298
484
  end
299
485
 
300
- it 'should return the attribute value from a given instance' do
301
- class Tomato
302
- include DataMapper::Resource
303
- property :id, Integer, :key => true
486
+ it 'should provide #custom?' do
487
+ Zoo.class_eval do
488
+ property :name, Name, :size => 50
489
+ property :state, String, :size => 2
304
490
  end
305
-
306
- tomato = Tomato.new(:id => 1)
307
- tomato.model.properties(:default)[:id].get(tomato).should == 1
491
+ Zoo.properties[:name].should be_custom
492
+ Zoo.properties[:state].should_not be_custom
308
493
  end
309
494
 
310
- it 'should set the attribute value in a given instance' do
311
- tomato = Tomato.new
312
- tomato.model.properties(:default)[:id].set(tomato, 2)
313
- tomato.id.should == 2
495
+ it "should set the field to the correct field_naming_convention" do
496
+ Zoo.class_eval { property :species, String }
497
+ Tomato.class_eval { property :genetic_history, DataMapper::Types::Text }
498
+
499
+ Zoo.properties[:species].field.should == "species"
500
+ Tomato.properties[:genetic_history].field.should == "genetic_history"
314
501
  end
315
502
 
316
- it 'should provide #custom?' do
317
- DataMapper::Property.new(Zoo, :name, Name, { :size => 50 }).should be_custom
318
- DataMapper::Property.new(Zoo, :state, String, { :size => 2 }).should_not be_custom
503
+ it "should provide the primitive mapping" do
504
+ Zoo.class_eval do
505
+ property :poverty, String
506
+ property :fortune, DataMapper::Types::Text
507
+ end
508
+
509
+ Zoo.properties[:poverty].primitive.should == String
510
+ Zoo.properties[:fortune].primitive.should == String
319
511
  end
320
512
 
321
- it "should set the field to the correct field_naming_convention" do
322
- DataMapper::Property.new(Zoo, :species, String, {}).field(:default).should == 'species'
323
- DataMapper::Property.new(Tomato, :genetic_history, DataMapper::Types::Text, {}).field(:default).should == "genetic_history"
513
+ it "should make it possible to define an integer size" do
514
+ Zoo.class_eval { property :cleanliness, String, :size => 100 }
515
+ Zoo.properties[:cleanliness].size.should == 100
324
516
  end
325
517
 
326
- it "should provide the primitive mapping" do
327
- DataMapper::Property.new(Zoo, :poverty, String, {}).primitive.should == String
328
- DataMapper::Property.new(Zoo, :fortune, DataMapper::Types::Text, {}).primitive.should == String
518
+ it "should make it possible to define an integer length (which defines size)" do
519
+ Zoo.class_eval { property :cleanliness, String, :length => 100 }
520
+ Zoo.properties[:cleanliness].size.should == 100
329
521
  end
330
522
 
331
- it "should provide a size/length" do
332
- DataMapper::Property.new(Zoo, :cleanliness, String, { :size => 100 }).size.should == 100
333
- DataMapper::Property.new(Zoo, :cleanliness, String, { :length => 200 }).size.should == 200
334
- DataMapper::Property.new(Zoo, :cleanliness, String, { :size => (0..100) }).size.should == 100
335
- DataMapper::Property.new(Zoo, :cleanliness, String, { :length => (0..200) }).size.should == 200
523
+ it "should make it possible to define a range size" do
524
+ Zoo.class_eval { property :cleanliness, String, :size => 0..100 }
525
+ Zoo.properties[:cleanliness].size.should == 100
336
526
  end
337
527
 
338
- it 'should provide #typecast' do
339
- DataMapper::Property.new(Zoo, :name, String).should respond_to(:typecast)
528
+ it "should make it possible to define a range length (which defines size)" do
529
+ Zoo.class_eval { property :cleanliness, String, :length => 0..100 }
530
+ Zoo.properties[:cleanliness].size.should == 100
340
531
  end
341
532
 
342
533
  describe '#typecast' do
@@ -349,169 +540,214 @@ describe DataMapper::Property do
349
540
  end
350
541
 
351
542
  it 'should pass through the value if it is the same type when typecasting' do
352
- value = 'San Diego'
353
- property = DataMapper::Property.new(Zoo, :name, String)
354
- property.typecast(value).object_id.should == value.object_id
543
+ Zoo.class_eval do
544
+ property :name, String
545
+ end
546
+ zoo = Zoo.new
547
+ value = "San Diego"
548
+ def value.to_s() "San Francisco" end
549
+ zoo.name = value
550
+ zoo.name.should == "San Diego"
355
551
  end
356
552
 
357
553
  it 'should pass through the value nil when typecasting' do
358
- property = DataMapper::Property.new(Zoo, :string, String)
359
- property.typecast(nil).should == nil
554
+ Zoo.class_eval do
555
+ property :name, String
556
+ end
557
+
558
+ zoo = Zoo.new
559
+ zoo.name = nil
560
+ zoo.name.should == nil
360
561
  end
361
562
 
362
563
  it 'should pass through the value for an Object property' do
363
- value = 'a ruby object'
364
- property = DataMapper::Property.new(Zoo, :object, Object)
365
- property.typecast(value).object_id.should == value.object_id
564
+ value = Object.new
565
+ Zoo.class_eval do
566
+ property :object, Object
567
+ end
568
+
569
+ zoo = Zoo.new
570
+ zoo.object = value
571
+ zoo.object.object_id.should == value.object_id
366
572
  end
367
573
 
368
574
  [ true, 'true', 'TRUE', 1, '1', 't', 'T' ].each do |value|
369
575
  it "should typecast #{value.inspect} to true for a TrueClass property" do
370
- property = DataMapper::Property.new(Zoo, :true_class, TrueClass)
371
- property.typecast(value).should == true
576
+ Zoo.class_eval do
577
+ property :boolean, TrueClass
578
+ end
579
+
580
+ zoo = Zoo.new
581
+ zoo.boolean = value
582
+ zoo.boolean.should == true
372
583
  end
373
584
  end
374
585
 
375
586
  [ false, 'false', 'FALSE', 0, '0', 'f', 'F' ].each do |value|
376
587
  it "should typecast #{value.inspect} to false for a Boolean property" do
377
- property = DataMapper::Property.new(Zoo, :true_class, TrueClass)
378
- property.typecast(value).should == false
588
+ Zoo.class_eval do
589
+ property :boolean, TrueClass
590
+ end
591
+
592
+ zoo = Zoo.new
593
+ zoo.boolean = value
594
+ zoo.boolean.should == false
379
595
  end
380
596
  end
381
597
 
382
598
  it 'should typecast nil to nil for a Boolean property' do
383
- property = DataMapper::Property.new(Zoo, :true_class, TrueClass)
384
- property.typecast(nil).should == nil
599
+ Zoo.class_eval do
600
+ property :boolean, TrueClass
601
+ end
602
+
603
+ zoo = Zoo.new
604
+ zoo.boolean = nil
605
+ zoo.boolean.should == nil
385
606
  end
386
607
 
387
608
  it 'should typecast "0" to "0" for a String property' do
388
- property = DataMapper::Property.new(Zoo, :string, String)
389
- property.typecast(0).should == '0'
609
+ Zoo.class_eval do
610
+ property :string, String
611
+ end
612
+
613
+ zoo = Zoo.new
614
+ zoo.string = "0"
615
+ zoo.string.should == "0"
390
616
  end
391
617
 
392
618
  { '0' => 0.0, '0.0' => 0.0, 0 => 0.0, 0.0 => 0.0, BigDecimal('0.0') => 0.0 }.each do |value,expected|
393
619
  it "should typecast #{format(value)} to #{format(expected)} for a Float property" do
394
- property = DataMapper::Property.new(Zoo, :float, Float)
395
- property.typecast(value).should == expected
396
- end
397
- end
398
-
399
- { '-8' => -8, '-8.0' => -8, -8 => -8, -8.0 => -8, BigDecimal('8.0') => 8 }.each do |value,expected|
400
- it "should typecast #{format(value)} to #{format(expected)} for an Integer property" do
401
- property = DataMapper::Property.new(Zoo, :integer, Integer)
402
- property.typecast(value).should == expected
403
- end
404
- end
620
+ Zoo.class_eval do
621
+ property :float, Float
622
+ end
405
623
 
406
- { '0' => 0, '0.0' => 0, 0 => 0, 0.0 => 0, BigDecimal('0.0') => 0 }.each do |value,expected|
407
- it "should typecast #{format(value)} to #{format(expected)} for an Integer property" do
408
- property = DataMapper::Property.new(Zoo, :integer, Integer)
409
- property.typecast(value).should == expected
624
+ zoo = Zoo.new
625
+ zoo.float = value
626
+ zoo.float.should == expected
410
627
  end
411
628
  end
412
629
 
413
- { '5' => 5, '5.0' => 5, 5 => 5, 5.0 => 5, BigDecimal('5.0') => 5 }.each do |value,expected|
630
+ { '-8' => -8, '-8.0' => -8, -8 => -8, -8.0 => -8, BigDecimal('8.0') => 8,
631
+ '0' => 0, '0.0' => 0, 0 => 0, 0.0 => 0, BigDecimal('0.0') => 0,
632
+ '5' => 5, '5.0' => 5, 5 => 5, 5.0 => 5, BigDecimal('5.0') => 5,
633
+ 'none' => nil, 'almost 5' => nil, '-3 change' => -3, '9 items' => 9}.each do |value,expected|
414
634
  it "should typecast #{format(value)} to #{format(expected)} for an Integer property" do
415
- property = DataMapper::Property.new(Zoo, :integer, Integer)
416
- property.typecast(value).should == expected
417
- end
418
- end
635
+ Zoo.class_eval do
636
+ property :int, Integer
637
+ end
419
638
 
420
- { 'none' => nil, 'almost 5' => nil, '-3 change' => -3, '9 items' => 9 }.each do |value,expected|
421
- it "should typecast #{format(value)} to #{format(expected)} for an Integer property" do
422
- property = DataMapper::Property.new(Zoo, :integer, Integer)
423
- property.typecast(value).should == expected
639
+ zoo = Zoo.new
640
+ zoo.int = value
641
+ zoo.int.should == expected
424
642
  end
425
643
  end
426
644
 
427
645
  { '0' => BigDecimal('0'), '0.0' => BigDecimal('0.0'), 0.0 => BigDecimal('0.0'), BigDecimal('0.0') => BigDecimal('0.0') }.each do |value,expected|
428
646
  it "should typecast #{format(value)} to #{format(expected)} for a BigDecimal property" do
429
- property = DataMapper::Property.new(Zoo, :big_decimal, BigDecimal)
430
- property.typecast(value).should == expected
647
+ Zoo.class_eval do
648
+ property :big_decimal, BigDecimal
649
+ end
650
+
651
+ zoo = Zoo.new
652
+ zoo.big_decimal = value
653
+ zoo.big_decimal.should == expected
431
654
  end
432
655
  end
433
656
 
434
657
  it 'should typecast value for a DateTime property' do
435
- property = DataMapper::Property.new(Zoo, :date_time, DateTime)
436
- property.typecast('2000-01-01 00:00:00').should == DateTime.new(2000, 1, 1, 0, 0, 0)
658
+ Zoo.class_eval { property :date_time, DateTime }
659
+ zoo = Zoo.new
660
+ zoo.date_time = '2000-01-01 00:00:00'
661
+ zoo.date_time.should == DateTime.new(2000, 1, 1, 0, 0, 0)
437
662
  end
438
663
 
439
664
  it 'should typecast value for a Date property' do
440
- property = DataMapper::Property.new(Zoo, :date, Date)
441
- property.typecast('2000-01-01').should == Date.new(2000, 1, 1)
665
+ Zoo.class_eval { property :date, Date }
666
+ zoo = Zoo.new
667
+ zoo.date = '2000-01-01'
668
+ zoo.date.should == Date.new(2000, 1, 1)
442
669
  end
443
670
 
444
671
  it 'should typecast value for a Time property' do
445
- property = DataMapper::Property.new(Zoo, :time, Time)
446
- property.typecast('2000-01-01 01:01:01.123456').should == Time.local(2000, 1, 1, 1, 1, 1, 123456)
672
+ Zoo.class_eval { property :time, Time }
673
+ zoo = Zoo.new
674
+ zoo.time = '2000-01-01 01:01:01.123456'
675
+ zoo.time.should == Time.local(2000, 1, 1, 1, 1, 1, 123456)
447
676
  end
448
677
 
449
678
  it 'should typecast Hash for a Time property' do
450
- property = DataMapper::Property.new(Zoo, :time, Time)
451
- property.typecast(
452
- :year => 2002, "month" => 1, :day => 1, "hour" => 12, :min => 0, :sec => 0
453
- ).should == Time.local(2002, 1, 1, 12, 0, 0)
679
+ Zoo.class_eval { property :time, Time }
680
+ zoo = Zoo.new
681
+ zoo.time = {:year => 2002, "month" => 1, :day => 1, "hour" => 12, :min => 0, :sec => 0}
682
+ zoo.time.should == Time.local(2002, 1, 1, 12, 0, 0)
454
683
  end
455
684
 
456
685
  it 'should typecast Hash for a Date property' do
457
- property = DataMapper::Property.new(Zoo, :date, Date)
458
- property.typecast(:year => 2002, "month" => 1, :day => 1).should == Date.new(2002, 1, 1)
686
+ Zoo.class_eval { property :date, Date }
687
+ zoo = Zoo.new
688
+ zoo.date = {:year => 2002, "month" => 1, :day => 1}
689
+ zoo.date.should == Date.new(2002, 1, 1)
459
690
  end
460
691
 
461
692
  it 'should typecast Hash for a DateTime property' do
462
- property = DataMapper::Property.new(Zoo, :date_time, DateTime)
463
- property.typecast(
464
- :year => 2002, :month => 1, :day => 1, "hour" => 12, :min => 0, "sec" => 0
465
- ).should == DateTime.new(2002, 1, 1, 12, 0, 0)
693
+ Zoo.class_eval { property :date_time, DateTime }
694
+ zoo = Zoo.new
695
+ zoo.date_time = {:year => 2002, :month => 1, :day => 1, "hour" => 12, :min => 0, "sec" => 0}
696
+ zoo.date_time.should == DateTime.new(2002, 1, 1, 12, 0, 0)
466
697
  end
467
698
 
468
699
  it 'should use now as defaults for missing parts of a Hash to Time typecast' do
469
700
  now = Time.now
470
- property = DataMapper::Property.new(Zoo, :time, Time)
471
- property.typecast(
472
- :month => 1, :day => 1
473
- ).should == Time.local(now.year, 1, 1, now.hour, now.min, now.sec)
701
+ Zoo.class_eval { property :time, Time }
702
+ zoo = Zoo.new
703
+ zoo.time = {:month => 1, :day => 1}
704
+ zoo.time.should == Time.local(now.year, 1, 1, now.hour, now.min, now.sec)
474
705
  end
475
706
 
476
707
  it 'should use now as defaults for missing parts of a Hash to Date typecast' do
477
708
  now = Time.now
478
- property = DataMapper::Property.new(Zoo, :date, Date)
479
- property.typecast(
480
- :month => 1, :day => 1
481
- ).should == Date.new(now.year, 1, 1)
709
+ Zoo.class_eval { property :date, Date }
710
+ zoo = Zoo.new
711
+ zoo.date = {:month => 1, :day => 1}
712
+ zoo.date.should == Date.new(now.year, 1, 1)
482
713
  end
483
714
 
484
715
  it 'should use now as defaults for missing parts of a Hash to DateTime typecast' do
485
716
  now = Time.now
486
- property = DataMapper::Property.new(Zoo, :date_time, DateTime)
487
- property.typecast(
488
- :month => 1, :day => 1
489
- ).should == DateTime.new(now.year, 1, 1, now.hour, now.min, now.sec)
717
+ Zoo.class_eval { property :date_time, DateTime }
718
+ zoo = Zoo.new
719
+ zoo.date_time = {:month => 1, :day => 1}
720
+ zoo.date_time.should == DateTime.new(now.year, 1, 1, now.hour, now.min, now.sec)
490
721
  end
491
722
 
492
723
  it 'should rescue after trying to typecast an invalid Date value from a hash' do
493
- property = DataMapper::Property.new(Zoo, :date, Date)
494
- property.typecast(:year => 2002, :month => 2, :day => 31).should == Date.new(2002, 3, 3)
724
+ now = Time.now
725
+ Zoo.class_eval { property :date, Date }
726
+ zoo = Zoo.new
727
+ zoo.date = {:year => 2002, :month => 2, :day => 31}
728
+ zoo.date.should == Date.new(2002, 3, 3)
495
729
  end
496
730
 
497
731
  it 'should rescue after trying to typecast an invalid DateTime value from a hash' do
498
- property = DataMapper::Property.new(Zoo, :date_time, DateTime)
499
- property.typecast(
732
+ now = Time.now
733
+ Zoo.class_eval { property :date_time, DateTime }
734
+ zoo = Zoo.new
735
+ zoo.date_time = {
500
736
  :year => 2002, :month => 2, :day => 31, :hour => 12, :min => 0, :sec => 0
501
- ).should == DateTime.new(2002, 3, 3, 12, 0, 0)
737
+ }
738
+ zoo.date_time.should == DateTime.new(2002, 3, 3, 12, 0, 0)
502
739
  end
503
740
 
504
741
  it 'should typecast value for a Class property' do
505
- property = DataMapper::Property.new(Zoo, :class, Class)
506
- property.typecast('Zoo').should == Zoo
742
+ Zoo.class_eval { property :klass, Class }
743
+ zoo = Zoo.new
744
+ zoo.klass = "Zoo"
745
+ zoo.klass.should == Zoo
507
746
  end
508
747
  end
509
748
 
510
- it 'should provide #inspect' do
511
- DataMapper::Property.new(Zoo, :name, String).should respond_to(:inspect)
512
- end
513
-
514
749
  it 'should return an abbreviated representation of the property when inspected' do
515
- DataMapper::Property.new(Zoo, :name, String).inspect.should == '#<Property:Zoo:name>'
750
+ Zoo.class_eval { property :name, String }
751
+ Zoo.properties[:name].inspect.should == '#<Property:Zoo:name>'
516
752
  end
517
753
  end