Implement non-destructive hash methods
When calling the following non-destructive hash methods: :compact :invert :reject :select :slice :transform_keys :transform_values we would be returned an instance of a standard Hash rather than a Mash (or subclass). This changes that behavior to instead return an instance of the class the method was called on.
This commit is contained in:
parent
1de19bff87
commit
3e64a4f58d
|
@ -1,6 +1,6 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2019-07-17 09:23:49 -0400 using RuboCop version 0.52.1.
|
||||
# on 2019-08-13 23:33:30 -0400 using RuboCop version 0.52.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
|
@ -13,13 +13,13 @@ Metrics/AbcSize:
|
|||
# Offense count: 2
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/ClassLength:
|
||||
Max: 221
|
||||
Max: 266
|
||||
|
||||
# Offense count: 7
|
||||
Metrics/CyclomaticComplexity:
|
||||
Max: 11
|
||||
|
||||
# Offense count: 19
|
||||
# Offense count: 18
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
Max: 28
|
||||
|
|
|
@ -207,6 +207,31 @@ module Hashie
|
|||
super(*keys.map { |key| convert_key(key) })
|
||||
end
|
||||
|
||||
# Returns a new instance of the class it was called on, with nil values
|
||||
# removed.
|
||||
def compact
|
||||
self.class.new(super)
|
||||
end
|
||||
|
||||
# Returns a new instance of the class it was called on, using its keys as
|
||||
# values, and its values as keys. The new values and keys will always be
|
||||
# strings.
|
||||
def invert
|
||||
self.class.new(super)
|
||||
end
|
||||
|
||||
# Returns a new instance of the class it was called on, containing elements
|
||||
# for which the given block returns false.
|
||||
def reject(&blk)
|
||||
self.class.new(super(&blk))
|
||||
end
|
||||
|
||||
# Returns a new instance of the class it was called on, containing elements
|
||||
# for which the given block returns true.
|
||||
def select(&blk)
|
||||
self.class.new(super(&blk))
|
||||
end
|
||||
|
||||
alias regular_dup dup
|
||||
# Duplicates the current mash as a new mash.
|
||||
def dup
|
||||
|
@ -320,6 +345,23 @@ module Hashie
|
|||
end
|
||||
end
|
||||
|
||||
with_minimum_ruby('2.4.0') do
|
||||
def transform_values(&blk)
|
||||
self.class.new(super(&blk))
|
||||
end
|
||||
end
|
||||
|
||||
with_minimum_ruby('2.5.0') do
|
||||
def slice(*keys)
|
||||
string_keys = keys.map { |key| convert_key(key) }
|
||||
self.class.new(super(*string_keys))
|
||||
end
|
||||
|
||||
def transform_keys(&blk)
|
||||
self.class.new(super(&blk))
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def method_name_and_suffix(method_name)
|
||||
|
|
|
@ -878,6 +878,90 @@ describe Hashie::Mash do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#compact' do
|
||||
subject(:mash) { described_class.new(a: 1, b: nil) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.compact).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'removes keys with nil values' do
|
||||
expect(mash.compact).to eq('a' => 1)
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1, b: nil) }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash.compact).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#invert' do
|
||||
subject(:mash) { described_class.new(a: 'apple', b: 4) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.invert).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'returns a mash with the keys and values inverted' do
|
||||
expect(mash.invert).to eq('apple' => 'a', '4' => 'b')
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1, b: nil) }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash.invert).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#reject' do
|
||||
subject(:mash) { described_class.new(a: 1, b: nil) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.reject { |_k, v| v.nil? }).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'rejects keys for which the block returns true' do
|
||||
expect(mash.reject { |_k, v| v.nil? }).to eq('a' => 1)
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1, b: nil) }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash.reject { |_k, v| v.nil? }).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#select' do
|
||||
subject(:mash) { described_class.new(a: 'apple', b: 4) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.select { |_k, v| v.is_a? String }).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'selects keys for which the block returns true' do
|
||||
expect(mash.select { |_k, v| v.is_a? String }).to eq('a' => 'apple')
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1, b: nil) }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash.select { |_k, v| v.is_a? String }).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
with_minimum_ruby('2.3.0') do
|
||||
describe '#dig' do
|
||||
subject { described_class.new(a: { b: 1 }) }
|
||||
|
@ -895,4 +979,71 @@ describe Hashie::Mash do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
with_minimum_ruby('2.4.0') do
|
||||
describe '#transform_values' do
|
||||
subject(:mash) { described_class.new(a: 1) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.transform_values(&:to_s)).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'transforms the value' do
|
||||
expect(mash.transform_values(&:to_s).a).to eql('1')
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1).transform_values { |a| a + 2 } }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
with_minimum_ruby('2.5.0') do
|
||||
describe '#slice' do
|
||||
subject(:mash) { described_class.new(a: 1, b: 2) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.slice(:a)).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'returns a Mash with only the keys passed' do
|
||||
expect(mash.slice(:a).to_hash).to eq('a' => 1)
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1, b: 2) }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash.slice(:a)).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#transform_keys' do
|
||||
subject(:mash) { described_class.new(a: 1, b: 2) }
|
||||
|
||||
it 'returns a Hashie::Mash' do
|
||||
expect(mash.transform_keys { |k| k + k }).to be_kind_of(described_class)
|
||||
end
|
||||
|
||||
it 'returns a Mash with transformed keys' do
|
||||
expect(mash.transform_keys { |k| k + k }).to eq('aa' => 1, 'bb' => 2)
|
||||
end
|
||||
|
||||
context 'when using with subclass' do
|
||||
let(:subclass) { Class.new(Hashie::Mash) }
|
||||
subject(:sub_mash) { subclass.new(a: 1, b: 2) }
|
||||
|
||||
it 'creates an instance of subclass' do
|
||||
expect(sub_mash.transform_keys { |k| k + k }).to be_kind_of(subclass)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue