darthjee-core_ext 1.7.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +7 -1
  3. data/.gitignore +2 -0
  4. data/.reek.yml +3 -0
  5. data/ARRAY_README.md +72 -15
  6. data/CLASS_README.md +154 -0
  7. data/DATE_README.md +19 -9
  8. data/Dockerfile +2 -5
  9. data/ENUMERABLE_README.md +154 -4
  10. data/HASH_README.md +276 -135
  11. data/MATH_README.md +14 -10
  12. data/OBJECT_README.md +18 -35
  13. data/README.md +8 -4
  14. data/Rakefile +1 -0
  15. data/SYMBOL_README.md +13 -18
  16. data/config/rubycritc.rb +12 -0
  17. data/config/yardstick.yml +45 -3
  18. data/core_ext.gemspec +10 -8
  19. data/docker-compose.yml +15 -7
  20. data/lib/darthjee/core_ext/array.rb +17 -12
  21. data/lib/darthjee/core_ext/array/hash_builder.rb +20 -4
  22. data/lib/darthjee/core_ext/class.rb +28 -10
  23. data/lib/darthjee/core_ext/date.rb +1 -0
  24. data/lib/darthjee/core_ext/enumerable.rb +67 -30
  25. data/lib/darthjee/core_ext/hash.rb +4 -2
  26. data/lib/darthjee/core_ext/hash/cameliazable.rb +39 -8
  27. data/lib/darthjee/core_ext/hash/chain_fetcher.rb +17 -1
  28. data/lib/darthjee/core_ext/hash/changeable.rb +88 -0
  29. data/lib/darthjee/core_ext/hash/deep_hash_constructor.rb +127 -63
  30. data/lib/darthjee/core_ext/hash/deep_hash_constructor/setter.rb +112 -0
  31. data/lib/darthjee/core_ext/hash/key_changeable.rb +126 -54
  32. data/lib/darthjee/core_ext/hash/key_changer.rb +140 -40
  33. data/lib/darthjee/core_ext/hash/keys_sorter.rb +42 -6
  34. data/lib/darthjee/core_ext/hash/squasher.rb +131 -18
  35. data/lib/darthjee/core_ext/hash/transformable.rb +133 -41
  36. data/lib/darthjee/core_ext/hash/transposeable.rb +37 -8
  37. data/lib/darthjee/core_ext/hash/value_changer.rb +76 -36
  38. data/lib/darthjee/core_ext/math.rb +37 -6
  39. data/lib/darthjee/core_ext/numeric.rb +10 -0
  40. data/lib/darthjee/core_ext/object.rb +29 -0
  41. data/lib/darthjee/core_ext/symbol.rb +22 -2
  42. data/lib/darthjee/core_ext/version.rb +1 -1
  43. data/scripts/check_readme.sh +6 -0
  44. data/scripts/rubycritic.sh +10 -0
  45. data/spec/integration/readme/array_spec.rb +96 -0
  46. data/spec/integration/readme/class_spec.rb +123 -0
  47. data/spec/integration/readme/date_spec.rb +20 -0
  48. data/spec/integration/readme/enumerable_spec.rb +87 -0
  49. data/spec/integration/readme/hash_spec.rb +391 -0
  50. data/spec/integration/readme/math_spec.rb +31 -0
  51. data/spec/integration/readme/object_spec.rb +49 -0
  52. data/spec/integration/readme/symbol_spec.rb +29 -0
  53. data/spec/integration/yard/darthjee/core_ext/enumerable_spec.rb +24 -4
  54. data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +11 -0
  55. data/spec/integration/yard/darthjee/core_ext/hash/changeable_spec.rb +68 -0
  56. data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +34 -0
  57. data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +65 -0
  58. data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +8 -0
  59. data/spec/integration/yard/darthjee/core_ext/hash/key_changer_spec.rb +59 -0
  60. data/spec/integration/yard/darthjee/core_ext/hash/keys_sorter_spec.rb +25 -0
  61. data/spec/integration/yard/darthjee/core_ext/hash/squasher_spec.rb +60 -0
  62. data/spec/integration/yard/darthjee/core_ext/hash/transformable_spec.rb +66 -36
  63. data/spec/integration/yard/darthjee/core_ext/hash/transposeable_spec.rb +35 -0
  64. data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +13 -2
  65. data/spec/integration/yard/darthjee/core_ext/math_spec.rb +28 -0
  66. data/spec/integration/yard/darthjee/core_ext/numeric_spec.rb +11 -0
  67. data/spec/integration/yard/darthjee/core_ext/object_spec.rb +47 -0
  68. data/spec/integration/yard/darthjee/core_ext/symbol_spec.rb +17 -0
  69. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +64 -0
  70. data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +16 -156
  71. data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +5 -4
  72. data/spec/lib/darthjee/core_ext/hash/squasher_spec.rb +8 -2
  73. data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +4 -12
  74. data/spec/lib/hash_spec.rb +92 -146
  75. data/spec/lib/object_spec.rb +32 -0
  76. data/spec/support/models/client.rb +22 -0
  77. data/spec/support/shared_examples/hash/deep_hash.rb +166 -0
  78. data/spec/support/shared_examples/hash/hash_squasher.rb +54 -9
  79. data/spec/support/shared_examples/hash/keys_sorter.rb +266 -6
  80. metadata +70 -8
  81. data/lib/darthjee/core_ext/hash/to_hash_mapper.rb +0 -25
  82. data/spec/lib/darthjee/core_ext/hash/to_hash_mapper_spec.rb +0 -11
