dm-core 1.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -501,6 +501,7 @@ module DataMapper
501
501
  #
502
502
  # @api public
503
503
  def each
504
+ return to_enum unless block_given?
504
505
  super do |resource|
505
506
  begin
506
507
  original, resource.collection = resource.collection, self
@@ -314,6 +314,7 @@ module DataMapper
314
314
  end
315
315
 
316
316
  def each(&block)
317
+ return to_enum unless block_given?
317
318
  all.each(&block)
318
319
  self
319
320
  end
@@ -234,6 +234,7 @@ module DataMapper
234
234
  #{writer_visibility}
235
235
  def #{writer_name}(value)
236
236
  property = properties[#{name.inspect}]
237
+ value = property.typecast(value)
237
238
  self.persistence_state = persistence_state.set(property, value)
238
239
  persistence_state.get(property)
239
240
  end
@@ -622,7 +622,7 @@ module DataMapper
622
622
  #
623
623
  # @api private
624
624
  def set(resource, value)
625
- set!(resource, typecast(value))
625
+ set!(resource, value)
626
626
  end
627
627
 
628
628
  # Set the ivar value in the resource
@@ -682,8 +682,10 @@ module DataMapper
682
682
  def typecast(value)
683
683
  if value.nil? || primitive?(value)
684
684
  value
685
- elsif respond_to?(:typecast_to_primitive)
685
+ elsif respond_to?(:typecast_to_primitive, true)
686
686
  typecast_to_primitive(value)
687
+ else
688
+ value
687
689
  end
688
690
  end
689
691
 
@@ -1017,7 +1017,7 @@ module DataMapper
1017
1017
  add_condition(condition)
1018
1018
 
1019
1019
  when Hash
1020
- condition.each { |kv| append_condition(*kv) }
1020
+ condition.each { |key, value| append_condition(key, value) }
1021
1021
 
1022
1022
  when Array
1023
1023
  statement, *bind_values = *condition
@@ -1053,6 +1053,9 @@ module DataMapper
1053
1053
  @order = Array(@order)
1054
1054
  @order = @order.map do |order|
1055
1055
  case order
1056
+ when Direction
1057
+ order.dup
1058
+
1056
1059
  when Operator
1057
1060
  target = order.target
1058
1061
  property = target.kind_of?(Property) ? target : @properties[target]
@@ -1065,9 +1068,6 @@ module DataMapper
1065
1068
  when Property
1066
1069
  Direction.new(order)
1067
1070
 
1068
- when Direction
1069
- order.dup
1070
-
1071
1071
  when Path
1072
1072
  Direction.new(order.property)
1073
1073
 
@@ -280,7 +280,10 @@ module DataMapper
280
280
  # @api public
281
281
  def attribute_set(name, value)
282
282
  property = properties[name]
283
- self.persistence_state = persistence_state.set(property, value) if property
283
+ if property
284
+ value = property.typecast(value)
285
+ self.persistence_state = persistence_state.set(property, value)
286
+ end
284
287
  end
285
288
 
286
289
  alias_method :[]=, :attribute_set
@@ -335,6 +338,10 @@ module DataMapper
335
338
  raise ArgumentError, "The attribute '#{name}' is not accessible in #{model}"
336
339
  end
337
340
  when Associations::Relationship, Property
341
+ # only call a public #typecast (e.g. on Property instances)
342
+ if name.respond_to?(:typecast)
343
+ value = name.typecast(value)
344
+ end
338
345
  self.persistence_state = persistence_state.set(name, value)
339
346
  end
340
347
  end
@@ -50,7 +50,20 @@ module DataMapper
50
50
 
51
51
  def set_default_value(subject)
52
52
  return if subject.loaded?(resource) || !subject.default?
53
- set(subject, subject.default_for(resource))
53
+ default = typecast_default(subject, subject.default_for(resource))
54
+ set(subject, default)
55
+ end
56
+
57
+ def typecast_default(subject, default)
58
+ return default unless subject.respond_to?(:typecast)
59
+
60
+ typecasted_default = subject.send(:typecast, default)
61
+ unless typecasted_default.eql?(default)
62
+ warn "Automatic typecasting of default property values is deprecated " +
63
+ "(#{default.inspect} was casted to #{typecasted_default.inspect}). " +
64
+ "Specify the correct type for #{resource.class}."
65
+ end
66
+ typecasted_default
54
67
  end
55
68
 
56
69
  def track(subject)
@@ -45,12 +45,11 @@ module DataMapper
45
45
  next if object.kind_of?(DataMapper::Logger) ||
46
46
  object.kind_of?(DataMapper::DescendantSet) ||
47
47
  object.kind_of?(DataMapper::Adapters::AbstractAdapter) ||
48
- object.class.name[0, 13] == 'DataObjects::'
48
+ object.class.name.to_s[0, 13] == 'DataObjects::'
49
49
 
50
50
  # skip classes and modules in the DataMapper namespace
51
51
  next if object.kind_of?(Module) &&
52
- !object.name.nil? &&
53
- object.name[0, 12] == 'DataMapper::'
52
+ object.name.to_s[0, 12] == 'DataMapper::'
54
53
 
55
54
  # skip when the ivar is no longer defined in the object
56
55
  next unless object.instance_variable_defined?(ivar)
@@ -115,7 +115,9 @@ module DataMapper
115
115
  end
116
116
 
117
117
  def connection_uri
118
- "#{adapter_name}://#{username}:#{password}@#{host}/#{storage_name}"
118
+ "#{adapter_name}://#{username}%s@#{host}/#{storage_name}".tap do |s|
119
+ return s % ((password.empty?) ? "" : ":#{password}")
120
+ end
119
121
  end
120
122
 
121
123
  def storage_name
@@ -233,13 +233,17 @@ share_examples_for 'A public Resource' do
233
233
  describe 'when a public mutator is specified' do
234
234
  before :all do
235
235
  rescue_if @skip do
236
- @user.attributes = { :name => 'dkubb' }
236
+ @user.attributes = { :name => 'dkubb', @user.class.properties[:age] => '42' }
237
237
  end
238
238
  end
239
239
 
240
240
  it 'should set the value' do
241
241
  @user.name.should eql('dkubb')
242
242
  end
243
+
244
+ it 'should typecast and set the value' do
245
+ @user.age.should eql(42)
246
+ end
243
247
  end
244
248
 
245
249
  describe 'when a non-public mutator is specified' do
@@ -139,7 +139,7 @@ module DataMapper
139
139
 
140
140
  # @return [Hash] The mash as a Hash with string keys.
141
141
  def to_hash
142
- Hash.new(default).merge(self)
142
+ Hash.new(default).replace(self)
143
143
  end
144
144
 
145
145
  protected
@@ -316,6 +316,7 @@ module DataMapper
316
316
  #
317
317
  # @api private
318
318
  def each
319
+ return to_enum unless block_given?
319
320
  entries.each { |entry| yield(entry) }
320
321
  self
321
322
  end
@@ -207,6 +207,7 @@ module DataMapper
207
207
  #
208
208
  # @api private
209
209
  def each
210
+ return to_enum unless block_given?
210
211
  entries.each { |entry| yield(entry) }
211
212
  self
212
213
  end
@@ -1,3 +1,3 @@
1
1
  module DataMapper
2
- VERSION = '1.2.0.rc1'
2
+ VERSION = '1.2.1'
3
3
  end
@@ -82,7 +82,7 @@ end
82
82
 
83
83
  # load the targets without references to a single source
84
84
  load_collection = lambda do |query|
85
- @author_model.get(*@author.key).articles(query)
85
+ @author_model.get!(*@author.key).articles(query)
86
86
  end
87
87
 
88
88
  @articles = load_collection.call(:title => 'Sample Article')
@@ -177,7 +177,7 @@ end
177
177
 
178
178
  # load the targets without references to a single source
179
179
  load_collection = lambda do |query|
180
- @author_model.get(*@author.key).articles(query)
180
+ @author_model.get!(*@author.key).articles(query)
181
181
  end
182
182
 
183
183
  @articles = load_collection.call(:title => 'Sample Article')
@@ -73,7 +73,7 @@ describe 'Many to One Associations' do
73
73
  user = @user_model.create(:name => 'dbussink', :age => 25, :description => 'Test')
74
74
  comment = @comment_model.create(:body => 'Cool spec', :user => user)
75
75
 
76
- @comment = @comment_model.get(*comment.key)
76
+ @comment = @comment_model.get!(*comment.key)
77
77
  @user = @comment.user
78
78
  end
79
79
 
@@ -62,7 +62,7 @@ require 'spec_helper'
62
62
 
63
63
  # load the targets without references to a single source
64
64
  load_collection = lambda do |query|
65
- @author_model.get(*@author.key).articles(query)
65
+ @author_model.get!(*@author.key).articles(query)
66
66
  end
67
67
 
68
68
  @articles = load_collection.call(:title => 'Sample Article')
@@ -72,7 +72,7 @@ describe 'One to One Associations' do
72
72
  comment = @comment_model.create(:body => 'Cool spec')
73
73
  user = @user_model.create(:name => 'dbussink', :age => 25, :description => 'Test', :comment => comment)
74
74
 
75
- @comment = @comment_model.get(*comment.key)
75
+ @comment = @comment_model.get!(*comment.key)
76
76
  @user = @comment.user
77
77
  end
78
78
 
@@ -164,7 +164,7 @@ describe 'One to One Through Associations' do
164
164
  comment = @comment_model.create(:body => 'Cool spec')
165
165
  user = @user_model.create(:name => 'dbussink', :age => 25, :description => 'Test', :comment => comment)
166
166
 
167
- @comment = @comment_model.get(*comment.key)
167
+ @comment = @comment_model.get!(*comment.key)
168
168
  @user = @comment.user
169
169
  end
170
170
 
@@ -72,7 +72,7 @@ share_examples_for 'it creates a one accessor' do
72
72
  # set the model scope to not match the expected resource
73
73
  @model.default_scope.update(:id.not => @resource.id)
74
74
 
75
- @return = @car.model.get(*@car.key).__send__(@name)
75
+ @return = @car.model.get!(*@car.key).__send__(@name)
76
76
  end
77
77
 
78
78
  it 'should return nil' do
@@ -111,13 +111,13 @@ share_examples_for 'it creates a one mutator' do
111
111
 
112
112
  it 'should persist the Resource' do
113
113
  @car.save.should be(true)
114
- @car.model.get(*@car.key).__send__(@name).should == @expected
114
+ @car.model.get!(*@car.key).__send__(@name).should == @expected
115
115
  end
116
116
 
117
117
  it 'should persist the associated Resource' do
118
118
  @car.save.should be(true)
119
119
  @expected.should be_saved
120
- @expected.model.get(*@expected.key).car.should == @car
120
+ @expected.model.get!(*@expected.key).car.should == @car
121
121
  end
122
122
  end
123
123
 
@@ -151,13 +151,13 @@ share_examples_for 'it creates a one mutator' do
151
151
 
152
152
  it 'should persist the Resource' do
153
153
  @car.save.should be(true)
154
- @car.model.get(*@car.key).__send__(@name).should == @return
154
+ @car.model.get!(*@car.key).__send__(@name).should == @return
155
155
  end
156
156
 
157
157
  it 'should persist the associated Resource' do
158
158
  @car.save.should be(true)
159
159
  @return.should be_saved
160
- @return.model.get(*@return.key).car.should == @car
160
+ @return.model.get!(*@return.key).car.should == @car
161
161
  end
162
162
  end
163
163
 
@@ -178,7 +178,7 @@ share_examples_for 'it creates a one mutator' do
178
178
 
179
179
  it 'should persist as nil' do
180
180
  @car.save.should be(true)
181
- @car.model.get(*@car.key).__send__(@name).should be_nil
181
+ @car.model.get!(*@car.key).__send__(@name).should be_nil
182
182
  end
183
183
  end
184
184
 
@@ -210,13 +210,13 @@ share_examples_for 'it creates a one mutator' do
210
210
 
211
211
  it 'should persist the Resource' do
212
212
  @car.save.should be(true)
213
- @car.model.get(*@car.key).__send__(@name).should == @expected
213
+ @car.model.get!(*@car.key).__send__(@name).should == @expected
214
214
  end
215
215
 
216
216
  it 'should persist the associated Resource' do
217
217
  @car.save.should be(true)
218
218
  @expected.should be_saved
219
- @expected.model.get(*@expected.key).car.should == @car
219
+ @expected.model.get!(*@expected.key).car.should == @car
220
220
  end
221
221
  end
222
222
  end
@@ -285,7 +285,7 @@ share_examples_for 'it creates a many accessor' do
285
285
  Hash[ @model.key(@repository.name).zip(@expected.key) ]
286
286
  )
