darthjee-core_ext 1.7.3 → 1.7.4

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +19 -8
  3. data/.gitignore +1 -0
  4. data/.rubocop.yml +7 -0
  5. data/.rubocop_todo.yml +7 -3
  6. data/Dockerfile +9 -0
  7. data/README.md +5 -6
  8. data/Rakefile +2 -0
  9. data/config/yardstick.rb +13 -0
  10. data/config/yardstick.yml +35 -0
  11. data/core_ext.gemspec +9 -7
  12. data/docker-compose.yml +3 -6
  13. data/lib/darthjee/core_ext/array.rb +2 -2
  14. data/lib/darthjee/core_ext/class.rb +90 -4
  15. data/lib/darthjee/core_ext/enumerable.rb +5 -1
  16. data/lib/darthjee/core_ext/hash.rb +30 -0
  17. data/lib/darthjee/core_ext/hash/cameliazable.rb +91 -0
  18. data/lib/darthjee/core_ext/hash/chain_fetcher.rb +10 -0
  19. data/lib/darthjee/core_ext/hash/key_changeable.rb +85 -53
  20. data/lib/darthjee/core_ext/hash/key_changer.rb +41 -31
  21. data/lib/darthjee/core_ext/hash/value_changer.rb +128 -11
  22. data/lib/darthjee/core_ext/version.rb +1 -1
  23. data/spec/integration/yard/{array → darthjee/core_ext/array}/hash_builder_spec.rb +3 -3
  24. data/spec/integration/yard/{array_spec.rb → darthjee/core_ext/array_spec.rb} +0 -0
  25. data/spec/integration/yard/darthjee/core_ext/class/default_value_spec.rb +143 -0
  26. data/spec/integration/yard/{date → darthjee/core_ext/date}/days_between_spec.rb +6 -6
  27. data/spec/integration/yard/{enumerable_spec.rb → darthjee/core_ext/enumerable_spec.rb} +0 -0
  28. data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +34 -0
  29. data/spec/integration/yard/darthjee/core_ext/hash/chain_fetcher_spec.rb +51 -0
  30. data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +48 -0
  31. data/spec/integration/yard/{hash → darthjee/core_ext/hash}/transformable_spec.rb +7 -3
  32. data/spec/integration/yard/darthjee/core_ext/hash/value_changer_spec.rb +66 -0
  33. data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +42 -0
  34. data/spec/lib/array_spec.rb +27 -17
  35. data/spec/lib/class_spec.rb +108 -7
  36. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +1 -1
  37. data/spec/lib/darthjee/core_ext/hash/key_changer_spec.rb +8 -8
  38. data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +1 -0
  39. data/spec/lib/darthjee/core_ext/hash/to_hash_mapper_spec.rb +1 -0
  40. data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +246 -0
  41. data/spec/lib/date_spec.rb +5 -4
  42. data/spec/lib/hash_spec.rb +45 -32
  43. data/spec/lib/math_spec.rb +1 -0
  44. data/spec/lib/numeric_spec.rb +39 -17
  45. data/spec/lib/object_spec.rb +7 -7
  46. data/spec/lib/symbol_spec.rb +2 -2
  47. data/spec/lib/time_spec.rb +5 -4
  48. data/spec/support/models/default_reader_model.rb +8 -0
  49. data/spec/support/models/default_value_model.rb +2 -0
  50. data/spec/support/models/dummy_iterator.rb +15 -0
  51. data/spec/support/models/dummy_transformer.rb +15 -0
  52. data/spec/support/shared_examples/array/array_random.rb +2 -1
  53. data/spec/support/shared_examples/clean.rb +20 -20
  54. data/spec/support/shared_examples/date.rb +18 -13
  55. data/spec/support/shared_examples/hash/chain_fetch.rb +4 -3
  56. data/spec/support/shared_examples/hash/chain_hash_keys_changer.rb +14 -7
  57. data/spec/support/shared_examples/hash/hash_keys_changer.rb +10 -4
  58. data/spec/support/shared_examples/hash/hash_transpose.rb +1 -1
  59. data/spec/support/shared_examples/hash/keys_appender.rb +14 -4
  60. data/spec/support/shared_examples/hash/keys_camelizer.rb +7 -7
  61. data/spec/support/shared_examples/hash/keys_sorter.rb +3 -3
  62. data/spec/support/shared_examples/hash/keys_underscorer.rb +2 -2
  63. data/spec/support/shared_examples/hash/map_to_hash.rb +14 -12
  64. data/spec/support/shared_examples/hash/remap.rb +4 -4
  65. data/spec/support/shared_examples/hash/value_changer.rb +40 -33
  66. metadata +70 -20
  67. data/spec/integration/yard/class/default_value_spec.rb +0 -58
