Permalink
Browse files

Merge branch 'nested_wrappers'

  • Loading branch information...
2 parents 7ea9a9f + a242400 commit 6b34add4da5611308e9c669aefb9979c3e9f14a3 @jpshackelford committed Aug 25, 2011
@@ -0,0 +1,13 @@
+class LibraryWithFines
+
+ include ROXML
+
+ xml_name 'library'
+
+ xml_accessor :name
+
+ xml_accessor :fines,
+ :as => { :key => 'name', :value => 'desc' },
+ :from => 'fine',
+ :in => 'policy/fines'
+end
@@ -0,0 +1,19 @@
+<library>
+ <name>Ruby library</name>
+ <policy>
+ <fines>
+ <fine>
+ <name>late-book</name>
+ <desc>The book was returned late.</desc>
+ </fine>
+ <fine>
+ <name>damaged-book</name>
+ <desc>The book was returned damaged.</desc>
+ </fine>
+ <fine>
+ <name>talking</name>
+ <desc>The librarian won't go out with you. Stop asking.</desc>
+ </fine>
+ </fines>
+ </policy>
+</library>
@@ -98,9 +98,12 @@ def wrap(xml, opts = {:always_create => false})
if !opts[:always_create] && (child = xml.children.find {|c| c.name == wrap_with })
return child
end
- XML.add_node(xml, wrap_with.to_s)
+
+ wraps = wrap_with.to_s.split('/')
+ wraps.inject(xml){|node,wrap| XML.add_node(node, wrap)}
end
+
def nodes_in(xml)
@default_namespace = xml.default_namespace
vals = xml.roxml_search(xpath, @instance.class.roxml_namespaces)
@@ -0,0 +1,39 @@
+require_relative './../spec_helper'
+require_relative './../../examples/library_with_fines'
+
+describe LibraryWithFines do
+
+ let(:xml) { File.read(xml_for('library_with_fines')) }
+ let(:library) { LibraryWithFines.from_xml(xml) }
+
+ it "should read nested elements" do
+ library.fines.should be_a(Hash)
+ library.fines.size == 3
+ library.fines.should have_key('talking')
+ library.fines['talking'].should match(/Stop asking/)
+ end
+
+ class String
+ def remove_whitespace
+ self.gsub(/\s{2,}/, '').gsub("\n", '')
+ end
+ end
+
+ it "should write deeply nested elements" do
+ xml_out = library.to_xml.to_s
+ xml_out.remove_whitespace.should == xml.remove_whitespace
+ end
+
+ it "should write two children of library: name and policy" do
+ library.to_xml.children.map{|e| e.name }.should == ['name', 'policy']
+ end
+
+ it "should be re-parsable via .from_xml" do
+ lib_reparsed = LibraryWithFines.from_xml(library.to_xml.to_s)
+ lib_reparsed.name.should == library.name
+ puts lib_reparsed.to_xml.xpath('name')
+ lib_reparsed.fines.should == library.fines
+ end
+
+
+end
View
@@ -0,0 +1,34 @@
+# encoding: utf-8
+require_relative './spec_helper'
+
+describe ROXML::XMLRef do
+
+ class Org
+ include ROXML
+ xml_accessor :fines,
+ :in => 'policy/fines',
+ :from => 'fine',
+ :as => { :key => 'name', :value => 'desc' }
+ end
+
+ let(:org) do
+ org = Org.new
+ org.fines = { 'name' => 'a fine', 'desc' => 'a desc' }
+ org
+ end
+
+ let(:reference) do
+ Org.roxml_attrs.first.to_ref(org)
+ end
+
+ it "should properly reconstruct wrappers with multiple elements" do
+
+ reference.should be_a(ROXML::XMLHashRef)
+
+ xml = ROXML::XML.new_node('org').tap do |root|
+ reference.update_xml(root, org.fines)
+ end
+
+ xml_path( xml ).should == %w{org policy fines fine name}
+ end
+end
View
@@ -1,5 +1,7 @@
require 'rubygems'
require 'pathname'
+require 'ostruct'
+
require_relative './../test/support/fixtures'
require_relative './../lib/roxml'
require_relative './shared_specs'
@@ -11,3 +13,12 @@ def xml_for(name)
class RoxmlObject
include ROXML
end
+
+# returns an array representing the path through first child of each element in the doc
+def xml_path(xml, path = [])
+ path << xml.name if xml.is_a?(Nokogiri::XML::Element)
+ unless xml.children.empty?
+ xml_path(xml.children.first, path)
+ end
+ return path
+end

0 comments on commit 6b34add

Please sign in to comment.