287
287
 
288
- @return = @car.model.get(*@car.key).__send__(@name)
288
+ @return = @car.model.get!(*@car.key).__send__(@name)
289
289
  end
290
290
 
291
291
  it 'should return a Collection' do
@@ -325,13 +325,13 @@ share_examples_for 'it creates a many mutator' do
325
325
 
326
326
  it 'should persist the Collection' do
327
327
  @car.save.should be(true)
328
- @car.model.get(*@car.key).__send__(@name).should == @expected
328
+ @car.model.get!(*@car.key).__send__(@name).should == @expected
329
329
  end
330
330
 
331
331
  it 'should persist the associated Resource' do
332
332
  @car.save.should be(true)
333
333
  @expected.each { |resource| resource.should be_saved }
334
- @expected.each { |resource| resource.model.get(*resource.key).car.should == @car }
334
+ @expected.each { |resource| resource.model.get!(*resource.key).car.should == @car }
335
335
  end
336
336
  end
337
337
 
@@ -360,13 +360,13 @@ share_examples_for 'it creates a many mutator' do
360
360
 
361
361
  it 'should persist the Collection' do
362
362
  @car.save.should be(true)
363
- @car.model.get(*@car.key).__send__(@name).should == @return
363
+ @car.model.get!(*@car.key).__send__(@name).should == @return
364
364
  end
