Skip to content

Commit 21bf454

Browse files
authored
Merge branch 'main' into fix-readjson
2 parents c67e7cd + ed474d2 commit 21bf454

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# frozen_string_literal: true
2+
3+
# @summary Sort an Array, Hash or String by mapping values through a given block.
4+
#
5+
# @example Sort local devices according to their used space.
6+
# $facts['mountpoints'].stdlib::sort_by |$m| { $m.dig(1, 'used_bytes') }
7+
#
8+
Puppet::Functions.create_function(:'stdlib::sort_by') do
9+
# @param ary The Array to sort.
10+
# @param block The block for transforming elements of ary.
11+
# @return [Array] Returns an ordered copy of ary.
12+
dispatch :sort_by_array do
13+
param 'Array', :ary
14+
block_param 'Callable[1,1]', :block
15+
end
16+
17+
# @param str The String to sort.
18+
# @param block The block for transforming elements of str.
19+
# @return [String] Returns an ordered copy of str.
20+
dispatch :sort_by_string do
21+
param 'String', :str
22+
block_param 'Callable[1,1]', :block
23+
end
24+
25+
# @param hsh The Hash to sort.
26+
# @param block The block for transforming elements of hsh.
27+
# The block may have arity of one or two.
28+
# @return [Hash] Returns an ordered copy of hsh.
29+
dispatch :sort_by_hash do
30+
param 'Hash', :hsh
31+
block_param 'Variant[Callable[1,1], Callable[2,2]]', :block
32+
end
33+
34+
def sort_by_iterable(iterable, &block)
35+
Puppet::Pops::Types::Iterable.asserted_iterable(self, iterable).sort_by(&block)
36+
end
37+
38+
def sort_by_array(ary, &block)
39+
sort_by_iterable(ary, &block)
40+
end
41+
42+
def sort_by_string(str, &block)
43+
sort_by_iterable(str, &block).join
44+
end
45+
46+
def sort_by_hash(hsh, &block)
47+
sort_by_iterable(hsh, &block).to_h
48+
end
49+
end

spec/functions/sort_by_spec.rb

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'stdlib::sort_by' do
6+
it { is_expected.not_to be_nil }
7+
8+
describe 'raise exception with inappropriate parameters' do
9+
it { is_expected.to run.with_params.and_raise_error(ArgumentError, Regexp.new('expects 1 argument, got none')) }
10+
it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, Regexp.new('expects a block')) }
11+
it { is_expected.to run.with_params(:undef).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Undef")) }
12+
it { is_expected.to run.with_params(true).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Boolean")) }
13+
it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Integer")) }
14+
it { is_expected.to run.with_params({}).with_lambda { 1 }.and_raise_error(ArgumentError, Regexp.new('block expects between 1 and 2 arguments, got none')) }
15+
end
16+
17+
# Puppet's each iterator considers Integers, Strings, Arrays and Hashes to be Iterable.
18+
unordered_array = ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
19+
ordered_array = ['The', 'brown', 'dog', 'fox', 'jumps', 'lazy', 'over', 'quick', 'the']
20+
unordered_hash = { 'The' => 'quick', 'brown' => 'fox', 'jumps' => 'over', 'the' => 'lazy', 'dog' => '.' }
21+
ordered_hash = { 'dog' => '.', 'brown' => 'fox', 'the' => 'lazy', 'jumps' => 'over', 'The' => 'quick' }
22+
unordered_string = 'The quick brown fox jumps over the lazy dog.'
23+
ordered_string = ' .Tabcdeeefghhijklmnoooopqrrstuuvwxyz'
24+
25+
describe 'with sane input' do
26+
it 'does sort Array' do
27+
expect(subject).to run \
28+
.with_params(unordered_array) \
29+
.with_lambda { |e| e } \
30+
.and_return(ordered_array)
31+
end
32+
33+
it 'does sort Hash by entry' do
34+
expect(subject).to run \
35+
.with_params(unordered_hash) \
36+
.with_lambda { |e| e[1] } \
37+
.and_return(ordered_hash)
38+
end
39+
40+
it 'does sort Hash by key-value pairs' do
41+
expect(subject).to run \
42+
.with_params(unordered_hash) \
43+
.with_lambda { |_, v| v } \
44+
.and_return(ordered_hash)
45+
end
46+
47+
it 'does sort String' do
48+
expect(subject).to run \
49+
.with_params(unordered_string) \
50+
.with_lambda { |e| e } \
51+
.and_return(ordered_string)
52+
end
53+
end
54+
end

0 commit comments

Comments
 (0)