Skip to content

Commit

Permalink
Merge branch 'main' into fix-readjson
Browse files Browse the repository at this point in the history
  • Loading branch information
gerases authored Mar 5, 2024
2 parents c67e7cd + ed474d2 commit 21bf454
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
49 changes: 49 additions & 0 deletions lib/puppet/functions/stdlib/sort_by.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# frozen_string_literal: true

# @summary Sort an Array, Hash or String by mapping values through a given block.
#
# @example Sort local devices according to their used space.
# $facts['mountpoints'].stdlib::sort_by |$m| { $m.dig(1, 'used_bytes') }
#
Puppet::Functions.create_function(:'stdlib::sort_by') do
# @param ary The Array to sort.
# @param block The block for transforming elements of ary.
# @return [Array] Returns an ordered copy of ary.
dispatch :sort_by_array do
param 'Array', :ary
block_param 'Callable[1,1]', :block
end

# @param str The String to sort.
# @param block The block for transforming elements of str.
# @return [String] Returns an ordered copy of str.
dispatch :sort_by_string do
param 'String', :str
block_param 'Callable[1,1]', :block
end

# @param hsh The Hash to sort.
# @param block The block for transforming elements of hsh.
# The block may have arity of one or two.
# @return [Hash] Returns an ordered copy of hsh.
dispatch :sort_by_hash do
param 'Hash', :hsh
block_param 'Variant[Callable[1,1], Callable[2,2]]', :block
end

def sort_by_iterable(iterable, &block)
Puppet::Pops::Types::Iterable.asserted_iterable(self, iterable).sort_by(&block)
end

def sort_by_array(ary, &block)
sort_by_iterable(ary, &block)
end

def sort_by_string(str, &block)
sort_by_iterable(str, &block).join
end

def sort_by_hash(hsh, &block)
sort_by_iterable(hsh, &block).to_h
end
end
54 changes: 54 additions & 0 deletions spec/functions/sort_by_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'stdlib::sort_by' do
it { is_expected.not_to be_nil }

describe 'raise exception with inappropriate parameters' do
it { is_expected.to run.with_params.and_raise_error(ArgumentError, Regexp.new('expects 1 argument, got none')) }
it { is_expected.to run.with_params([]).and_raise_error(ArgumentError, Regexp.new('expects a block')) }
it { is_expected.to run.with_params(:undef).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Undef")) }
it { is_expected.to run.with_params(true).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Boolean")) }
it { is_expected.to run.with_params(1).and_raise_error(ArgumentError, Regexp.new("rejected: parameter 'ary' expects an Array value, got Integer")) }
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')) }
end

# Puppet's each iterator considers Integers, Strings, Arrays and Hashes to be Iterable.
unordered_array = ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']
ordered_array = ['The', 'brown', 'dog', 'fox', 'jumps', 'lazy', 'over', 'quick', 'the']
unordered_hash = { 'The' => 'quick', 'brown' => 'fox', 'jumps' => 'over', 'the' => 'lazy', 'dog' => '.' }
ordered_hash = { 'dog' => '.', 'brown' => 'fox', 'the' => 'lazy', 'jumps' => 'over', 'The' => 'quick' }
unordered_string = 'The quick brown fox jumps over the lazy dog.'
ordered_string = ' .Tabcdeeefghhijklmnoooopqrrstuuvwxyz'

describe 'with sane input' do
it 'does sort Array' do
expect(subject).to run \
.with_params(unordered_array) \
.with_lambda { |e| e } \
.and_return(ordered_array)
end

it 'does sort Hash by entry' do
expect(subject).to run \
.with_params(unordered_hash) \
.with_lambda { |e| e[1] } \
.and_return(ordered_hash)
end

it 'does sort Hash by key-value pairs' do
expect(subject).to run \
.with_params(unordered_hash) \
.with_lambda { |_, v| v } \
.and_return(ordered_hash)
end

it 'does sort String' do
expect(subject).to run \
.with_params(unordered_string) \
.with_lambda { |e| e } \
.and_return(ordered_string)
end
end
end

0 comments on commit 21bf454

Please sign in to comment.