From e288ab88f5e6021210937a83d10a207c14eacc2a Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Tue, 26 Aug 2014 20:22:28 +0200 Subject: [PATCH] Support for the XPath boolean() function. --- lib/oga/xpath/evaluator.rb | 23 +++++++++ .../oga/xpath/evaluator/calls/boolean_spec.rb | 50 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 spec/oga/xpath/evaluator/calls/boolean_spec.rb diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index 4231341..d97295d 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -1031,6 +1031,29 @@ module Oga return replaced end + ## + # Processes the `boolean()` function call. + # + # This function converts the 1st argument to a boolean. + # + # The boolean `true` is returned for the following: + # + # * A non empty string + # * A non empty node set + # * A non zero number, either positive or negative + # + # The boolean `false` is returned for all other cases. + # + def on_call_boolean(context, expression) + retval = process(expression, context) + + if retval.is_a?(Numeric) + return !retval.nan? && !retval.zero? + else + return retval && !retval.empty? + end + end + ## # Processes an `(int)` node. # diff --git a/spec/oga/xpath/evaluator/calls/boolean_spec.rb b/spec/oga/xpath/evaluator/calls/boolean_spec.rb new file mode 100644 index 0000000..e0b3328 --- /dev/null +++ b/spec/oga/xpath/evaluator/calls/boolean_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' + +describe Oga::XPath::Evaluator do + context 'boolean() function' do + before do + @document = parse('foo') + @evaluator = described_class.new(@document) + end + + example 'return true for a non empty string literal' do + @evaluator.evaluate('boolean("foo")').should == true + end + + example 'return false for an empty string' do + @evaluator.evaluate('boolean("")').should == false + end + + example 'return true for a positive integer' do + @evaluator.evaluate('boolean(10)').should == true + end + + example 'return true for a positive float' do + @evaluator.evaluate('boolean(10.5)').should == true + end + + example 'return true for a negative integer' do + @evaluator.evaluate('boolean(-5)').should == true + end + + example 'return true for a negative float' do + @evaluator.evaluate('boolean(-5.2)').should == true + end + + example 'return false for a zero integer' do + @evaluator.evaluate('boolean(0)').should == false + end + + example 'return false for a zero float' do + @evaluator.evaluate('boolean(0.0)').should == false + end + + example 'return true for a non empty node set' do + @evaluator.evaluate('boolean(root/a)').should == true + end + + example 'return false for an empty node set' do + @evaluator.evaluate('boolean(root/b)').should == false + end + end +end