@@ -1,11 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Math
4
- def self.average(values)
5
- values = values.map { |v| [v, 1] }.to_h unless values.is_a?(Hash)
3
+ module Darthjee
4
+ module CoreExt
5
+ # @api public
6
+ module Math
7
+ # Calculates avarage from a series of values
8
+ #
9
+ # @overload average(values)
10
+ # @param values [::Array] list of values
11
+ #
12
+ # @overload average(values)
13
+ # @param values [::Hash] hash of values and its weights
14
+ #
15
+ # @return [::Float]
16
+ #
17
+ # @example Average of array
18
+ # values = [1,2,3,4]
19
+ #
20
+ # Math.average(values) # returns 2.5
21
+ #
22
+ # @example Average of hash
23
+ # values = { 1 => 3, 7 => 1 }
24
+ #
25
+ # Math.average(values) # returns 2.5
26
+ def average(values)
27
+ if values.is_a?(Hash)
28
+ weight_sum = values.values.sum
29
+ values = values.map { |value, weight| value * weight }
30
+ else
31
+ weight_sum = values.length
32
+ end
6
33
 
7
- values.inject(0) do |sum, vals|
8
- sum + vals.inject { |a, b| a * b }
9
- end / values.values.sum.to_f
34
+ values.sum / weight_sum.to_f
35
+ end
36
+ end
10
37
  end
11
38
  end
39
+
40
+ module Math
41
+ extend Darthjee::CoreExt::Math
42
+ end
@@ -2,7 +2,17 @@
2
2
 
3
3
  module Darthjee
4
4
  module CoreExt
5
+ # @api public
5
6
  module Numeric
7
+ # Returns the percentage over total
8
+ #
9
+ # @param total [::Numeric] total over which to calculate
10
+ # the percentage
11
+ #
12
+ # @return [::Float]
13
+ #
14
+ # @example
15
+ # 10.percent_of(30) # returns 33.33333333333333
6
16
  def percent_of(total)
7
17
  return Float::INFINITY if total&.zero?
8
18
  (to_f / total.to_f) * 100.0
@@ -2,12 +2,41 @@
2
2
 
3
3
  module Darthjee
4
4
  module CoreExt
5
+ # @api public
5
6
  module Object
7
+ # Checks if object is any of the given classes
8
+ #
9
+ # @param classes [::Array<::Class>] classes to be checked
10
+ # against
11
+ #
12
+ # @return [::TrueClass,::FalseClass]
13
+ #
14
+ # @example
15
+ # object = [1, 2, 3]
16
+ #
17
+ # object.is_any?(Hash, Class) # false
18
+ # object.is_any?(Hash, Array) # true
19
+ # object.is_any?(Enumerable, Class) # true
6
20
  def is_any?(*classes)
