deep_hash_transformer 0.1.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1e1a32abac6889cf4b76e86815e230a64e35a24d
4
- data.tar.gz: 87d63d20fba0c52e59d81d32a2425700300695c9
2
+ SHA256:
3
+ metadata.gz: fd4691f4f42a7a731098aeb989eb7f333e5d34a2a627ddb3229653ff8e1a3a6f
4
+ data.tar.gz: 95b96a971d5b65f37411ead70ffd93d92624a145e65125a81d992cc238a87978
5
5
  SHA512:
6
- metadata.gz: d6725f7676defb9af3e5bb19844bae02cf39d79d5f08138dff128cde79443a81d5a81c3a94c2a277d59a4e0bcaf71bf20603f28983fdd097bf6b06ae5a9e6f37
7
- data.tar.gz: 503147021c5078826c189223e28a7edb9aba91ff27360d81694f43775398dfeb669ee589d8a4d5479aa98ec9839638a6d87d6b05fddc011f860cdded0165f6be
6
+ metadata.gz: f5f0e923fbed861df614b33a0e3465a8ebb24da4020750414ff911b779e07520507d6cf85c44ffa88bb0009b0fffcea192c3743a9ed7c5aa9562b2f28dc12861
7
+ data.tar.gz: 99412bba8c0260a5c90cd126726380f0336dfd5570d806b107601ca735edd2295d9fe8f642af9e5ac4b6a401ae8268e26fce8b59210143fabfe89e7274687180
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DeepHashTransformer
4
+ module Operation
5
+ class << self
6
+ def camel_case(val)
7
+ pascal_case(val)
8
+ .sub(/^[A-Z]/, &:downcase)
9
+ end
10
+
11
+ def dasherize(val)
12
+ stringify(val)
13
+ .tr('_', '-')
14
+ end
15
+
16
+ def identity(val)
17
+ val
18
+ end
19
+
20
+ def pascal_case(val)
21
+ stringify(val)
22
+ .split(/(?=[A-Z])|[-_]/)
23
+ .map(&:capitalize)
24
+ .join
25
+ end
26
+
27
+ def stringify(val)
28
+ val.to_s
29
+ end
30
+
31
+ def symbolize(val)
32
+ val.to_sym
33
+ end
34
+
35
+ def underscore(val)
36
+ stringify(val)
37
+ .tr('-', '_')
38
+ end
39
+
40
+ def snake_case(val)
41
+ stringify(val)
42
+ .gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
43
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
44
+ .tr('-', '_')
45
+ .downcase
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DeepHashTransformer
2
- VERSION = '0.1.1'.freeze
4
+ VERSION = '2.1.0'
3
5
  end
@@ -1,25 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'deep_hash_transformer/operation'
1
4
  require 'deep_hash_transformer/version'
2
5
 
3
6
  class DeepHashTransformer
4
- attr_reader :hash
5
-
6
- OPS = {
7
- dasherize: ->(val) { val.to_s.tr('_'.freeze, '-'.freeze) },
8
- identity: ->(val) { val },
9
- stringify: ->(val) { val.to_s },
10
- symbolize: ->(val) { val.to_sym },
11
- underscore: ->(val) { val.to_s.tr('-'.freeze, '_'.freeze) }
12
- }.freeze
7
+ OPS = %i[
8
+ camel_case
9
+ dasherize
10
+ identity
11
+ pascal_case
12
+ snake_case
13
+ stringify
14
+ symbolize
15
+ underscore
16
+ ].freeze
13
17
 
14
18
  def initialize(hash)
15
19
  @hash = hash
16
20
  end
17
21
 
18
22
  def tr(*ops)
23
+ unknown_transformtions = ops.map(&:to_s) - OPS.map(&:to_s)
24
+ if unknown_transformtions.any?
25
+ raise(
26
+ ArgumentError, "unknown transformation(s): #{unknown_transformtions.join(',')}"
27
+ )
28
+ end
29
+
19
30
  transform_value(hash, ops)
20
31
  end
21
32
 
22
- OPS.keys.each do |operation|
33
+ OPS.each do |operation|
23
34
  define_method(operation) { tr(operation) }
24
35
  end
25
36
 
@@ -32,9 +43,7 @@ class DeepHashTransformer
32
43
  when Array
33
44
  value.map { |e| transform_value(e, ops) }
34
45
  when Hash
35
- Hash[
36
- value.map { |k, v| [transform_key(k, ops), transform_value(v, ops)] }
37
- ]
46
+ value.map { |k, v| [transform_key(k, ops), transform_value(v, ops)] }.to_h
38
47
  else
39
48
  value
40
49
  end
@@ -43,6 +52,6 @@ class DeepHashTransformer
43
52
  def transform_key(key, ops)
44
53
  return key unless [String, Symbol].include?(key.class)
45
54
 
46
- ops.inject(key) { |k, op| OPS.fetch(op).call(k) }
55
+ ops.inject(key) { |k, op| Operation.public_send(op, k) }
47
56
  end
