Fixing CastedModel bug that modified casted objects
Also refactored code for skipping casting of nil-valued properties Added and re-arranged specs
This commit is contained in:
parent
101024aabc
commit
96f8d1aa96
|
@ -39,9 +39,10 @@ module CouchRest
|
||||||
self.class.properties.each do |property|
|
self.class.properties.each do |property|
|
||||||
next unless property.casted
|
next unless property.casted
|
||||||
key = self.has_key?(property.name) ? property.name : property.name.to_sym
|
key = self.has_key?(property.name) ? property.name : property.name.to_sym
|
||||||
|
# Don't cast the property unless it has a value
|
||||||
|
next unless self[key]
|
||||||
target = property.type
|
target = property.type
|
||||||
if target.is_a?(Array)
|
if target.is_a?(Array)
|
||||||
next unless self[key]
|
|
||||||
klass = ::CouchRest.constantize(target[0])
|
klass = ::CouchRest.constantize(target[0])
|
||||||
self[property.name] = self[key].collect do |value|
|
self[property.name] = self[key].collect do |value|
|
||||||
# Auto parse Time objects
|
# Auto parse Time objects
|
||||||
|
@ -56,8 +57,7 @@ module CouchRest
|
||||||
else
|
else
|
||||||
# Let people use :send as a Time parse arg
|
# Let people use :send as a Time parse arg
|
||||||
klass = ::CouchRest.constantize(target)
|
klass = ::CouchRest.constantize(target)
|
||||||
# Only cast this key if it has a value. Otherwise, leave nil.
|
klass.send(property.init_method, self[key].dup)
|
||||||
self[key].nil? ? nil : klass.send(property.init_method, self[key])
|
|
||||||
end
|
end
|
||||||
self[property.name].casted_by = self if self[property.name].respond_to?(:casted_by)
|
self[property.name].casted_by = self if self[property.name].respond_to?(:casted_by)
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,23 +18,58 @@ end
|
||||||
|
|
||||||
describe "casting an extended document" do
|
describe "casting an extended document" do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@driver = Driver.new(:name => 'Matt')
|
||||||
|
@car = Car.new(:name => 'Renault 306', :driver => @driver)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should retain all properties of the casted attribute" do
|
||||||
|
@car.driver.should == @driver
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should let the casted document know who casted it" do
|
||||||
|
@car.driver.casted_by.should == @car
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "assigning a value to casted attribute after initializing an object" do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@car = Car.new(:name => 'Renault 306')
|
@car = Car.new(:name => 'Renault 306')
|
||||||
@driver = Driver.new(:name => 'Matt')
|
@driver = Driver.new(:name => 'Matt')
|
||||||
end
|
end
|
||||||
|
|
||||||
# it "should not create an empty casted object" do
|
it "should not create an empty casted object" do
|
||||||
# @car.driver.should be_nil
|
@car.driver.should be_nil
|
||||||
# end
|
end
|
||||||
|
|
||||||
it "should let you assign the casted attribute after instantializing an object" do
|
# Note that this isn't casting the attribute, it's just assigning it a value
|
||||||
|
# (see "should not cast attribute")
|
||||||
|
it "should let you assign the value" do
|
||||||
@car.driver = @driver
|
@car.driver = @driver
|
||||||
@car.driver.name.should == 'Matt'
|
@car.driver.name.should == 'Matt'
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should let the casted document who casted it" do
|
it "should not cast attribute" do
|
||||||
Car.new(:name => 'Renault 306', :driver => @driver)
|
@car.driver = JSON.parse(JSON.generate(@driver))
|
||||||
@car.driver.casted_by.should == @car
|
@car.driver.should_not be_instance_of(Driver)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "casting an extended document from parsed JSON" do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@driver = Driver.new(:name => 'Matt')
|
||||||
|
@car = Car.new(:name => 'Renault 306', :driver => @driver)
|
||||||
|
@new_car = Car.new(JSON.parse(JSON.generate(@car)))
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should cast casted attribute" do
|
||||||
|
@new_car.driver.should be_instance_of(Driver)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should retain all properties of the casted attribute" do
|
||||||
|
@new_car.driver.should == @driver
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue