diff --git a/lib/oga/xpath/evaluator.rb b/lib/oga/xpath/evaluator.rb index fad3207..8f561a7 100644 --- a/lib/oga/xpath/evaluator.rb +++ b/lib/oga/xpath/evaluator.rb @@ -780,7 +780,7 @@ module Oga convert = process(expression, context) if convert.is_a?(XML::NodeSet) - convert = convert.first + convert = convert[0] end else convert = current_node @@ -815,9 +815,28 @@ module Oga # @return [Float] # def on_call_number(context, expression = nil) - str_val = on_call_string(context, expression) + convert = nil - return Float(str_val) rescue Float::NAN + if expression + exp_retval = process(expression, context) + + if exp_retval.is_a?(XML::NodeSet) + convert = first_node_text(exp_retval) + + elsif exp_retval == true + convert = 1.0 + + elsif exp_retval == false + convert = 0.0 + + elsif exp_retval + convert = exp_retval + end + else + convert = current_node.text + end + + return Float(convert) rescue Float::NAN end ## diff --git a/spec/oga/xpath/evaluator/calls/number_spec.rb b/spec/oga/xpath/evaluator/calls/number_spec.rb index 7f856e1..231ec6d 100644 --- a/spec/oga/xpath/evaluator/calls/number_spec.rb +++ b/spec/oga/xpath/evaluator/calls/number_spec.rb @@ -15,6 +15,14 @@ describe Oga::XPath::Evaluator do @evaluator.evaluate('number("10.5")').should == 10.5 end + example 'convert boolean true to a number' do + @evaluator.evaluate('number(true())').should == 1.0 + end + + example 'convert boolean false to a number' do + @evaluator.evaluate('number(false())').should be_zero + end + example 'convert a node set to a number' do @evaluator.evaluate('number(root/a)').should == 10.0 end @@ -30,5 +38,9 @@ describe Oga::XPath::Evaluator do example 'return NaN for values that can not be converted to floats' do @evaluator.evaluate('number("a")').should be_nan end + + example 'return NaN for empty node sets' do + @evaluator.evaluate('number(foo)').should be_nan + end end end