48
57
  end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe DeepHashTransformer::Operation do
4
+ examples = [
5
+ :symbol, 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under_scored'
6
+ ]
7
+
8
+ subject do
9
+ examples.map { |value| described_class.public_send(method, value) }
10
+ end
11
+
12
+ # rubocop:disable Layout/HashAlignment, Style/SymbolArray, Style/WordArray
13
+ expected_output = {
14
+ camel_case: ['symbol', 'string', 'camelCase', 'dashedKey', 'pascalCase', 'underScored'],
15
+ dasherize: ['symbol', 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under-scored'],
16
+ identity: [:symbol, 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under_scored'],
17
+ pascal_case: ['Symbol', 'String', 'CamelCase', 'DashedKey', 'PascalCase', 'UnderScored'],
18
+ snake_case: ['symbol', 'string', 'camel_case', 'dashed_key', 'pascal_case', 'under_scored'],
19
+ stringify: ['symbol', 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under_scored'],
20
+ symbolize: [:symbol, :string, :camelCase, :'dashed-key', :PascalCase, :under_scored],
21
+ underscore: ['symbol', 'string', 'camelCase', 'dashed_key', 'PascalCase', 'under_scored']
22
+ }
23
+ # rubocop:enable Layout/HashAlignment, Style/SymbolArray, Style/WordArray
24
+
25
+ DeepHashTransformer::OPS.each do |method|
26
+ describe "##{method}" do
27
+ let(:method) { method }
28
+
29
+ it { is_expected.to eq(expected_output[method]) }
30
+ end
31
+ end
32
+ end
@@ -1,85 +1,79 @@
1
- RSpec.describe DeepHashTransformer do
2
- let(:hash) do
3
- {
4
- Integer => 123,
5
- :foobar => { bar: 'bar' },
6
- 'aa_zz' => [{ 'bar' => :bar, 'a-z' => 'a-z' }]
7
- }
8
- end
1
+ # frozen_string_literal: true
9
2
 
10
- describe '#tr with `%i[underscore symbolize]`' do
11
- subject { DeepHashTransformer.new(hash).tr(:underscore, :symbolize) }
3
+ RSpec.describe DeepHashTransformer do
4
+ subject(:operation) { described_class.new(example) }
12
5
 
13
- it do
14
- is_expected.to eq(
15
- Integer => 123,
16
- :foobar => { bar: 'bar' },
17
- :aa_zz => [{ bar: :bar, a_z: 'a-z' }]
18
- )
19
- end
20
- end
6
+ let(:example) { { foo: 'bar' } }
21
7
 
22
- describe '#dasherize' do
23
- subject { DeepHashTransformer.new(hash).dasherize }
8
+ describe 'autogenerated methods' do
9
+ DeepHashTransformer::OPS.each do |method|
10
+ describe ".#{method}" do
11
+ it "delegates to `Operation.#{method}`" do
12
+ expect(
13
+ DeepHashTransformer::Operation
14
+ ).to receive(method).with(:foo).once # rubocop:disable RSpec/MessageSpies
24
15
 
25
- it do
26
- is_expected.to eq(
27
- Integer => 123,
28
- 'foobar' => { 'bar' => 'bar' },
29
- 'aa-zz' => [{ 'bar' => :bar, 'a-z' => 'a-z' }]
30
- )
16
+ operation.public_send(method)
17
+ end
18
+ end
31
19
  end
32
20
  end
33
21
 
34
- describe '#identity' do
35
- subject { DeepHashTransformer.new(hash).identity }
22
+ describe '#tr' do
23
+ context 'with `:snake_case, :symbolize`' do
24
+ subject { super().tr(:snake_case, :symbolize) }
36
25
 
37
- it do
38
- is_expected.to eq(
39
- Integer => 123,
40
- :foobar => { bar: 'bar' },
41
- 'aa_zz' => [{ 'bar' => :bar, 'a-z' => 'a-z' }]
42
- )
43
- end
44
- end
45
-
46
- describe '#stringify' do
47
- subject { DeepHashTransformer.new(hash).stringify }
26
+ let(:example) { { 'FooBar' => 'baz' } }
48
27
 
49
- it do
50
- is_expected.to eq(
51
- Integer => 123,
52
- 'foobar' => { 'bar' => 'bar' },
53
- 'aa_zz' => [{ 'bar' => :bar, 'a-z' => 'a-z' }]
54
- )
28
+ it { is_expected.to eq(foo_bar: 'baz') }
55
29
  end
56
- end
57
30
 
58
- describe '#symbolize' do
59
- subject { DeepHashTransformer.new(hash).symbolize }
31
+ context 'with an unknown transformation' do
32
+ subject(:unknown_ops) { operation.tr(:unknown) }
60
33
 
61
- it do
62
- is_expected.to eq(
63
- Integer => 123,
64
- :foobar => { bar: 'bar' },
65
- :aa_zz => [{ :bar => :bar, :'a-z' => 'a-z' }]
66
- )
34
+ it 'raise an exception' do
35
+ expect { unknown_ops }.to raise_error(ArgumentError, /unknown/)
36
+ end
67
37
  end
68
- end
69
38
 
70
- describe '#underscore' do
71
- subject { DeepHashTransformer.new(hash).underscore }
39
+ context 'with a complex, nested example' do
40
+ subject { super().tr(:camel_case, :symbolize) }
41
+
42
+ let(:example) do
43
+ {
44
+ Integer => 123,
45
+ :symbol => { foo_bar: 'bar' },
46
+ 'string' => { 'foo_bar' => 123 },
47
+ 'nested-array' => [
48
+ {
49
+ 'camelCased' => 'camelCased',
50
+ 'dashed-key' => 'dashed-key',
51
+ 'PascalCased' => 'PascalCased',
52
+ 'under_scored' => 'under_scored'
53
+ }
54
+ ]
55
+ }
56
+ end
72
57
 
73
- it do
74
- is_expected.to eq(
75
- Integer => 123,
76
- 'foobar' => { 'bar' => 'bar' },
77
- 'aa_zz' => [{ 'bar' => :bar, 'a_z' => 'a-z' }]
78
- )
58
+ it do # rubocop:disable RSpec/ExampleLength
59
+ is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject
60
+ Integer => 123,
61
+ :symbol => { fooBar: 'bar' },
62
+ :string => { fooBar: 123 },
63
+ :nestedArray => [
64
+ {
65
+ camelCased: 'camelCased',
66
+ dashedKey: 'dashed-key',
67
+ pascalCased: 'PascalCased',
68
+ underScored: 'under_scored'
69
+ }
70
+ ]
71
+ )
72
+ end
79
73
  end
80
74
  end
81
75
 
82
76
  it 'has a version number' do
83
- expect(DeepHashTransformer::VERSION).not_to be nil
77
+ expect(DeepHashTransformer::VERSION).not_to be_nil
84
78
  end
85
79
  end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/setup'
2
- require 'coveralls'
3
4
  require 'deep_hash_transformer'
5
+ require 'deep_hash_transformer/operation'
6
+ require 'simplecov'
7
+
8
+ SimpleCov.start do
9
+ if ENV['CI']
10
+ require 'simplecov-lcov'
11
+
12
+ SimpleCov::Formatter::LcovFormatter.config do |c|
13
+ c.report_with_single_file = true
14
+ c.single_report_path = 'coverage/lcov.info'
15
+ end
4
16
 
5
- Coveralls.wear!
17
+ formatter SimpleCov::Formatter::LcovFormatter
18
+ end
19
+
20
+ add_filter %w[version.rb initializer.rb]
21
+ end
6
22
 
7
23
  RSpec.configure do |config|
8
24
  # Enable flags like --only-failures and --next-failure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep_hash_transformer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Spickermann
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-27 00:00:00.000000000 Z
11
+ date: 2022-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: coveralls
42
+ name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,35 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: rubocop-performance
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop-rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rspec
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - ">="
@@ -66,7 +94,36 @@ dependencies:
66
94
  - - ">="
67
95
  - !ruby/object:Gem::Version
68
96
  version: '0'
69
- description: " DeepHashTransformer helps to transform deeply nested hash structures\n"
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov-lcov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: " DeepHashTransformer helps to transform keys in deeply nested hash
126
+ structures\n"
70
127
  email:
71
128
  - spickermann@gmail.com
72
129
  executables: []
@@ -75,14 +132,17 @@ extra_rdoc_files: []
75
132
  files:
76
133
  - MIT-LICENSE
77
134
  - lib/deep_hash_transformer.rb
135
+ - lib/deep_hash_transformer/operation.rb
78
136
  - lib/deep_hash_transformer/version.rb
137
+ - spec/deep_hash_transformer/operation_spec.rb
79
138
  - spec/deep_hash_transformer_spec.rb
80
139
  - spec/spec_helper.rb
81
140
  homepage: https://github.com/spickermann/deep_hash_transformer
82
141
  licenses:
83
142
  - MIT
84
- metadata: {}
85
- post_install_message:
143
+ metadata:
144
+ rubygems_mfa_required: 'true'
145
+ post_install_message:
86
146
  rdoc_options: []
87
147
  require_paths:
88
148
  - lib
@@ -90,16 +150,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
90
150
  requirements:
91
151
  - - ">="
92
152
  - !ruby/object:Gem::Version
93
- version: '0'
153
+ version: 2.5.0
94
154
  required_rubygems_version: !ruby/object:Gem::Requirement
95
155
  requirements:
96
156
  - - ">="
97
157
  - !ruby/object:Gem::Version
98
158
  version: '0'
99
159
  requirements: []
100
- rubyforge_project:
101
- rubygems_version: 2.6.11
102
- signing_key:
160
+ rubygems_version: 3.3.3
161
+ signing_key:
103
162
  specification_version: 4
104
163
  summary: Transforms deeply nested hash structure
105
164
  test_files: []