@@ -3,10 +3,11 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Date do
6
- let(:year) { 2018 }
7
- let(:month) { 10 }
8
- let(:day) { 4 }
9
- let(:subject) { Date.new(year, month, day) }
6
+ subject(:date) { described_class.new(year, month, day) }
7
+
8
+ let(:year) { 2018 }
9
+ let(:month) { 10 }
10
+ let(:day) { 4 }
10
11
 
11
12
  describe '#days_between' do
12
13
  it_behaves_like 'an object that knows how to calculate days between'
@@ -28,34 +28,36 @@ describe Hash do
28
28
  let(:result) { hash.sort_keys(**options) }
29
29
  end
30
30
 
31
- describe :exclusive_merge do
32
- let(:subject) { { a: 1, b: 2 } }
31
+ describe '#exclusive_merge' do
32
+ subject(:hash) { { a: 1, b: 2 } }
33
+
33
34
  let(:other) { { b: 3, c: 4 } }
34
35
 
35
36
  it 'merge only the common keys' do
36
- expect(subject.exclusive_merge(other)).to eq(a: 1, b: 3)
37
+ expect(hash.exclusive_merge(other)).to eq(a: 1, b: 3)
37
38
  end
38
39
 
39
40
  it 'does not change the original hash' do
40
- expect { subject.exclusive_merge(other) }.not_to(change { subject })
41
+ expect { hash.exclusive_merge(other) }.not_to(change { hash })
41
42
  end
42
43
  end
43
44
 
44
- describe :exclusive_merge! do
45
- let(:subject) { { a: 1, b: 2 } }
45
+ describe '#exclusive_merge!' do
46
+ subject(:hash) { { a: 1, b: 2 } }
47
+
46
48
  let(:other) { { b: 3, c: 4 } }
47
49
 
48
50
  it 'merge only the common keys' do
49
- expect(subject.exclusive_merge!(other)).to eq(a: 1, b: 3)
51
+ expect(hash.exclusive_merge!(other)).to eq(a: 1, b: 3)
50
52
  end
51
53
 
52
54
  it 'does not change the original hash' do
53
- expect { subject.exclusive_merge!(other) }.to(change { subject })
55
+ expect { hash.exclusive_merge!(other) }.to(change { hash })
54
56
  end
55
57
  end
56
58
 