7
21
  classes.any? do |clazz|
8
22
  is_a?(clazz)
9
23
  end
10
24
  end
25
+
26
+ # Checks if object is evaluated to true
27
+ #
28
+ # @return [::TrueClass,::FalseClass]
29
+ #
30
+ # @example
31
+ # nil.trueful? # returns false
32
+ # [].trueful? # returns true
33
+ # {}.trueful? # returns true
34
+ # "".trueful? # returns true
35
+ def trueful?
36
+ # rubocop: disable Style/DoubleNegation
37
+ !!self
38
+ # rubocop: enable Style/DoubleNegation
39
+ end
11
40
  end
12
41
  end
13
42
  end
@@ -2,11 +2,31 @@
2
2
 
3
3
  module Darthjee
4
4
  module CoreExt
5
+ # @api public
6
+ #
7
+ # @author darthjee
5
8
  module Symbol
6
- def camelize(type = :upper)
7
- to_s.camelize(type).to_sym
9
+ # Creates new symbol camelized
10
+ #
11
+ # @param first_letter [::Symbol] type of first letter
12
+ #
13
+ # @return [::Symbol]
14
+ #
15
+ # @example
16
+ # :the_symbol.camelize # returns :TheSymbol
17
+ def camelize(first_letter = :upper)
18
+ to_s.camelize(first_letter).to_sym
8
19
  end
9
20
 
21
+ # The reverse of {#camelize}
22
+ #
23
+ # Makes an underscored, lowercase form from
24
+ # the expression in the Symbol
25
+ #
26
+ # @return [::Symbol]
27
+ #
28
+ # @example
29
+ # :theSymbol.camelize # returns :the_symbol
10
30
  def underscore
11
31
  to_s.underscore.to_sym
12
32
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Darthjee
4
4
  module CoreExt
5
- VERSION = '1.7.4'
5
+ VERSION = '2.0.0'
6
6
  end
7
7
  end
