Skip to content
Browse files

Element attribute mappings work as expected

  • Loading branch information...
1 parent 6323251 commit 4bcbc227c20327bb104051b5019fedd6dd668d28 @craigambrose committed May 13, 2012
View
12 lib/sax_stream/internal/child_mapping.rb
@@ -23,18 +23,6 @@ def handler_for(node_path, collector, handler_stack, parent_object)
nil
end
- def is_attribute?
- false
- end
-
- def is_base_attribute?
- false
- end
-
- def is_element?
- false
- end
-
def map_value_onto_object(object, value)
end
View
17 lib/sax_stream/internal/element_attribute_mapping.rb
@@ -0,0 +1,17 @@
+require 'sax_stream/internal/element_mapping'
+
+module SaxStream
+ module Internal
+ class ElementAttributeMapping < ElementMapping
+ def update_dom_node(object, node)
+ node[base_attribute_name] = value_from_object(object)
+ end
+
+ private
+
+ def base_attribute_name
+ path_parts.last.sub(/^@/, '')
+ end
+ end
+ end
+end
View
63 lib/sax_stream/internal/element_content_mapping.rb
@@ -1,68 +1,11 @@
+require 'sax_stream/internal/element_mapping'
+
module SaxStream
module Internal
- class ElementContentMapping
- def initialize(name, options = {})
- @name = name.to_s
- @path = options[:to]
- process_conversion_type(options[:as])
- end
-
- def map_value_onto_object(object, value)
- if value && @parser
- value = @parser.parse(value)
- end
- if object.respond_to?(setter_method)
- object.send(setter_method, value)
- else
- object[@name] = value
- end
- end
-
- def value_from_object(object)
- object[@name]
- end
-
- def handler_for(name, collector, handler_stack, parent_object)
- end
-
- def is_attribute?
- path_parts.last =~ /^@/
- end
-
- def is_base_attribute?
- @path =~ /^@/
- end
-
- def is_element?
- !is_base_attribute?
- end
-
- def base_attribute_name
- @path.sub(/^@/, '')
- end
-
- def path_parts
- @path.split('/')
- end
-
+ class ElementContentMapping < ElementMapping
def update_dom_node(object, node)
node.content = value_from_object(object)
end
-
- private
- def setter_method
- "#{@name}=".to_sym
- end
-
- def process_conversion_type(as)
- if as
- if as.respond_to?(:parse)
- @parser = as
- else
- raise ArgumentError, ":as options for #{@name} field is a #{as.inspect} which must respond to parse"
- end
- end
- end
end
end
end
View
48 lib/sax_stream/internal/element_mapping.rb
@@ -0,0 +1,48 @@
+module SaxStream
+ module Internal
+ class ElementMapping
+ def initialize(name, options = {})
+ @name = name.to_s
+ @path = options[:to]
+ process_conversion_type(options[:as])
+ end
+
+ def map_value_onto_object(object, value)
+ if value && @parser
+ value = @parser.parse(value)
+ end
+ if object.respond_to?(setter_method)
+ object.send(setter_method, value)
+ else
+ object[@name] = value
+ end
+ end
+
+ def value_from_object(object)
+ object[@name]
+ end
+
+ def handler_for(name, collector, handler_stack, parent_object)
+ end
+
+ def path_parts
+ @path.split('/')
+ end
+
+ private
+ def setter_method
+ "#{@name}=".to_sym
+ end
+
+ def process_conversion_type(as)
+ if as
+ if as.respond_to?(:parse)
+ @parser = as
+ else
+ raise ArgumentError, ":as options for #{@name} field is a #{as.inspect} which must respond to parse"
+ end
+ end
+ end
+ end
+ end
+end
View
49 lib/sax_stream/internal/xml_builder.rb
@@ -11,15 +11,6 @@ def build_xml_for(object)
object.mappings.each do |mapping|
add_mapping(doc, base, object, mapping)
end
-
- # noko_builder = Nokogiri::XML::Builder.new
- # noko_builder.send(object.node_name, base_attributes_hash(object, mappings))
- # # do |xml|
- # # element_mappings(mappings).each do |mapping|
- # # map_child_element(xml, mapping, object, mapping.path_parts)
- # # end
- # # end
- # raise noko_builder.doc.inspect
doc.to_xml
end
@@ -38,8 +29,12 @@ def add_mapping(doc, base, object, mapping)
def find_or_insert_nested_element(doc, base, path_parts)
part = path_parts.shift
if part
- result = find_or_insert_child_element(doc, base, part)
- find_or_insert_nested_element(doc, result, path_parts)
+ if part =~ /^@/
+ return base
+ else
+ result = find_or_insert_child_element(doc, base, part)
+ find_or_insert_nested_element(doc, result, path_parts)
+ end
else
base
end
@@ -54,38 +49,6 @@ def insert_child_element(doc, base, part)
base << element
end
end
-
- # def map_child_element(xml, mapping, object, path_parts)
- # part = path_parts.shift
- # if path_parts.length == 1 && path_parts.first =~ /^@/
- # # We are mapping an attribute
- # value = mapping.value_from_object(object)
- # attribute_key = path_parts.first.sub(/^@/, '')
- # xml.send(part, attribute_key => value)
- # elsif path_parts.empty?
- # value = mapping.value_from_object(object)
- # xml.send(part, value)
- # else
- # xml.send(part, nil) do |child_xml|
- # map_child_element(child_xml, mapping, object, path_parts)
- # end
- # end
- # end
- #
- # def base_attributes_hash(object, mappings)
- # attributes_array = base_attribute_mappings(mappings).map do |mapping|
- # [mapping.base_attribute_name, mapping.value_from_object(object)]
- # end
- # Hash[*attributes_array.flatten]
- # end
- #
- # def base_attribute_mappings(mappings)
- # mappings.select(&:is_base_attribute?)
- # end
- #
- # def element_mappings(mappings)
- # mappings.select(&:is_element?)
- # end
end
end
end
View
12 spec/sax_stream/internal/element_content_mapping_spec.rb
@@ -48,18 +48,6 @@ class NoParse
object['foobar'].should == nil
end
end
-
- context "is attribute" do
- it "is true if last name part starts with @" do
- ElementContentMapping.new('foobar', :to => '@foobar').is_attribute?.should be_true
- ElementContentMapping.new('foobar', :to => 'foo/@bar').is_attribute?.should be_true
- end
-
- it "is false if last name part doesnt start with @" do
- ElementContentMapping.new('foobar', :to => 'foobar').is_attribute?.should be_false
- ElementContentMapping.new('foobar', :to => 'foo/bar').is_attribute?.should be_false
- end
- end
end
end
end
View
26 spec/sax_stream/internal/xml_builder_spec.rb
@@ -1,15 +1,16 @@
require 'spec_helper'
require 'sax_stream/internal/xml_builder'
require 'sax_stream/internal/element_content_mapping'
+require 'sax_stream/internal/element_attribute_mapping'
module SaxStream
module Internal
describe XmlBuilder do
let(:builder) { XmlBuilder.new }
let(:object) { double("mappable object", :node_name => 'FooBar', :attributes => {}, :mappings => []) }
- def base_attribute_mapping(name, value)
- ElementContentMapping.new(name, :to => "@#{name}").tap do |result|
+ def attribute_mapping(path, value)
+ ElementAttributeMapping.new(path.gsub(/^@/, ''), :to => path).tap do |result|
result.stub!(:value_from_object).with(object).and_return(value)
end
end
@@ -26,8 +27,7 @@ def element_mapping(path, value)
end
it "includes attributes of the main node" do
- pending
- object.stub(:mappings => [base_attribute_mapping('a', 'b')])
+ object.stub(:mappings => [attribute_mapping('@a', 'b')])
builder.build_xml_for(object).should == "<?xml version=\"1.0\"?>\n<FooBar a=\"b\"/>\n"
end
@@ -46,15 +46,15 @@ def element_mapping(path, value)
builder.build_xml_for(object).should == "<?xml version=\"1.0\"?>\n<FooBar>\n <red>\n <fox>value</fox>\n <goose>value2</goose>\n </red>\n</FooBar>\n"
end
- # it "includes sub element attribute" do
- # object.stub(:mappings => [element_mapping('red/@fox', 'value')])
- # builder.build_xml_for(object).should == "<?xml version=\"1.0\"?>\n<FooBar>\n <red fox=\"value\"/>\n</FooBar>\n"
- # end
- #
- # it "includes sub element attribute and value" do
- # object.stub(:mappings => [element_mapping('red/@fox', 'value'), element_mapping('red', 'value2')])
- # builder.build_xml_for(object).should == "<?xml version=\"1.0\"?>\n<FooBar>\n <red fox=\"value\">value2</red>\n</FooBar>\n"
- # end
+ it "includes sub element attribute" do
+ object.stub(:mappings => [attribute_mapping('red/@fox', 'value')])
+ builder.build_xml_for(object).should == "<?xml version=\"1.0\"?>\n<FooBar>\n <red fox=\"value\"/>\n</FooBar>\n"
+ end
+
+ it "includes sub element attribute and value" do
+ object.stub(:mappings => [attribute_mapping('red/@fox', 'value'), element_mapping('red', 'value2')])
+ builder.build_xml_for(object).should == "<?xml version=\"1.0\"?>\n<FooBar>\n <red fox=\"value\">value2</red>\n</FooBar>\n"
+ end
end
end

0 comments on commit 4bcbc22

Please sign in to comment.
Something went wrong with that request. Please try again.