From 27782242bc27dced7bed316a01c21fffd94e34f8 Mon Sep 17 00:00:00 2001 From: Michael Polenchuk Date: Wed, 18 Nov 2015 14:32:24 +0300 Subject: Add clamp function Clamp keeps value within the range. Employ of soft() makes the whole thing is independant of order. --- README.markdown | 8 ++++++++ lib/puppet/parser/functions/clamp.rb | 30 +++++++++++++++++++++++++++ spec/acceptance/clamp_spec.rb | 40 ++++++++++++++++++++++++++++++++++++ spec/functions/clamp_spec.rb | 16 +++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 lib/puppet/parser/functions/clamp.rb create mode 100755 spec/acceptance/clamp_spec.rb create mode 100644 spec/functions/clamp_spec.rb diff --git a/README.markdown b/README.markdown index 9ff242c..0931e63 100644 --- a/README.markdown +++ b/README.markdown @@ -202,6 +202,14 @@ Removes the record separator from the end of a string or an array of strings; fo Returns a new string with the last character removed. If the string ends with '\r\n', both characters are removed. Applying `chop` to an empty string returns an empty string. If you want to merely remove record separators, then you should use the `chomp` function. Requires a string or an array of strings as input. *Type*: rvalue. +#### `clamp` + +Keeps value within the range [Min, X, Max] by sort based on integer value (order of params doesn't matter). Takes strings, arrays or numerics. Strings are converted and compared numerically. Arrays of values are flattened into a list for further handling. For example: + * `clamp('24', [575, 187])` returns 187. + * `clamp(16, 88, 661)` returns 88. + * `clamp([4, 3, '99'])` returns 4. + *Type*: rvalue. + #### `concat` Appends the contents of multiple arrays onto the first array given. For example: diff --git a/lib/puppet/parser/functions/clamp.rb b/lib/puppet/parser/functions/clamp.rb new file mode 100644 index 0000000..432c7c1 --- /dev/null +++ b/lib/puppet/parser/functions/clamp.rb @@ -0,0 +1,30 @@ +# +# clamp.rb +# + +module Puppet::Parser::Functions + newfunction(:clamp, :type => :rvalue, :arity => -2, :doc => <<-EOS + Clamps value to a range. + EOS + ) do |args| + + args.flatten! + + raise(Puppet::ParseError, 'clamp(): Wrong number of arguments, ' + + 'need three to clamp') if args.size != 3 + + # check values out + args.each do |value| + case [value.class] + when [String] + raise(Puppet::ParseError, "clamp(): Required explicit numeric (#{value}:String)") unless value =~ /^\d+$/ + when [Hash] + raise(Puppet::ParseError, "clamp(): The Hash type is not allowed (#{value})") + end + end + + # convert to numeric each element + # then sort them and get a middle value + args.map{ |n| n.to_i }.sort[1] + end +end diff --git a/spec/acceptance/clamp_spec.rb b/spec/acceptance/clamp_spec.rb new file mode 100755 index 0000000..0189258 --- /dev/null +++ b/spec/acceptance/clamp_spec.rb @@ -0,0 +1,40 @@ +#! /usr/bin/env ruby -S rspec +require 'spec_helper_acceptance' + +describe 'clamp function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('operatingsystem')) do + describe 'success' do + it 'clamps list of values' do + pp = <<-EOS + $x = 17 + $y = 225 + $z = 155 + $o = clamp($x, $y, $z) + if $o == $z { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + it 'clamps array of values' do + pp = <<-EOS + $a = [7, 19, 66] + $b = 19 + $o = clamp($a) + if $o == $b { + notify { 'output correct': } + } + EOS + + apply_manifest(pp, :catch_failures => true) do |r| + expect(r.stdout).to match(/Notice: output correct/) + end + end + end + describe 'failure' do + it 'handles improper argument counts' + it 'handles no arguments' + end +end diff --git a/spec/functions/clamp_spec.rb b/spec/functions/clamp_spec.rb new file mode 100644 index 0000000..3e2fe7a --- /dev/null +++ b/spec/functions/clamp_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe 'clamp' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(ArgumentError) } + it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params(12, 88, 71, 190).and_raise_error(Puppet::ParseError, /Wrong number of arguments, need three to clamp/) } + it { is_expected.to run.with_params('12string', 88, 15).and_raise_error(Puppet::ParseError, /Required explicit numeric/) } + it { is_expected.to run.with_params(1, 2, {'a' => 55}).and_raise_error(Puppet::ParseError, /The Hash type is not allowed/) } + it { is_expected.to run.with_params('24', [575, 187]).and_return(187) } + it { is_expected.to run.with_params([4, 3, '99']).and_return(4) } + it { is_expected.to run.with_params(16, 750, 88).and_return(88) } + it { is_expected.to run.with_params([3, 873], 73).and_return(73) } + it { is_expected.to run.with_params([4], 8, 75).and_return(8) } + it { is_expected.to run.with_params([6], [31], 9911).and_return(31) } +end -- cgit v1.2.3