@@ -0,0 +1,6 @@
1
+ #! /bin/bash
2
+
3
+ PROJECT=darthjee/core_ext
4
+ VERSION=$(grep VERSION lib/$PROJECT/version.rb | sed -e "s/.*'\(.*\)'/\1/g")
5
+
6
+ grep https://www.rubydoc.info/gems/darthjee-core_ext/$VERSION README.md
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ DIFF_LIST=$(git diff --name-only $CIRCLE_SHA1 $(git merge-base $CIRCLE_SHA1 origin/master) | grep "^lib/")
4
+
5
+ if [ ! -z "$DIFF_LIST" ]; then
6
+ mkdir -p tmp/rubycritic/compare
7
+ bundle exec rubycritic --format console --branch origin/master -t 0 $DIFF_LIST
8
+ else
9
+ echo "No changes detected. Skipping rubycritic..."
10
+ fi
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Array do
4
+ describe 'readme' do
5
+ describe '#as_hash' do
6
+ subject(:array) { [10, 20, 30, 40] }
7
+
8
+ let(:keys) { %i[ten twenty thirty fourty] }
9
+
10
+ it 'pairs keys and values' do
11
+ expect(array.as_hash(keys))
12
+ .to eq(ten: 10, twenty: 20, thirty: 30, fourty: 40)
13
+ end
14
+ end
15
+
16
+ describe '#average' do
17
+ subject(:array) { [1, 2, 3, 4] }
18
+
19
+ it 'calculates the average' do
20
+ expect(array.average).to eq(2.5)
21
+ end
22
+ end
23
+
24
+ describe '#chain_map' do
25
+ subject(:array) { %i[a long_name sym] }
26
+
27
+ it 'maps calling the methods' do
28
+ expect(array.chain_map(:to_s, :size, :to_s))
29
+ .to eq(%w[1 9 3])
30
+ end
31
+
32
+ context 'when giving a block' do
33
+ let(:mapped) do
34
+ array.chain_map(:to_s, :size) { |v| "final: #{v}" }
35
+ end
36
+
37
+ it 'maps calling the methods' do
38
+ expect(mapped)
39
+ .to eq(['final: 1', 'final: 9', 'final: 3'])
40
+ end
41
+ end
42
+ end
43
+
44
+ describe 'mapk' do
45
+ let(:array) do
46
+ [
47
+ { a: { b: 1 }, b: 2 },
48
+ { a: { b: 3 }, b: 4 }
49
+ ]
50
+ end
51
+
52
+ it 'maps fetching keys' do
53
+ expect(array.mapk(:a, :b)).to eq([1, 3])
54
+ end
55
+ end
56
+
57
+ describe '#procedural_join' do
58
+ subject(:array) { [1, 2, -3, -4, 5] }
59
+
60
+ let(:mapper) { proc { |value| value.to_f.to_s } }
61
+ let(:string) do
62
+ array.procedural_join(mapper) do |_previous, nexte|
63
+ nexte.positive? ? ' +' : ' '
64
+ end
65
+ end
66
+
67
+ it 'joins with grace' do
68
+ expect(string).to eq('1.0 +2.0 -3.0 -4.0 +5.0')
69
+ end
70
+ end
71
+
72
+ describe '#random' do
73
+ let(:array) { [10, 20, 30] }
74
+
75
+ it 'returns a random element' do
76
+ expect(array).to include(array.random)
77
+ end
78
+ end
79
+
80
+ describe '#random!' do
81
+ let(:array) { [10, 20, 30] }
82
+
83
+ it 'returns a random element' do
84
+ expect(array.dup).to include(array.random!)
85
+ end
86
+
87
+ it 'removes an element from array' do
88
+ expect { array.random! }.to change(array, :size).by(-1)
89
+ end
90
+
91
+ it 'no longer includes removed element' do
92
+ expect(array).not_to include(array.random!)
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: false
2
+
3
+ describe Class do
4
+ describe 'readme' do
5
+ let(:instance) { klass.new }
6
+ let(:other) { klass.new }
7
+
8
+ describe '#default_value' do
9
+ let(:klass) do
10
+ Class.new do |clazz|
11
+ clazz.send(:default_value, :name, 'John')
12
+ end
13
+ end
14
+
15
+ it 'adds method with default value' do
16
+ expect(instance.name)
17
+ .to eq('John')
18
+ end
19
+
20
+ it 'returns the same instance' do
21
+ expect(instance.name)
22
+ .to be_equal(other.name)
23
+ end
24
+ end
25
+
26
+ describe '#default_values' do
27
+ let(:klass) do
28
+ Class.new do |clazz|
29
+ clazz.send(
30
+ :default_values, :name, :nick_name, 'John'
31
+ )
32
+ end
33
+ end
34
+
35
+ it 'adds methods with default value' do
36
+ expect(instance.name)
37
+ .to eq('John')
38
+ end
39
+
40
+ it 'adds methods with default value on both methods' do
41
+ expect(instance.nick_name)
42
+ .to eq('John')
43
+ end
44
+
45
+ it 'returns the same instance' do
46
+ expect(instance.name)
47
+ .to be_equal(other.name)
48
+ end
49
+ end
50
+
51
+ describe '#default_reader' do
52
+ let(:klass) do
53
+ Class.new do |clazz|
54
+ clazz.send(:attr_writer, :name)
55
+ clazz.send(:default_reader, :name, 'John Doe')
56
+ end
57
+ end
58
+
59
+ it 'adds method returning default value' do
60
+ expect(instance.name).to eq('John Doe')
61
+ end
62
+
63
+ context 'when value is changed' do
64
+ before do
65
+ instance.name = 'Joe'
66
+ end
67
+
68
+ it 'returns new value' do
69
+ expect(instance.name).to eq('Joe')
70
+ end
71
+
72
+ context 'when it is changed to nil' do
73
+ before do
74
+ instance.name = nil
75
+ end
76
+
77
+ it { expect(instance.name).to be_nil }
78
+ end
79
+
80
+ context 'when another instance calls the method' do
81
+ it 'does not change the result of another instance' do
82
+ expect(instance.name).not_to eq(other.name)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ describe '#default_readers' do
89
+ let(:klass) do
90
+ Class.new do |clazz|
91
+ clazz.send(:attr_writer, :cars, :houses)
92
+ clazz.send(:default_readers, :cars, :houses, 'none')
93
+ end
94
+ end
95
+
96
+ it 'adds method returning default value' do
97
+ expect(instance.cars).to eq('none')
98
+ end
99
+
100
+ it 'returns the same instance for both methods' do
101
+ expect(instance.cars).to be_equal(instance.houses)
102
+ end
103
+
104
+ context 'when setting cars' do
105
+ before { instance.cars = ['volvo'] }
106
+
107
+ it 'sets the value' do
108
+ expect(instance.cars).to eq(['volvo'])
109
+ end
110
+
111
+ it 'does not change the value on the other method' do
112
+ expect(instance.houses).to eq('none')
113
+ end
114
+
115
+ context 'when setting to nil' do
116
+ before { instance.cars = nil }
117
+
118
+ it { expect(instance.cars).to be_nil }
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Date do
6
+ describe 'readme' do
7
+ subject(:date) { described_class.new(2106, 10, 11) }
8
+
9
+ let(:future) { date + 1.year }
10
+ let(:past) { date - 1.year }
11
+
12
+ it 'returns days between' do
13
+ expect(date.days_between(future)).to eq(365)
14
+ end
15
+
16
+ it 'returns positive' do
17
+ expect(date.days_between(past)).to eq(365)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Enumerable do
4
+ describe 'readme' do
5
+ describe '#clean' do
6
+ let(:array) { [1, [], nil, {}, '', hash] }
7
+ let(:hash) { { b: [], c: nil, d: {}, e: '' } }
8
+
9
+ it 'cleans array' do
10
+ expect(array.clean).to eq([1])
11
+ end
12
+ end
13
+
14
+ describe '#clean!' do
15
+ let(:hash) do
16
+ {
17
+ a: 1,
18
+ b: [],
19
+ c: nil,
20
+ d: {},
21
+ e: '',
22
+ f: {
23
+ b: [],
24
+ c: nil,
25
+ d: {},
26
+ e: ''
27
+ }
28
+ }
29
+ end
30
+
31
+ it 'cleans array' do
32
+ expect { hash.clean! }.to change { hash }
33
+ .to(a: 1)
34
+ end
35
+ end
36
+
37
+ describe '#map_and_find' do
38
+ let(:ids) { [10, 21, 30, 31, 51, 55] }
39
+ let(:client) { Client.new(existing_ids) }
40
+ let(:existing_ids) { [1, 11, 21, 31, 41, 51] }
41
+ let(:request) { client.method(:request) }
42
+
43
+ it 'returns the value found' do
44
+ expect(ids.map_and_find(&request)).to eq(id: 21)
45
+ end
46
+
47
+ it 'does not perform all requests all' do
48
+ expect { ids.map_and_find(&request) }
49
+ .to change(client, :requested)
50
+ .from([]).to([10, 21])
51
+ end
52
+ end
53
+
54
+ describe '#map_and_select' do
55
+ let(:ids) { [10, 21, 30, 31, 51, 55] }
56
+ let(:client) { Client.new(existing_ids) }
57
+ let(:existing_ids) { [1, 11, 21, 31, 41, 51] }
58
+ let(:request) { client.method(:request) }
59
+
60
+ it 'returns all values found' do
61
+ expect(ids.map_and_select(&request))
62
+ .to eq([{ id: 21 }, { id: 31 }, { id: 51 }])
63
+ end
64
+ end
65
+
66
+ describe '#map_to_hash' do
67
+ let(:ids) { [10, 21, 30, 31, 51, 55] }
68
+ let(:client) { Client.new(existing_ids) }
69
+ let(:existing_ids) { [1, 11, 21, 31, 41, 51] }
70
+ let(:request) { client.method(:request) }
71
+ let(:expected) do
72
+ {
73
+ 10 => nil,
74
+ 21 => { id: 21 },
75
+ 30 => nil,
76
+ 31 => { id: 31 },
77
+ 51 => { id: 51 },
78
+ 55 => nil
79
+ }
80
+ end
81
+
82
+ it 'returns a hash with the mapped' do
83
+ expect(ids.map_to_hash(&request)).to eq(expected)
84
+ end
85
+ end
86
+ end
87
+ end