From ac7eee575933c26af0a626fbf2ea624b704414f3 Mon Sep 17 00:00:00 2001 From: petersquire Date: Mon, 30 Sep 2024 12:36:42 +0100 Subject: [PATCH 1/2] EPB-11376 refactor deep_find and deep_find_parent logic methods to return false if a key has that value --- lib/hash_miner/hash.rb | 14 +++++++++----- spec/hash_miner_spec.rb | 31 ++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/lib/hash_miner/hash.rb b/lib/hash_miner/hash.rb index da5a807..48974c6 100644 --- a/lib/hash_miner/hash.rb +++ b/lib/hash_miner/hash.rb @@ -245,37 +245,41 @@ def deep_remove_logic_parent(hash:, key:, parent:) end def deep_find_logic(hash:, key:) - hash.filter_map do |k, v| + results = hash.map do |k, v| if k.eql? key v elsif v.is_a?(Hash) deep_find_logic(hash: v, key: key) elsif v.is_a?(Array) - [v.filter_map do |item| + [v.map do |item| deep_find_logic(hash: item, key: key) if item.is_a?(Hash) && item.deep_contains?(key: key) end] end end.flatten + + results.all?(nil) ? results.uniq : results.compact end def deep_find_parent_logic(hash:, key:, parent:) - hash.filter_map do |k, v| + results = hash.map do |k, v| if (parent.is_a?(Array) && parent.include?(k)) || parent.eql?(k) case v when Hash deep_find_logic(key: key, hash: v) when Array - [v.filter_map do |item| + [v.map do |item| deep_find_logic(key: key, hash: item) if item.is_a?(Hash) && item.deep_contains?(key: key) end] end elsif v.is_a?(Hash) && v.deep_contains?(key: key) deep_find_parent_logic(hash: v, key: key, parent: parent) elsif v.is_a?(Array) - [v.filter_map do |item| + [v.map do |item| deep_find_parent_logic(hash: item, key: key, parent: parent) if item.is_a?(Hash) && item.deep_contains?(key: key) end] end end.flatten + + results.all?(nil) ? results.uniq : results.compact end end diff --git a/spec/hash_miner_spec.rb b/spec/hash_miner_spec.rb index b77c640..5385a59 100644 --- a/spec/hash_miner_spec.rb +++ b/spec/hash_miner_spec.rb @@ -2,10 +2,15 @@ RSpec.describe HashMiner do before(:example) do - @nasty_hash = { my: { super: { duper: { deeply: 'nested hash', - is: [{ duper: 'gross', random: nil }, 'a', 1, nil] } }, - hey: { duper: :a, blah: '', foo: [nil] }, - deeply: [{ nested: 'hash' }] } } + @nasty_hash = { my: + { super: + { duper: + { deeply: 'nested hash', is: [{ duper: 'gross', random: nil }, 'a', 1, nil] } }, + hey: { duper: :a, blah: '', foo: [nil] }, + test: nil, + not_true: { my_false_key: false }, + deeply: [{ nested: 'hash' }] }, + more_deeplyer: { test: nil } } end it 'has a version number' do @@ -15,8 +20,9 @@ context ' deep_contains?' do it 'returns true when key found' do expect(@nasty_hash.deep_contains?(key: :foo)).to be true + expect(@nasty_hash.deep_contains?(key: :my_false_key)).to be true end - it 'returns false when key found' do + it 'returns false when key not found' do expect(@nasty_hash.deep_contains?(key: [:foo])).to be false expect(@nasty_hash.deep_contains?(key: 'foo')).to be false expect(@nasty_hash.deep_contains?(key: nil)).to be false @@ -32,9 +38,10 @@ it 'returns the count when key found' do expect(@nasty_hash.deep_count(key: :foo)).to eq 1 expect(@nasty_hash.deep_count(key: :duper)).to eq 3 + expect(@nasty_hash.deep_count(key: :my_false_key)).to eq 1 end - it 'returns 0 when key found' do + it 'returns 0 when key not found' do expect(@nasty_hash.deep_count(key: [:foo])).to eq 0 expect(@nasty_hash.deep_count(key: 'foo')).to eq 0 expect(@nasty_hash.deep_count(key: nil)).to eq 0 @@ -55,12 +62,16 @@ ]) expect(@nasty_hash.deep_find(key: :deeply)).to eq(['nested hash', { nested: 'hash' }]) expect(@nasty_hash.deep_find(key: :nested)).to eq(['hash']) + expect(@nasty_hash.deep_find(key: :not_true)).to eq([{ my_false_key: false }]) + expect(@nasty_hash.deep_find(key: :my_false_key)).to eq([false]) end it 'returns nil when key not found' do expect(@nasty_hash.deep_find(key: [:foo])).to be nil expect(@nasty_hash.deep_find(key: 'foo')).to be nil expect(@nasty_hash.deep_find(key: nil)).to be nil + expect(@nasty_hash.deep_find(key: 'does_not_exist')).to be nil + end it 'returns nil when not a Hash object' do @@ -71,12 +82,13 @@ it 'can be scoped with a parent key' do expect(@nasty_hash.deep_find(key: :duper, parent: :hey)).to eq([:a]) expect(@nasty_hash.deep_find(key: :duper, parent: [:hey])).to eq([:a]) + expect(@nasty_hash.deep_find(key: :my_false_key, parent: :not_true)).to eq([false]) expect(@nasty_hash.deep_find(key: :duper, parent: %i[hey super])).to eq([ - { deeply: 'nested hash', - is: [{ duper: 'gross', random: nil }, 'a', 1, nil] }, :a - ]) + { deeply: 'nested hash', + is: [{ duper: 'gross', random: nil }, 'a', 1, nil] }, :a + ]) end it 'will only find keys if within a parent if given' do @@ -100,6 +112,7 @@ is: [{ duper: 'gross' }, 'a', 1, nil] } }, hey: { duper: :a, foo: [nil] }, + not_true: { my_false_key: false }, deeply: [{ nested: 'hash' }] } }) end end From 0d9236ecbf84d89da672a55a7f9d1e57e435a57e Mon Sep 17 00:00:00 2001 From: p-sqr Date: Tue, 1 Oct 2024 12:04:28 +0100 Subject: [PATCH 2/2] EPB-11376 Up version number add check for Ruby v3.2 --- .github/workflows/push_to_branch.yml | 2 +- lib/hash_miner/hash.rb | 2 +- lib/hash_miner/version.rb | 2 +- spec/hash_miner_spec.rb | 15 ++++++++------- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/push_to_branch.yml b/.github/workflows/push_to_branch.yml index 5f93267..613269b 100644 --- a/.github/workflows/push_to_branch.yml +++ b/.github/workflows/push_to_branch.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - ruby-version: ['2.7', '3.0', '3.1', head] + ruby-version: ['2.7', '3.0', '3.1', '3.2', head] steps: - uses: actions/checkout@v3 diff --git a/lib/hash_miner/hash.rb b/lib/hash_miner/hash.rb index 48974c6..3c57231 100644 --- a/lib/hash_miner/hash.rb +++ b/lib/hash_miner/hash.rb @@ -11,7 +11,7 @@ class Hash # # @return [Boolean] whether the key was found def deep_contains?(key:, hash: self) - return nil unless hash.is_a? Hash + return false unless hash.is_a? Hash return true if hash.include? key hash.filter_map do |_k, v| diff --git a/lib/hash_miner/version.rb b/lib/hash_miner/version.rb index 3b21947..7599777 100644 --- a/lib/hash_miner/version.rb +++ b/lib/hash_miner/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module HashMiner - VERSION = '1.1.1' + VERSION = '1.1.2' end diff --git a/spec/hash_miner_spec.rb b/spec/hash_miner_spec.rb index 5385a59..e15f889 100644 --- a/spec/hash_miner_spec.rb +++ b/spec/hash_miner_spec.rb @@ -28,9 +28,9 @@ expect(@nasty_hash.deep_contains?(key: nil)).to be false end - it 'returns nil when not a Hash object' do - expect(@nasty_hash.deep_contains?(key: nil, hash: [])).to be nil - expect(@nasty_hash.deep_contains?(key: nil, hash: 'a')).to be nil + it 'returns false when not a Hash object' do + expect(@nasty_hash.deep_contains?(key: nil, hash: [])).to be false + expect(@nasty_hash.deep_contains?(key: nil, hash: 'a')).to be false end end @@ -71,7 +71,6 @@ expect(@nasty_hash.deep_find(key: 'foo')).to be nil expect(@nasty_hash.deep_find(key: nil)).to be nil expect(@nasty_hash.deep_find(key: 'does_not_exist')).to be nil - end it 'returns nil when not a Hash object' do @@ -86,9 +85,11 @@ expect(@nasty_hash.deep_find(key: :duper, parent: %i[hey super])).to eq([ - { deeply: 'nested hash', - is: [{ duper: 'gross', random: nil }, 'a', 1, nil] }, :a - ]) + { deeply: 'nested hash', + is: [ + { duper: 'gross', random: nil }, 'a', 1, nil + ] }, :a + ]) end it 'will only find keys if within a parent if given' do