365
365
 
366
366
  it 'should persist the associated Resource' do
367
367
  @car.save.should be(true)
368
368
  @return.each { |resource| resource.should be_saved }
369
- @return.each { |resource| resource.model.get(*resource.key).car.should == @car }
369
+ @return.each { |resource| resource.model.get!(*resource.key).car.should == @car }
370
370
  end
371
371
  end
372
372
 
@@ -387,7 +387,7 @@ share_examples_for 'it creates a many mutator' do
387
387
 
388
388
  it 'should persist as an empty Collection' do
389
389
  @car.save.should be(true)
390
- @car.model.get(*@car.key).__send__(@name).should be_empty
390
+ @car.model.get!(*@car.key).__send__(@name).should be_empty
391
391
  end
392
392
  end
393
393
 
@@ -417,13 +417,13 @@ share_examples_for 'it creates a many mutator' do
417
417
 
418
418
  it 'should persist the Resource' do
419
419
  @car.save.should be(true)
420
- @car.model.get(*@car.key).__send__(@name).should == @expected
420
+ @car.model.get!(*@car.key).__send__(@name).should == @expected
421
421
  end
422
422
 
423
423
  it 'should persist the associated Resource' do
424
424
  @car.save.should be(true)
425
425
  @expected.each { |resource| resource.should be_saved }
