diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 9d1b6df..03c6ba2 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -966,6 +966,22 @@ module Oga return haystack_str[start_index..stop_index] end + ## + # Processes the `string-length()` function. + # + # This function returns the length of the string given in the 1st argument + # *or* the current context node. If the expression is not a string it's + # converted to a string using the `string()` function. + # + # @see [#on_call_string] + # @param [Oga::XML::NodeSet] context + # @param [Oga::XPath::Node] expression + # @return [Float] + # + def on_call_string_length(context, expression = nil) + return on_call_string(context, expression).length.to_f + end + ## # Processes an `(int)` node. # diff --git a/spec/oga/xpath/evaluator/calls/string_length_spec.rb b/spec/oga/xpath/evaluator/calls/string_length_spec.rb new file mode 100644 index 0000000..1a63da6 --- /dev/null +++ b/spec/oga/xpath/evaluator/calls/string_length_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe Oga::XPath::Evaluator do + context 'string-length() function' do + before do + @document = parse('x') + @evaluator = described_class.new(@document) + end + + context 'outside predicates' do + example 'return the length of a literal string' do + @evaluator.evaluate('string-length("foo")').should == 3.0 + end + + example 'return the length of a literal integer' do + @evaluator.evaluate('string-length(10)').should == 2.0 + end + + example 'return the length of a literal float' do + # This includes the counting of the dot. That is, "10.5".length => 4 + @evaluator.evaluate('string-length(10.5)').should == 4.0 + end + + example 'return the length of a string in a node set' do + @evaluator.evaluate('string-length(root)').should == 1.0 + end + end + + context 'inside predicates' do + before do + # Since the length of is 1 this should just return the node. + @set = @evaluator.evaluate('root/a[string-length()]') + end + + it_behaves_like :node_set, :length => 1 + + example 'return the node' do + @set[0].should == @document.children[0].children[0] + end + end + end +end