deep_hash_transformer 2.2.0 → 2.2.1
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 +4 -4
- data/lib/deep_hash_transformer/blank.rb +4 -4
- data/lib/deep_hash_transformer/collection_operation.rb +1 -1
- data/lib/deep_hash_transformer/element_operation.rb +3 -3
- data/lib/deep_hash_transformer/version.rb +1 -1
- data/lib/deep_hash_transformer.rb +11 -11
- data/spec/deep_hash_transformer/blank_spec.rb +3 -3
- data/spec/deep_hash_transformer/collection_operation_spec.rb +5 -5
- data/spec/deep_hash_transformer/element_operation_spec.rb +9 -9
- data/spec/deep_hash_transformer_spec.rb +40 -40
- data/spec/spec_helper.rb +15 -11
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd3cd6700a7e51238c1c16feb30a81fb8debe53c5225401f33442ef29d771c92
|
4
|
+
data.tar.gz: 93aeb34e4a4e0bdbefa97d6d946d21fc8ab87457bd8361d992aa66399100849e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 515fe31abc501135498b1450e9f90820c7612161e643198f9276006095abc5eff05e5c54cb924c37ae4e801e078a9cf9f26ccb17900341b2b7f093e86f9d4c03
|
7
|
+
data.tar.gz: 4cb38f5bcfcf1265f77244e61c8d4b13f0d833a52b6ef4e334cbe43bbe157eeee4a3c467f5d08f45b2e738cfee936395cee3a073e79e2c9453a7ba8aef7ab001
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class DeepHashTransformer
|
4
4
|
class Blank
|
5
|
-
BLANK_STRING = /\A[[:space:]]*\z
|
5
|
+
BLANK_STRING = /\A[[:space:]]*\z/
|
6
6
|
|
7
7
|
def self.call(value)
|
8
8
|
new(value).blank?
|
@@ -13,10 +13,10 @@ class DeepHashTransformer
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def blank?
|
16
|
-
return true
|
17
|
-
return value.blank?
|
16
|
+
return true unless value
|
17
|
+
return value.blank? if value.respond_to?(:blank?)
|
18
18
|
return BLANK_STRING.match?(value) if value.is_a?(String)
|
19
|
-
return value.empty?
|
19
|
+
return value.empty? if value.respond_to?(:empty?)
|
20
20
|
|
21
21
|
false
|
22
22
|
end
|
@@ -10,7 +10,7 @@ class DeepHashTransformer
|
|
10
10
|
|
11
11
|
def dasherize(val)
|
12
12
|
stringify(val)
|
13
|
-
.tr(
|
13
|
+
.tr("_", "-")
|
14
14
|
end
|
15
15
|
|
16
16
|
def identity(val)
|
@@ -34,14 +34,14 @@ class DeepHashTransformer
|
|
34
34
|
|
35
35
|
def underscore(val)
|
36
36
|
stringify(val)
|
37
|
-
.tr(
|
37
|
+
.tr("-", "_")
|
38
38
|
end
|
39
39
|
|
40
40
|
def snake_case(val)
|
41
41
|
stringify(val)
|
42
42
|
.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
43
43
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
44
|
-
.tr(
|
44
|
+
.tr("-", "_")
|
45
45
|
.downcase
|
46
46
|
end
|
47
47
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "deep_hash_transformer/collection_operation"
|
4
|
+
require "deep_hash_transformer/element_operation"
|
5
|
+
require "deep_hash_transformer/version"
|
6
6
|
|
7
7
|
class DeepHashTransformer
|
8
8
|
ELEMENT_OPS = %i[
|
@@ -31,7 +31,7 @@ class DeepHashTransformer
|
|
31
31
|
unknown_transformations = ops.map(&:to_s) - OPS.map(&:to_s)
|
32
32
|
if unknown_transformations.any?
|
33
33
|
raise(
|
34
|
-
ArgumentError, "unknown transformation(s): #{unknown_transformations.join(
|
34
|
+
ArgumentError, "unknown transformation(s): #{unknown_transformations.join(",")}"
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
@@ -54,13 +54,13 @@ class DeepHashTransformer
|
|
54
54
|
|
55
55
|
def transform_value(value, ops)
|
56
56
|
collection = case value
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
when Array
|
58
|
+
value.map { |e| transform_value(e, ops) }
|
59
|
+
when Hash
|
60
|
+
value.map { |k, v| [transform_key(k, ops), transform_value(v, ops)] }.to_h
|
61
|
+
else
|
62
|
+
value
|
63
|
+
end
|
64
64
|
|
65
65
|
transform_collection(collection, ops)
|
66
66
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe DeepHashTransformer::Blank do
|
4
|
-
describe
|
4
|
+
describe ".call" do
|
5
5
|
subject { described_class.call(value) }
|
6
6
|
|
7
|
-
presents = [true, 1, 0,
|
8
|
-
blanks
|
7
|
+
presents = [true, 1, 0, "any", [nil], {A: nil}]
|
8
|
+
blanks = [nil, false, "", " ", [], {}]
|
9
9
|
|
10
10
|
presents.each do |value|
|
11
11
|
context "with #{value.inspect}" do
|
@@ -2,28 +2,28 @@
|
|
2
2
|
|
3
3
|
RSpec.describe DeepHashTransformer::CollectionOperation do
|
4
4
|
examples = [
|
5
|
-
{
|
5
|
+
{a: "b"}, {a: nil}, {a: " "}, [:foo], ["", nil]
|
6
6
|
]
|
7
7
|
|
8
8
|
subject do
|
9
9
|
examples.map { |value| described_class.public_send(method, value) }
|
10
10
|
end
|
11
11
|
|
12
|
-
describe
|
12
|
+
describe ".compact" do
|
13
13
|
let(:method) { :compact }
|
14
14
|
|
15
15
|
expected_output = [
|
16
|
-
{
|
16
|
+
{a: "b"}, {}, {a: " "}, [:foo], [""]
|
17
17
|
]
|
18
18
|
|
19
19
|
it { is_expected.to eq(expected_output) }
|
20
20
|
end
|
21
21
|
|
22
|
-
describe
|
22
|
+
describe ".compact_blank" do
|
23
23
|
let(:method) { :compact_blank }
|
24
24
|
|
25
25
|
expected_output = [
|
26
|
-
{
|
26
|
+
{a: "b"}, {}, {}, [:foo], []
|
27
27
|
]
|
28
28
|
|
29
29
|
it { is_expected.to eq(expected_output) }
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
RSpec.describe DeepHashTransformer::ElementOperation do
|
4
4
|
examples = [
|
5
|
-
:symbol,
|
5
|
+
:symbol, "string", "camelCase", "dashed-key", "PascalCase", "under_scored"
|
6
6
|
]
|
7
7
|
|
8
8
|
subject do
|
@@ -11,14 +11,14 @@ RSpec.describe DeepHashTransformer::ElementOperation do
|
|
11
11
|
|
12
12
|
# rubocop:disable Layout/HashAlignment, Style/SymbolArray, Style/WordArray
|
13
13
|
expected_output = {
|
14
|
-
camel_case: [
|
15
|
-
dasherize: [
|
16
|
-
identity: [:symbol,
|
17
|
-
pascal_case: [
|
18
|
-
snake_case: [
|
19
|
-
stringify: [
|
20
|
-
symbolize: [:symbol,
|
21
|
-
underscore: [
|
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
22
|
}
|
23
23
|
# rubocop:enable Layout/HashAlignment, Style/SymbolArray, Style/WordArray
|
24
24
|
|
@@ -3,9 +3,9 @@
|
|
3
3
|
RSpec.describe DeepHashTransformer do
|
4
4
|
subject(:operation) { described_class.new(example) }
|
5
5
|
|
6
|
-
let(:example) { {
|
6
|
+
let(:example) { {foo: "bar"} }
|
7
7
|
|
8
|
-
describe
|
8
|
+
describe "autogenerated methods" do
|
9
9
|
DeepHashTransformer::ELEMENT_OPS.each do |method|
|
10
10
|
describe ".#{method}" do
|
11
11
|
it "delegates to `Operation.#{method}`" do
|
@@ -19,37 +19,37 @@ RSpec.describe DeepHashTransformer do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
describe
|
23
|
-
context
|
22
|
+
describe "#tr" do
|
23
|
+
context "with `:snake_case, :symbolize`" do
|
24
24
|
subject { super().tr(:snake_case, :symbolize) }
|
25
25
|
|
26
|
-
let(:example) { {
|
26
|
+
let(:example) { {"FooBar" => "baz"} }
|
27
27
|
|
28
|
-
it { is_expected.to eq(foo_bar:
|
28
|
+
it { is_expected.to eq(foo_bar: "baz") }
|
29
29
|
end
|
30
30
|
|
31
|
-
context
|
31
|
+
context "with an unknown transformation" do
|
32
32
|
subject(:unknown_ops) { operation.tr(:unknown) }
|
33
33
|
|
34
|
-
it
|
34
|
+
it "raise an exception" do
|
35
35
|
expect { unknown_ops }.to raise_error(ArgumentError, /unknown/)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
context
|
39
|
+
context "with a complex, nested example" do
|
40
40
|
subject { super().tr(:camel_case, :symbolize) }
|
41
41
|
|
42
42
|
let(:example) do
|
43
43
|
{
|
44
44
|
Integer => 123,
|
45
|
-
:symbol => {
|
46
|
-
|
47
|
-
|
45
|
+
:symbol => {foo_bar: "bar"},
|
46
|
+
"string" => {"foo_bar" => 123},
|
47
|
+
"nested-array" => [
|
48
48
|
{
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
"camelCased" => "camelCased",
|
50
|
+
"dashed-key" => "dashed-key",
|
51
|
+
"PascalCased" => "PascalCased",
|
52
|
+
"under_scored" => "under_scored"
|
53
53
|
}
|
54
54
|
]
|
55
55
|
}
|
@@ -58,71 +58,71 @@ RSpec.describe DeepHashTransformer do
|
|
58
58
|
it do # rubocop:disable RSpec/ExampleLength
|
59
59
|
is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject
|
60
60
|
Integer => 123,
|
61
|
-
:symbol => {
|
62
|
-
:string => {
|
61
|
+
:symbol => {fooBar: "bar"},
|
62
|
+
:string => {fooBar: 123},
|
63
63
|
:nestedArray => [
|
64
64
|
{
|
65
|
-
camelCased:
|
66
|
-
dashedKey:
|
67
|
-
pascalCased:
|
68
|
-
underScored:
|
65
|
+
camelCased: "camelCased",
|
66
|
+
dashedKey: "dashed-key",
|
67
|
+
pascalCased: "PascalCased",
|
68
|
+
underScored: "under_scored"
|
69
69
|
}
|
70
70
|
]
|
71
71
|
)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
context
|
75
|
+
context "with nil values" do
|
76
76
|
subject { super().tr(:compact, :stringify) }
|
77
77
|
|
78
78
|
let(:example) do
|
79
|
-
{
|
79
|
+
{a: {b: ["", nil, :value], c: "", d: nil, e: true, f: false, g: 123, h: [""]}}
|
80
80
|
end
|
81
81
|
|
82
82
|
it do # rubocop:disable RSpec/ExampleLength
|
83
83
|
is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
84
|
+
"a" => {
|
85
|
+
"b" => ["", :value],
|
86
|
+
"c" => "",
|
87
|
+
"e" => true,
|
88
|
+
"f" => false,
|
89
|
+
"g" => 123,
|
90
|
+
"h" => [""]
|
91
91
|
}
|
92
92
|
)
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
context
|
96
|
+
context "with blank values" do
|
97
97
|
subject { super().tr(:compact_blank, :stringify) }
|
98
98
|
|
99
99
|
let(:example) do
|
100
|
-
{
|
100
|
+
{a: {b: ["", nil, :value], c: "", d: nil, e: true, f: false, g: 123, h: [""]}}
|
101
101
|
end
|
102
102
|
|
103
103
|
it do # rubocop:disable RSpec/ExampleLength
|
104
104
|
is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
105
|
+
"a" => {
|
106
|
+
"b" => [:value],
|
107
|
+
"e" => true,
|
108
|
+
"g" => 123
|
109
109
|
}
|
110
110
|
)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
context
|
114
|
+
context "with deeply nested blank values" do
|
115
115
|
subject { super().tr(:compact_blank) }
|
116
116
|
|
117
117
|
let(:example) do
|
118
|
-
{
|
118
|
+
{a: {b: [nil, {c: nil}]}}
|
119
119
|
end
|
120
120
|
|
121
121
|
it { is_expected.to eq({}) }
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
it
|
125
|
+
it "has a version number" do
|
126
126
|
expect(DeepHashTransformer::VERSION).not_to be_nil
|
127
127
|
end
|
128
128
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
|
3
|
+
require "bundler/setup"
|
4
|
+
require "deep_hash_transformer"
|
5
|
+
require "deep_hash_transformer/blank"
|
6
|
+
require "deep_hash_transformer/collection_operation"
|
7
|
+
require "deep_hash_transformer/element_operation"
|
8
|
+
|
9
|
+
require "simplecov"
|
9
10
|
|
10
11
|
SimpleCov.start do
|
11
|
-
if ENV[
|
12
|
-
require
|
12
|
+
if ENV["CI"]
|
13
|
+
require "simplecov_json_formatter"
|
14
|
+
require "simplecov-lcov"
|
13
15
|
|
14
16
|
SimpleCov::Formatter::LcovFormatter.config do |c|
|
15
17
|
c.report_with_single_file = true
|
16
|
-
c.single_report_path =
|
18
|
+
c.single_report_path = "coverage/lcov.info"
|
17
19
|
end
|
18
20
|
|
19
|
-
formatter SimpleCov::Formatter::
|
21
|
+
formatter SimpleCov::Formatter::MultiFormatter.new [
|
22
|
+
SimpleCov::Formatter::JSONFormatter, SimpleCov::Formatter::LcovFormatter
|
23
|
+
]
|
20
24
|
end
|
21
25
|
|
22
26
|
add_filter %w[version.rb initializer.rb]
|
@@ -24,7 +28,7 @@ end
|
|
24
28
|
|
25
29
|
RSpec.configure do |config|
|
26
30
|
# Enable flags like --only-failures and --next-failure
|
27
|
-
config.example_status_persistence_file_path =
|
31
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
28
32
|
|
29
33
|
config.expect_with :rspec do |c|
|
30
34
|
c.syntax = :expect
|
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: 2.2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Spickermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-25 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: " DeepHashTransformer helps to transform keys in deeply nested hash
|
14
14
|
structures\n"
|
@@ -42,14 +42,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version:
|
45
|
+
version: 3.0.0
|
46
46
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
47
|
requirements:
|
48
48
|
- - ">="
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: '0'
|
51
51
|
requirements: []
|
52
|
-
rubygems_version: 3.
|
52
|
+
rubygems_version: 3.5.3
|
53
53
|
signing_key:
|
54
54
|
specification_version: 4
|
55
55
|
summary: Transforms deeply nested hash structure
|