XPath compiler support for sum()

This commit is contained in:
Yorick Peterse 2015-08-18 15:33:47 +02:00
parent e7e5b123cf
commit 106d83e780
2 changed files with 48 additions and 15 deletions

View File

@ -1103,6 +1103,28 @@ module Oga
end end
end end
# @param [Oga::Ruby::Node] input
# @param [AST::Node] arg
# @return [Oga::Ruby::Node]
def on_call_sum(input, arg)
unless return_nodeset?(arg)
raise TypeError, 'sum() can only operate on a path, axis or predicate'
end
sum_var = unique_literal(:sum)
conversion = literal(Conversion)
sum_var.assign(literal(0.0))
.followed_by do
process(arg, input) do |matched_node|
sum_var.assign(sum_var + conversion.to_float(matched_node.text))
end
end
.followed_by do
block_given? ? sum_var.zero?.not.if_true { yield } : sum_var
end
end
## ##
# Delegates type tests to specific handlers. # Delegates type tests to specific handlers.
# #

View File

@ -4,8 +4,11 @@ describe Oga::XPath::Compiler do
describe 'sum() spec' do describe 'sum() spec' do
before do before do
@document = parse('<root><a>1</a><b>2</b></root>') @document = parse('<root><a>1</a><b>2</b></root>')
@a1 = @document.children[0].children[0]
end end
describe 'at the top-level' do
it 'returns the sum of the <root> node' do it 'returns the sum of the <root> node' do
# The test of <root> is "12", which is then converted to a number. # The test of <root> is "12", which is then converted to a number.
evaluate_xpath(@document, 'sum(root)').should == 12.0 evaluate_xpath(@document, 'sum(root)').should == 12.0
@ -25,4 +28,12 @@ describe Oga::XPath::Compiler do
block.should raise_error(TypeError) block.should raise_error(TypeError)
end end
end end
describe 'in a predicate' do
it 'returns a NodeSet containing all matching nodes' do
evaluate_xpath(@document, 'root/a[sum(/root/*)]')
.should == node_set(@a1)
end
end
end
end end