darthjee-core_ext 1.7.3 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.
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