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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Darthjee
4
4
  module CoreExt
5
- VERSION = '1.7.3'
5
+ VERSION = '1.7.4'
6
6
  end
7
7
  end
@@ -5,13 +5,13 @@ require 'spec_helper'
5
5
  describe Darthjee::CoreExt::Array::HashBuilder do
6
6
  describe 'yard' do
7
7
  describe '#build' do
8
- subject { described_class.new(values, keys) }
8
+ subject(:builder) { described_class.new(values, keys) }
9
9
 
10
10
  let(:values) { [10, 20, 30] }
11
11
  let(:keys) { %i[a b c] }
12
12
 
13
13
  it 'builds a hash pairing the keys and values' do
14
- expect(subject.build).to eq(
14
+ expect(builder.build).to eq(
15
15
  a: 10, b: 20, c: 30
16
16
  )
17
17
  end
@@ -22,7 +22,7 @@ describe Darthjee::CoreExt::Array::HashBuilder do
22
22
  let(:keys) { hash.keys }
23
23
 
24
24
  it 'rebuilds the original hash' do
25
- expect(subject.build).to eq(hash)
25
+ expect(builder.build).to eq(hash)
26
26
  end
27
27
  end
28
28
  end
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Class do
6
+ describe 'yard' do
7
+ subject(:instance) { klass.new }
8
+
9
+ describe '#default_value' do
10
+ let(:klass) do
11
+ Class.new do
12
+ default_value :name, 'John'
13
+ end
14
+ end
15
+
16
+ context 'when calling method' do
17
+ it 'returns the same value always' do
18
+ expect(instance.name).to eq('John')
19
+ end
20
+
21
+ it 'returns the same instance accros instances of the class' do
22
+ expect(instance.name).not_to be_equal('John')
23
+ expect(instance.name).to be_equal(klass.new.name)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '#default_values' do
29
+ let(:klass) do
30
+ Class.new do
31
+ default_values :name, :nick_name, 'John'
32
+ end
33
+ end
34
+
35
+ context 'when calling method' do
36
+ it 'returns the same value always for first method' do
37
+ expect(instance.name).to eq('John')
38
+ end
39
+
40
+ it 'returns the same value always for second method' do
41
+ expect(instance.nick_name).to eq('John')
42
+ end
43
+
44
+ it 'returns the same instance accros instances of the class' do
45
+ expect(instance.name).not_to be_equal('John')
46
+ expect(instance.name).to be_equal(klass.new.name)
47
+ end
48
+
49
+ it 'returns the same instance for all methods' do
50
+ expect(instance.nick_name).not_to be_equal('John')
51
+ expect(instance.name).to be_equal(instance.nick_name)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe '#default_reader' do
57
+ let(:klass) do
58
+ Class.new do
59
+ attr_writer :name
60
+ default_reader :name, 'John Doe'
61
+ end
62
+ end
63
+
64
+ context 'when calling method' do
65
+ it 'returns the default value' do
66
+ expect(instance.name).to eq('John Doe')
67
+ end
68
+
69
+ context 'when setting the variable' do
70
+ before { instance.name = 'Joe' }
71
+
72
+ it 'returns the new value' do
73
+ expect(instance.name).to eq('Joe')
74
+ end
75
+ end
76
+
77
+ context 'when setting the variable to be nil' do
78
+ before { instance.name = nil }
79
+
80
+ it 'returns nil' do
81
+ expect(instance.name).to be_nil
82
+ end
83
+ end
84
+
85
+ context 'when setting a variable in one instance' do
86
+ before { klass.new.name = 'Bob' }
87
+
88
+ it 'does not change the value in the other' do
89
+ expect(instance.name).to eq('John Doe')
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '.default_readers' do
96
+ let(:klass) do
97
+ Class.new do
98
+ attr_writer :cars, :houses
99
+ default_readers :cars, :houses, 'none'
100
+ end
101
+ end
102
+
103
+ context 'when calling first method' do
104
+ it 'returns the default value' do
105
+ expect(instance.cars).to eq('none')
106
+ end
107
+
108
+ context 'when setting the variable' do
109
+ before { instance.cars = ['volvo'] }
110
+
111
+ it 'returns the new value' do
112
+ expect(instance.cars).to eq(['volvo'])
113
+ end
114
+
115
+ it 'does not change the value of the second method' do
116
+ expect(instance.houses).to eq('none')
117
+ end
118
+ end
119
+
120
+ context 'when setting the variable to be nil' do
121
+ before { instance.cars = nil }
122
+
123
+ it 'returns nil' do
124
+ expect(instance.cars).to be_nil
125
+ end
126
+ end
127
+
128
+ context 'when setting a variable in one instance' do
129
+ before { klass.new.cars = ['volvo'] }
130
+
131
+ it 'does not change the value in the other' do
132
+ expect(instance.cars).to eq('none')
133
+ end
134
+ end
135
+
136
+ it 'returns the same instance for all methods' do
137
+ expect(instance.cars).not_to be_equal('none')
138
+ expect(instance.cars).to be_equal(instance.houses)
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -5,21 +5,21 @@ require 'spec_helper'
5
5
  describe Date do
6
6
  describe 'yard' do
7
7
  describe '#days_between' do
8
- subject { Date.new(2018, 11, 21) }
8
+ subject(:date) { described_class.new(2018, 11, 21) }
9
9
 
10
10
  context 'when checking against another date' do
11
- let(:other_date) { Date.new(2019, 11, 21) }
11
+ let(:other_date) { described_class.new(2019, 11, 21) }
12
12
 
13
13
  it 'returns the days between' do
14
- expect(subject.days_between(other_date)).to eq(365)
14
+ expect(date.days_between(other_date)).to eq(365)
15
15
  end
16
16
  end
17
17
 
18
18
  context 'when cheking agains a 4 years apart date' do
19
- let(:other_date) { Date.new(2014, 11, 21) }
19
+ let(:other_date) { described_class.new(2014, 11, 21) }
20
20
 
21
21
  it 'returns the days between' do
22
- expect(subject.days_between(other_date)).to eq(1461)
22
+ expect(date.days_between(other_date)).to eq(1461)
23
23
  end
24
24
  end
25
25
 
@@ -27,7 +27,7 @@ describe Date do
27
27
  let(:time) { Time.new(2017, 11, 21, 12, 0, 0) }
28
28
 
29
29
  it 'ignores the hours' do
30
- expect(subject.days_between(time)).to eq(365)
30
+ expect(date.days_between(time)).to eq(365)
31
31
  end
32
32
  end
33
33
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Darthjee::CoreExt::Hash::Cameliazable do
4
+ describe 'camlize_keys' do
5
+ subject(:hash) do
6
+ { first_key: 1, 'second_key' => 2 }
7
+ end
8
+
9
+ context 'when no option is given' do
10
+ it 'camelize all keys' do
11
+ result = hash.camelize_keys
12
+ expect(result).to eq(FirstKey: 1, 'SecondKey' => 2)
13
+ end
14
+ end
15
+
16
+ context 'when passing uppercase_first_letter option' do
17
+ it 'camelize all keys' do
18
+ result = hash.camelize_keys(uppercase_first_letter: false)
19
+ expect(result).to eq(firstKey: 1, 'secondKey' => 2)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe '#lower_camelize_keys' do
25
+ subject(:hash) do
26
+ { first_key: 1, 'second_key' => 2 }
27
+ end
28
+
29
+ it 'camelize all keys' do
30
+ result = hash.lower_camelize_keys
31
+ expect(result).to eq(firstKey: 1, 'secondKey' => 2)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Darthjee::CoreExt::Hash::ChainFetcher do
4
+ let(:hash) do
5
+ {
6
+ a: {
7
+ b: { c: 1, d: 2 }
8
+ }
9
+ }
10
+ end
11
+
12
+ context 'when not giving a block' do
13
+ subject(:fetcher) do
14
+ described_class.new(hash, *keys)
15
+ end
16
+
17
+ context 'when keys are found' do
18
+ let(:keys) { %i[a b c] }
19
+
20
+ it 'returns the value found' do
21
+ expect(fetcher.fetch).to eq(1)
22
+ end
23
+ end
24
+
25
+ context 'when key is not found' do
26
+ let(:keys) { %i[a c d] }
27
+
28
+ it do
29
+ expect { fetcher.fetch }.to raise_error(KeyError)
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'when giving a block' do
35
+ subject(:fetcher) do
36
+ described_class.new(hash, *keys) { |*args| args }
37
+ end
38
+
39
+ context 'when keys are not found' do
40
+ let(:keys) { %i[a c d] }
41
+
42
+ it do
43
+ expect { fetcher.fetch }.not_to raise_error
44
+ end
45
+
46
+ it 'returns the result of the block' do
47
+ expect(fetcher.fetch).to eq([:c, [:d]])
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Darthjee::CoreExt::Hash::KeyChangeable do
4
+ describe '#remap_keys' do
5
+ subject(:hash) { { a: 1, b: 2 } }
6
+
7
+ it 'remaps the keys' do
8
+ expect(hash.remap_keys(a: :b, b: :c)).to eq(b: 1, c: 2)
9
+ end
10
+ end
11
+
12
+ describe '#change_keys' do
13
+ subject(:hash) { { '1' => 1, '2' => { '3' => 2 } } }
14
+
15
+ context 'when not passing options' do
16
+ let(:result) do
17
+ hash.change_keys do |k|
18
+ (k.to_i + 1).to_s.to_sym
19
+ end
20
+ end
21
+
22
+ it 'uses the block to change the keys' do
23
+ expect(result).to eq('2': 1, '3': { '4': 2 })
24
+ end
25
+ end
26
+
27
+ context 'when passing recursive option' do
28
+ let(:result) do
29
+ hash.change_keys(recursive: false) do |k|
30
+ (k.to_i + 1).to_s.to_sym
31
+ end
32
+ end
33
+
34
+ it 'uses the block to change the keys' do
35
+ expect(result).to eq('2': 1, '3': { '3' => 2 })
36
+ end
37
+ end
38
+ end
39
+
40
+ describe '#chain_change_keys' do
41
+ subject(:hash) { { first: 1, second: 2 } }
42
+
43
+ it 'uses the block to change the keys' do
44
+ result = hash.chain_change_keys(:to_s, :size, :to_s, :to_sym)
45
+ expect(result).to eq('5': 1, '6': 2)
46
+ end
47
+ end
48
+ end
@@ -6,6 +6,7 @@ describe Hash do
6
6
  describe 'yard' do
7
7
  describe '#exclusive_merge' do
8
8
  subject(:hash) { { a: 1, b: 2, c: 3 } }
9
+
9
10
  let(:other) { { b: 4, 'c' => 5, e: 6 } }
10
11
 
11
12
  it 'merges only the existing keys' do
@@ -21,6 +22,7 @@ describe Hash do
21
22
 
22
23
  describe '#exclusive_merge' do
23
24
  subject(:hash) { { a: 1, b: 2, c: 3 } }
25
+
24
26
  let(:other) { { b: 4, 'c' => 5, e: 6 } }
25
27
 
26
28
  it 'merges only the existing keys' do
@@ -38,11 +40,13 @@ describe Hash do
38
40
  describe '#map_to_hash' do
39
41
  subject(:hash) { { a: 'word', b: 'bigword', c: 'c' } }
40
42
 
41
- it 'remaps the values keeping the original keys' do
42
- new_hash = hash.map_to_hash do |key, value|
43
+ let(:new_hash) do
44
+ hash.map_to_hash do |key, value|
43
45
  "#{key}->#{value.size}"
44
46
  end
47
+ end
45
48
 
49
+ it 'remaps the values keeping the original keys' do
46
50
  expect(new_hash).to eq(
47
51
  a: 'a->4',
48
52
  b: 'b->7',
@@ -60,7 +64,7 @@ describe Hash do
60
64
 
61
65
  context 'when squashing the result of a deep hash' do
62
66
  let(:person_data) { { 'person.name' => 'John', 'person.age' => 23 } }
63
- let(:person) { person_data.to_deep_hash }
67
+ let(:person) { person_data.to_deep_hash }
64
68
 
65
69
  it 'is the reverse operation' do
66
70
  expect(person.squash).to eq(person_data)
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Darthjee::CoreExt::Hash::ValueChanger do
6
+ describe 'yard' do
7
+ subject(:changer) { described_class.new(options, &block) }
8
+
9
+ describe '#initialize' do
10
+ let(:options) { { recursive: false, skip_inner: false } }
11
+ let(:block) { proc(&:class) }
12
+ let(:hash) { { a: 1, b: { c: 2 }, d: [{ e: 1 }] } }
13
+
14
+ it 'initialize options' do
15
+ expect(changer.change(hash)).to eq(
16
+ a: Integer, b: Hash, d: Array
17
+ )
18
+ end
19
+ end
20
+
21
+ describe '#change' do
22
+ let(:options) { {} }
23
+ let(:block) { proc { |value| value.to_s.size } }
24
+
25
+ context 'when object is a Hash' do
26
+ let(:hash) { { a: 15, b: { c: 2 }, d: [{ e: 100 }] } }
27
+
28
+ it 'transforms values' do
29
+ expect(changer.change(hash)).to eq(
30
+ a: 2, b: { c: 1 }, d: [{ e: 3 }]
31
+ )
32
+ end
33
+
34
+ context 'when not skipping inner' do
35
+ let(:options) { { skip_inner: false } }
36
+
37
+ it 'transforms values' do
38
+ expect(changer.change(hash)).to eq(
39
+ a: 2, b: 7, d: 11
40
+ )
41
+ end
42
+ end
43
+
44
+ context 'when skipping recursive' do
45
+ let(:options) { { recursive: false } }
46
+
47
+ it 'transforms values' do
48
+ expect(changer.change(hash)).to eq(
49
+ a: 2, b: { c: 2 }, d: [{ e: 100 }]
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'when object is an array' do
56
+ let(:array) { [15, { c: 2 }, [{ e: 100 }]] }
57
+
58
+ it 'transforms values' do
59
+ expect(changer.change(array)).to eq(
60
+ [2, { c: 1 }, [{ e: 3 }]]
61
+ )
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end