57
- describe :to_deep_hash do
58
- let(:subject) do
59
+ describe '#to_deep_hash' do
60
+ subject(:hash) do
59
61
  {
60
62
  'person.name' => 'Some name',
61
63
  'person.age' => 22,
@@ -74,11 +76,11 @@ describe Hash do
74
76
  end
75
77
 
76
78
  it 'build a deep hash' do
77
- expect(subject.to_deep_hash).to eq(expected)
79
+ expect(hash.to_deep_hash).to eq(expected)
78
80
  end
79
81
 
80
82
  context 'with indexed keys' do
81
- let(:subject) do
83
+ subject(:hash) do
82
84
  {
83
85
  'person[0].name' => 'First person',
84
86
  'person[0].age' => 22,
@@ -102,12 +104,12 @@ describe Hash do
102
104
  end
103
105
 
104
106
  it 'build a deep hash with arrays' do
105
- expect(subject.to_deep_hash).to eq(expected)
107
+ expect(hash.to_deep_hash).to eq(expected)
106
108
  end
107
109
  end
108
110
 
109
111
  context 'with a n level hash' do
110
- let(:subject) do
112
+ subject(:hash) do
111
113
  {
112
114
  'quote_request.personal.person.name' => 'Some name',
113
115
  'quote_request.personal.person.age' => 22,
@@ -134,12 +136,12 @@ describe Hash do
134
136
  end
135
137
 
136
138
  it 'build a deep hash with arrays' do
137
- expect(subject.to_deep_hash).to eq(expected)
139
+ expect(hash.to_deep_hash).to eq(expected)
138
140
  end
139
141
  end
140
142
 
141
143
  context 'with a n level hash and arrays' do
142
- let(:subject) do
144
+ subject(:hash) do
143
145
  {
144
146
  'quote_request.personal.person[0].name' => 'Some name 1',
145
147
  'quote_request.personal.person[0].age' => 22,
@@ -172,12 +174,12 @@ describe Hash do
172
174
  end
173
175
 
174
176
  it 'build a deep hash with arrays' do
175
- expect(subject.to_deep_hash).to eq(expected)
177
+ expect(hash.to_deep_hash).to eq(expected)
176
178
  end
177
179
  end
178
180
 
179
181
  context 'with custom separator' do
180
- let(:subject) do
182
+ subject(:hash) do
181
183
  {
182
184
  'person_name' => 'Some name',
183
185
  'person_age' => 22,
@@ -188,12 +190,12 @@ describe Hash do
188
190
  end
189
191
 
190
192
  it 'build a deep hash with arrays' do
191
- expect(subject.to_deep_hash('_')).to eq(expected)
193
+ expect(hash.to_deep_hash('_')).to eq(expected)
192
194
  end
193
195
  end
194
196
 
195
197
  context 'with custom separator on n level deep hash' do
196
- let(:subject) do
198
+ subject(:hash) do
197
199
  {
198
200
  'person_name_clazz' => String
199
201
  }
@@ -208,22 +210,24 @@ describe Hash do
208
210
  end
209
211
 
210
212
  it 'build a deep hash with arrays' do
211
- expect(subject.to_deep_hash('_')).to eq(expected)
213
+ expect(hash.to_deep_hash('_')).to eq(expected)
212
214
  end
213
215
  end
214
216
  end
215
217
 
216
218
  describe '#map_and_find' do
217
- let(:hash) { { a: 1, b: 2, c: 3, d: 4 } }
219
+ let(:hash) { { a: 1, b: 2, c: 3, d: 4 } }
218
220
  let(:value) { hash.map_and_find(&block) }
219
221
 
220
222
  context 'when block returns nil' do
221
223
  let(:block) { proc {} }
224
+
222
225
  it { expect(value).to be_nil }
223
226
  end
224
227
 
225
228
  context 'when block returns false' do
226
229
  let(:block) { proc { false } }
230
+
227
231
  it { expect(value).to be_nil }
228
232
  end
229
233
 
@@ -238,18 +242,22 @@ describe Hash do
238
242
  it { expect(value).to eq(:b) }
239
243
  end
240
244
 
241
- context 'but not for the first value' do
242
- let(:transformer) { double(:transformer) }
245
+ context 'when first value returns nothing' do
243
246
  let(:block) { proc { |_, v| transformer.transform(v) } }
244
247
 
245
- before do
246
- allow(transformer).to receive(:transform) do |v|
247
- v.to_s if v > 1
248
+ let(:transformer) do
249
+ DummyTransformer.new do |value|
250
+ value.to_s if value > 1
248
251
  end
252
+ end
253
+
254
+ before do
255
+ allow(transformer).to receive(:transform).and_call_original
249
256
  value
250
257
  end
251
258
 
252
259
  it { expect(value).to eq('2') }
260
+
253
261
  it 'calls the mapping only until it returns a valid value' do
254
262
  expect(transformer).to have_received(:transform).exactly(2)
255
263
  end
@@ -271,11 +279,13 @@ describe Hash do
271
279
 
272
280
  context 'when block returns nil' do
273
281
  let(:block) { proc {} }
282
+
274
283
  it { expect(list).to be_empty }
275
284
  end
276
285
 
277
286
  context 'when block returns false' do
278
287
  let(:block) { proc { false } }
288
+
279
289
  it { expect(list).to be_empty }
280
290
  end
281
291
 
@@ -290,14 +300,17 @@ describe Hash do
290
300
  it { expect(list).to eq(%i[b c d]) }
291
301
  end
292
302
 
293
- context 'but not for the first value' do
294
- let(:transformer) { double(:transformer) }
303
+ context 'when first value does not return a value' do
295
304
  let(:block) { proc { |_, v| transformer.transform(v) } }
296
305
 
297
- before do
298
- allow(transformer).to receive(:transform) do |v|
299
- v.to_s if v > 1
306
+ let(:transformer) do
307
+ DummyTransformer.new do |value|
308
+ value.to_s if value > 1
300
309
  end
310
+ end
311
+
312
+ before do
313
+ allow(transformer).to receive(:transform).and_call_original
301
314
  list
302
315
  end
303
316
 
@@ -13,6 +13,7 @@ describe Math do
13
13
 
14
14
  context 'when average is not a round number' do
15
15
  let(:values) { [0, 1, 2, 3] }
16
+
16
17
  it 'returns the average' do
17
18
  expect(described_class.average(values)).to eq(1.5)
18
19
  end
@@ -7,38 +7,60 @@ describe Numeric do
7
7
  context 'when number is float' do
8
8
  let(:number) { 120.0 }
9
9
 
10
- it 'converts to percentage of number' do
11
- expect(number.percent_of(240)).to eq(50)
10
+ context 'when total is bigger than number' do
11
+ it 'converts to percentage of number' do
12
+ expect(number.percent_of(240)).to eq(50)
13
+ end
12
14
  end
13
15
 
14
- it 'converts to percentage of number' do
15
- expect(number.percent_of(60)).to eq(200)
16
+ context 'when total is smaller than number' do
17
+ it 'converts to percentage of number' do
18
+ expect(number.percent_of(60)).to eq(200)
19
+ end
16
20
  end
17
21
 
18
- it 'do not raise an error when divisor is 0' do
19
- expect(100.0.percent_of(0)).to eq(Float::INFINITY)
22
+ context 'when total is equal number' do
23
+ it 'converts to percentage of number' do
24
+ expect(number.percent_of(number)).to eq(100)
25
+ end
20
26
  end
21
27
 
22
- it 'do not raise an error when divisor is 0.0' do
23
- expect(100.0.percent_of(0.0)).to eq(Float::INFINITY)
28
+ context 'when divisor is 0' do
29
+ it 'do not raise an error' do
30
+ expect(100.0.percent_of(0)).to eq(Float::INFINITY)
31
+ end
32
+ end
33
+
34
+ context 'when divisor is 0.0' do
35
+ it 'do not raise an error when divisor is 0.0' do
36
+ expect(100.0.percent_of(0.0)).to eq(Float::INFINITY)
37
+ end
24
38
  end
25
39
  end
26
40
 
27
41
  context 'when number is integer' do
28
- it 'converts to percentage of number' do
29
- expect(500.percent_of(50)).to eq(1000)
42
+ context 'when number is bigger than total' do
43
+ it 'converts to percentage of number' do
44
+ expect(500.percent_of(50)).to eq(1000)
45
+ end
30
46
  end
31
47
 
32
- it 'converts to percentage of number' do
33
- expect(0.percent_of(50)).to eq(0)
48
+ context 'when number is 0' do
49
+ it 'converts to percentage of number' do
50
+ expect(0.percent_of(50)).to eq(0)
51
+ end
34
52
  end
35
53
 
36
- it 'converts to percentage of number' do
37
- expect(10.percent_of(100)).to eq(10)
54
+ context 'when number is smaller than total' do
55
+ it 'converts to percentage of number' do
56
+ expect(10.percent_of(100)).to eq(10)
57
+ end
38
58
  end
39
59
 
40
- it 'do not raise an error when divisor is 0' do
41
- expect(100.percent_of(0)).to eq(Float::INFINITY)
60
+ context 'when total is 0' do
61
+ it 'do not raise an error' do
62
+ expect(100.percent_of(0)).to eq(Float::INFINITY)
63
+ end
42
64
  end
43
65
  end
44
66
 
@@ -51,7 +73,7 @@ describe Numeric do
51
73
  it { expect(100.percent_of(0)).to eq(Float::INFINITY) }
52
74
  end
53
75
 
54
- context 'both are 0' do
76
+ context 'when both are 0' do
55
77
  it { expect(0.percent_of(0)).to eq(Float::INFINITY) }
56
78
  end
57
79
  end
@@ -4,33 +4,33 @@ require 'spec_helper'
4
4
 
5
5
  describe Object do
6
6
  describe '#is_any?' do
7
- subject { 1 }
7
+ subject(:object) { 1 }
8
8
 
9
9
  it do
10
- expect(subject).to respond_to(:is_any?)
10
+ expect(object).to respond_to(:is_any?)
11
11
  end
12
12
 
13
13
  context 'when no argument is passed' do
14
14
  it do
15
- expect(subject.is_any?).to be_falsey
15
+ expect(object).not_to be_is_any
16
16
  end
17
17
  end
18
18
 
19
19
  context 'when passing the correct class as argument' do
20
20
  it do
21
- expect(subject.is_any?(subject.class)).to be_truthy
21
+ expect(object).to be_is_any(object.class)
22
22
  end
23
23
 
24
- context 'along any other class' do
24
+ context 'when passing any other class' do
25
25
  it do
26
- expect(subject.is_any?(Symbol, subject.class)).to be_truthy
26
+ expect(object).to be_is_any(Symbol, object.class)
27
27
  end
28
28
  end
29
29
  end
30
30
 
31
31
  context 'when passing the wrong class' do
32
32
  it do
33
- expect(subject.is_any?(Symbol)).to be_falsey
33
+ expect(object).not_to be_is_any(Symbol)
34
34
  end
35
35
  end
36
36
  end
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  describe Symbol do
6
6
  describe '#camelize' do
7
- it { expect(:sym.camelize).to be_kind_of(Symbol) }
7
+ it { expect(:sym.camelize).to be_kind_of(described_class) }
8
8
 
9
9
  context 'when called with upper option' do
10
10
  it 'camelize the symbol' do
@@ -26,7 +26,7 @@ describe Symbol do
26
26
  end
27
27
 
28
28
  describe '#underscore' do
29
- it { expect(:symBol.underscore).to be_kind_of(Symbol) }
29
+ it { expect(:symBol.underscore).to be_kind_of(described_class) }
30
30
 
31
31
  context 'when called with upper option' do
32
32
  it 'underscore the symbol' do
@@ -3,10 +3,11 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Time do
6
- let(:year) { 2018 }
7
- let(:month) { 10 }
8
- let(:day) { 4 }
9
- let(:subject) { Time.new(year, month, day, 10, 0, 0) }
6
+ subject(:date) { described_class.new(year, month, day, 10, 0, 0) }
7
+
8
+ let(:year) { 2018 }
9
+ let(:month) { 10 }
10
+ let(:day) { 4 }
10
11
 
11
12
  describe '#days_between' do
12
13
  it_behaves_like 'an object that knows how to calculate days between'
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DefaultReaderModel
4
+ attr_writer :name, :cars
5
+
6
+ default_reader :name, 'John'
7
+ default_readers :cars, :houses, 2
8
+ end
@@ -3,4 +3,6 @@
3
3
  class DefaultValueModel
4
4
  default_value :x, 10
5
5
  default_values :y, :z, 20
6
+ default_value :array, [10, 20]
7
+ default_values :hash, :json, a: 1
6
8
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DummyIterator
4
+ def initialize(array)
5
+ @array = array
6
+ end
7
+
8
+ def map(*args, &block)
9
+ @array.map(*args, &block)
10
+ end
11
+
12
+ def each(*args, &block)
13
+ @array.each(*args, &block)
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DummyTransformer
4
+ def initialize(&block)
5
+ @block = block
6
+ end
7
+
8
+ def transform(value)
9
+ block.call(value)
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :block
15
+ end
@@ -6,8 +6,9 @@ shared_examples 'a method that returns a random element' do |method|
6
6
  (0..2).each do |index|
7
7
  context "when random returns #{index}" do
8
8
  let!(:expected) { array[index] }
9
+
9
10
  before do
10
- allow_any_instance_of(Array).to receive(:rand)
11
+ allow(Random).to receive(:rand)
11
12
  .with(array.size) { index }
12
13
  end
13
14