From e6916f83fd35989db4b86dfb10716c9198994389 Mon Sep 17 00:00:00 2001 From: Steve Huff Date: Fri, 29 Mar 2013 10:04:05 -0400 Subject: Enable num2bool to accept numeric input Also ignore rspec fixtures directory --- spec/unit/puppet/parser/functions/num2bool_spec.rb | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'spec/unit/puppet') diff --git a/spec/unit/puppet/parser/functions/num2bool_spec.rb b/spec/unit/puppet/parser/functions/num2bool_spec.rb index 640c689..e51ee45 100644 --- a/spec/unit/puppet/parser/functions/num2bool_spec.rb +++ b/spec/unit/puppet/parser/functions/num2bool_spec.rb @@ -12,13 +12,33 @@ describe "the num2bool function" do lambda { scope.function_num2bool([]) }.should( raise_error(Puppet::ParseError)) end - it "should return true if 1" do + it "should return true if passed string 1" do result = scope.function_num2bool(["1"]) result.should(be_true) end - it "should return false if 0" do + it "should return true if passed number 1" do + result = scope.function_num2bool([1]) + result.should(be_true) + end + + it "should return false if passed string 0" do result = scope.function_num2bool(["0"]) result.should(be_false) end + + it "should return false if passed number 0" do + result = scope.function_num2bool([0]) + result.should(be_false) + end + + it "should return false if passed string -1" do + result = scope.function_num2bool(["-1"]) + result.should(be_false) + end + + it "should return false if passed number -1" do + result = scope.function_num2bool([-1]) + result.should(be_false) + end end -- cgit v1.2.3 From 4a5218a8af8c3ffaf9ea2348a3900b19d6a95416 Mon Sep 17 00:00:00 2001 From: Steve Huff Date: Fri, 29 Mar 2013 12:03:33 -0400 Subject: Reworked number-handling logic No more coercing to String and regex matching. Instead, we now coerce to Integer at the beginning or raise an error if we cannot coerce to Integer. A consequence of this change is that the function will now accept blatantly non-numeric strings as input, and return false. This seems a bit goofy to me, but it's how String#to_i works. If we really don't like this, then I'm open to suggestions. --- lib/puppet/parser/functions/num2bool.rb | 35 +++++++--------------- spec/unit/puppet/parser/functions/num2bool_spec.rb | 11 ++++++- 2 files changed, 21 insertions(+), 25 deletions(-) (limited to 'spec/unit/puppet') diff --git a/lib/puppet/parser/functions/num2bool.rb b/lib/puppet/parser/functions/num2bool.rb index 638f693..15dd560 100644 --- a/lib/puppet/parser/functions/num2bool.rb +++ b/lib/puppet/parser/functions/num2bool.rb @@ -2,39 +2,26 @@ # num2bool.rb # -# TODO(Krzysztof Wilczynski): We probably need to approach numeric values differently ... - module Puppet::Parser::Functions newfunction(:num2bool, :type => :rvalue, :doc => <<-EOS -This function converts a number into a true boolean. Zero becomes false. Numbers -higher then 0 become true. +This function converts a number or a string representation of a number into a +true boolean. Zero or anything non-numeric becomes false. Numbers higher then 0 +become true. EOS ) do |arguments| raise(Puppet::ParseError, "num2bool(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 - - # Since we're matching against a regex, coerce to String - number = arguments[0].to_s - - # Only numbers allowed ... - unless number.match(/^\-?\d+$/) - raise(Puppet::ParseError, 'num2bool(): Requires integer to work with') - end + "given (#{arguments.size} for 1)") if arguments.size != 1 - result = case number - when /^0$/ - false - when /^\-?\d+$/ - # Numbers in Puppet are often string-encoded which is troublesome ... - number = number.to_i - # We yield true for any positive number and false otherwise ... - number > 0 ? true : false - else - raise(Puppet::ParseError, 'num2bool(): Unknown numeric format given') + # we need to get an Integer out of this + begin + number = arguments[0].to_i + rescue NoMethodError + raise(Puppet::ParseError, 'num2bool(): Unable to parse number: ' + $!) end - return result + # Return true for any positive number and false otherwise + return number > 0 ? true : false end end diff --git a/spec/unit/puppet/parser/functions/num2bool_spec.rb b/spec/unit/puppet/parser/functions/num2bool_spec.rb index e51ee45..5ce981e 100644 --- a/spec/unit/puppet/parser/functions/num2bool_spec.rb +++ b/spec/unit/puppet/parser/functions/num2bool_spec.rb @@ -8,10 +8,14 @@ describe "the num2bool function" do Puppet::Parser::Functions.function("num2bool").should == "function_num2bool" end - it "should raise a ParseError if there is less than 1 arguments" do + it "should raise a ParseError if there are no arguments" do lambda { scope.function_num2bool([]) }.should( raise_error(Puppet::ParseError)) end + it "should raise a ParseError if there are more than 1 arguments" do + lambda { scope.function_num2bool(["foo","bar"]) }.should( raise_error(Puppet::ParseError)) + end + it "should return true if passed string 1" do result = scope.function_num2bool(["1"]) result.should(be_true) @@ -41,4 +45,9 @@ describe "the num2bool function" do result = scope.function_num2bool([-1]) result.should(be_false) end + + it "should return false if passed something non-numeric" do + result = scope.function_num2bool(["xyzzy"]) + result.should(be_false) + end end -- cgit v1.2.3 From 8d217f0012fef332642faf485ad187773a95bcc1 Mon Sep 17 00:00:00 2001 From: Steve Huff Date: Fri, 29 Mar 2013 15:06:36 -0400 Subject: (19864) num2bool match fix This is a bit more heavy-handed than I might like, but it does appear to do the right things: * accepts numeric input appropriately, truncating floats * matches string input against a regex, then coerces number-looking strings to int * makes a best effort to coerce anything else to a string, then subjects it to the same treatment * raises an error in the event of incorrect number of arguments or non-number-looking strings I've also included some additional unit tests. --- lib/puppet/parser/functions/num2bool.rb | 29 ++++++++++++++---- spec/unit/puppet/parser/functions/num2bool_spec.rb | 34 ++++++++++++++++++++-- 2 files changed, 56 insertions(+), 7 deletions(-) (limited to 'spec/unit/puppet') diff --git a/lib/puppet/parser/functions/num2bool.rb b/lib/puppet/parser/functions/num2bool.rb index 15dd560..cf98f80 100644 --- a/lib/puppet/parser/functions/num2bool.rb +++ b/lib/puppet/parser/functions/num2bool.rb @@ -13,13 +13,32 @@ become true. raise(Puppet::ParseError, "num2bool(): Wrong number of arguments " + "given (#{arguments.size} for 1)") if arguments.size != 1 - # we need to get an Integer out of this - begin - number = arguments[0].to_i - rescue NoMethodError - raise(Puppet::ParseError, 'num2bool(): Unable to parse number: ' + $!) + number = arguments[0] + + case number + when Numeric + # Yay, it's a number + when String + # Deal with strings later + else + begin + number = number.to_s + rescue NoMethodError + raise(Puppet::ParseError, 'num2bool(): Unable to parse argument: ' + $!) + end + end + + case number + when String + # Only accept strings that look somewhat like numbers + unless number =~ /^-?\d+/ + raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number") + end end + # Truncate floats + number = number.to_i + # Return true for any positive number and false otherwise return number > 0 ? true : false end diff --git a/spec/unit/puppet/parser/functions/num2bool_spec.rb b/spec/unit/puppet/parser/functions/num2bool_spec.rb index 5ce981e..038881f 100644 --- a/spec/unit/puppet/parser/functions/num2bool_spec.rb +++ b/spec/unit/puppet/parser/functions/num2bool_spec.rb @@ -16,6 +16,10 @@ describe "the num2bool function" do lambda { scope.function_num2bool(["foo","bar"]) }.should( raise_error(Puppet::ParseError)) end + it "should raise a ParseError if passed something non-numeric" do + lambda { scope.function_num2bool(["xyzzy"]) }.should( raise_error(Puppet::ParseError)) + end + it "should return true if passed string 1" do result = scope.function_num2bool(["1"]) result.should(be_true) @@ -26,6 +30,16 @@ describe "the num2bool function" do result.should(be_true) end + it "should return true if passed array with string 1" do + result = scope.function_num2bool([["1"]]) + result.should(be_true) + end + + it "should return true if passed array with number 1" do + result = scope.function_num2bool([[1]]) + result.should(be_true) + end + it "should return false if passed string 0" do result = scope.function_num2bool(["0"]) result.should(be_false) @@ -36,6 +50,16 @@ describe "the num2bool function" do result.should(be_false) end + it "should return false if passed array with string 0" do + result = scope.function_num2bool([["0"]]) + result.should(be_false) + end + + it "should return false if passed array with number 0" do + result = scope.function_num2bool([[0]]) + result.should(be_false) + end + it "should return false if passed string -1" do result = scope.function_num2bool(["-1"]) result.should(be_false) @@ -46,8 +70,14 @@ describe "the num2bool function" do result.should(be_false) end - it "should return false if passed something non-numeric" do - result = scope.function_num2bool(["xyzzy"]) + it "should return false if passed array with string -1" do + result = scope.function_num2bool([["-1"]]) result.should(be_false) end + + it "should return false if passed array with number -1" do + result = scope.function_num2bool([[-1]]) + result.should(be_false) + end + end -- cgit v1.2.3 From c372f177708df4c844337e9901646b7b84b86cd8 Mon Sep 17 00:00:00 2001 From: Steve Huff Date: Mon, 1 Apr 2013 11:44:09 -0400 Subject: Cleanup per adrianthebo suggestions * use Float() to process string arguments * get rid of doubly nested arrays * removing needless ternary operator * improving error message handling --- lib/puppet/parser/functions/num2bool.rb | 22 ++++++------- spec/unit/puppet/parser/functions/num2bool_spec.rb | 36 ++++++---------------- 2 files changed, 19 insertions(+), 39 deletions(-) (limited to 'spec/unit/puppet') diff --git a/lib/puppet/parser/functions/num2bool.rb b/lib/puppet/parser/functions/num2bool.rb index cf98f80..af0e6ed 100644 --- a/lib/puppet/parser/functions/num2bool.rb +++ b/lib/puppet/parser/functions/num2bool.rb @@ -19,28 +19,24 @@ become true. when Numeric # Yay, it's a number when String - # Deal with strings later + begin + number = Float(number) + rescue ArgumentError => ex + raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number: #{ex.message}") + end else begin number = number.to_s - rescue NoMethodError - raise(Puppet::ParseError, 'num2bool(): Unable to parse argument: ' + $!) - end - end - - case number - when String - # Only accept strings that look somewhat like numbers - unless number =~ /^-?\d+/ - raise(Puppet::ParseError, "num2bool(): '#{number}' does not look like a number") + rescue NoMethodError => ex + raise(Puppet::ParseError, "num2bool(): Unable to parse argument: #{ex.message}") end end - # Truncate floats + # Truncate Floats number = number.to_i # Return true for any positive number and false otherwise - return number > 0 ? true : false + return number > 0 end end diff --git a/spec/unit/puppet/parser/functions/num2bool_spec.rb b/spec/unit/puppet/parser/functions/num2bool_spec.rb index 038881f..b56196d 100644 --- a/spec/unit/puppet/parser/functions/num2bool_spec.rb +++ b/spec/unit/puppet/parser/functions/num2bool_spec.rb @@ -25,18 +25,13 @@ describe "the num2bool function" do result.should(be_true) end - it "should return true if passed number 1" do - result = scope.function_num2bool([1]) - result.should(be_true) - end - - it "should return true if passed array with string 1" do - result = scope.function_num2bool([["1"]]) + it "should return true if passed string 1.5" do + result = scope.function_num2bool(["1.5"]) result.should(be_true) end - it "should return true if passed array with number 1" do - result = scope.function_num2bool([[1]]) + it "should return true if passed number 1" do + result = scope.function_num2bool([1]) result.should(be_true) end @@ -50,34 +45,23 @@ describe "the num2bool function" do result.should(be_false) end - it "should return false if passed array with string 0" do - result = scope.function_num2bool([["0"]]) - result.should(be_false) - end - - it "should return false if passed array with number 0" do - result = scope.function_num2bool([[0]]) - result.should(be_false) - end - it "should return false if passed string -1" do result = scope.function_num2bool(["-1"]) result.should(be_false) end - it "should return false if passed number -1" do - result = scope.function_num2bool([-1]) + it "should return false if passed string -1.5" do + result = scope.function_num2bool(["-1.5"]) result.should(be_false) end - it "should return false if passed array with string -1" do - result = scope.function_num2bool([["-1"]]) + it "should return false if passed number -1" do + result = scope.function_num2bool([-1]) result.should(be_false) end - it "should return false if passed array with number -1" do - result = scope.function_num2bool([[-1]]) + it "should return false if passed float -1.5" do + result = scope.function_num2bool([-1.5]) result.should(be_false) end - end -- cgit v1.2.3