(MODULE-2456) Modify union to accept more than two arrays

Add spec tests to test the new functionality:
 *Case for 3 arrays.
 *Case for 4 arrays.
Modify README to note new functionality.

This is for issue MODULE-2456, follow the precedent of MODULE-444.

This change allows union to be much more useful, unioning many arrays
in one line rather than in n lines. Additionally, as this is only added
functionality, and does not affect the 2 array case that all modules
currently using array are using, it should not affect any existing
modules utilizing union.

This is now useful, for example, for merging many arrays of resources
(eg: packages.) to generate just one list with no duplicates, to avoid
duplicate resource declarations.
This commit is contained in:
Jetroid 2015-08-24 12:01:29 +01:00
parent 1d89df906e
commit 1d9189d860
4 changed files with 15 additions and 18 deletions

View file

@ -704,7 +704,7 @@ Returns the literal type when passed a value. Requires the new parser. Useful fo
#### `union` #### `union`
Returns a union of two arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"]. Returns a union of two or more arrays, without duplicates. For example, `union(["a","b","c"],["b","c","d"])` returns ["a","b","c","d"].
#### `unique` #### `unique`

View file

@ -4,7 +4,7 @@
module Puppet::Parser::Functions module Puppet::Parser::Functions
newfunction(:union, :type => :rvalue, :doc => <<-EOS newfunction(:union, :type => :rvalue, :doc => <<-EOS
This function returns a union of two arrays. This function returns a union of two or more arrays.
*Examples:* *Examples:*
@ -14,20 +14,15 @@ Would return: ["a","b","c","d"]
EOS EOS
) do |arguments| ) do |arguments|
# Two arguments are required # Check that 2 or more arguments have been given ...
raise(Puppet::ParseError, "union(): Wrong number of arguments " + raise(Puppet::ParseError, "union(): Wrong number of arguments " +
"given (#{arguments.size} for 2)") if arguments.size != 2 "given (#{arguments.size} for < 2)") if arguments.size < 2
first = arguments[0] arguments.each do |argument|
second = arguments[1] raise(Puppet::ParseError, 'union(): Every parameter must be an array') unless argument.is_a?(Array)
unless first.is_a?(Array) && second.is_a?(Array)
raise(Puppet::ParseError, 'union(): Requires 2 arrays')
end end
result = first | second arguments.reduce(:|)
return result
end end
end end

View file

@ -6,9 +6,10 @@ describe 'union function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('opera
it 'unions arrays' do it 'unions arrays' do
pp = <<-EOS pp = <<-EOS
$a = ["the","public"] $a = ["the","public"]
$b = ["art","galleries"] $b = ["art"]
$c = ["galleries"]
# Anagram: Large picture halls, I bet # Anagram: Large picture halls, I bet
$o = union($a,$b) $o = union($a,$b,$c)
notice(inline_template('union is <%= @o.inspect %>')) notice(inline_template('union is <%= @o.inspect %>'))
EOS EOS

View file

@ -5,10 +5,9 @@ describe 'union' do
it { is_expected.not_to eq(nil) } it { is_expected.not_to eq(nil) }
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) }
it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, /Every parameter must be an array/) }
it { is_expected.to run.with_params('one', []).and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /Every parameter must be an array/) }
it { is_expected.to run.with_params([], 'two').and_raise_error(Puppet::ParseError, /Requires 2 arrays/) } it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /Every parameter must be an array/) }
it { is_expected.to run.with_params({}, {}).and_raise_error(Puppet::ParseError, /Requires 2 arrays/) }
end end
it { is_expected.to run.with_params([], []).and_return([]) } it { is_expected.to run.with_params([], []).and_return([]) }
@ -19,5 +18,7 @@ describe 'union' do
it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) }
it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'two', 'three'], ['two', 'three']).and_return(['one', 'two', 'three']) }
it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], ['two', 'two', 'three']).and_return(['one', 'two', 'three']) }
it { is_expected.to run.with_params(['one', 'two'], ['two', 'three'], ['one', 'three']).and_return(['one', 'two', 'three']) }
it { is_expected.to run.with_params(['one', 'two'], ['three', 'four'], ['one', 'two', 'three'], ['four']).and_return(['one', 'two', 'three', 'four']) }
it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3', 1, 2]) end it 'should not confuse types' do is_expected.to run.with_params(['1', '2', '3'], [1, 2]).and_return(['1', '2', '3', 1, 2]) end
end end