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|
|
||||
current = context_node
|
||||
|
||||
while current.respond_to?(:next)
|
||||
next_node = current.next
|
||||
|
||||
if can_match_node?(next_node) and node_matches?(next_node, node)
|
||||
nodes << next_node
|
||||
end
|
||||
|
||||
# When this returns nil the loop automaticall breaks since `nil`
|
||||
# doesn't respond to `next`.
|
||||
current = next_node
|
||||
end
|
||||
# TODO: implement me properly this time.
|
||||
#
|
||||
# Step 1: gather *all* the nodes that come after the current node,
|
||||
# regardless of their nesting.
|
||||
#
|
||||
# Step 2: compare all those nodes with the given test, only return
|
||||
# those that match.
|
||||
end
|
||||
|
||||
return nodes
|
||||
|
|
|
@ -3,45 +3,65 @@ require 'spec_helper'
|
|||
describe Oga::XPath::Evaluator do
|
||||
context 'following axis' 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]
|
||||
@second_c = document.children[0].children[2]
|
||||
@evaluator = described_class.new(document)
|
||||
@first_baz = @document.children[0].children[1]
|
||||
@second_baz = @first_baz.children[0]
|
||||
@third_baz = @document.children[0].children[0].children[1]
|
||||
@evaluator = described_class.new(@document)
|
||||
end
|
||||
|
||||
# This should return an empty set since the document doesn't have any
|
||||
# following nodes.
|
||||
context 'using a document as the root' do
|
||||
before do
|
||||
@set = @evaluator.evaluate('following::a')
|
||||
@set = @evaluator.evaluate('following::foo')
|
||||
end
|
||||
|
||||
it_behaves_like :empty_node_set
|
||||
end
|
||||
|
||||
context 'matching following elements using a name' do
|
||||
context 'matching nodes in the current context' do
|
||||
before do
|
||||
@set = @evaluator.evaluate('a/b/following::c')
|
||||
@set = @evaluator.evaluate('root/foo/following::baz')
|
||||
end
|
||||
|
||||
it_behaves_like :node_set, :length => 2
|
||||
it_behaves_like :node_set, :length => 1
|
||||
|
||||
example 'return the first <c> node' do
|
||||
@set[0].should == @first_c
|
||||
end
|
||||
|
||||
example 'return the second <c> node' do
|
||||
@set[1].should == @second_c
|
||||
example 'return the second <baz> node' do
|
||||
@set[0].should == @first_baz
|
||||
end
|
||||
end
|
||||
|
||||
context 'matching following elements using a wildcard' do
|
||||
context 'matching nodes in other contexts' do
|
||||
before do
|
||||
@set = @evaluator.evaluate('a/b/following::*')
|
||||
@set = @evaluator.evaluate('root/foo/bar/following::baz')
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue