darthjee-core_ext 1.7.4 → 3.0.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 +5 -5
- data/.circleci/config.yml +63 -9
- data/.gitignore +2 -0
- data/.reek.yml +3 -0
- data/.rubocop.yml +18 -1
- data/.rubocop_todo.yml +15 -8
- data/ARRAY_README.md +72 -15
- data/CLASS_README.md +154 -0
- data/DATE_README.md +19 -9
- data/Dockerfile +18 -5
- data/ENUMERABLE_README.md +154 -4
- data/Gemfile +13 -0
- data/HASH_README.md +276 -135
- data/MATH_README.md +14 -10
- data/Makefile +7 -0
- data/OBJECT_README.md +18 -35
- data/README.md +12 -4
- data/Rakefile +1 -0
- data/SYMBOL_README.md +13 -18
- data/config/check_specs.yml +20 -0
- data/config/rubycritc.rb +12 -0
- data/config/yardstick.yml +45 -3
- data/core_ext.gemspec +10 -18
- data/docker-compose.yml +24 -7
- data/lib/darthjee/core_ext/array/hash_builder.rb +22 -5
- data/lib/darthjee/core_ext/array.rb +22 -14
- data/lib/darthjee/core_ext/class.rb +29 -10
- data/lib/darthjee/core_ext/date.rb +1 -0
- data/lib/darthjee/core_ext/enumerable.rb +67 -29
- data/lib/darthjee/core_ext/hash/cameliazable.rb +52 -21
- data/lib/darthjee/core_ext/hash/chain_fetcher.rb +18 -1
- data/lib/darthjee/core_ext/hash/changeable.rb +88 -0
- data/lib/darthjee/core_ext/hash/deep_hash_constructor/setter.rb +112 -0
- data/lib/darthjee/core_ext/hash/deep_hash_constructor.rb +127 -62
- data/lib/darthjee/core_ext/hash/key_changeable.rb +138 -66
- data/lib/darthjee/core_ext/hash/key_changer.rb +146 -45
- data/lib/darthjee/core_ext/hash/keys_sorter.rb +43 -6
- data/lib/darthjee/core_ext/hash/squasher.rb +131 -18
- data/lib/darthjee/core_ext/hash/transformable.rb +133 -41
- data/lib/darthjee/core_ext/hash/transposeable.rb +37 -8
- data/lib/darthjee/core_ext/hash/value_changer.rb +76 -36
- data/lib/darthjee/core_ext/hash.rb +6 -4
- data/lib/darthjee/core_ext/math.rb +37 -6
- data/lib/darthjee/core_ext/numeric.rb +13 -2
- data/lib/darthjee/core_ext/object.rb +27 -0
- data/lib/darthjee/core_ext/symbol.rb +22 -2
- data/lib/darthjee/core_ext/version.rb +1 -1
- data/scripts/check_readme.sh +6 -0
- data/scripts/rubycritic.sh +10 -0
- data/spec/integration/readme/array_spec.rb +96 -0
- data/spec/integration/readme/class_spec.rb +123 -0
- data/spec/integration/readme/date_spec.rb +20 -0
- data/spec/integration/readme/enumerable_spec.rb +87 -0
- data/spec/integration/readme/hash_spec.rb +400 -0
- data/spec/integration/readme/math_spec.rb +31 -0
- data/spec/integration/readme/object_spec.rb +49 -0
- data/spec/integration/readme/symbol_spec.rb +29 -0
- data/spec/integration/yard/darthjee/core_ext/array_spec.rb +1 -1
- data/spec/integration/yard/darthjee/core_ext/class/default_value_spec.rb +10 -8
- data/spec/integration/yard/darthjee/core_ext/enumerable_spec.rb +24 -4
- data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +11 -0
- data/spec/integration/yard/darthjee/core_ext/hash/changeable_spec.rb +68 -0
- data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +34 -0
- data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +65 -0
- data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +8 -0
- data/spec/integration/yard/darthjee/core_ext/hash/key_changer_spec.rb +59 -0
- data/spec/integration/yard/darthjee/core_ext/hash/keys_sorter_spec.rb +25 -0
- data/spec/integration/yard/darthjee/core_ext/hash/squasher_spec.rb +60 -0
- data/spec/integration/yard/darthjee/core_ext/hash/transformable_spec.rb +67 -37
- data/spec/integration/yard/darthjee/core_ext/hash/transposeable_spec.rb +35 -0
- data/spec/integration/yard/darthjee/core_ext/hash/value_changer_spec.rb +1 -1
- data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +13 -2
- data/spec/integration/yard/darthjee/core_ext/math_spec.rb +28 -0
- data/spec/integration/yard/darthjee/core_ext/numeric_spec.rb +11 -0
- data/spec/integration/yard/darthjee/core_ext/object_spec.rb +47 -0
- data/spec/integration/yard/darthjee/core_ext/symbol_spec.rb +17 -0
- data/spec/lib/array_spec.rb +2 -1
- data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +64 -0
- data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +16 -156
- data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +5 -4
- data/spec/lib/darthjee/core_ext/hash/squasher_spec.rb +8 -2
- data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +5 -13
- data/spec/lib/hash_spec.rb +87 -147
- data/spec/lib/object_spec.rb +32 -0
- data/spec/lib/symbol_spec.rb +2 -2
- data/spec/spec_helper.rb +4 -2
- data/spec/support/models/client.rb +23 -0
- data/spec/support/models/dummy_iterator.rb +4 -4
- data/spec/support/models/hash/value_changer/dummy.rb +1 -0
- data/spec/support/shared_examples/array/array_random.rb +2 -3
- data/spec/support/shared_examples/hash/chain_hash_keys_changer.rb +1 -1
- data/spec/support/shared_examples/hash/deep_hash.rb +166 -0
- data/spec/support/shared_examples/hash/hash_keys_changer.rb +3 -3
- data/spec/support/shared_examples/hash/hash_squasher.rb +54 -9
- data/spec/support/shared_examples/hash/keys_sorter.rb +266 -6
- data/spec/support/shared_examples/hash/map_to_hash.rb +1 -1
- data/spec/support/shared_examples/hash/remap.rb +4 -4
- data/spec/support/shared_examples/hash/value_changer.rb +2 -2
- metadata +41 -189
- data/lib/darthjee/core_ext/hash/to_hash_mapper.rb +0 -25
- data/spec/lib/darthjee/core_ext/hash/to_hash_mapper_spec.rb +0 -11
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
shared_examples 'a method that returns a deep hash' do
|
4
|
+
subject(:hash) do
|
5
|
+
{
|
6
|
+
'person.name' => 'Some name',
|
7
|
+
'person.age' => 22,
|
8
|
+
'status' => :success,
|
9
|
+
'vehicle.fuel' => 'GASOLINE',
|
10
|
+
'vehicle.doors' => 4
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:args) { [] }
|
15
|
+
|
16
|
+
let(:expected) do
|
17
|
+
{
|
18
|
+
'person' => { 'name' => 'Some name', 'age' => 22 },
|
19
|
+
'vehicle' => { 'fuel' => 'GASOLINE', 'doors' => 4 },
|
20
|
+
'status' => :success
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'build a deep hash' do
|
25
|
+
expect(result).to eq(expected)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with indexed keys' do
|
29
|
+
subject(:hash) do
|
30
|
+
{
|
31
|
+
'person[0].name' => 'First person',
|
32
|
+
'person[0].age' => 22,
|
33
|
+
'person[1].name' => 'Second person',
|
34
|
+
'person[1].age' => 27,
|
35
|
+
'device[0]' => 'GEAR_LOCK',
|
36
|
+
'device[1]' => 'GPS',
|
37
|
+
'zipCode' => '122345-123'
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:expected) do
|
42
|
+
{
|
43
|
+
'person' => [
|
44
|
+
{ 'name' => 'First person', 'age' => 22 },
|
45
|
+
{ 'name' => 'Second person', 'age' => 27 }
|
46
|
+
],
|
47
|
+
'device' => %w[GEAR_LOCK GPS],
|
48
|
+
'zipCode' => '122345-123'
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'build a deep hash with arrays' do
|
53
|
+
expect(result).to eq(expected)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'with a n level hash' do
|
58
|
+
subject(:hash) do
|
59
|
+
{
|
60
|
+
'quote_request.personal.person.name' => 'Some name',
|
61
|
+
'quote_request.personal.person.age' => 22,
|
62
|
+
'quote_request.insurance.vehicle.fuel' => 'GASOLINE',
|
63
|
+
'quote_request.insurance.vehicle.doors' => 4,
|
64
|
+
'request.status' => :success,
|
65
|
+
'trials' => 3
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
let(:expected) do
|
70
|
+
{
|
71
|
+
'quote_request' => {
|
72
|
+
'personal' => {
|
73
|
+
'person' => { 'name' => 'Some name', 'age' => 22 }
|
74
|
+
},
|
75
|
+
'insurance' => {
|
76
|
+
'vehicle' => { 'fuel' => 'GASOLINE', 'doors' => 4 }
|
77
|
+
}
|
78
|
+
},
|
79
|
+
'request' => { 'status' => :success },
|
80
|
+
'trials' => 3
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'build a deep hash with arrays' do
|
85
|
+
expect(result).to eq(expected)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with a n level hash and arrays' do
|
90
|
+
subject(:hash) do
|
91
|
+
{
|
92
|
+
'quote_request.personal.person[0].name' => 'Some name 1',
|
93
|
+
'quote_request.personal.person[0].age' => 22,
|
94
|
+
'quote_request.personal.person[1].name' => 'Some name 2',
|
95
|
+
'quote_request.personal.person[1].age' => 23,
|
96
|
+
'request[0].status.clazz' => 'String',
|
97
|
+
'request[1].status.clazz' => 'Integer',
|
98
|
+
'request[2].status.clazz' => 'Date',
|
99
|
+
'trials' => 3
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
let(:expected) do
|
104
|
+
{
|
105
|
+
'quote_request' => {
|
106
|
+
'personal' => {
|
107
|
+
'person' => [
|
108
|
+
{ 'name' => 'Some name 1', 'age' => 22 },
|
109
|
+
{ 'name' => 'Some name 2', 'age' => 23 }
|
110
|
+
]
|
111
|
+
}
|
112
|
+
},
|
113
|
+
'request' => [
|
114
|
+
{ 'status' => { 'clazz' => 'String' } },
|
115
|
+
{ 'status' => { 'clazz' => 'Integer' } },
|
116
|
+
{ 'status' => { 'clazz' => 'Date' } }
|
117
|
+
],
|
118
|
+
'trials' => 3
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'build a deep hash with arrays' do
|
123
|
+
expect(result).to eq(expected)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'with custom separator' do
|
128
|
+
subject(:hash) do
|
129
|
+
{
|
130
|
+
'person_name' => 'Some name',
|
131
|
+
'person_age' => 22,
|
132
|
+
'status' => :success,
|
133
|
+
'vehicle_fuel' => 'GASOLINE',
|
134
|
+
'vehicle_doors' => 4
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:args) { ['_'] }
|
139
|
+
|
140
|
+
it 'build a deep hash with arrays' do
|
141
|
+
expect(result).to eq(expected)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'with custom separator on n level deep hash' do
|
146
|
+
subject(:hash) do
|
147
|
+
{
|
148
|
+
'person_name_clazz' => 'String'
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
let(:args) { ['_'] }
|
153
|
+
|
154
|
+
let(:expected) do
|
155
|
+
{
|
156
|
+
'person' => {
|
157
|
+
'name' => { 'clazz' => 'String' }
|
158
|
+
}
|
159
|
+
}
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'build a deep hash with arrays' do
|
163
|
+
expect(result).to eq(expected)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
@@ -27,7 +27,7 @@ end
|
|
27
27
|
|
28
28
|
shared_examples 'a method that is able to change keys' do |method|
|
29
29
|
let(:foo_sym_transformation) do
|
30
|
-
hash.public_send(method) { |k| "foo_#{k}"
|
30
|
+
hash.public_send(method) { |k| :"foo_#{k}" }
|
31
31
|
end
|
32
32
|
|
33
33
|
context 'with simple level hash' do
|
@@ -52,7 +52,7 @@ shared_examples 'a method that is able to change keys' do |method|
|
|
52
52
|
|
53
53
|
context 'with recursive hash' do
|
54
54
|
let(:hash) { { 'a' => 1, b: { c: 3, 'd' => 4 } } }
|
55
|
-
let(:result) { hash.public_send(method, options) { |k| "foo_#{k}" } }
|
55
|
+
let(:result) { hash.public_send(method, **options) { |k| "foo_#{k}" } }
|
56
56
|
let(:expected) do
|
57
57
|
{ 'foo_a' => 1, 'foo_b' => { 'foo_c' => 3, 'foo_d' => 4 } }
|
58
58
|
end
|
@@ -64,7 +64,7 @@ shared_examples 'a method that is able to change keys' do |method|
|
|
64
64
|
end
|
65
65
|
|
66
66
|
context 'when options are given' do
|
67
|
-
let(:options) { { recursive:
|
67
|
+
let(:options) { { recursive: } }
|
68
68
|
|
69
69
|
context 'with recursion' do
|
70
70
|
let(:recursive) { true }
|
@@ -2,22 +2,67 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
shared_examples 'a
|
6
|
-
|
7
|
-
|
5
|
+
shared_examples 'a method to squash a hash' do |joiner = '.'|
|
6
|
+
let(:hash) { { a: { b: 1, c: { d: 2 } } } }
|
7
|
+
|
8
|
+
context 'with hash values' do
|
9
|
+
let(:key1) { %w[a b].join(joiner) }
|
10
|
+
let(:key2) { %w[a c d].join(joiner) }
|
8
11
|
|
9
12
|
it 'flattens the hash' do
|
10
|
-
expect(squashed).to eq(
|
13
|
+
expect(squashed).to eq(key1 => 1, key2 => 2)
|
11
14
|
end
|
12
15
|
|
13
16
|
it { expect { hash.squash }.not_to(change { hash }) }
|
17
|
+
end
|
14
18
|
|
15
|
-
|
16
|
-
|
19
|
+
context 'with simple array value' do
|
20
|
+
let(:hash) do
|
21
|
+
{
|
22
|
+
'person' => %w[John Wick]
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'squash also hash' do
|
27
|
+
expect(squashed).to eq(
|
28
|
+
'person[0]' => 'John',
|
29
|
+
'person[1]' => 'Wick'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with array containing hashes' do
|
35
|
+
let(:hash) { { a: { b: [1, { x: 3, y: { z: 4 } }] } } }
|
36
|
+
let(:key) { %w[a b].join(joiner) }
|
37
|
+
|
38
|
+
let(:expected) do
|
39
|
+
{
|
40
|
+
"#{key}[0]" => 1,
|
41
|
+
"#{key}[1]#{joiner}x" => 3,
|
42
|
+
"#{key}[1]#{joiner}y#{joiner}z" => 4
|
43
|
+
}
|
44
|
+
end
|
17
45
|
|
18
|
-
|
19
|
-
|
20
|
-
|
46
|
+
it 'flattens the hash' do
|
47
|
+
expect(squashed).to eq(expected)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with array containing arrays' do
|
52
|
+
let(:hash) { { a: { b: [[11, 12], [21, 22]] } } }
|
53
|
+
let(:key) { %w[a b].join(joiner) }
|
54
|
+
|
55
|
+
let(:expected) do
|
56
|
+
{
|
57
|
+
"#{key}[0][0]" => 11,
|
58
|
+
"#{key}[0][1]" => 12,
|
59
|
+
"#{key}[1][0]" => 21,
|
60
|
+
"#{key}[1][1]" => 22
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'flattens the hash' do
|
65
|
+
expect(squashed).to eq(expected)
|
21
66
|
end
|
22
67
|
end
|
23
68
|
end
|
@@ -10,6 +10,10 @@ shared_examples 'a class with a keys sort method' do
|
|
10
10
|
it 'sorts keys as symbols' do
|
11
11
|
expect(result).to eq(a: 2, b: 1)
|
12
12
|
end
|
13
|
+
|
14
|
+
it 'sorts keys' do
|
15
|
+
expect(result.keys).to eq(%i[a b])
|
16
|
+
end
|
13
17
|
end
|
14
18
|
|
15
19
|
context 'when keys are strings' do
|
@@ -18,6 +22,10 @@ shared_examples 'a class with a keys sort method' do
|
|
18
22
|
it 'sorts keys as string' do
|
19
23
|
expect(result).to eq('a' => 2, 'b' => 1)
|
20
24
|
end
|
25
|
+
|
26
|
+
it 'sorts keys' do
|
27
|
+
expect(result.keys).to eq(%w[a b])
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
31
|
context 'when there is a nested hash' do
|
@@ -27,6 +35,14 @@ shared_examples 'a class with a keys sort method' do
|
|
27
35
|
it 'sorts keys recursively' do
|
28
36
|
expect(result).to eq(a: { c: 4, d: 3 }, b: 1)
|
29
37
|
end
|
38
|
+
|
39
|
+
it 'sorts keys' do
|
40
|
+
expect(result.keys).to eq(%i[a b])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'sorts inner keys' do
|
44
|
+
expect(result[:a].keys).to eq(%i[c d])
|
45
|
+
end
|
30
46
|
end
|
31
47
|
|
32
48
|
context 'when recursive option is given' do
|
@@ -35,6 +51,14 @@ shared_examples 'a class with a keys sort method' do
|
|
35
51
|
it 'sorts keys recursively when argumen is passed' do
|
36
52
|
expect(result).to eq(a: { c: 4, d: 3 }, b: 1)
|
37
53
|
end
|
54
|
+
|
55
|
+
it 'sorts keys' do
|
56
|
+
expect(result.keys).to eq(%i[a b])
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'sorts inner keys' do
|
60
|
+
expect(result[:a].keys).to eq(%i[c d])
|
61
|
+
end
|
38
62
|
end
|
39
63
|
|
40
64
|
context 'when no recursive option is given' do
|
@@ -43,24 +67,260 @@ shared_examples 'a class with a keys sort method' do
|
|
43
67
|
it 'does not sorts keys recursively when argumen is passed' do
|
44
68
|
expect(result).to eq(a: { d: 3, c: 4 }, b: 1)
|
45
69
|
end
|
70
|
+
|
71
|
+
it 'sorts keys' do
|
72
|
+
expect(result.keys).to eq(%i[a b])
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'does not sort inner keys' do
|
76
|
+
expect(result[:a].keys).to eq(%i[d c])
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'does not change inner hash' do
|
80
|
+
expect { result }.not_to change(hash[:a], :keys)
|
81
|
+
end
|
46
82
|
end
|
47
83
|
end
|
48
84
|
|
49
85
|
context 'when it is deep nestled' do
|
50
|
-
let(:hash) { { b: 1, a: { d: 2, c: {
|
86
|
+
let(:hash) { { b: 1, a: { d: 2, c: { f: 3, e: 4 } } } }
|
51
87
|
|
52
88
|
it 'sort recursevely on many levels' do
|
53
|
-
expected = { a: { c: { f:
|
54
|
-
expect(
|
89
|
+
expected = { a: { c: { f: 3, e: 4 }, d: 2 }, b: 1 }
|
90
|
+
expect(result).to eq(expected)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'sorts keys' do
|
94
|
+
expect(result.keys).to eq(%i[a b])
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'sorts inner keys' do
|
98
|
+
expect(result[:a].keys).to eq(%i[c d])
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'sorts deeper inner keys' do
|
102
|
+
expect(result[:a][:c].keys).to eq(%i[e f])
|
55
103
|
end
|
56
104
|
end
|
57
105
|
|
58
106
|
context 'when it has a nestled array' do
|
59
|
-
let(:hash) { { b: 1, a: { d: 2, c: [{
|
107
|
+
let(:hash) { { b: 1, a: { d: 2, c: [{ f: 3, e: 4 }] } } }
|
60
108
|
|
61
109
|
it 'applies to arrays as well' do
|
62
|
-
expected = { a: { c: [{ f:
|
63
|
-
expect(
|
110
|
+
expected = { a: { c: [{ f: 3, e: 4 }], d: 2 }, b: 1 }
|
111
|
+
expect(result).to eq(expected)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'sorts keys' do
|
115
|
+
expect(result.keys).to eq(%i[a b])
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'sorts inner keys' do
|
119
|
+
expect(result[:a].keys).to eq(%i[c d])
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'does not sort array deeper inner keys' do
|
123
|
+
expect(result[:a][:c].map(&:keys)).to eq([%i[f e]])
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'does not change array deeper inner hash' do
|
127
|
+
expect { result }.not_to(change { hash[:a][:c].map(&:keys) })
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
shared_examples 'a class with a keys sort method that changes original' do
|
134
|
+
describe '#sort_keys' do
|
135
|
+
let(:options) { {} }
|
136
|
+
|
137
|
+
context 'when keys are symbols' do
|
138
|
+
let(:hash) { { b: 1, a: 2 } }
|
139
|
+
|
140
|
+
it 'changes original hash' do
|
141
|
+
expect { result }.to change(hash, :keys)
|
142
|
+
.from(%i[b a]).to(%i[a b])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'when keys are strings' do
|
147
|
+
let(:hash) { { 'b' => 1, 'a' => 2 } }
|
148
|
+
|
149
|
+
it 'changes original hash' do
|
150
|
+
expect { result }.to change(hash, :keys)
|
151
|
+
.from(%w[b a]).to(%w[a b])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'when there is a nested hash' do
|
156
|
+
let(:hash) { { b: 1, a: { d: 3, c: 4 } } }
|
157
|
+
|
158
|
+
context 'when no option is given' do
|
159
|
+
it 'changes original hash' do
|
160
|
+
expect { result }.to change(hash, :keys)
|
161
|
+
.from(%i[b a]).to(%i[a b])
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'changes inner hash' do
|
165
|
+
expect { result }.to change(hash[:a], :keys)
|
166
|
+
.from(%i[d c]).to(%i[c d])
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when recursive option is given' do
|
171
|
+
let(:options) { { recursive: true } }
|
172
|
+
|
173
|
+
it 'changes original hash' do
|
174
|
+
expect { result }.to change(hash, :keys)
|
175
|
+
.from(%i[b a]).to(%i[a b])
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'changes inner hash' do
|
179
|
+
expect { result }.to change(hash[:a], :keys)
|
180
|
+
.from(%i[d c]).to(%i[c d])
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when no recursive option is given' do
|
185
|
+
let(:options) { { recursive: false } }
|
186
|
+
|
187
|
+
it 'changes original hash' do
|
188
|
+
expect { result }.to change(hash, :keys)
|
189
|
+
.from(%i[b a]).to(%i[a b])
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'does not change inner hash' do
|
193
|
+
expect { result }.not_to change(hash[:a], :keys)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context 'when it is deep nestled' do
|
199
|
+
let(:hash) { { b: 1, a: { d: 2, c: { f: 3, e: 4 } } } }
|
200
|
+
|
201
|
+
it 'changes original hash' do
|
202
|
+
expect { result }.to change(hash, :keys)
|
203
|
+
.from(%i[b a]).to(%i[a b])
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'changes inner hash' do
|
207
|
+
expect { result }.to change(hash[:a], :keys)
|
208
|
+
.from(%i[d c]).to(%i[c d])
|
209
|
+
end
|
210
|
+
|
211
|
+
it 'changes deeper inner hash' do
|
212
|
+
expect { result }.to change(hash[:a][:c], :keys)
|
213
|
+
.from(%i[f e]).to(%i[e f])
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'when it has a nestled array' do
|
218
|
+
let(:hash) { { b: 1, a: { d: 2, c: [{ f: 3, e: 4 }] } } }
|
219
|
+
|
220
|
+
it 'changes original hash' do
|
221
|
+
expect { result }.to change(hash, :keys)
|
222
|
+
.from(%i[b a]).to(%i[a b])
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'changes inner hash' do
|
226
|
+
expect { result }.to change(hash[:a], :keys)
|
227
|
+
.from(%i[d c]).to(%i[c d])
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'does not change array deeper inner hash' do
|
231
|
+
expect { result }.not_to(change { hash[:a][:c].map(&:keys) })
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
shared_examples 'a class with a keys sort method that not change self' do
|
238
|
+
describe '#sort_keys' do
|
239
|
+
let(:options) { {} }
|
240
|
+
|
241
|
+
context 'when keys are symbols' do
|
242
|
+
let(:hash) { { b: 1, a: 2 } }
|
243
|
+
|
244
|
+
it 'changes original hash' do
|
245
|
+
expect { result }.not_to change(hash, :keys)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
context 'when keys are strings' do
|
250
|
+
let(:hash) { { 'b' => 1, 'a' => 2 } }
|
251
|
+
|
252
|
+
it 'changes original hash' do
|
253
|
+
expect { result }.not_to change(hash, :keys)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'when there is a nested hash' do
|
258
|
+
let(:hash) { { b: 1, a: { d: 3, c: 4 } } }
|
259
|
+
|
260
|
+
context 'when no option is given' do
|
261
|
+
it 'changes original hash' do
|
262
|
+
expect { result }.not_to change(hash, :keys)
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'changes inner hash' do
|
266
|
+
expect { result }.not_to change(hash[:a], :keys)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'when recursive option is given' do
|
271
|
+
let(:options) { { recursive: true } }
|
272
|
+
|
273
|
+
it 'changes original hash' do
|
274
|
+
expect { result }.not_to change(hash, :keys)
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'changes inner hash' do
|
278
|
+
expect { result }.not_to change(hash[:a], :keys)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
context 'when no recursive option is given' do
|
283
|
+
let(:options) { { recursive: false } }
|
284
|
+
|
285
|
+
it 'changes original hash' do
|
286
|
+
expect { result }.not_to change(hash, :keys)
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'does not change inner hash' do
|
290
|
+
expect { result }.not_to change(hash[:a], :keys)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
context 'when it is deep nestled' do
|
296
|
+
let(:hash) { { b: 1, a: { d: 2, c: { f: 3, e: 4 } } } }
|
297
|
+
|
298
|
+
it 'changes original hash' do
|
299
|
+
expect { result }.not_to change(hash, :keys)
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'changes inner hash' do
|
303
|
+
expect { result }.not_to change(hash[:a], :keys)
|
304
|
+
end
|
305
|
+
|
306
|
+
it 'changes deeper inner hash' do
|
307
|
+
expect { result }.not_to change(hash[:a][:c], :keys)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'when it has a nestled array' do
|
312
|
+
let(:hash) { { b: 1, a: { d: 2, c: [{ f: 3, e: 4 }] } } }
|
313
|
+
|
314
|
+
it 'changes original hash' do
|
315
|
+
expect { result }.not_to change(hash, :keys)
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'changes inner hash' do
|
319
|
+
expect { result }.not_to change(hash[:a], :keys)
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'does not change array deeper inner hash' do
|
323
|
+
expect { result }.not_to(change { hash[:a][:c].map(&:keys) })
|
64
324
|
end
|
65
325
|
end
|
66
326
|
end
|
@@ -4,7 +4,7 @@ shared_examples 'an array with map_to_hash method' do
|
|
4
4
|
describe '#map_to_hash' do
|
5
5
|
subject(:hash) { %w[word1 wooord2] }
|
6
6
|
|
7
|
-
let(:mapping_block) { proc
|
7
|
+
let(:mapping_block) { proc(&:length) }
|
8
8
|
let(:mapped) { hash.map_to_hash(&mapping_block) }
|
9
9
|
let(:expected) { { 'word1' => 5, 'wooord2' => 7 } }
|
10
10
|
|
@@ -57,18 +57,18 @@ shared_examples 'a method that remaps the keys' do |method|
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
context 'when remap
|
60
|
+
context 'when remap swap keys' do
|
61
61
|
let(:remap) { { b: :a, a: :b } }
|
62
62
|
|
63
|
-
it '
|
63
|
+
it 'swap keys' do
|
64
64
|
expect(result).to eq(b: 1, a: 2)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
context 'when remap has
|
68
|
+
context 'when remap has one of the keys swapped' do
|
69
69
|
let(:remap) { { a: :b, b: :c } }
|
70
70
|
|
71
|
-
it '
|
71
|
+
it 'swap just that key' do
|
72
72
|
expect(result).to eq(b: 1, c: 2)
|
73
73
|
end
|
74
74
|
end
|
@@ -103,7 +103,7 @@ shared_examples 'a method that change the hash values' do |method|
|
|
103
103
|
|
104
104
|
it 'ignore hash and does not work recursively when option is passed' do
|
105
105
|
options = { skip_inner: false, recursive: false }
|
106
|
-
result = hash.public_send(method, options) do |value|
|
106
|
+
result = hash.public_send(method, **options) do |value|
|
107
107
|
value.is_a?(Hash) ? value : value + 1
|
108
108
|
end
|
109
109
|
expect(result).to eq(a: 2, b: 3, c: { d: 3, e: 4 })
|
@@ -142,7 +142,7 @@ shared_examples 'a method that change the hash values' do |method|
|
|
142
142
|
|
143
143
|
it 'ignore hash and does not work recursively when option is passed' do
|
144
144
|
options = { skip_inner: false, recursive: false }
|
145
|
-
result = hash.public_send(method, options) do |value|
|
145
|
+
result = hash.public_send(method, **options) do |value|
|
146
146
|
value.is_a?(Array) ? value : value + 1
|
147
147
|
end
|
148
148
|
expect(result).to eq(a: 2, b: 3, c: [{ d: 3 }, { e: { f: 4 } }, 5])
|