diff --git a/lib/sinatra/indifferent_hash.rb b/lib/sinatra/indifferent_hash.rb index 3043a5a949..89b348fd86 100644 --- a/lib/sinatra/indifferent_hash.rb +++ b/lib/sinatra/indifferent_hash.rb @@ -180,6 +180,20 @@ def transform_keys! end end + def select(*args, &block) + return to_enum(:select) unless block_given? + dup.tap { |hash| hash.select!(*args, &block) } + end + + def reject(*args, &block) + return to_enum(:reject) unless block_given? + dup.tap { |hash| hash.reject!(*args, &block) } + end + + def compact + dup.tap(&:compact!) + end if method_defined?(:compact) # Added in Ruby 2.4 + private def convert_key(key) diff --git a/test/indifferent_hash_test.rb b/test/indifferent_hash_test.rb index 88d9e73dd0..8b720295a1 100644 --- a/test/indifferent_hash_test.rb +++ b/test/indifferent_hash_test.rb @@ -262,4 +262,57 @@ def test_transform_keys assert_equal :a, hash2[:A] assert_equal :a, hash2[?A] end + + def test_select + hash = @hash.select { |k, v| v == :a } + assert_equal Sinatra::IndifferentHash[a: :a], hash + assert_instance_of Sinatra::IndifferentHash, hash + + hash2 = @hash.select { |k, v| true } + assert_equal @hash, hash2 + assert_instance_of Sinatra::IndifferentHash, hash2 + + enum = @hash.select + assert_instance_of Enumerator, enum + end + + def test_select! + @hash.select! { |k, v| v == :a } + assert_equal Sinatra::IndifferentHash[a: :a], @hash + end + + def test_reject + hash = @hash.reject { |k, v| v != :a } + assert_equal Sinatra::IndifferentHash[a: :a], hash + assert_instance_of Sinatra::IndifferentHash, hash + + hash2 = @hash.reject { |k, v| false } + assert_equal @hash, hash2 + assert_instance_of Sinatra::IndifferentHash, hash2 + + enum = @hash.reject + assert_instance_of Enumerator, enum + end + + def test_reject! + @hash.reject! { |k, v| v != :a } + assert_equal Sinatra::IndifferentHash[a: :a], @hash + end + + def test_compact + skip_if_lacking :compact + + hash_with_nil_values = @hash.merge({?z => nil}) + compacted_hash = hash_with_nil_values.compact + assert_equal @hash, compacted_hash + assert_instance_of Sinatra::IndifferentHash, compacted_hash + + empty_hash = Sinatra::IndifferentHash.new + compacted_hash = empty_hash.compact + assert_equal empty_hash, compacted_hash + + non_empty_hash = Sinatra::IndifferentHash[a: :a] + compacted_hash = non_empty_hash.compact + assert_equal non_empty_hash, compacted_hash + end end