From b688c6dc1bbebe78bfb10caa76b67ed2be84bb3c Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Sat, 23 Aug 2014 20:24:18 +0200 Subject: [PATCH] Support for the XPath concat() function. --- lib/oga/xpath/evaluator.rb | 25 ++++++++++++++-- spec/oga/xpath/evaluator/calls/concat_spec.rb | 30 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 spec/oga/xpath/evaluator/calls/concat_spec.rb diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 6593121..354708d 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -786,8 +786,29 @@ module Oga end ## - # Processes an `(int)` node. This method simply returns the value as a - # Float. + # Processes the `concat()` function call. + # + # This function call converts its arguments to strings and concatenates + # them. In case of node sets the text of the set is used. + # + # @param [Oga::XML::NodeSet] context + # @param [Oga::XPath::Node] first + # @param [Oga::XPath::Node] second + # @param [Array] rest + # + def on_call_concat(context, first, second, *rest) + args = [first, second] + rest + retval = '' + + args.each do |arg| + retval << on_call_string(context, arg) + end + + return retval + end + + ## + # Processes an `(int)` node. # # @param [Oga::XPath::Node] ast_node # @param [Oga::XML::NodeSet] context diff --git a/spec/oga/xpath/evaluator/calls/concat_spec.rb b/spec/oga/xpath/evaluator/calls/concat_spec.rb new file mode 100644 index 0000000..1378507 --- /dev/null +++ b/spec/oga/xpath/evaluator/calls/concat_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe Oga::XPath::Evaluator do + context 'concat() function' do + before do + @document = parse('foobar') + @evaluator = described_class.new(@document) + end + + example 'concatenate two strings' do + @evaluator.evaluate('concat("foo", "bar")').should == 'foobar' + end + + example 'concatenate two integers' do + @evaluator.evaluate('concat(10, 20)').should == '1020' + end + + example 'concatenate two floats' do + @evaluator.evaluate('concat(10.5, 20.5)').should == '10.520.5' + end + + example 'concatenate two node sets' do + @evaluator.evaluate('concat(root/a, root/b)').should == 'foobar' + end + + example 'concatenate a node set and a string' do + @evaluator.evaluate('concat(root/a, "baz")').should == 'foobaz' + end + end +end