dm-core 0.9.5 → 0.9.6

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 (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