Prepare setup for *actual* following support.
The previous commit was nonsense as I didn't understand XPath's "following" axis properly. This commit introduces proper tests and a note for future me so that I can implement it properly.
This commit is contained in:
parent
9a97d936e3
commit
52a4375278
|
@ -254,17 +254,13 @@ module Oga
|
||||||
context.each do |context_node|
|
context.each do |context_node|
|
||||||
current = context_node
|
current = context_node
|
||||||
|
|
||||||
while current.respond_to?(:next)
|
# TODO: implement me properly this time.
|
||||||
next_node = current.next
|
#
|
||||||
|
# Step 1: gather *all* the nodes that come after the current node,
|
||||||
if can_match_node?(next_node) and node_matches?(next_node, node)
|
# regardless of their nesting.
|
||||||
nodes << next_node
|
#
|
||||||
end
|
# Step 2: compare all those nodes with the given test, only return
|
||||||
|
# those that match.
|
||||||
# When this returns nil the loop automaticall breaks since `nil`
|
|
||||||
# doesn't respond to `next`.
|
|
||||||
current = next_node
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
|
|
|
@ -3,45 +3,65 @@ require 'spec_helper'
|
||||||
describe Oga::XPath::Evaluator do
|
describe Oga::XPath::Evaluator do
|
||||||
context 'following axis' do
|
context 'following axis' do
|
||||||
before do
|
before do
|
||||||
document = parse('<a><b></b><c></c><c></c></a>')
|
# Strip whitespace so it's easier to retrieve/compare elements.
|
||||||
|
@document = parse(<<-EOF.strip.gsub(/\s+/m, ''))
|
||||||
|
<root>
|
||||||
|
<foo>
|
||||||
|
<bar></bar>
|
||||||
|
<baz>
|
||||||
|
<baz></baz>
|
||||||
|
</baz>
|
||||||
|
</foo>
|
||||||
|
<baz></baz>
|
||||||
|
</root>
|
||||||
|
EOF
|
||||||
|
|
||||||
@first_c = document.children[0].children[1]
|
@first_baz = @document.children[0].children[1]
|
||||||
@second_c = document.children[0].children[2]
|
@second_baz = @first_baz.children[0]
|
||||||
@evaluator = described_class.new(document)
|
@third_baz = @document.children[0].children[0].children[1]
|
||||||
|
@evaluator = described_class.new(@document)
|
||||||
end
|
end
|
||||||
|
|
||||||
# This should return an empty set since the document doesn't have any
|
# This should return an empty set since the document doesn't have any
|
||||||
# following nodes.
|
# following nodes.
|
||||||
context 'using a document as the root' do
|
context 'using a document as the root' do
|
||||||
before do
|
before do
|
||||||
@set = @evaluator.evaluate('following::a')
|
@set = @evaluator.evaluate('following::foo')
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like :empty_node_set
|
it_behaves_like :empty_node_set
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'matching following elements using a name' do
|
context 'matching nodes in the current context' do
|
||||||
before do
|
before do
|
||||||
@set = @evaluator.evaluate('a/b/following::c')
|
@set = @evaluator.evaluate('root/foo/following::baz')
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like :node_set, :length => 2
|
it_behaves_like :node_set, :length => 1
|
||||||
|
|
||||||
example 'return the first <c> node' do
|
example 'return the second <baz> node' do
|
||||||
@set[0].should == @first_c
|
@set[0].should == @first_baz
|
||||||
end
|
|
||||||
|
|
||||||
example 'return the second <c> node' do
|
|
||||||
@set[1].should == @second_c
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'matching following elements using a wildcard' do
|
context 'matching nodes in other contexts' do
|
||||||
before do
|
before do
|
||||||
@set = @evaluator.evaluate('a/b/following::*')
|
@set = @evaluator.evaluate('root/foo/bar/following::baz')
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like :node_set, :length => 2
|
it_behaves_like :node_set, :length => 3
|
||||||
|
|
||||||
|
example 'return the first <baz> node' do
|
||||||
|
@set[0].should == @first_baz
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'return the second <baz> node' do
|
||||||
|
@set[1].should == @second_baz
|
||||||
|
end
|
||||||
|
|
||||||
|
example 'return the third <baz> node' do
|
||||||
|
@set[2].should == @third_baz
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue