Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check the hash given to #from_hash is a hash #16

Merged
merged 32 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0cc6ce2
Update image in docker-compose.yml
ianoxley Sep 30, 2022
30cd981
Remove version specs in gemspec
ianoxley Sep 30, 2022
5f48ecd
Raise an ArgumentError if hash is not a hash
ianoxley Sep 30, 2022
0cd8701
Fix Rubocop warnings
ianoxley Sep 30, 2022
0f2ae15
Add docs to #from_hash
ianoxley Jan 27, 2023
49cb663
Add GitHub Actions CI yml files
ianoxley Jan 27, 2023
7b43d48
Remove .travis.yml
ianoxley Jan 27, 2023
fc2cfe9
cd into gem_src before running bundle
ianoxley Jan 27, 2023
bf589d3
Fix prefix for code coverage locations
ianoxley Jan 27, 2023
152cdd5
Use checkout@v3
ianoxley Jan 27, 2023
1a9b019
Use v3.2.0 of codeclimate-action
ianoxley Jan 27, 2023
a74fa9b
Set debug: true
ianoxley Jan 27, 2023
f8cbc67
Set verifyDownload: true
ianoxley Jan 27, 2023
f794f5f
Remove prefix
ianoxley Jan 27, 2023
1a0bd91
Update Ruby image to 2.7.8
ianoxley Jul 28, 2023
2f4de41
Move docker-compose.yml to root dir
ianoxley Jul 28, 2023
75f0cf2
Update to latest codeclimate-action
ianoxley Jul 28, 2023
57e236e
Debug github.workspace
ianoxley Jul 28, 2023
60734c4
More build debugging
ianoxley Jul 28, 2023
d3975bf
Update coverageLocations
ianoxley Jul 28, 2023
4a76a3a
Revert "Update coverageLocations"
ianoxley Jul 28, 2023
9484557
More debugging
ianoxley Jul 28, 2023
6e565b2
Use simplecov v0.18.x to try and fix code coverage error
ianoxley Jul 28, 2023
8a71ecc
Revert "Use simplecov v0.18.x to try and fix code coverage error"
ianoxley Jul 28, 2023
5db6400
Use simplecov ~> 0.21 and configure JSON formatter
ianoxley Jul 28, 2023
796d3f7
More debugging
ianoxley Jul 28, 2023
ab26efb
Debug: cat contents of .resultset.json
ianoxley Jul 28, 2023
d682947
Set prefix to /gem_src
ianoxley Jul 28, 2023
f548d95
Update coverageLocations to use coverage.json
ianoxley Jul 28, 2023
5863c01
Remove debugging from Run tests step
ianoxley Jul 28, 2023
39b825e
Add frozen_string_literal comment to gemspec
ianoxley Jul 28, 2023
752417e
Replace double quotes with single quotes
ianoxley Jul 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions hash_kit.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

spec.add_development_dependency 'bundler', '~> 1.11'
spec.add_development_dependency 'bundler'
spec.add_development_dependency 'pry'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'rake'
spec.add_development_dependency 'rspec'
spec.add_development_dependency 'simplecov'
end
53 changes: 30 additions & 23 deletions lib/hash_kit/helper.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# frozen_string_literal: true

module HashKit
# Hash kit Helper class
class Helper

#This method is called to make a hash allow indifferent access (it will accept both strings & symbols for a valid key).
# This method is called to make a hash allow indifferent access (it will
# accept both strings & symbols for a valid key).
def indifferent!(hash)
unless hash.is_a?(Hash)
return
end
return unless hash.is_a?(Hash)

#set the default proc to allow the key to be either string or symbol if a matching key is found.
# Set the default proc to allow the key to be either string or symbol if
# a matching key is found.
hash.default_proc = proc do |h, k|
if h.key?(k.to_s)
h[k.to_s]
Expand All @@ -18,9 +20,9 @@ def indifferent!(hash)
end
end

#recursively process any child hashes
# Recursively process any child hashes
hash.each do |key,value|
if hash[key] != nil
unless hash[key].nil?
if hash[key].is_a?(Hash)
indifferent!(hash[key])
elsif hash[key].is_a?(Array)
Expand All @@ -33,9 +35,7 @@ def indifferent!(hash)
end

def indifferent_array!(array)
unless array.is_a?(Array)
return
end
return unless array.is_a?(Array)

array.each do |i|
if i.is_a?(Hash)
Expand All @@ -46,14 +46,16 @@ def indifferent_array!(array)
end
end

#This method is called to convert all the keys of a hash into symbols to allow consistent usage of hashes within your Ruby application.
# This method is called to convert all the keys of a hash into symbols to
# allow consistent usage of hashes within your Ruby application.
def symbolize(hash)
{}.tap do |h|
hash.each { |key, value| h[key.to_sym] = map_value_symbol(value) }
end
end

