darthjee-core_ext 1.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +5 -0
  5. data/Gemfile.lock +62 -0
  6. data/LICENSE +22 -0
  7. data/README.md +188 -0
  8. data/Rakefile +7 -0
  9. data/core_ext.gemspec +27 -0
  10. data/lib/array.rb +23 -0
  11. data/lib/array/hash_builder.rb +20 -0
  12. data/lib/darthjee.rb +4 -0
  13. data/lib/darthjee/core_ext.rb +12 -0
  14. data/lib/darthjee/core_ext/version.rb +5 -0
  15. data/lib/enumerable.rb +45 -0
  16. data/lib/hash.rb +195 -0
  17. data/lib/hash/deep_hash_constructor.rb +83 -0
  18. data/lib/hash/key_changer.rb +76 -0
  19. data/lib/hash/value_changer.rb +61 -0
  20. data/lib/numeric.rb +6 -0
  21. data/lib/symbol.rb +9 -0
  22. data/spec/lib/array_spec.rb +229 -0
  23. data/spec/lib/enumerable_spec.rb +31 -0
  24. data/spec/lib/hash/deep_hash_constructor_spec.rb +167 -0
  25. data/spec/lib/hash/key_changer_spec.rb +55 -0
  26. data/spec/lib/hash_spec.rb +347 -0
  27. data/spec/lib/numeric_spec.rb +61 -0
  28. data/spec/lib/symbol_spec.rb +35 -0
  29. data/spec/spec_helper.rb +32 -0
  30. data/spec/support/models/hash/value_changer/dummy.rb +15 -0
  31. data/spec/support/models/hash/value_changer/dummy_iteractor.rb +12 -0
  32. data/spec/support/shared_examples/array_random.rb +16 -0
  33. data/spec/support/shared_examples/chain_fetch.rb +88 -0
  34. data/spec/support/shared_examples/chain_hash_keys_changer.rb +88 -0
  35. data/spec/support/shared_examples/clean.rb +143 -0
  36. data/spec/support/shared_examples/expected.rb +6 -0
  37. data/spec/support/shared_examples/hash_keys_changer.rb +85 -0
  38. data/spec/support/shared_examples/keys_appender.rb +43 -0
  39. data/spec/support/shared_examples/keys_camelizer.rb +285 -0
  40. data/spec/support/shared_examples/keys_underscorer.rb +82 -0
  41. data/spec/support/shared_examples/remap.rb +89 -0
  42. data/spec/support/shared_examples/value_changer.rb +92 -0
  43. metadata +217 -0
