1
0
mirror of https://github.com/meineerde/rackstash.git synced 2026-01-31 17:27:13 +00:00

Add Fields::Hash#each and make the Hash class an Enumerable

This commit is contained in:
Holger Just 2017-12-12 19:58:46 +01:00
parent e472b7fbce
commit 1671b04dfb
2 changed files with 126 additions and 0 deletions

View File

@ -10,6 +10,8 @@ require 'rackstash/fields/abstract_collection'
module Rackstash
module Fields
class Hash < AbstractCollection
include ::Enumerable
# @return [Set<String>] a frozen list of strings which are not allowed to
# be used as keys in this hash.
attr_reader :forbidden_keys
@ -224,6 +226,59 @@ module Rackstash
merge!(hash, force: force, scope: scope, &resolver)
end
# Calls the given block once for each key in the hash, passing the
# key-value pair as parameters.
#
# If no block is given, an `Enumerator` is returned instead.
#
# @yield [key, value] calls the given block once for each key in the hash
# @yieldparam key [String] the yielded key
# @yieldparam value [Object] the yielded value
# @return [Enumerator, self] `self` if a block was given or an
# `Enumerator` if no block was given.
def each
return enum_for(__method__) unless block_given?
@raw.each_pair do |key, value|
yield key, value
end
self
end
alias each_pair each
# Calls the given block once for each key in the hash, passing the key as
# a parameter.
#
# If no block is given, an `Enumerator` is returned instead.
#
# @yield [key] calls the given block once for each key in the hash
# @yieldparam key [String] the yielded key
# @return [Enumerator, self] `self` if a block was given or an
# `Enumerator` if no block was given.
def each_key
return enum_for(__method__) unless block_given?
@raw.each_key do |key|
yield key
end
self
end
# Calls the given block once for each key in the hash, passing the value
# at the respective key as a parameter.
#
# If no block is given, an `Enumerator` is returned instead.
#
# @yield [value] calls the given block once for each key in the hash
# @yieldparam value [Object] the yielded value of the key
# @return [Enumerator, self] `self` if a block was given or an
# `Enumerator` if no block was given.
def each_value
return enum_for(__method__) unless block_given?
@raw.each_value do |value|
yield value
end
self
end
# @return [Boolean] `true` if the Hash contains no ley-value pairs,
# `false` otherwise.
def empty?

View File

@ -13,6 +13,12 @@ describe Rackstash::Fields::Hash do
let(:forbidden_keys) { Set.new }
let(:hash) { Rackstash::Fields::Hash.new(forbidden_keys: forbidden_keys) }
it 'is an Enumerable' do
expect(described_class).to be < Enumerable
expect(::Enumerable.public_instance_methods - hash.methods)
.to be_empty
end
describe '#initialize' do
it 'can be initialized without any arguments' do
Rackstash::Fields::Hash.new
@ -383,6 +389,71 @@ describe Rackstash::Fields::Hash do
end
end
describe '#each' do
it 'yields each key-value pair' do
hash['foo'] = 'string'
hash[:bar] = 42
expect { |b| hash.each(&b) }
.to yield_successive_args(['foo', 'string'], ['bar', 42])
end
it 'returns the hash if a block was provided' do
hash['foo'] = 'bar'
expect(hash.each {}).to equal hash
end
it 'returns an Enumerator if no block was provided' do
hash['foo'] = 'bar'
expect(hash.each).to be_instance_of Enumerator
end
it 'can use the alias #each_pair' do
expect(hash.method(:each_pair)).to eql hash.method(:each)
end
end
describe '#each_key' do
it 'yields each key' do
hash['foo'] = 'string'
hash[:bar] = 42
expect { |b| hash.each_key(&b) }
.to yield_successive_args('foo', 'bar')
end
it 'returns the hash if a block was provided' do
hash['foo'] = 'bar'
expect(hash.each_key {}).to equal hash
end
it 'returns an Enumerator if no block was provided' do
hash['foo'] = 'bar'
expect(hash.each_key).to be_instance_of Enumerator
end
end
describe '#each_value' do
it 'yields each value' do
hash['foo'] = 'string'
hash[:bar] = 42
hash['double'] = 'string'
expect { |b| hash.each_value(&b) }
.to yield_successive_args('string', 42, 'string')
end
it 'returns the hash if a block was provided' do
hash['foo'] = 'bar'
expect(hash.each_value {}).to equal hash
end
it 'returns an Enumerator if no block was provided' do
hash['foo'] = 'bar'
expect(hash.each_value).to be_instance_of Enumerator
end
end
describe '#empty?' do
it 'returns true of there are any fields' do
expect(hash.empty?).to be true