#This method is called to convert all the keys of a hash into strings to allow consistent usage of hashes within your Ruby application.
# This method is called to convert all the keys of a hash into strings to
# allow consistent usage of hashes within your Ruby application.
def stringify(hash)
{}.tap do |h|
hash.each { |key, value| h[key.to_s] = map_value_string(value) }
Expand All @@ -73,18 +75,22 @@ def to_hash(obj)
hash
end

def from_hash(hash, klass, transforms = [])
# Return an object of type klass from the values in the given hash
#
# @param [Hash] hash
# @param [Class] klass
# @param [Array] transforms
# @return [Object]
def from_hash(hash, klass, transforms = [])
obj = klass.new
if hash ==nil || hash == {}
return obj
end
return obj if hash.nil? || hash.empty?
raise ArgumentError, "#{hash.inspect} is not a hash" unless hash.is_a?(Hash)

hash.each do |k, v|
next unless obj.respond_to?(k)

hash.each do |k,v|
if !obj.respond_to?(k)
next
end
transform = transforms.detect { |t| t.key.to_sym == k.to_sym }
if transform != nil
if !transform.nil?
if v.is_a?(Hash)
child = from_hash(v, transform.klass, transforms)
obj.instance_variable_set("@#{k}", child)
Expand All @@ -98,7 +104,8 @@ def from_hash(hash, klass, transforms = [])
obj.instance_variable_set("@#{k}", v)
end
end
return obj

obj
end

private
Expand Down
13 changes: 7 additions & 6 deletions script/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
gem_test_runner:
image: codeguru/ruby:2.3.1-alpine-3.4
container_name: gem_test_runner
command: bash -c "while true; do echo 'Container is running...'; sleep 2; done"
volumes:
- ../:/gem_src
services:
gem_test_runner:
image: ruby:2.7.6-bullseye
container_name: gem_test_runner
command: bash -c "while true; do echo 'Container is running...'; sleep 2; done"
volumes:
- ../:/gem_src
53 changes: 30 additions & 23 deletions spec/hash_kit/helper_spec.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe HashKit::Helper do
describe '#symbolize' do

context 'when a single layer hash with string keys is specified' do
let(:hash) { { 'key1' => 'value1', 'key2' => 'value2' } }

Expand Down Expand Up @@ -64,7 +65,6 @@
end

describe '#stringify' do

context 'when a single layer hash with symbol keys is specified' do
let(:hash) { { :key1 => 'value1', :key2 => 'value2' } }

Expand Down Expand Up @@ -122,11 +122,9 @@
expect(new_hash['key3'][1].has_key?(:key4)).to be false
end
end

end

describe '#to_hash' do

let(:key1) do
{ key1: 'value1' }
end
Expand Down Expand Up @@ -195,7 +193,7 @@
end

[
"string" ,
'string' ,
101 ,
1.01 ,
Time.now ,
Expand Down Expand Up @@ -237,36 +235,35 @@
end

describe '#from_hash' do

let(:child_hash) do
{
text: 'abc',
numeric: 5,
time: Time.now,
invalid_key: 5,
bool: true
text: 'abc',
numeric: 5,
time: Time.now,
invalid_key: 5,
bool: true
}
end

let(:parent_hash) do
{
text: 'abc',
numeric: 5,
time: Time.now,
entity: child_hash,
entity_array: [child_hash, child_hash],
invalid_key: 5,
bool: true
text: 'abc',
numeric: 5,
time: Time.now,
entity: child_hash,
entity_array: [child_hash, child_hash],
invalid_key: 5,
bool: true
}
end

let(:string_hash) do
{
'text' => 'abc',
'numeric' => 5,
'time' => Time.now,
'invalid_key' => 5,
'bool' => true
'text' => 'abc',
'numeric' => 5,
'time' => Time.now,
'invalid_key' => 5,
'bool' => true
}
end

Expand Down Expand Up @@ -337,6 +334,12 @@
expect(obj.entity_array[1]).to be_a(TestEntity)
end
end

context 'when hash is not a hash' do
it 'raises an ArgumentError' do
expect { subject.from_hash('Not a hash', TestEntity, transforms) }.to raise_error(ArgumentError)
end
end
end

describe '#indifferent' do
Expand All @@ -356,18 +359,22 @@
}
}
end

it 'should allow access to a string key from a symbol' do
subject.indifferent!(hash)
expect(hash[:key1]).to eq 'value1'
end

it 'should allow access to a symbol key from a string' do
subject.indifferent!(hash)
expect(hash['key2']).to eq 'value2'
end

it 'should allow indifferent access to a key within an array' do
subject.indifferent!(hash)
expect(hash[:key3][0]['key4']).to eq 'value4'
end

it 'should allow indifferent access to a key within an nested hash' do
subject.indifferent!(hash)
expect(hash[:key6]['key7']).to eq 'value7'
Expand Down