diff --git a/README.md b/README.md index 2b6a64bd9..80c870d4f 100644 --- a/README.md +++ b/README.md @@ -1649,6 +1649,24 @@ Returns the number of elements in a string, an array or a hash. This function wi *Type*: rvalue. +#### `sprintf_hash` + +Perform printf-style formatting with named references of text. + +The first paameter is format string describing how the rest of the parameters in the hash +should be formatted. See the documentation for the `Kernel::sprintf` function in Ruby for +all the details. + +*Example:* + +```puppet +$output = sprintf_hash('String: %s / number converted to binary: %b', + { 'foo' => 'a string', 'number' => 5 }) +# $output = 'String: a string / number converted to binary: 101' +``` + +*Type*: rvalue + #### `sort` Sorts strings and arrays lexically. diff --git a/lib/puppet/functions/sprintf_hash.rb b/lib/puppet/functions/sprintf_hash.rb new file mode 100644 index 000000000..2536bc9dd --- /dev/null +++ b/lib/puppet/functions/sprintf_hash.rb @@ -0,0 +1,29 @@ +# Uses sprintf with named references. +# +# The first parameter is format string describing how the rest of the parameters in the hash +# should be formatted. See the documentation for the `Kernel::sprintf` function in Ruby for +# all the details. +# +# In the given argument hash with parameters, all keys are converted to symbols so they work +# with the `sprintf` function. +# +# @example Format a string and number +# $output = sprintf_hash('String: %s / number converted to binary: %b', +# { 'foo' => 'a string', 'number' => 5 }) +# # $output = 'String: a string / number converted to binary: 101' +# +Puppet::Functions.create_function(:sprintf_hash) do + # @param format The format to use. + # @param arguments Hash with parameters. + # @return The formatted string. + dispatch :sprintf_hash do + param 'String', :format + param 'Hash', :arguments + # Disabled for now. This gives issues on puppet 4.7.1. + # return_type 'String' + end + + def sprintf_hash(format, arguments) + Kernel.sprintf(format, Hash[arguments.map { |(k, v)| [k.to_sym, v] }]) + end +end diff --git a/spec/functions/sprintf_hash_spec.rb b/spec/functions/sprintf_hash_spec.rb new file mode 100644 index 000000000..1323094a8 --- /dev/null +++ b/spec/functions/sprintf_hash_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe 'sprintf_hash' do + it 'exists' do + is_expected.not_to eq(nil) + end + + context 'validate param count' do + it 'fails with no arguments' do + is_expected.to run.with_params.and_raise_error(ArgumentError, %r{expects 2 arguments}i) + end + it 'fails with 1 argument' do + is_expected.to run.with_params('').and_raise_error(ArgumentError, %r{expects 2 arguments}i) + end + it 'fails with too many arguments' do + is_expected.to run.with_params('', '', '').and_raise_error(ArgumentError, %r{expects 2 arguments}i) + end + end + + context 'validate param type' do + it 'fails with wrong format type' do + is_expected.to run.with_params(false, {}).and_raise_error(ArgumentError, %r{parameter 'format' expects a String value}i) + end + it 'fails with wrong arguments type' do + is_expected.to run.with_params('', false).and_raise_error(ArgumentError, %r{parameter 'arguments' expects a Hash value}i) + end + end + + it 'prints formats with name placeholders' do + is_expected.to run.with_params('string %s and integer %b', 'foo' => '_foo_', 'bar' => 5).and_return('string _foo_ and integer 101') + end +end