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