add xml_name option to properties_dsl
also: * only allow symbols as name and xml_name * use public_send instead of send
This commit is contained in:
parent
0deb74c103
commit
71b1d6dc1e
7 changed files with 84 additions and 29 deletions
|
|
@ -8,10 +8,9 @@ module DiasporaFederation
|
|||
property :guid
|
||||
|
||||
# @!attribute [r] diaspora_id
|
||||
# @todo refactoring with properties_dsl, xml name should be diaspora_handle
|
||||
# The diaspora ID of the person
|
||||
# @return [String] diaspora ID
|
||||
property :diaspora_id
|
||||
property :diaspora_id, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] url
|
||||
# @see WebFinger#seed_url
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@ module DiasporaFederation
|
|||
# this entity contains all the profile data of a person
|
||||
class Profile < Entity
|
||||
# @!attribute [r] diaspora_id
|
||||
# @todo refactoring with properties_dsl, xml name should be diaspora_handle
|
||||
# The diaspora ID of the person
|
||||
# @see Person#diaspora_id
|
||||
# @return [String] diaspora ID
|
||||
property :diaspora_id
|
||||
property :diaspora_id, xml_name: :diaspora_handle
|
||||
|
||||
# @!attribute [r] first_name
|
||||
# @deprecated
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ module DiasporaFederation
|
|||
# property :prop
|
||||
# property :optional, default: false
|
||||
# property :dynamic_default, default: -> { Time.now }
|
||||
# property :another_prop, xml_name: :another_name
|
||||
# entity :nested, NestedEntity
|
||||
# entity :multiple, [OtherEntity]
|
||||
# end
|
||||
|
|
@ -59,7 +60,7 @@ module DiasporaFederation
|
|||
# @return [Hash] entity data (mostly equal to the hash used for initialization).
|
||||
def to_h
|
||||
self.class.class_prop_names.each_with_object({}) do |prop, hash|
|
||||
hash[prop] = send(prop)
|
||||
hash[prop] = public_send(prop)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -120,24 +121,28 @@ module DiasporaFederation
|
|||
doc = Nokogiri::XML::DocumentFragment.new(Nokogiri::XML::Document.new)
|
||||
Nokogiri::XML::Element.new(self.class.entity_name, doc).tap do |root_element|
|
||||
self.class.class_props.each do |prop_def|
|
||||
name = prop_def[:name]
|
||||
add_property_to_xml(doc, prop_def, root_element)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_property_to_xml(doc, prop_def, root_element)
|
||||
property = prop_def[:name]
|
||||
type = prop_def[:type]
|
||||
if type == String
|
||||
root_element << simple_node(doc, name)
|
||||
root_element << simple_node(doc, prop_def[:xml_name], property)
|
||||
else
|
||||
# call #to_xml for each item and append to root
|
||||
[*send(name)].compact.each do |item|
|
||||
[*public_send(property)].compact.each do |item|
|
||||
root_element << item.to_xml
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# create simple node, fill it with text and append to root
|
||||
def simple_node(doc, name)
|
||||
def simple_node(doc, name, property)
|
||||
Nokogiri::XML::Element.new(name.to_s, doc).tap do |node|
|
||||
data = send(name).to_s
|
||||
data = public_send(property).to_s
|
||||
node.content = data unless data.empty?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ module DiasporaFederation
|
|||
# property :prop
|
||||
# property :optional, default: false
|
||||
# property :dynamic_default, default: -> { Time.now }
|
||||
# property :another_prop, xml_name: :another_name
|
||||
# entity :nested, NestedEntity
|
||||
# entity :multiple, [OtherEntity]
|
||||
module PropertiesDSL
|
||||
|
|
@ -19,6 +20,7 @@ module DiasporaFederation
|
|||
# @param [Hash] opts further options
|
||||
# @option opts [Object, #call] :default a default value, making the
|
||||
# property optional
|
||||
# @option opts [Symbol] :xml_name another name used for xml generation
|
||||
def property(name, opts={})
|
||||
define_property name, String, opts
|
||||
end
|
||||
|
|
@ -69,7 +71,14 @@ module DiasporaFederation
|
|||
def define_property(name, type, opts={})
|
||||
raise InvalidName unless name_valid?(name)
|
||||
|
||||
class_props << {name: name, type: type}
|
||||
xml_name = name
|
||||
if opts.has_key? :xml_name
|
||||
raise ArgumentError, "xml_name is not supported for nested entities" unless type == String
|
||||
xml_name = opts[:xml_name]
|
||||
raise InvalidName, "invalid xml_name" unless name_valid?(xml_name)
|
||||
end
|
||||
|
||||
class_props << {name: name, xml_name: xml_name, type: type}
|
||||
default_props[name] = opts[:default] if opts.has_key? :default
|
||||
|
||||
instance_eval { attr_reader name }
|
||||
|
|
@ -79,7 +88,7 @@ module DiasporaFederation
|
|||
# @param [String, Symbol] name the name to check
|
||||
# @return [Boolean]
|
||||
def name_valid?(name)
|
||||
name.instance_of?(Symbol) || name.instance_of?(String)
|
||||
name.instance_of?(Symbol)
|
||||
end
|
||||
|
||||
# checks if the type extends {Entity}
|
||||
|
|
|
|||
|
|
@ -20,5 +20,10 @@ module DiasporaFederation
|
|||
entity :test, TestEntity
|
||||
entity :multi, [OtherEntity]
|
||||
end
|
||||
|
||||
class TestEntityWithXmlName < DiasporaFederation::Entity
|
||||
property :test
|
||||
property :qwer, xml_name: :asdf
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ module DiasporaFederation
|
|||
|
||||
it "contains nodes for each of the properties" do
|
||||
entity = Entities::TestDefaultEntity.new(data)
|
||||
entity.to_xml.children.each do |node|
|
||||
xml_children = entity.to_xml.children
|
||||
expect(xml_children).to have_exactly(4).items
|
||||
xml_children.each do |node|
|
||||
expect(%w(test1 test2 test3 test4)).to include(node.name)
|
||||
end
|
||||
end
|
||||
|
|
@ -92,6 +94,7 @@ module DiasporaFederation
|
|||
it "gets xml-ified by #to_xml" do
|
||||
entity = Entities::TestNestedEntity.new(nested_data)
|
||||
xml = entity.to_xml
|
||||
expect(xml.children).to have_exactly(4).items
|
||||
xml.children.each do |node|
|
||||
expect(%w(asdf test_entity other_entity)).to include(node.name)
|
||||
end
|
||||
|
|
@ -99,5 +102,23 @@ module DiasporaFederation
|
|||
expect(xml.xpath("other_entity")).to have_exactly(2).items
|
||||
end
|
||||
end
|
||||
|
||||
context "xml_name" do
|
||||
let(:hash) { {test: "test", qwer: "qwer"} }
|
||||
|
||||
it "uses xml_name for the #to_xml" do
|
||||
entity = Entities::TestEntityWithXmlName.new(hash)
|
||||
xml_children = entity.to_xml.children
|
||||
expect(xml_children).to have_exactly(2).items
|
||||
xml_children.each do |node|
|
||||
expect(%w(test asdf)).to include(node.name)
|
||||
end
|
||||
end
|
||||
|
||||
it "should not use the xml_name for the #to_h" do
|
||||
entity = Entities::TestEntityWithXmlName.new(hash)
|
||||
expect(entity.to_h).to eq(hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,19 +8,12 @@ module DiasporaFederation
|
|||
properties = dsl.class_props
|
||||
expect(properties).to have(1).item
|
||||
expect(properties.first[:name]).to eq(:test)
|
||||
expect(properties.first[:type]).to eq(String)
|
||||
end
|
||||
|
||||
it "can name simple properties by string" do
|
||||
dsl.property "test"
|
||||
properties = dsl.class_props
|
||||
expect(properties).to have(1).item
|
||||
expect(properties.first[:name]).to eq("test")
|
||||
expect(properties.first[:xml_name]).to eq(:test)
|
||||
expect(properties.first[:type]).to eq(String)
|
||||
end
|
||||
|
||||
it "will not accept other types for names" do
|
||||
[1234, true, {}].each do |val|
|
||||
["test", 1234, true, {}].each do |val|
|
||||
expect {
|
||||
dsl.property val
|
||||
}.to raise_error PropertiesDSL::InvalidName
|
||||
|
|
@ -34,8 +27,26 @@ module DiasporaFederation
|
|||
properties = dsl.class_props
|
||||
expect(properties).to have(3).items
|
||||
expect(properties.map {|e| e[:name] }).to include(:test, :asdf, :zzzz)
|
||||
expect(properties.map {|e| e[:xml_name] }).to include(:test, :asdf, :zzzz)
|
||||
properties.each {|e| expect(e[:type]).to eq(String) }
|
||||
end
|
||||
|
||||
it "can add an xml name to simple properties with a symbol" do
|
||||
dsl.property :test, xml_name: :xml_test
|
||||
properties = dsl.class_props
|
||||
expect(properties).to have(1).item
|
||||
expect(properties.first[:name]).to eq(:test)
|
||||
expect(properties.first[:xml_name]).to eq(:xml_test)
|
||||
expect(properties.first[:type]).to eq(String)
|
||||
end
|
||||
|
||||
it "will not accept other types for xml names" do
|
||||
["test", 1234, true, {}].each do |val|
|
||||
expect {
|
||||
dsl.property :test, xml_name: val
|
||||
}.to raise_error PropertiesDSL::InvalidName, "invalid xml_name"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "nested entities" do
|
||||
|
|
@ -75,6 +86,12 @@ module DiasporaFederation
|
|||
}.to raise_error PropertiesDSL::InvalidType
|
||||
end
|
||||
end
|
||||
|
||||
it "can not add an xml name to a nested entity" do
|
||||
expect {
|
||||
dsl.entity :other, Entities::TestEntity, xml_name: :other_name
|
||||
}.to raise_error ArgumentError, "xml_name is not supported for nested entities"
|
||||
end
|
||||
end
|
||||
|
||||
describe ".default_values" do
|
||||
|
|
|
|||
Loading…
Reference in a new issue