From 5b65d6c31aadc1a39e391941e7f2d31f7114827f Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Mon, 25 Aug 2014 09:43:06 +0200 Subject: [PATCH] Support for the xpath starts-with() function. --- lib/oga/xpath/evaluator.rb | 21 ++++++++++ .../xpath/evaluator/calls/starts_with_spec.rb | 38 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 spec/oga/xpath/evaluator/calls/starts_with_spec.rb diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 354708d..a555e01 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -807,6 +807,27 @@ module Oga return retval end + ## + # Processes the `starts-with()` function call. + # + # This function call returns `true` if the string in the 1st argument + # starts with the string in the 2nd argument. + # + # @example + # starts-with("hello world", "hello") # => true + # + # @param [Oga::XML::NodeSet] context + # @param [Oga::XPath::Node] haystack The string to search. + # @param [Oga::XPath::Node] needle The string to search for. + # @return [TrueClass|FalseClass] + # + def on_call_starts_with(context, haystack, needle) + haystack_str = on_call_string(context, haystack) + needle_str = on_call_string(context, needle) + + return haystack_str.start_with?(needle_str) + end + ## # Processes an `(int)` node. # diff --git a/spec/oga/xpath/evaluator/calls/starts_with_spec.rb b/spec/oga/xpath/evaluator/calls/starts_with_spec.rb new file mode 100644 index 0000000..5153d0b --- /dev/null +++ b/spec/oga/xpath/evaluator/calls/starts_with_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' + +describe Oga::XPath::Evaluator do + context 'starts-with() function' do + before do + @document = parse('foofoobar') + @evaluator = described_class.new(@document) + end + + example 'return true if the 1st string starts with the 2nd string' do + @evaluator.evaluate('starts-with("foobar", "foo")').should == true + end + + example "return false if the 1st string doesn't start with the 2nd string" do + @evaluator.evaluate('starts-with("foobar", "baz")').should == false + end + + example 'return true if the 1st node set starts with the 2nd string' do + @evaluator.evaluate('starts-with(root/a, "foo")').should == true + end + + example 'return true if the 1st node set starts with the 2nd node set' do + @evaluator.evaluate('starts-with(root/b, root/a)').should == true + end + + example "return false if the 1st node set doesn't start with the 2nd string" do + @evaluator.evaluate('starts-with(root/a, "baz")').should == false + end + + example 'return true if the 1st string starts with the 2nd node set' do + @evaluator.evaluate('starts-with("foobar", root/a)').should == true + end + + example 'return true when using two empty strings' do + @evaluator.evaluate('starts-with("", "")').should == true + end + end +end