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.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +63 -9
  3. data/.gitignore +2 -0
  4. data/.reek.yml +3 -0
  5. data/.rubocop.yml +18 -1
  6. data/.rubocop_todo.yml +15 -8
  7. data/ARRAY_README.md +72 -15
  8. data/CLASS_README.md +154 -0
  9. data/DATE_README.md +19 -9
  10. data/Dockerfile +18 -5
  11. data/ENUMERABLE_README.md +154 -4
  12. data/Gemfile +13 -0
  13. data/HASH_README.md +276 -135
  14. data/MATH_README.md +14 -10
  15. data/Makefile +7 -0
  16. data/OBJECT_README.md +18 -35
  17. data/README.md +12 -4
  18. data/Rakefile +1 -0
  19. data/SYMBOL_README.md +13 -18
  20. data/config/check_specs.yml +20 -0
  21. data/config/rubycritc.rb +12 -0
  22. data/config/yardstick.yml +45 -3
  23. data/core_ext.gemspec +10 -18
  24. data/docker-compose.yml +24 -7
  25. data/lib/darthjee/core_ext/array/hash_builder.rb +22 -5
  26. data/lib/darthjee/core_ext/array.rb +22 -14
  27. data/lib/darthjee/core_ext/class.rb +29 -10
  28. data/lib/darthjee/core_ext/date.rb +1 -0
  29. data/lib/darthjee/core_ext/enumerable.rb +67 -29
  30. data/lib/darthjee/core_ext/hash/cameliazable.rb +52 -21
  31. data/lib/darthjee/core_ext/hash/chain_fetcher.rb +18 -1
  32. data/lib/darthjee/core_ext/hash/changeable.rb +88 -0
  33. data/lib/darthjee/core_ext/hash/deep_hash_constructor/setter.rb +112 -0
  34. data/lib/darthjee/core_ext/hash/deep_hash_constructor.rb +127 -62
  35. data/lib/darthjee/core_ext/hash/key_changeable.rb +138 -66
  36. data/lib/darthjee/core_ext/hash/key_changer.rb +146 -45
  37. data/lib/darthjee/core_ext/hash/keys_sorter.rb +43 -6
  38. data/lib/darthjee/core_ext/hash/squasher.rb +131 -18
  39. data/lib/darthjee/core_ext/hash/transformable.rb +133 -41
  40. data/lib/darthjee/core_ext/hash/transposeable.rb +37 -8
  41. data/lib/darthjee/core_ext/hash/value_changer.rb +76 -36
  42. data/lib/darthjee/core_ext/hash.rb +6 -4
  43. data/lib/darthjee/core_ext/math.rb +37 -6
  44. data/lib/darthjee/core_ext/numeric.rb +13 -2
  45. data/lib/darthjee/core_ext/object.rb +27 -0
  46. data/lib/darthjee/core_ext/symbol.rb +22 -2
  47. data/lib/darthjee/core_ext/version.rb +1 -1
  48. data/scripts/check_readme.sh +6 -0
  49. data/scripts/rubycritic.sh +10 -0
  50. data/spec/integration/readme/array_spec.rb +96 -0
  51. data/spec/integration/readme/class_spec.rb +123 -0
  52. data/spec/integration/readme/date_spec.rb +20 -0
  53. data/spec/integration/readme/enumerable_spec.rb +87 -0
  54. data/spec/integration/readme/hash_spec.rb +400 -0
  55. data/spec/integration/readme/math_spec.rb +31 -0
  56. data/spec/integration/readme/object_spec.rb +49 -0
  57. data/spec/integration/readme/symbol_spec.rb +29 -0
  58. data/spec/integration/yard/darthjee/core_ext/array_spec.rb +1 -1
  59. data/spec/integration/yard/darthjee/core_ext/class/default_value_spec.rb +10 -8
  60. data/spec/integration/yard/darthjee/core_ext/enumerable_spec.rb +24 -4
  61. data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +11 -0
  62. data/spec/integration/yard/darthjee/core_ext/hash/changeable_spec.rb +68 -0
  63. data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +34 -0
  64. data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +65 -0
  65. data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +8 -0
  66. data/spec/integration/yard/darthjee/core_ext/hash/key_changer_spec.rb +59 -0
  67. data/spec/integration/yard/darthjee/core_ext/hash/keys_sorter_spec.rb +25 -0
  68. data/spec/integration/yard/darthjee/core_ext/hash/squasher_spec.rb +60 -0
  69. data/spec/integration/yard/darthjee/core_ext/hash/transformable_spec.rb +67 -37
  70. data/spec/integration/yard/darthjee/core_ext/hash/transposeable_spec.rb +35 -0
  71. data/spec/integration/yard/darthjee/core_ext/hash/value_changer_spec.rb +1 -1
  72. data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +13 -2
  73. data/spec/integration/yard/darthjee/core_ext/math_spec.rb +28 -0
  74. data/spec/integration/yard/darthjee/core_ext/numeric_spec.rb +11 -0
  75. data/spec/integration/yard/darthjee/core_ext/object_spec.rb +47 -0
  76. data/spec/integration/yard/darthjee/core_ext/symbol_spec.rb +17 -0
  77. data/spec/lib/array_spec.rb +2 -1
  78. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +64 -0
  79. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +16 -156
  80. data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +5 -4
  81. data/spec/lib/darthjee/core_ext/hash/squasher_spec.rb +8 -2
  82. data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +5 -13
  83. data/spec/lib/hash_spec.rb +87 -147
  84. data/spec/lib/object_spec.rb +32 -0
  85. data/spec/lib/symbol_spec.rb +2 -2
  86. data/spec/spec_helper.rb +4 -2
  87. data/spec/support/models/client.rb +23 -0
  88. data/spec/support/models/dummy_iterator.rb +4 -4
  89. data/spec/support/models/hash/value_changer/dummy.rb +1 -0
  90. data/spec/support/shared_examples/array/array_random.rb +2 -3
  91. data/spec/support/shared_examples/hash/chain_hash_keys_changer.rb +1 -1
  92. data/spec/support/shared_examples/hash/deep_hash.rb +166 -0
  93. data/spec/support/shared_examples/hash/hash_keys_changer.rb +3 -3
  94. data/spec/support/shared_examples/hash/hash_squasher.rb +54 -9
  95. data/spec/support/shared_examples/hash/keys_sorter.rb +266 -6
  96. data/spec/support/shared_examples/hash/map_to_hash.rb +1 -1
  97. data/spec/support/shared_examples/hash/remap.rb +4 -4
  98. data/spec/support/shared_examples/hash/value_changer.rb +2 -2
  99. metadata +41 -189
  100. data/lib/darthjee/core_ext/hash/to_hash_mapper.rb +0 -25
  101. 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}".to_sym }
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: 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 class that has a method to squash a hash' do
6
- describe '#squash' do
7
- let(:hash) { { a: { b: 1, c: { d: 2 } } } }
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('a.b' => 1, 'a.c.d' => 2)
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
- context 'with array value' do
16
- let(:hash) { { a: { b: [1, { x: 3, y: { z: 4 } }] } } }
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
- it 'flattens the hash' do
19
- expect(squashed).to eq('a.b' => [1, { x: 3, y: { z: 4 } }])
20
- end
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: { e: 3, f: 4 } } } }
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: 4, e: 3 }, d: 2 }, b: 1 }
54
- expect(hash.sort_keys(recursive: true)).to eq(expected)
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: [{ e: 3, f: 4 }] } } }
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: 4, e: 3 }], d: 2 }, b: 1 }
63
- expect(hash.sort_keys(recursive: true)).to eq(expected)
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 { |word| word.length } }
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 has original array keys' do
60
+ context 'when remap swap keys' do
61
61
  let(:remap) { { b: :a, a: :b } }
62
62
 
63
- it 'does not remap the keys' do
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 original array keys' do
68
+ context 'when remap has one of the keys swapped' do
69
69
  let(:remap) { { a: :b, b: :c } }
70
70
 
71
- it 'does not remap the keys' do
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])