diff --git a/lib/oga/xpath/compiler.rb b/lib/oga/xpath/compiler.rb index 038052c..c5d3eb7 100644 --- a/lib/oga/xpath/compiler.rb +++ b/lib/oga/xpath/compiler.rb @@ -352,18 +352,20 @@ module Oga node = node_literal doc_node = literal(:doc_node) - orig_input.is_a?(XML::Node) - .if_true { root.assign(orig_input.root_node) } - .else { root.assign(orig_input) } - .followed_by do - root.each_node.add_block(doc_node) do - doc_node.eq(input) - .if_true { self.break } - .followed_by do - process(ast, doc_node).if_true { yield doc_node } + input.is_a?(XML::Node).if_true do + root.assign(input.root_node) + .followed_by do + document_or_node(root).if_true do + root.each_node.add_block(doc_node) do + doc_node.eq(input) + .if_true { self.break } + .followed_by do + process(ast, doc_node).if_true { yield doc_node } + end end + end end - end + end end # @param [AST::Node] ast diff --git a/spec/oga/xpath/compiler/axes/preceding_spec.rb b/spec/oga/xpath/compiler/axes/preceding_spec.rb index de1deb1..d56298b 100644 --- a/spec/oga/xpath/compiler/axes/preceding_spec.rb +++ b/spec/oga/xpath/compiler/axes/preceding_spec.rb @@ -1,10 +1,9 @@ require 'spec_helper' describe Oga::XPath::Compiler do - describe 'preceding axis' do - before do - @document = parse(<<-EOF.strip.gsub(/\s+/m, '')) - + before do + @document = parse(<<-EOF.strip.gsub(/^\s+|\n/m, '')) + @@ -13,27 +12,64 @@ describe Oga::XPath::Compiler do - EOF + EOF - @foo1 = @document.children[0].children[0] - @bar1 = @foo1.children[0] - @baz1 = @foo1.children[1] - @baz2 = @baz1.children[0] - @baz3 = @document.children[0].children[1] + @foo1 = @document.children[0].children[0] + @bar1 = @foo1.children[0] + @baz1 = @foo1.children[1] + @baz2 = @baz1.children[0] + @baz3 = @document.children[0].children[1] + end + + describe 'relative to a document' do + describe 'preceding::*' do + it 'returns an empty NodeSet' do + evaluate_xpath(@document).should == node_set + end end - it 'returns a node set containing preceding nodes of root/foo/baz' do - evaluate_xpath(@document, 'root/foo/baz/preceding::bar') - .should == node_set(@bar1) + describe 'root/foo/baz/preceding::bar' do + it 'returns a NodeSet' do + evaluate_xpath(@document).should == node_set(@bar1) + end end - it 'returns a node set containing preceding nodes for root/baz' do - evaluate_xpath(@document, 'root/baz/preceding::baz') - .should == node_set(@baz1, @baz2) + describe 'root/baz/preceding::baz' do + it 'returns a NodeSet' do + evaluate_xpath(@document).should == node_set(@baz1, @baz2) + end + end + end + + describe 'relative to an element' do + describe 'preceding::root' do + it 'returns a NodeSet' do + evaluate_xpath(@foo1).should == @document.children + end end - it 'returns a node set containing preceding nodes relative to root/baz' do - evaluate_xpath(@baz3, 'preceding::baz').should == node_set(@baz1, @baz2) + describe 'preceding::baz' do + it 'returns a NodeSet' do + evaluate_xpath(@baz3).should == node_set(@baz1, @baz2) + end + end + end + + describe 'relative to the root element' do + describe 'preceding::*' do + it 'returns an empty NodeSet' do + evaluate_xpath(@document.children[0]).should == node_set + end + end + end + + describe 'relative to an attribute' do + describe 'preceding::*' do + it 'returns an empty NodeSet' do + root = @document.children[0] + + evaluate_xpath(root.attribute('foo')).should == node_set + end end end end