]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
Add new functions validate_numeric() and validate_integer().
authorOliver Bertuch <oliver@majinai.net>
Thu, 4 Dec 2014 21:33:15 +0000 (22:33 +0100)
committerOliver Bertuch <oliver@majinai.net>
Thu, 4 Dec 2014 21:33:15 +0000 (22:33 +0100)
README.markdown
lib/puppet/parser/functions/validate_integer.rb [new file with mode: 0644]
lib/puppet/parser/functions/validate_numeric.rb [new file with mode: 0644]
spec/functions/validate_integer_spec.rb [new file with mode: 0755]
spec/functions/validate_numeric_spec.rb [new file with mode: 0755]

index 78839c665ca6763e94761c4755b1814392af2da6..69c5d3ddbc750f720405325274485bbd6c74a05a 100644 (file)
@@ -579,6 +579,76 @@ The first argument of this function should be the string to test, and the second
   
   *Type*: statement
 
+* `validate_integer`: Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail.
+    
+  The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
+
+  The third argument is optional and passes a minimum.  (All elements of) the first argument has to be greater or equal to this min.
+  If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
+  if (all elements of) the first argument are greater or equal to the given minimum.
+
+  It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer.
+
+  The following values will pass:
+
+  ```
+  validate_integer(1)
+  validate_integer(1, 2)
+  validate_integer(1, 1)
+  validate_integer(1, 2, 0)
+  validate_integer(2, 2, 2)
+  validate_integer(2, '', 0)
+  validate_integer(2, undef, 0)
+  $foo = undef
+  validate_integer(2, $foo, 0)
+  validate_integer([1,2,3,4,5], 6)
+  validate_integer([1,2,3,4,5], 6, 0)
+  ```
+
+  * Plus all of the above, but any combination of values passed as strings ('1' or "1").
+  * Plus all of the above, but with (correct) combinations of negative integer values.
+
+  The following values will fail, causing compilation to abort:
+
+  ```
+  validate_integer(true)
+  validate_integer(false)
+  validate_integer(7.0)
+  validate_integer({ 1 => 2 })
+  $foo = undef
+  validate_integer($foo)
+  validate_integer($foobaridontexist)
+
+  validate_integer(1, 0)
+  validate_integer(1, true)
+  validate_integer(1, '')
+  validate_integer(1, undef)
+  validate_integer(1, , 0)
+  validate_integer(1, 2, 3)
+  validate_integer(1, 3, 2)
+  validate_integer(1, 3, true)
+  ```
+
+  * Plus all of the above, but any combination of values passed as strings ('false' or "false").
+  * Plus all of the above, but with incorrect combinations of negative integer values.
+  * Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument.
+
+  *Type*: statement
+
+* `validate_numeric`: Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail.
+
+  The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
+
+  The third argument is optional and passes a minimum.  (All elements of) the first argument has to be greater or equal to this min.
+  If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
+  if (all elements of) the first argument are greater or equal to the given minimum.
+
+  It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric.
+
+  For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too.
+
+  *Type*: statement
+
 * `validate_re`: Performs simple validation of a string against one or more regular expressions. The first argument of this function should be the string to
 test, and the second argument should be a stringified regular expression
 (without the // delimiters) or an array of regular expressions. If none
diff --git a/lib/puppet/parser/functions/validate_integer.rb b/lib/puppet/parser/functions/validate_integer.rb
new file mode 100644 (file)
index 0000000..c12d676
--- /dev/null
@@ -0,0 +1,128 @@
+module Puppet::Parser::Functions
+
+  newfunction(:validate_integer, :doc => <<-'ENDHEREDOC') do |args|
+    Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail.
+    
+    The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
+
+    The third argument is optional and passes a minimum.  (All elements of) the first argument has to be greater or equal to this min.
+    If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
+    if (all elements of) the first argument are greater or equal to the given minimum.
+
+    It will fail if the first argument is not an integer or array of integers, and if arg 2 and arg 3 are not convertable to an integer.
+
+    The following values will pass:
+
+      validate_integer(1)
+      validate_integer(1, 2)
+      validate_integer(1, 1)
+      validate_integer(1, 2, 0)
+      validate_integer(2, 2, 2)
+      validate_integer(2, '', 0)
+      validate_integer(2, undef, 0)
+      $foo = undef
+      validate_integer(2, $foo, 0)
+      validate_integer([1,2,3,4,5], 6)
+      validate_integer([1,2,3,4,5], 6, 0)
+
+    Plus all of the above, but any combination of values passed as strings ('1' or "1").
+    Plus all of the above, but with (correct) combinations of negative integer values.
+
+    The following values will not:
+
+      validate_integer(true)
+      validate_integer(false)
+      validate_integer(7.0)
+      validate_integer({ 1 => 2 })
+      $foo = undef
+      validate_integer($foo)
+      validate_integer($foobaridontexist)
+
+      validate_integer(1, 0)
+      validate_integer(1, true)
+      validate_integer(1, '')
+      validate_integer(1, undef)
+      validate_integer(1, , 0)
+      validate_integer(1, 2, 3)
+      validate_integer(1, 3, 2)
+      validate_integer(1, 3, true)
+
+    Plus all of the above, but any combination of values passed as strings ('false' or "false").
+    Plus all of the above, but with incorrect combinations of negative integer values.
+    Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument.
+
+    ENDHEREDOC
+
+    # tell the user we need at least one, and optionally up to two other parameters
+    raise Puppet::ParseError, "validate_integer(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4
+
+    input, max, min = *args
+
+    # check maximum parameter
+    if args.length > 1
+      max = max.to_s
+      # allow max to be empty (or undefined) if we have a minimum set
+      if args.length > 2 and max == ''
+        max = nil
+      else
+        begin
+          max = Integer(max)
+        rescue TypeError, ArgumentError
+          raise Puppet::ParseError, "validate_integer(): Expected second argument to be unset or an Integer, got #{max}:#{max.class}"
+        end
+      end
+    else
+      max = nil
+    end
+
+    # check minimum parameter
+    if args.length > 2
+      begin
+        min = Integer(min.to_s)
+      rescue TypeError, ArgumentError
+        raise Puppet::ParseError, "validate_integer(): Expected third argument to be unset or an Integer, got #{min}:#{min.class}"
+      end
+    else
+      min = nil
+    end
+
+    # ensure that min < max
+    if min and max and min > max
+      raise Puppet::ParseError, "validate_integer(): Expected second argument to be larger than third argument, got #{max} < #{min}"
+    end
+
+    # create lamba validator function
+    validator = lambda do |num|
+      # check input < max
+      if max and num > max
+        raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
+      end
+      # check input > min (this will only be checked if no exception has been raised before)
+      if min and num < min
+        raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
+      end
+    end
+
+    # if this is an array, handle it.
+    case input
+    when Array
+      # check every element of the array
+      input.each_with_index do |arg, pos|
+        begin
+          arg = Integer(arg.to_s)
+          validator.call(arg)
+        rescue TypeError, ArgumentError
+          raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}"
+        end
+      end
+    # check the input. this will also fail any stuff other than pure, shiny integers
+    else
+      begin
+        input = Integer(input.to_s)
+        validator.call(input)
+      rescue TypeError, ArgumentError
+        raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
+      end
+    end
+  end
+end
diff --git a/lib/puppet/parser/functions/validate_numeric.rb b/lib/puppet/parser/functions/validate_numeric.rb
new file mode 100644 (file)
index 0000000..27eec30
--- /dev/null
@@ -0,0 +1,90 @@
+module Puppet::Parser::Functions
+
+  newfunction(:validate_numeric, :doc => <<-'ENDHEREDOC') do |args|
+    Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail.
+    
+    The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
+
+    The third argument is optional and passes a minimum.  (All elements of) the first argument has to be greater or equal to this min.
+    If, and only if, a minimum is given, the second argument may be an empty string or undef, which will be handled to just check
+    if (all elements of) the first argument are greater or equal to the given minimum.
+
+    It will fail if the first argument is not a numeric (Integer or Float) or array of numerics, and if arg 2 and arg 3 are not convertable to a numeric.
+
+    For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too.
+
+    ENDHEREDOC
+
+    # tell the user we need at least one, and optionally up to two other parameters
+    raise Puppet::ParseError, "validate_numeric(): Wrong number of arguments; must be 1, 2 or 3, got #{args.length}" unless args.length > 0 and args.length < 4
+
+    input, max, min = *args
+
+    # check maximum parameter
+    if args.length > 1
+      max = max.to_s
+      # allow max to be empty (or undefined) if we have a minimum set
+      if args.length > 2 and max == ''
+        max = nil
+      else
+        begin
+          max = Float(max)
+        rescue TypeError, ArgumentError
+          raise Puppet::ParseError, "validate_numeric(): Expected second argument to be unset or a Numeric, got #{max}:#{max.class}"
+        end
+      end
+    else
+      max = nil
+    end
+
+    # check minimum parameter
+    if args.length > 2
+      begin
+        min = Float(min.to_s)
+      rescue TypeError, ArgumentError
+        raise Puppet::ParseError, "validate_numeric(): Expected third argument to be unset or a Numeric, got #{min}:#{min.class}"
+      end
+    else
+      min = nil
+    end
+
+    # ensure that min < max
+    if min and max and min > max
+      raise Puppet::ParseError, "validate_numeric(): Expected second argument to be larger than third argument, got #{max} < #{min}"
+    end
+
+    # create lamba validator function
+    validator = lambda do |num|
+      # check input < max
+      if max and num > max
+        raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
+      end
+      # check input > min (this will only be checked if no exception has been raised before)
+      if min and num < min
+        raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
+      end
+    end
+
+    # if this is an array, handle it.
+    case input
+    when Array
+      # check every element of the array
+      input.each_with_index do |arg, pos|
+        begin
+          arg = Float(arg.to_s)
+          validator.call(arg)
+        rescue TypeError, ArgumentError
+          raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}"
+        end
+      end
+    # check the input. this will also fail any stuff other than pure, shiny integers
+    else
+      begin
+        input = Float(input.to_s)
+        validator.call(input)
+      rescue TypeError, ArgumentError
+        raise Puppet::ParseError, "validate_numeric(): Expected first argument to be a Numeric or Array, got #{input.class}"
+      end
+    end
+  end
+end
diff --git a/spec/functions/validate_integer_spec.rb b/spec/functions/validate_integer_spec.rb
new file mode 100755 (executable)
index 0000000..dff3415
--- /dev/null
@@ -0,0 +1,219 @@
+#! /usr/bin/env ruby -S rspec
+
+require 'spec_helper'
+
+describe Puppet::Parser::Functions.function(:validate_integer) do
+  let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
+
+  describe 'when calling validate_integer from puppet without any argument or to many' do
+    it "should not compile when no argument is passed" do
+      Puppet[:code] = "validate_integer()"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/)
+    end
+    it "should not compile when more than three arguments are passed" do
+      Puppet[:code] = "validate_integer(1, 1, 1, 1)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/)
+    end
+  end
+
+  describe 'when calling validate_integer from puppet only with input' do
+    %w{ 1 -1 }.each do |the_number|
+      it "should compile when #{the_number} is an encapsulated integer" do
+        Puppet[:code] = "validate_integer('#{the_number}')"
+        scope.compiler.compile
+      end
+      it "should compile when #{the_number} is an bare integer" do
+        Puppet[:code] = "validate_integer(#{the_number})"
+        scope.compiler.compile
+      end
+    end
+
+    %w{ [1,2,3,4,5] ['1','2','3','4','5'] }.each do |the_number|
+      it "should compile when multiple Integer arguments are passed in an Array" do
+        Puppet[:code] = "validate_integer(#{the_number})"
+        scope.compiler.compile
+      end
+    end
+
+    %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_number|
+      it "should not compile when #{the_number} is in a string" do
+        Puppet[:code] = "validate_integer('#{the_number}')"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/)
+      end
+
+      it "should not compile when #{the_number} is a bare word" do
+        Puppet[:code] = "validate_integer(#{the_number})"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/)
+      end
+    end
+
+    it "should not compile when an Integer is part of a larger String" do
+      Puppet[:code] = "validate_integer('1 test')"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/)
+    end
+
+    it "should not compile when an Array with a non-Integer value is passed" do
+      Puppet[:code] = "validate_integer([1, '-7.0'])"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /at array position 1 to be an Integer/)
+    end
+
+    it "should not compile when a Hash is passed" do
+      Puppet[:code] = "validate_integer({ 1 => 2 })"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer or Array/)
+    end
+
+    it "should not compile when an explicitly undef variable is passed" do
+      Puppet[:code] = <<-'ENDofPUPPETcode'
+        $foo = undef
+        validate_integer($foo)
+      ENDofPUPPETcode
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/)
+    end
+
+    it "should not compile when an undefined variable is passed" do
+      Puppet[:code] = <<-'ENDofPUPPETcode'
+        validate_integer($foobarbazishouldnotexist)
+      ENDofPUPPETcode
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be an Integer/)
+    end
+  end
+
+  describe 'when calling validate_integer from puppet with input and a maximum' do
+    max = 10
+    %w{ 1 -1 }.each do |the_number|
+      it "should compile when #{the_number} is lower than a maximum of #{max}" do
+        Puppet[:code] = "validate_integer(#{the_number},#{max})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should compile when an Integer is equal the maximum" do
+      Puppet[:code] = "validate_integer(#{max},#{max})"
+      scope.compiler.compile
+    end
+
+    it "should not compile when #{max+1} is greater than a maximum of #{max}" do
+      Puppet[:code] = "validate_integer(#{max+1},#{max})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/)
+    end
+
+    %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number|
+      it "should compile when each element of #{the_number} is lower than a maximum of #{max}" do
+        Puppet[:code] = "validate_integer(#{the_number},#{max})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should not compile when an element of an Array [-10,1,2,3,4,5,#{max+1}] is greater than a maximum of #{max}" do
+      Puppet[:code] = "validate_integer([-10,1,2,3,4,5,#{max+1}],#{max})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/)
+    end
+
+    %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_max|
+      it "should not compile when a non-Integer maximum #{the_max}, encapsulated in a String, is passed" do
+        Puppet[:code] = "validate_integer(1,'#{the_max}')"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+      end
+      it "should not compile when a non-Integer maximum #{the_max} bare word is passed" do
+        Puppet[:code] = "validate_integer(1,#{the_max})"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+      end
+    end
+
+    it "should not compile when an explicitly undefined variable is passed as maximum and no minimum is passed" do
+      Puppet[:code] = <<-'ENDofPUPPETcode'
+        $foo = undef
+        validate_integer(10, $foo)
+      ENDofPUPPETcode
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+    end
+    it "should not compile when an explicitly undef is passed as maximum and no minimum is passed" do
+      Puppet[:code] = "validate_integer(10, undef)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+    end
+    it "should not compile when an empty string is passed as maximum and no minimum is passed" do
+      Puppet[:code] = "validate_integer(10, '')"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+    end
+    it "should not compile when an undefined variable for a maximum is passed" do
+      Puppet[:code] = "validate_integer(10, $foobarbazishouldnotexist)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+    end
+  end
+
+  describe 'when calling validate_integer from puppet with input, a maximum and a minimum' do
+    it "should not compile when a minimum larger than maximum is passed" do
+      Puppet[:code] = "validate_integer(1,1,2)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /second argument to be larger than third argument/)
+    end
+
+    max = 10
+    min = -10
+    %w{ 1 -1 }.each do |the_number|
+      it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do
+        Puppet[:code] = "validate_integer(#{the_number},#{max},#{min})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should compile when an Integer is equal the minimum" do
+      Puppet[:code] = "validate_integer(#{min},#{max},#{min})"
+      scope.compiler.compile
+    end
+
+    it "should compile when an Integer is equal the minimum and maximum" do
+      Puppet[:code] = "validate_integer(#{max},#{max},#{max})"
+      scope.compiler.compile
+    end
+
+    it "should compile when an empty maximum is passed and the Integer is greater than the minimum" do
+      Puppet[:code] = "validate_integer(#{max},'',#{min})"
+      scope.compiler.compile
+    end
+    it "should compile when an explicitly undefined maximum is passed and the Integer is greater than the minimum" do
+      Puppet[:code] = "validate_integer(#{max},undef,#{min})"
+      scope.compiler.compile
+    end
+    it "should compile when an explicitly undefined variable is passed for maximum and the Integer is greater than the minimum" do
+      Puppet[:code] = <<-"ENDofPUPPETcode"
+        $foo = undef
+        validate_integer(#{max}, $foo, #{min})
+      ENDofPUPPETcode
+      scope.compiler.compile
+    end
+    it "should not compile when no maximum value is given and the Integer is greater than the minimum" do
+      Puppet[:code] = "validate_integer(#{max},,#{min})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::Error, /Syntax error at ','/)
+    end
+
+    it "should not compile when #{min-1} is lower than a minimum of #{min}" do
+      Puppet[:code] = "validate_integer(#{min-1},#{max},#{min})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/)
+    end
+
+    %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number|
+      it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do
+        Puppet[:code] = "validate_integer(#{the_number},#{max},#{min})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should not compile when an element of an Array [#{min-1},1,2,3,4,5,10] is lower than a minimum of #{min}" do
+      Puppet[:code] = "validate_integer([#{min-1},1,2,3,4,5,10],#{max},#{min})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/)
+    end
+
+    %w{ true false iAmAString 1test 7.0 -7.0 }.each do |the_min|
+      it "should not compile when a non-Integer minimum #{the_min}, encapsulated in a String, is passed" do
+        Puppet[:code] = "validate_integer(1,#{max},'#{the_min}')"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+      end
+      it "should not compile when a non-Integer minimum #{the_min} bare word is passed" do
+        Puppet[:code] = "validate_integer(1,#{max},#{the_min})"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or an Integer/)
+      end
+    end
+  end
+end
diff --git a/spec/functions/validate_numeric_spec.rb b/spec/functions/validate_numeric_spec.rb
new file mode 100755 (executable)
index 0000000..c8b0e4d
--- /dev/null
@@ -0,0 +1,217 @@
+#! /usr/bin/env ruby -S rspec
+
+require 'spec_helper'
+
+describe Puppet::Parser::Functions.function(:validate_numeric) do
+  let(:scope) { PuppetlabsSpec::PuppetInternals.scope }
+
+  describe 'when calling validate_numeric from puppet without any argument or to many' do
+    it "should not compile when no argument is passed" do
+      Puppet[:code] = "validate_numeric()"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/)
+    end
+    it "should not compile when more than three arguments are passed" do
+      Puppet[:code] = "validate_numeric(1, 1, 1, 1)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /Wrong number of arguments/)
+    end
+  end
+
+  describe 'when calling validate_numeric from puppet only with input' do
+    %w{ 1 -1 1.0 -1.0 }.each do |the_number|
+      it "should compile when #{the_number} is an encapsulated numeric" do
+        Puppet[:code] = "validate_numeric('#{the_number}')"
+        scope.compiler.compile
+      end
+      it "should compile when #{the_number} is a bare numeric" do
+        Puppet[:code] = "validate_numeric(#{the_number})"
+        scope.compiler.compile
+      end
+    end
+
+    %w{ [1,2,3,4,5] ['1','2','3','4','5'] [1.1,2.2,3.3,4.4,5.5] ['1.1','2.2','3.3','4.4','5.5'] }.each do |the_number|
+      it "should compile when multiple Numeric arguments are passed in an Array" do
+        Puppet[:code] = "validate_numeric(#{the_number})"
+        scope.compiler.compile
+      end
+    end
+
+    %w{ true false iAmAString 1test }.each do |the_number|
+      it "should not compile when #{the_number} is in a string" do
+        Puppet[:code] = "validate_numeric('#{the_number}')"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/)
+      end
+
+      it "should not compile when #{the_number} is a bare word" do
+        Puppet[:code] = "validate_numeric(#{the_number})"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/)
+      end
+    end
+
+    it "should not compile when a Numeric is part of a larger String" do
+      Puppet[:code] = "validate_numeric('1.0 test')"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/)
+    end
+
+    it "should not compile when an Array with a non-Numeric value is passed" do
+      Puppet[:code] = "validate_numeric([1, 'test'])"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /at array position 1 to be a Numeric/)
+    end
+
+    it "should not compile when a Hash is passed" do
+      Puppet[:code] = "validate_numeric({ 1 => 2 })"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric or Array/)
+    end
+
+    it "should not compile when an explicitly undef variable is passed" do
+      Puppet[:code] = <<-'ENDofPUPPETcode'
+        $foo = undef
+        validate_numeric($foo)
+      ENDofPUPPETcode
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/)
+    end
+
+    it "should not compile when an undefined variable is passed" do
+      Puppet[:code] = 'validate_numeric($foobarbazishouldnotexist)'
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be a Numeric/)
+    end
+  end
+
+  describe 'when calling validate_numeric from puppet with input and a maximum' do
+    max = 10
+    %w{ 1 -1 1.0 -1.0 }.each do |the_number|
+      it "should compile when #{the_number} is lower than a maximum of #{max}" do
+        Puppet[:code] = "validate_numeric(#{the_number},#{max})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should compile when a Numeric is equal the maximum" do
+      Puppet[:code] = "validate_numeric(#{max},#{max})"
+      scope.compiler.compile
+    end
+
+    it "should not compile when #{max+1} is greater than a maximum of #{max}" do
+      Puppet[:code] = "validate_numeric(#{max+1},#{max})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/)
+    end
+
+    %w{ [-10,1,2,3,4,5,10] ['-10','1','2','3','4','5','10'] }.each do |the_number|
+      it "should compile when each element of #{the_number} is lower than a maximum of #{max}" do
+        Puppet[:code] = "validate_numeric(#{the_number},#{max})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should not compile when an element of an Array [-10,1,2,3,4,5,#{max+1}] is greater than a maximum of #{max}" do
+      Puppet[:code] = "validate_numeric([-10,1,2,3,4,5,#{max+1}],#{max})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be smaller or equal to/)
+    end
+
+    %w{ true false iAmAString 1test }.each do |the_max|
+      it "should not compile when a non-Numeric maximum #{the_max}, encapsulated in a String, is passed" do
+        Puppet[:code] = "validate_numeric(1,'#{the_max}')"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+      end
+      it "should not compile when a non-Numeric maximum #{the_max} bare word is passed" do
+        Puppet[:code] = "validate_numeric(1,#{the_max})"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+      end
+    end
+
+    it "should not compile when an explicitly undefined variable is passed as maximum and no minimum is passed" do
+      Puppet[:code] = <<-'ENDofPUPPETcode'
+        $foo = undef
+        validate_numeric(10, $foo)
+      ENDofPUPPETcode
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+    end
+    it "should not compile when an explicitly undef is passed as maximum and no minimum is passed" do
+      Puppet[:code] = "validate_numeric(10, undef)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+    end
+    it "should not compile when an empty string is passed as maximum and no minimum is passed" do
+      Puppet[:code] = "validate_numeric(10, '')"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+    end
+    it "should not compile when an undefined variable for a maximum is passed" do
+      Puppet[:code] = "validate_numeric(10, $foobarbazishouldnotexist)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+    end
+  end
+
+  describe 'when calling validate_numeric from puppet with input, a maximum and a minimum' do
+    it "should not compile when a minimum larger than maximum is passed" do
+      Puppet[:code] = "validate_numeric(1,1,2)"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /second argument to be larger than third argument/)
+    end
+
+    max = 10
+    min = -10
+    %w{ 1 -1 }.each do |the_number|
+      it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do
+        Puppet[:code] = "validate_numeric(#{the_number},#{max},#{min})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should compile when a Numeric is equal the minimum" do
+      Puppet[:code] = "validate_numeric(#{min},#{max},#{min})"
+      scope.compiler.compile
+    end
+
+    it "should compile when a Numeric is equal the minimum and maximum" do
+      Puppet[:code] = "validate_numeric(#{max},#{max},#{max})"
+      scope.compiler.compile
+    end
+
+    it "should compile when an empty maximum is passed and the Numeric is greater than the minimum" do
+      Puppet[:code] = "validate_numeric(#{max}.1,'',#{min})"
+      scope.compiler.compile
+    end
+    it "should compile when an explicitly undefined maximum is passed and the Numeric is greater than the minimum" do
+      Puppet[:code] = "validate_numeric(#{max}.1,undef,#{min})"
+      scope.compiler.compile
+    end
+    it "should compile when an explicitly undefined variable is passed for maximum and the Numeric is greater than the minimum" do
+      Puppet[:code] = <<-"ENDofPUPPETcode"
+        $foo = undef
+        validate_numeric(#{max}.1, $foo, #{min})
+      ENDofPUPPETcode
+      scope.compiler.compile
+    end
+    it "should not compile when no maximum value is given and the Numeric is greater than the minimum" do
+      Puppet[:code] = "validate_numeric(#{max}.1,,#{min})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::Error, /Syntax error at ','/)
+    end
+
+    it "should not compile when #{min-1} is lower than a minimum of #{min}" do
+      Puppet[:code] = "validate_numeric(#{min-1.0},#{max},#{min})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/)
+    end
+
+    %w{ [-10,1,2,3,4,5,10] ['-10.0','1','2','3','4','5','10.0'] }.each do |the_number|
+      it "should compile when each element of #{the_number} is within a range from #{min} to #{max}" do
+        Puppet[:code] = "validate_numeric(#{the_number},#{max},#{min})"
+        scope.compiler.compile
+      end
+    end
+
+    it "should not compile when an element of an Array [#{min-1.1},1,2,3,4,5,10.0] is lower than a minimum of #{min}" do
+      Puppet[:code] = "validate_numeric([#{min-1},1,2,3,4,5,10],#{max},#{min})"
+      expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be greater or equal to/)
+    end
+
+    %w{ true false iAmAString 1test }.each do |the_min|
+      it "should not compile when a non-Numeric minimum #{the_min}, encapsulated in a String, is passed" do
+        Puppet[:code] = "validate_numeric(1,#{max},'#{the_min}')"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+      end
+      it "should not compile when a non-Numeric minimum #{the_min} bare word is passed" do
+        Puppet[:code] = "validate_numeric(1,#{max},#{the_min})"
+        expect { scope.compiler.compile }.to raise_error(Puppet::ParseError, /to be unset or a Numeric/)
+      end
+    end
+  end
+end