Retrieving root nodes using Node#root_node.

This method uses a loop to traverse upwards the DOM tree in order to find the
root document/element. While this might have an impact on performance I don't
expect Oga itself to call this method very often. The benefit is that Node
instances don't require users to manually pass the top level document as an
argument.
This commit is contained in:
Yorick Peterse 2014-07-03 00:26:15 +02:00
parent e69fbc3ea7
commit a15c19c4af
2 changed files with 95 additions and 0 deletions

View File

@ -80,6 +80,26 @@ module Oga
return index <= length ? node_set[index] : nil return index <= length ? node_set[index] : nil
end 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 # Generates the inspect value for the current node. Sub classes can
# overwrite the {#extra_inspect_data} method to customize the output # overwrite the {#extra_inspect_data} method to customize the output

View File

@ -16,6 +16,29 @@ describe Oga::XML::Node do
end end
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 context '#children=' do
example 'set the child nodes using an Array' do example 'set the child nodes using an Array' do
child = described_class.new child = described_class.new
@ -35,4 +58,56 @@ describe Oga::XML::Node do
node.children[0].should == child node.children[0].should == child
end end
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 end