Skip to content

Commit 41965fd

Browse files
committed
Merge pull request #375 from poikilotherm/feature/master/validate_integer_and_numeric
(MODULES-560) Add new functions validate_numeric() and validate_integer().
2 parents 706b9e8 + 3053427 commit 41965fd

5 files changed

Lines changed: 730 additions & 0 deletions

File tree

README.markdown

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,76 @@ If a third argument is specified, this will be the error message raised and seen
613613
614614
*Type*: statement
615615
616+
* `validate_integer`: Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail.
617+
618+
The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
619+
620+
The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min.
621+
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
622+
if (all elements of) the first argument are greater or equal to the given minimum.
623+
624+
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.
625+
626+
The following values will pass:
627+
628+
```
629+
validate_integer(1)
630+
validate_integer(1, 2)
631+
validate_integer(1, 1)
632+
validate_integer(1, 2, 0)
633+
validate_integer(2, 2, 2)
634+
validate_integer(2, '', 0)
635+
validate_integer(2, undef, 0)
636+
$foo = undef
637+
validate_integer(2, $foo, 0)
638+
validate_integer([1,2,3,4,5], 6)
639+
validate_integer([1,2,3,4,5], 6, 0)
640+
```
641+
642+
* Plus all of the above, but any combination of values passed as strings ('1' or "1").
643+
* Plus all of the above, but with (correct) combinations of negative integer values.
644+
645+
The following values will fail, causing compilation to abort:
646+
647+
```
648+
validate_integer(true)
649+
validate_integer(false)
650+
validate_integer(7.0)
651+
validate_integer({ 1 => 2 })
652+
$foo = undef
653+
validate_integer($foo)
654+
validate_integer($foobaridontexist)
655+
656+
validate_integer(1, 0)
657+
validate_integer(1, true)
658+
validate_integer(1, '')
659+
validate_integer(1, undef)
660+
validate_integer(1, , 0)
661+
validate_integer(1, 2, 3)
662+
validate_integer(1, 3, 2)
663+
validate_integer(1, 3, true)
664+
```
665+
666+
* Plus all of the above, but any combination of values passed as strings ('false' or "false").
667+
* Plus all of the above, but with incorrect combinations of negative integer values.
668+
* Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument.
669+
670+
*Type*: statement
671+
672+
* `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.
673+
674+
The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
675+
676+
The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min.
677+
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
678+
if (all elements of) the first argument are greater or equal to the given minimum.
679+
680+
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.
681+
682+
For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too.
683+
684+
*Type*: statement
685+
616686
* `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
617687
test, and the second argument should be a stringified regular expression
618688
(without the // delimiters) or an array of regular expressions. If none
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
module Puppet::Parser::Functions
2+
3+
newfunction(:validate_integer, :doc => <<-'ENDHEREDOC') do |args|
4+
Validate that the first argument is an integer (or an array of integers). Abort catalog compilation if any of the checks fail.
5+
6+
The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
7+
8+
The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min.
9+
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
10+
if (all elements of) the first argument are greater or equal to the given minimum.
11+
12+
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.
13+
14+
The following values will pass:
15+
16+
validate_integer(1)
17+
validate_integer(1, 2)
18+
validate_integer(1, 1)
19+
validate_integer(1, 2, 0)
20+
validate_integer(2, 2, 2)
21+
validate_integer(2, '', 0)
22+
validate_integer(2, undef, 0)
23+
$foo = undef
24+
validate_integer(2, $foo, 0)
25+
validate_integer([1,2,3,4,5], 6)
26+
validate_integer([1,2,3,4,5], 6, 0)
27+
28+
Plus all of the above, but any combination of values passed as strings ('1' or "1").
29+
Plus all of the above, but with (correct) combinations of negative integer values.
30+
31+
The following values will not:
32+
33+
validate_integer(true)
34+
validate_integer(false)
35+
validate_integer(7.0)
36+
validate_integer({ 1 => 2 })
37+
$foo = undef
38+
validate_integer($foo)
39+
validate_integer($foobaridontexist)
40+
41+
validate_integer(1, 0)
42+
validate_integer(1, true)
43+
validate_integer(1, '')
44+
validate_integer(1, undef)
45+
validate_integer(1, , 0)
46+
validate_integer(1, 2, 3)
47+
validate_integer(1, 3, 2)
48+
validate_integer(1, 3, true)
49+
50+
Plus all of the above, but any combination of values passed as strings ('false' or "false").
51+
Plus all of the above, but with incorrect combinations of negative integer values.
52+
Plus all of the above, but with non-integer crap in arrays or maximum / minimum argument.
53+
54+
ENDHEREDOC
55+
56+
# tell the user we need at least one, and optionally up to two other parameters
57+
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
58+
59+
input, max, min = *args
60+
61+
# check maximum parameter
62+
if args.length > 1
63+
max = max.to_s
64+
# allow max to be empty (or undefined) if we have a minimum set
65+
if args.length > 2 and max == ''
66+
max = nil
67+
else
68+
begin
69+
max = Integer(max)
70+
rescue TypeError, ArgumentError
71+
raise Puppet::ParseError, "validate_integer(): Expected second argument to be unset or an Integer, got #{max}:#{max.class}"
72+
end
73+
end
74+
else
75+
max = nil
76+
end
77+
78+
# check minimum parameter
79+
if args.length > 2
80+
begin
81+
min = Integer(min.to_s)
82+
rescue TypeError, ArgumentError
83+
raise Puppet::ParseError, "validate_integer(): Expected third argument to be unset or an Integer, got #{min}:#{min.class}"
84+
end
85+
else
86+
min = nil
87+
end
88+
89+
# ensure that min < max
90+
if min and max and min > max
91+
raise Puppet::ParseError, "validate_integer(): Expected second argument to be larger than third argument, got #{max} < #{min}"
92+
end
93+
94+
# create lamba validator function
95+
validator = lambda do |num|
96+
# check input < max
97+
if max and num > max
98+
raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
99+
end
100+
# check input > min (this will only be checked if no exception has been raised before)
101+
if min and num < min
102+
raise Puppet::ParseError, "validate_integer(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
103+
end
104+
end
105+
106+
# if this is an array, handle it.
107+
case input
108+
when Array
109+
# check every element of the array
110+
input.each_with_index do |arg, pos|
111+
begin
112+
arg = Integer(arg.to_s)
113+
validator.call(arg)
114+
rescue TypeError, ArgumentError
115+
raise Puppet::ParseError, "validate_integer(): Expected element at array position #{pos} to be an Integer, got #{arg.class}"
116+
end
117+
end
118+
# for the sake of compatibility with ruby 1.8, we need extra handling of hashes
119+
when Hash
120+
raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
121+
# check the input. this will also fail any stuff other than pure, shiny integers
122+
else
123+
begin
124+
input = Integer(input.to_s)
125+
validator.call(input)
126+
rescue TypeError, ArgumentError
127+
raise Puppet::ParseError, "validate_integer(): Expected first argument to be an Integer or Array, got #{input.class}"
128+
end
129+
end
130+
end
131+
end
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module Puppet::Parser::Functions
2+
3+
newfunction(:validate_numeric, :doc => <<-'ENDHEREDOC') do |args|
4+
Validate that the first argument is a numeric value (or an array of numeric values). Abort catalog compilation if any of the checks fail.
5+
6+
The second argument is optional and passes a maximum. (All elements of) the first argument has to be less or equal to this max.
7+
8+
The third argument is optional and passes a minimum. (All elements of) the first argument has to be greater or equal to this min.
9+
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
10+
if (all elements of) the first argument are greater or equal to the given minimum.
11+
12+
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.
13+
14+
For passing and failing usage, see `validate_integer()`. It is all the same for validate_numeric, yet now floating point values are allowed, too.
15+
16+
ENDHEREDOC
17+
18+
# tell the user we need at least one, and optionally up to two other parameters
19+
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
20+
21+
input, max, min = *args
22+
23+
# check maximum parameter
24+
if args.length > 1
25+
max = max.to_s
26+
# allow max to be empty (or undefined) if we have a minimum set
27+
if args.length > 2 and max == ''
28+
max = nil
29+
else
30+
begin
31+
max = Float(max)
32+
rescue TypeError, ArgumentError
33+
raise Puppet::ParseError, "validate_numeric(): Expected second argument to be unset or a Numeric, got #{max}:#{max.class}"
34+
end
35+
end
36+
else
37+
max = nil
38+
end
39+
40+
# check minimum parameter
41+
if args.length > 2
42+
begin
43+
min = Float(min.to_s)
44+
rescue TypeError, ArgumentError
45+
raise Puppet::ParseError, "validate_numeric(): Expected third argument to be unset or a Numeric, got #{min}:#{min.class}"
46+
end
47+
else
48+
min = nil
49+
end
50+
51+
# ensure that min < max
52+
if min and max and min > max
53+
raise Puppet::ParseError, "validate_numeric(): Expected second argument to be larger than third argument, got #{max} < #{min}"
54+
end
55+
56+
# create lamba validator function
57+
validator = lambda do |num|
58+
# check input < max
59+
if max and num > max
60+
raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be smaller or equal to #{max}, got #{input.inspect}."
61+
end
62+
# check input > min (this will only be checked if no exception has been raised before)
63+
if min and num < min
64+
raise Puppet::ParseError, "validate_numeric(): Expected #{input.inspect} to be greater or equal to #{min}, got #{input.inspect}."
65+
end
66+
end
67+
68+
# if this is an array, handle it.
69+
case input
70+
when Array
71+
# check every element of the array
72+
input.each_with_index do |arg, pos|
73+
begin
74+
arg = Float(arg.to_s)
75+
validator.call(arg)
76+
rescue TypeError, ArgumentError
77+
raise Puppet::ParseError, "validate_numeric(): Expected element at array position #{pos} to be a Numeric, got #{arg.class}"
78+
end
79+
end
80+
# for the sake of compatibility with ruby 1.8, we need extra handling of hashes
81+
when Hash
82+
raise Puppet::ParseError, "validate_integer(): Expected first argument to be a Numeric or Array, got #{input.class}"
83+
# check the input. this will also fail any stuff other than pure, shiny integers
84+
else
85+
begin
86+
input = Float(input.to_s)
87+
validator.call(input)
88+
rescue TypeError, ArgumentError
89+
raise Puppet::ParseError, "validate_numeric(): Expected first argument to be a Numeric or Array, got #{input.class}"
90+
end
91+
end
92+
end
93+
end

0 commit comments

Comments
 (0)