Entity#to_h returns nested entities as hash

This commit is contained in:
Benjamin Neff 2016-05-29 19:59:24 +02:00
parent 8d422ddff1
commit 4ded6da139
3 changed files with 43 additions and 12 deletions

View file

@ -65,12 +65,21 @@ module DiasporaFederation
validate
end
# Returns a Hash representing this Entity (attributes => values)
# Returns a Hash representing this Entity (attributes => values).
# Nested entities are also converted to a Hash.
# @return [Hash] entity data (mostly equal to the hash used for initialization).
def to_h
self.class.class_props.keys.each_with_object({}) do |prop, hash|
hash[prop] = public_send(prop)
end
Hash[properties.map {|key, value|
type = self.class.class_props[key]
if type == String || value.nil?
[key, value]
elsif type.instance_of?(Class)
[key, value.to_h]
elsif type.instance_of?(Array)
[key, value.map(&:to_h)]
end
}]
end
# Returns the XML representation for this entity constructed out of
@ -150,7 +159,7 @@ module DiasporaFederation
end
def setable_nested?(type, val)
type.is_a?(Class) && type.ancestors.include?(Entity) && val.is_a?(Entity)
type.instance_of?(Class) && type.ancestors.include?(Entity) && val.is_a?(Entity)
end
def setable_multi?(type, val)
@ -178,8 +187,15 @@ module DiasporaFederation
"Failed validation for properties: #{errors.join(' | ')}"
end
# @return [Hash] hash with all properties
def properties
self.class.class_props.keys.each_with_object({}) do |prop, hash|
hash[prop] = public_send(prop)
end
end
def xml_elements
Hash[to_h.map {|name, value| [name, self.class.class_props[name] == String ? value.to_s : value] }]
Hash[properties.map {|name, value| [name, self.class.class_props[name] == String ? value.to_s : value] }]
end
def add_property_to_xml(doc, root_element, name, value)

View file

@ -251,9 +251,16 @@ XML
}
}
it "gets returned by #to_h" do
it "gets returned as Hash by #to_h" do
entity = Entities::TestNestedEntity.new(nested_data)
expect(entity.to_h).to eq(nested_data)
nested_hash = {
asdf: nested_data[:asdf],
test: nested_data[:test].to_h,
multi: nested_data[:multi].map(&:to_h)
}
expect(entity.to_h).to eq(nested_hash)
end
it "gets xml-ified by #to_xml" do

View file

@ -25,10 +25,18 @@ shared_examples "an Entity subclass" do |ignored_props=[]|
end
describe "#to_h" do
it "should resemble the input data" do
hash = instance.to_h
ignored_props.each {|key| data.delete(key) }
expect(hash).to eq(data)
it "should return a hash with nested data" do
expected_data = Hash[data.reject {|key, _| ignored_props.include?(key) }.map {|key, value|
if [String, TrueClass, FalseClass, Fixnum, Time, NilClass].include?(value.class)
[key, value]
elsif value.instance_of?(Array)
[key, value.map(&:to_h)]
else
[key, value.to_h]
end
}]
expect(instance.to_h).to eq(expected_data)
end
end