diff --git a/lib/oga/xml/node.rb b/lib/oga/xml/node.rb index 0e01331..bf59f69 100644 --- a/lib/oga/xml/node.rb +++ b/lib/oga/xml/node.rb @@ -80,6 +80,26 @@ module Oga return index <= length ? node_set[index] : nil end + ## + # Returns the root document/node of the current node. The node is + # retrieved by traversing upwards in the DOM tree from the current node. + # + # @return [Oga::XML::Document|Oga::XML::Node] + # + def root_node + node = self + + loop do + if !node.is_a?(Document) and node.node_set + node = node.node_set.owner + else + break + end + end + + return node + end + ## # Generates the inspect value for the current node. Sub classes can # overwrite the {#extra_inspect_data} method to customize the output diff --git a/spec/oga/xml/node_spec.rb b/spec/oga/xml/node_spec.rb index 2123693..428d679 100644 --- a/spec/oga/xml/node_spec.rb +++ b/spec/oga/xml/node_spec.rb @@ -16,6 +16,29 @@ describe Oga::XML::Node do end end + context '#children' do + example 'return an empty set by default' do + described_class.new.children.empty?.should == true + end + + example 'return a set that was created manually' do + set = Oga::XML::NodeSet.new([described_class.new]) + node = described_class.new(:children => set) + + node.children.should == set + end + end + + context '#parent' do + example 'return the parent of the node' do + owner = described_class.new + set = Oga::XML::NodeSet.new([], owner) + node = described_class.new(:node_set => set) + + node.parent.should == owner + end + end + context '#children=' do example 'set the child nodes using an Array' do child = described_class.new @@ -35,4 +58,56 @@ describe Oga::XML::Node do node.children[0].should == child end end + + context '#previous' do + before do + owner = described_class.new + @n1 = described_class.new + @n2 = described_class.new + @set = Oga::XML::NodeSet.new([@n1, @n2], owner) + end + + example 'return the previous node' do + @n2.previous.should == @n1 + end + + example 'return nil if there is no previous node' do + @n1.previous.nil?.should == true + end + end + + context '#next' do + before do + owner = described_class.new + @n1 = described_class.new + @n2 = described_class.new + @set = Oga::XML::NodeSet.new([@n1, @n2], owner) + end + + example 'return the next node' do + @n1.next.should == @n2 + end + + example 'return nil if there is no previous node' do + @n2.next.nil?.should == true + end + end + + context '#root_node' do + before do + @n4 = described_class.new + @n3 = described_class.new(:children => [@n4]) + @n2 = described_class.new + @n1 = described_class.new(:children => [@n2]) + @doc = Oga::XML::Document.new(:children => [@n1]) + end + + example 'return the root document of an element' do + @n2.root_node.should == @doc + end + + example 'return the root element of another element' do + @n4.root_node.should == @n3 + end + end end