]> gitweb.fluxo.info Git - puppet-stdlib.git/commitdiff
Add clamp function
authorMichael Polenchuk <mpolenchuk@mirantis.com>
Wed, 18 Nov 2015 11:32:24 +0000 (14:32 +0300)
committerMichael Polenchuk <mpolenchuk@mirantis.com>
Thu, 31 Dec 2015 09:46:07 +0000 (12:46 +0300)
Clamp keeps value within the range.
Employ of soft() makes the whole thing is independant of order.

README.markdown
lib/puppet/parser/functions/clamp.rb [new file with mode: 0644]
spec/acceptance/clamp_spec.rb [new file with mode: 0755]
spec/functions/clamp_spec.rb [new file with mode: 0644]

index 9ff242cd80db82cd1c5774889c5ddd62bf913eea..0931e633a3165a5e6d9a989bb829a5bbdf518d4f 100644 (file)
@@ -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 (file)
index 0000000..432c7c1
--- /dev/null
@@ -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 (executable)
index 0000000..0189258
--- /dev/null
@@ -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 (file)
index 0000000..3e2fe7a
--- /dev/null
@@ -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