@@ -0,0 +1,6 @@
1
+ shared_examples 'result is as expected' do
2
+ it 'is as expected' do
3
+ expect(result).to eq(expected)
4
+ end
5
+ end
6
+
@@ -0,0 +1,85 @@
1
+ shared_examples 'a class with change_key method' do
2
+ let(:hash) do
3
+ { 'a' => 1, b: 2, c: { d: 3, e: 4 }, f: [{ g: 5 }, { h: 6 }] }
4
+ end
5
+
6
+ describe :change_keys do
7
+ it_behaves_like 'a method that is able to change keys', :change_keys
8
+ it 'does not affects the original hash' do
9
+ expect do
10
+ hash.change_keys(recursive: true) { |k| "foo_#{k}" }
11
+ end.not_to change { hash }
12
+ end
13
+ end
14
+
15
+ describe :change_keys! do
16
+ it_behaves_like 'a method that is able to change keys', :change_keys!
17
+
18
+ it 'affects the original hash' do
19
+ expect do
20
+ hash.change_keys!(recursive: true) { |k| "foo_#{k}" }
21
+ end.to change { hash }
22
+ end
23
+ end
24
+ end
25
+
26
+ shared_examples 'a method that is able to change keys' do |method|
27
+ let(:foo_sym_transformation) do
28
+ hash.public_send(method) { |k| "foo_#{k}".to_sym }
29
+ end
30
+
31
+ context 'with simple level hash' do
32
+ let(:hash) { { 'a' => 1, b: 2 } }
33
+
34
+ context 'with string transformation' do
35
+ let(:result) do
36
+ hash.public_send(method) { |k| "foo_#{k}" }
37
+ end
38
+ let(:expected) { { 'foo_a' => 1, 'foo_b' => 2 } }
39
+ it_behaves_like 'result is as expected'
40
+ end
41
+
42
+ context 'with symbol transformation' do
43
+ let(:result) { foo_sym_transformation }
44
+ let(:expected) { { foo_a: 1, foo_b: 2 } }
45
+ it_behaves_like 'result is as expected'
46
+ end
47
+ end
48
+
49
+ context 'with recursive hash' do
50
+ let(:hash) { { 'a' => 1, b: { c: 3, 'd' => 4 } } }
51
+ let(:result) { hash.public_send(method, options) { |k| "foo_#{k}" } }
52
+ let(:expected) do
53
+ { 'foo_a' => 1, 'foo_b' => { 'foo_c' => 3, 'foo_d' => 4 } }
54
+ end
55
+
56
+ context 'when no options are given' do
57
+ let(:options) { {} }
58
+ it_behaves_like 'result is as expected'
59
+ end
60
+
61
+ context 'when options are given' do
62
+ let(:options) { { recursive: recursive } }
63
+
64
+ context 'with recursion' do
65
+ let(:recursive) { true }
66
+ it_behaves_like 'result is as expected'
67
+ end
68
+
69
+ context 'without recursion' do
70
+ let(:recursive) { false }
71
+ let(:expected) { { 'foo_a' => 1, 'foo_b' => { c: 3, 'd' => 4 } } }
72
+ it_behaves_like 'result is as expected'
73
+ end
74
+ end
75
+ end
76
+
77
+ context 'with many many levels' do
78
+ let(:hash) { { a: 1, b: { c: 2, d: { e: 3, f: 4 } } } }
79
+ let(:expected) do
80
+ { foo_a: 1, foo_b: { foo_c: 2, foo_d: { foo_e: 3, foo_f: 4 } } }
81
+ end
82
+ let(:result) { foo_sym_transformation }
83
+ it_behaves_like 'result is as expected'
84
+ end
85
+ end
@@ -0,0 +1,43 @@
1
+ shared_examples 'a class with append_keys method' do
2
+ describe :prepend_to_keys do
3
+ it 'accepts block to change the keys' do
4
+ expect({ a: 1, 'b' => 2 }.prepend_to_keys('foo_')).to eq(foo_a: 1, 'foo_b' => 2)
5
+ end
6
+ it 'applies the block recursively' do
7
+ expect({ 'a' => 1, b: { c: 3, 'd' => 4 } }.prepend_to_keys('foo_')).to eq('foo_a' => 1, foo_b: { foo_c: 3, 'foo_d' => 4 })
8
+ end
9
+ it 'changes type when type option is passed' do
10
+ expect({ 'a' => 1, b: 2 }.prepend_to_keys('foo_', type: :string)).to eq('foo_a' => 1, 'foo_b' => 2)
11
+ end
12
+ it 'changes type when type option is passed' do
13
+ expect({ 'a' => 1, b: 2 }.prepend_to_keys('foo_', type: :symbol)).to eq(foo_a: 1, foo_b: 2)
14
+ end
15
+ it 'keep type when type option is passed as keep' do
16
+ expect({ 'a' => 1, b: 2 }.prepend_to_keys('foo_', type: :keep)).to eq('foo_a' => 1, foo_b: 2)
17
+ end
18
+ it 'applies to array as well' do
19
+ expect({ 'a' => 1, b: [{ c: 2 }, { d: 3 }] }.prepend_to_keys('foo_', type: :keep)).to eq('foo_a' => 1, foo_b: [{ foo_c: 2 }, { foo_d: 3 }])
20
+ end
21
+ end
22
+
23
+ describe :append_to_keys do
24
+ it 'accepts block to change the keys' do
25
+ expect({ a: 1, 'b' => 2 }.append_to_keys('_bar')).to eq(a_bar: 1, 'b_bar' => 2)
26
+ end
27
+ it 'applies the block recursively' do
28
+ expect({ 'a' => 1, b: { c: 3, 'd' => 4 } }.append_to_keys('_bar')).to eq('a_bar' => 1, b_bar: { c_bar: 3, 'd_bar' => 4 })
29
+ end
30
+ it 'changes type when type option is passed' do
31
+ expect({ 'a' => 1, b: 2 }.append_to_keys('_bar', type: :string)).to eq('a_bar' => 1, 'b_bar' => 2)
32
+ end
33
+ it 'changes type when type option is passed' do
34
+ expect({ 'a' => 1, b: 2 }.append_to_keys('_bar', type: :symbol)).to eq(a_bar: 1, b_bar: 2)
35
+ end
36
+ it 'keep type when type option is passed as keep' do
37
+ expect({ 'a' => 1, b: 2 }.append_to_keys('_bar', type: :keep)).to eq('a_bar' => 1, b_bar: 2)
38
+ end
39
+ it 'applies to array as well' do
40
+ expect({ 'a' => 1, b: [{ c: 2 }, { d: 3 }] }.append_to_keys('_bar', type: :keep)).to eq('a_bar' => 1, b_bar: [{ c_bar: 2 }, { d_bar: 3 }])
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,285 @@
1
+ shared_examples 'a class with camlize_keys method' do
2
+ describe :lower_camelize_keys do
3
+ let(:expected) { { inputKey: 'value' } }
4
+
5
+ context 'with underscore keys' do
6
+ let(:hash) { { input_key: 'value' } }
7
+
8
+ it 'converts the keys to lower camel case' do
9
+ expect(hash.lower_camelize_keys).to eq(expected)
10
+ end
11
+
12
+ it 'does not change original hash' do
13
+ expect { hash.lower_camelize_keys }.not_to change { hash }
14
+ end
15
+ end
16
+
17
+ context 'with camel case keys' do
18
+ let(:hash) { { InputKey: 'value' } }
19
+
20
+ it 'converts the keys to lower camel case' do
21
+ expect(hash.lower_camelize_keys).to eq(expected)
22
+ end
23
+ end
24
+
25
+ context 'with string keys' do
26
+ let(:expected) { { 'inputKey' => 'value' } }
27
+ let(:hash) { { 'InputKey' => 'value' } }
28
+
29
+ it 'converts the keys to lower camel case' do
30
+ expect(hash.lower_camelize_keys).to eq(expected)
31
+ end
32
+ end
33
+
34
+ context 'with deep keys change' do
35
+ let(:expected) { { inputKey: { innerKey: 'value' } } }
36
+ let(:hash) { { InputKey: { InnerKey: 'value' } } }
37
+
38
+ it 'converts the keys to lower camel case' do
39
+ expect(hash.lower_camelize_keys).to eq(expected)
40
+ end
41
+ end
42
+
43
+ context 'with array keys change' do
44
+ let(:expected) { { inputKey: [{ innerKey: 'value' }] } }
45
+ let(:hash) { { InputKey: [{ InnerKey: 'value' }] } }
46
+
47
+ it 'converts the keys to camle case' do
48
+ expect(hash.lower_camelize_keys).to eq(expected)
49
+ end
50
+ end
51
+
52
+ context 'without recursive options' do
53
+ context 'with deep keys change' do
54
+ let(:expected) { { inputKey: { InnerKey: 'value' } } }
55
+ let(:hash) { { InputKey: { InnerKey: 'value' } } }
56
+
57
+ it 'converts the keys to lower camel case' do
58
+ expect(hash.lower_camelize_keys(recursive: false)).to eq(expected)
59
+ end
60
+ end
61
+
62
+ context 'with array keys change' do
63
+ let(:expected) { { inputKey: [{ InnerKey: 'value' }] } }
64
+ let(:hash) { { InputKey: [{ InnerKey: 'value' }] } }
65
+
66
+ it 'converts the keys to camle case' do
67
+ expect(hash.lower_camelize_keys(recursive: false)).to eq(expected)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ describe :lower_camelize_keys! do
74
+ let(:expected) { { inputKey: 'value' } }
75
+
76
+ context 'with underscore keys' do
77
+ let(:hash) { { input_key: 'value' } }
78
+
79
+ it 'converts the keys to lower camel case' do
80
+ expect(hash.lower_camelize_keys!).to eq(expected)
81
+ end
82
+
83
+ it 'does not change original hash' do
84
+ expect { hash.lower_camelize_keys! }.to change { hash }
85
+ end
86
+ end
87
+
88
+ context 'with camel case keys' do
89
+ let(:hash) { { InputKey: 'value' } }
90
+
91
+ it 'converts the keys to lower camel case' do
92
+ expect(hash.lower_camelize_keys!).to eq(expected)
93
+ end
94
+ end
95
+
96
+ context 'with string keys' do
97
+ let(:expected) { { 'inputKey' => 'value' } }
98
+ let(:hash) { { 'InputKey' => 'value' } }
99
+
100
+ it 'converts the keys to lower camel case' do
101
+ expect(hash.lower_camelize_keys).to eq(expected)
102
+ end
103
+ end
104
+
105
+ context 'with deep keys change' do
106
+ let(:expected) { { inputKey: { innerKey: 'value' } } }
107
+ let(:hash) { { InputKey: { InnerKey: 'value' } } }
108
+
109
+ it 'converts the keys to lower camel case' do
110
+ expect(hash.lower_camelize_keys!).to eq(expected)
111
+ end
112
+ end
113
+
114
+ context 'with array keys change' do
115
+ let(:expected) { { inputKey: [{ innerKey: 'value' }] } }
116
+ let(:hash) { { InputKey: [{ InnerKey: 'value' }] } }
117
+
118
+ it 'converts the keys to camle case' do
119
+ expect(hash.lower_camelize_keys!).to eq(expected)
120
+ end
121
+ end
122
+
123
+ context 'without recursive options' do
124
+ context 'with deep keys change' do
125
+ let(:expected) { { inputKey: { InnerKey: 'value' } } }
126
+ let(:hash) { { InputKey: { InnerKey: 'value' } } }
127
+
128
+ it 'converts the keys to lower camel case' do
129
+ expect(hash.lower_camelize_keys!(recursive: false)).to eq(expected)
130
+ end
131
+ end
132
+
133
+ context 'with array keys change' do
134
+ let(:expected) { { inputKey: [{ InnerKey: 'value' }] } }
135
+ let(:hash) { { InputKey: [{ InnerKey: 'value' }] } }
136
+
137
+ it 'converts the keys to camle case' do
138
+ expect(hash.lower_camelize_keys!(recursive: false)).to eq(expected)
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ describe :camelize_keys do
145
+ let(:expected) { { InputKey: 'value' } }
146
+
147
+ context 'with underscore keys' do
148
+ let(:hash) { { input_key: 'value' } }
149
+
150
+ it 'converts the keys to camel case' do
151
+ expect(hash.camelize_keys).to eq(expected)
152
+ end
153
+
154
+ it 'does not change original hash' do
155
+ expect { hash.camelize_keys }.not_to change { hash }
156
+ end
157
+ end
158
+
159
+ context 'with lower camel case keys' do
160
+ let(:hash) { { inputKey: 'value' } }
161
+
162
+ it 'converts the keys to camle case' do
163
+ expect(hash.camelize_keys).to eq(expected)
164
+ end
165
+ end
166
+
167
+ context 'with string keys' do
168
+ let(:expected) { { 'InputKey' => 'value' } }
169
+ let(:hash) { { 'inputKey' => 'value' } }
170
+
171
+ it 'converts the keys to lower camel case' do
172
+ expect(hash.camelize_keys).to eq(expected)
173
+ end
174
+ end
175
+
176
+ context 'with deep keys change' do
177
+ let(:expected) { { InputKey: { InnerKey: 'value' } } }
178
+ let(:hash) { { inputKey: { innerKey: 'value' } } }
179
+
180
+ it 'converts the keys to camle case' do
181
+ expect(hash.camelize_keys).to eq(expected)
182
+ end
183
+ end
184
+
185
+ context 'with array keys change' do
186
+ let(:expected) { { InputKey: [{ InnerKey: 'value' }] } }
187
+ let(:hash) { { inputKey: [{ innerKey: 'value' }] } }
188
+
189
+ it 'converts the keys to camle case' do
190
+ expect(hash.camelize_keys).to eq(expected)
191
+ end
192
+ end
193
+
194
+ context 'without recursive options' do
195
+ context 'with deep keys change' do
196
+ let(:expected) { { InputKey: { InnerKey: 'value' } } }
197
+ let(:hash) { { inputKey: { InnerKey: 'value' } } }
198
+
199
+ it 'converts the keys to lower camel case' do
200
+ expect(hash.camelize_keys(recursive: false)).to eq(expected)
201
+ end
202
+ end
203
+
204
+ context 'with array keys change' do
205
+ let(:expected) { { InputKey: [{ InnerKey: 'value' }] } }
206
+ let(:hash) { { inputKey: [{ InnerKey: 'value' }] } }
207
+
208
+ it 'converts the keys to camle case' do
209
+ expect(hash.camelize_keys(recursive: false)).to eq(expected)
210
+ end
211
+ end
212
+ end
213
+ end
214
+
215
+ describe :camelize_keys! do
216
+ let(:expected) { { InputKey: 'value' } }
217
+
218
+ context 'with underscore keys' do
219
+ let(:hash) { { input_key: 'value' } }
220
+
221
+ it 'converts the keys to camel case' do
222
+ expect(hash.camelize_keys!).to eq(expected)
223
+ end
224
+
225
+ it 'does not change original hash' do
226
+ expect { hash.camelize_keys! }.to change { hash }
227
+ end
228
+ end
229
+
230
+ context 'with lower camel case keys' do
231
+ let(:hash) { { inputKey: 'value' } }
232
+
233
+ it 'converts the keys to camle case' do
234
+ expect(hash.camelize_keys!).to eq(expected)
235
+ end
236
+ end
237
+
238
+ context 'with string keys' do
239
+ let(:expected) { { 'InputKey' => 'value' } }
240
+ let(:hash) { { 'inputKey' => 'value' } }
241
+
242
+ it 'converts the keys to lower camel case' do
243
+ expect(hash.camelize_keys!).to eq(expected)
244
+ end
245
+ end
246
+
247
+ context 'with deep keys change' do
248
+ let(:expected) { { InputKey: { InnerKey: 'value' } } }
249
+ let(:hash) { { inputKey: { innerKey: 'value' } } }
250
+
251
+ it 'converts the keys to camle case' do
252
+ expect(hash.camelize_keys!).to eq(expected)
253
+ end
254
+ end
255
+
256
+ context 'with array keys change' do
257
+ let(:expected) { { InputKey: [{ InnerKey: 'value' }] } }
258
+ let(:hash) { { inputKey: [{ innerKey: 'value' }] } }
259
+
260
+ it 'converts the keys to camle case' do
261
+ expect(hash.camelize_keys!).to eq(expected)
262
+ end
263
+ end
264
+
265
+ context 'without recursive options' do
266
+ context 'with deep keys change' do
267
+ let(:expected) { { InputKey: { InnerKey: 'value' } } }
268
+ let(:hash) { { inputKey: { InnerKey: 'value' } } }
269
+
270
+ it 'converts the keys to lower camel case' do
271
+ expect(hash.camelize_keys!(recursive: false)).to eq(expected)
272
+ end
273
+ end
274
+
275
+ context 'with array keys change' do
276
+ let(:hash) { { inputKey: [{ InnerKey: 'value' }] } }
277
+ let(:expected) { { InputKey: [{ InnerKey: 'value' }] } }
278
+
279
+ it 'converts the keys to camle case' do
280
+ expect(hash.camelize_keys!(recursive: false)).to eq(expected)
281
+ end
282
+ end
283
+ end
284
+ end
285
+ end
@@ -0,0 +1,82 @@
1
+ shared_examples 'a class with underscore_keys method basic' do |method|
2
+ describe :underscore_keys do
3
+ let(:expected) { { input_key: 'value' } }
4
+
5
+ context 'with camel case keys' do
6
+ let(:hash) { { inputKey: 'value' } }
7
+
8
+ it 'converts the keys to snake case' do
9
+ expect(hash.send(method)).to eq(expected)
10
+ end
11
+ end
12
+
13
+ context 'with string keys' do
14
+ let(:expected) { { 'input_key' => 'value' } }
15
+ let(:hash) { { 'InputKey' => 'value' } }
16
+
17
+ it 'converts the keys to snake case' do
18
+ expect(hash.send(method)).to eq(expected)
19
+ end
20
+ end
21
+
22
+ context 'with deep keys change' do
23
+ let(:expected) { { input_key: { inner_key: 'value' } } }
24
+ let(:hash) { { InputKey: { InnerKey: 'value' } } }
25
+
26
+ it 'converts the keys to snake case' do
27
+ expect(hash.send(method)).to eq(expected)
28
+ end
29
+ end
30
+
31
+ context 'with array keys change' do
32
+ let(:expected) { { input_key: [{ inner_key: 'value' }] } }
33
+ let(:hash) { { InputKey: [{ InnerKey: 'value' }] } }
34
+
35
+ it 'converts the keys to snake case' do
36
+ expect(hash.send(method)).to eq(expected)
37
+ end
38
+ end
39
+
40
+ context 'without recursive options' do
41
+ context 'with deep keys change' do
42
+ let(:expected) { { input_key: { InnerKey: 'value' } } }
43
+ let(:hash) { { InputKey: { InnerKey: 'value' } } }
44
+
45
+ it 'converts the keys to lower camel case' do
46
+ expect(hash.send(method, recursive: false)).to eq(expected)
47
+ end
48
+ end
49
+
50
+ context 'with array keys change' do
51
+ let(:expected) { { input_key: [{ InnerKey: 'value' }] } }
52
+ let(:hash) { { InputKey: [{ InnerKey: 'value' }] } }
53
+
54
+ it 'converts the keys to camle case' do
55
+ expect(hash.send(method, recursive: false)).to eq(expected)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ shared_examples 'a class with underscore_keys! method' do
63
+ let(:hash) { { inputKey: 'value' } }
64
+
65
+ it_behaves_like 'a class with underscore_keys method basic', :underscore_keys!
66
+
67
+ it 'changes original hash' do
68
+ expect { hash.underscore_keys! }.to change { hash }
69
+ end
70
+ end
71
+
72
+ shared_examples 'a class with underscore_keys method' do
73
+ let(:hash) { { inputKey: 'value' } }
74
+
75
+ it_behaves_like 'a class with underscore_keys method basic', :underscore_keys
76
+ it_behaves_like 'a class with underscore_keys! method'
77
+
78
+ it 'does not change original hash' do
79
+ expect { hash.underscore_keys }.not_to change { hash }
80
+ end
81
+ end
82
+