426
- @expected.each { |resource| resource.model.get(*resource.key).car.should == @car }
426
+ @expected.each { |resource| resource.model.get!(*resource.key).car.should == @car }
427
427
  end
428
428
  end
429
429
  end
@@ -111,7 +111,7 @@ describe DataMapper::Model do
111
111
  end
112
112
 
113
113
  it 'should add the resources to the alternate repository' do
114
- @article.model.get(*@heff1.key).should_not be_nil
114
+ @article.model.get!(*@heff1.key).should_not be_nil
115
115
  end
116
116
  end
117
117
  end
@@ -117,11 +117,11 @@ describe DataMapper::Property::Discriminator do
117
117
  end
118
118
 
119
119
  it 'should persist the type' do
120
- @announcement.model.get(*@announcement.key).type.should equal(@announcement_model)
120
+ @announcement.model.get!(*@announcement.key).type.should equal(@announcement_model)
121
121
  end
122
122
 
123
123
  it 'should be retrieved as an instance of the correct class' do
124
- @announcement.model.get(*@announcement.key).should be_instance_of(@announcement_model)
124
+ @announcement.model.get!(*@announcement.key).should be_instance_of(@announcement_model)
125
125
  end
126
126
 
127
127
  it 'should include descendants in finders' do
@@ -30,13 +30,24 @@ describe DataMapper::Property, 'Object type' do
30
30
  it { should respond_to(:typecast) }
31
31
 
32
32
  describe '#typecast' do
33
+ subject { @property.typecast(@value) }
34
+
33
35
  before do
34
36
  @value = { 'lang' => 'en_CA' }
35
37
  end
36
38
 
37
- subject { @property.typecast(@value) }
39
+ context 'when the value is a primitive' do
40
+ it { should equal(@value) }
41
+ end
38
42
 
39
- it { should equal(@value) }
43
+ context 'when the value is not a primitive' do
44
+ before do
45
+ # simulate the value not being a primitive
46
+ @property.should_receive(:primitive?).with(@value).and_return(false)
47
+ end
48
+
49
+ it { should equal(@value) }
50
+ end
40
51
  end
41
52
 
42
53
  it { should respond_to(:dump) }
@@ -263,12 +263,6 @@ describe DataMapper::Property do
263
263
 
264
264
  it 'triggers lazy loading for given resource'
265
265
 
266
- it 'type casts given value' do
267
- @property.set(@image, Addressable::URI.parse('http://test.example/'))
268
- # get a string that has been typecasted using #to_str
269
- @image.title.should == 'http://test.example/'
270
- end
271
-
272
266
  it 'sets new property value' do
273
267
  @property.set(@image, 'Updated value')
274
268
  @image.title.should == 'Updated value'