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.
- data/Manifest.txt +3 -0
- data/lib/dm-core.rb +14 -20
- data/lib/dm-core/adapters.rb +18 -0
- data/lib/dm-core/adapters/abstract_adapter.rb +17 -10
- data/lib/dm-core/adapters/data_objects_adapter.rb +17 -22
- data/lib/dm-core/adapters/in_memory_adapter.rb +87 -0
- data/lib/dm-core/adapters/mysql_adapter.rb +1 -1
- data/lib/dm-core/adapters/postgres_adapter.rb +2 -2
- data/lib/dm-core/adapters/sqlite3_adapter.rb +1 -1
- data/lib/dm-core/associations.rb +3 -2
- data/lib/dm-core/associations/many_to_many.rb +3 -3
- data/lib/dm-core/associations/one_to_many.rb +10 -2
- data/lib/dm-core/associations/relationship.rb +20 -16
- data/lib/dm-core/auto_migrations.rb +5 -4
- data/lib/dm-core/collection.rb +10 -6
- data/lib/dm-core/dependency_queue.rb +2 -1
- data/lib/dm-core/identity_map.rb +3 -6
- data/lib/dm-core/model.rb +48 -27
- data/lib/dm-core/property.rb +57 -37
- data/lib/dm-core/property_set.rb +29 -22
- data/lib/dm-core/query.rb +57 -49
- data/lib/dm-core/repository.rb +3 -3
- data/lib/dm-core/resource.rb +17 -15
- data/lib/dm-core/scope.rb +7 -7
- data/lib/dm-core/support/kernel.rb +6 -2
- data/lib/dm-core/transaction.rb +7 -7
- data/lib/dm-core/version.rb +1 -1
- data/script/performance.rb +114 -22
- data/spec/integration/association_spec.rb +31 -2
- data/spec/integration/association_through_spec.rb +2 -0
- data/spec/integration/associations/many_to_many_spec.rb +152 -0
- data/spec/integration/associations/one_to_many_spec.rb +40 -3
- data/spec/integration/dependency_queue_spec.rb +0 -12
- data/spec/integration/postgres_adapter_spec.rb +1 -1
- data/spec/integration/property_spec.rb +3 -3
- data/spec/integration/query_spec.rb +39 -8
- data/spec/integration/resource_spec.rb +10 -6
- data/spec/integration/sti_spec.rb +22 -0
- data/spec/integration/strategic_eager_loading_spec.rb +21 -6
- data/spec/integration/type_spec.rb +1 -0
- data/spec/lib/model_loader.rb +10 -1
- data/spec/models/content.rb +16 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/unit/adapters/data_objects_adapter_spec.rb +11 -11
- data/spec/unit/adapters/in_memory_adapter_spec.rb +98 -0
- data/spec/unit/associations/many_to_many_spec.rb +16 -1
- data/spec/unit/model_spec.rb +0 -16
- data/spec/unit/property_set_spec.rb +8 -1
- data/spec/unit/property_spec.rb +476 -240
- data/spec/unit/query_spec.rb +41 -0
- data/spec/unit/resource_spec.rb +75 -56
- data/tasks/ci.rb +4 -36
- data/tasks/dm.rb +3 -3
- 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
|
data/spec/unit/model_spec.rb
CHANGED
@@ -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|
|
data/spec/unit/property_spec.rb
CHANGED
@@ -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 :
|
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
|
-
|
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
|
31
|
-
lambda{
|
32
|
-
|
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
|
-
|
36
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
75
|
+
before(:each) do
|
76
|
+
Zoo.class_eval do
|
77
|
+
property :location, String, :field => "City"
|
64
78
|
|
65
|
-
|
66
|
-
|
79
|
+
repository(:mock) do
|
80
|
+
property :location, String, :field => "MockCity"
|
81
|
+
end
|
82
|
+
end
|
67
83
|
end
|
68
84
|
|
69
|
-
it 'should
|
70
|
-
|
85
|
+
it 'should accept a custom field' do
|
86
|
+
Zoo.properties[:location].field.should == 'City'
|
71
87
|
end
|
72
|
-
end
|
73
88
|
|
74
|
-
|
75
|
-
|
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
|
-
|
81
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
106
|
+
it 'should set the ivar to the default' do
|
107
|
+
@resource.name.should == 'San Diego'
|
108
|
+
end
|
88
109
|
|
89
|
-
|
90
|
-
@resource.
|
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
|
-
|
95
|
-
|
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
|
-
|
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
|
-
@
|
136
|
+
@resource.name
|
137
|
+
@resource.original_values[:name].should == "San Diego".hash
|
138
|
+
end
|
102
139
|
|
103
|
-
|
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
|
-
|
109
|
-
|
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 '
|
113
|
-
it
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
121
|
-
|
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
|
-
|
127
|
-
|
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
|
-
@
|
132
|
-
@
|
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
|
-
|
137
|
-
|
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
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
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
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
|
-
|
278
|
+
Zoo.class_eval do
|
279
|
+
property :name, String, :size => 30
|
280
|
+
end
|
160
281
|
|
161
|
-
|
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
|
-
|
166
|
-
|
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
|
-
|
171
|
-
|
332
|
+
Zoo.class_eval do
|
333
|
+
property :name, Name
|
172
334
|
end
|
173
335
|
|
174
|
-
|
336
|
+
Zoo.auto_migrate!
|
175
337
|
|
176
|
-
|
177
|
-
|
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
|
-
|
183
|
-
|
343
|
+
Zoo.class_eval do
|
344
|
+
property :name, Name, :track => :get
|
345
|
+
end
|
184
346
|
|
185
|
-
|
186
|
-
end
|
347
|
+
Zoo.auto_migrate!
|
187
348
|
|
188
|
-
|
189
|
-
|
190
|
-
|
349
|
+
Zoo.create(:name => %w(Awesome Person\ Dude))
|
350
|
+
zoo = Zoo.first
|
351
|
+
zoo.name = %w(Awesome Person\ Dude)
|
191
352
|
|
192
|
-
|
193
|
-
|
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
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
202
|
-
|
203
|
-
|
369
|
+
it "should determine nullness" do
|
370
|
+
Zoo.properties[:botanical_name].options[:nullable].should be_true
|
371
|
+
end
|
204
372
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
end
|
373
|
+
it "should determine its name" do
|
374
|
+
Zoo.properties[:botanical_name].name.should == :botanical_name
|
375
|
+
end
|
209
376
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
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
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
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
|
-
|
246
|
-
|
247
|
-
|
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
|
-
|
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
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
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
|
-
|
297
|
-
|
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
|
301
|
-
|
302
|
-
|
303
|
-
property :
|
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
|
-
|
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
|
311
|
-
|
312
|
-
|
313
|
-
|
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
|
317
|
-
|
318
|
-
|
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
|
322
|
-
|
323
|
-
|
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
|
327
|
-
|
328
|
-
|
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
|
332
|
-
|
333
|
-
|
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
|
339
|
-
|
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
|
-
|
353
|
-
|
354
|
-
|
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
|
-
|
359
|
-
|
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 =
|
364
|
-
|
365
|
-
|
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
|
-
|
371
|
-
|
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
|
-
|
378
|
-
|
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
|
-
|
384
|
-
|
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
|
-
|
389
|
-
|
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
|
-
|
395
|
-
|
396
|
-
|
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
|
-
|
407
|
-
|
408
|
-
|
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
|
-
{ '
|
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
|
-
|
416
|
-
|
417
|
-
|
418
|
-
end
|
635
|
+
Zoo.class_eval do
|
636
|
+
property :int, Integer
|
637
|
+
end
|
419
638
|
|
420
|
-
|
421
|
-
|
422
|
-
|
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
|
-
|
430
|
-
|
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
|
-
|
436
|
-
|
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
|
-
|
441
|
-
|
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
|
-
|
446
|
-
|
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
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
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
|
-
|
458
|
-
|
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
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
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
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
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
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
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
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
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
|
-
|
494
|
-
|
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
|
-
|
499
|
-
property
|
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
|
-
|
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
|
-
|
506
|
-
|
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
|
-
|
750
|
+
Zoo.class_eval { property :name, String }
|
751
|
+
Zoo.properties[:name].inspect.should == '#<Property:Zoo:name>'
|
516
752
|
end
|
517
753
|
end
|