corefines 1.10.0 → 1.11.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c4f2aa64f58e3be7d11dc02d322111b762bfe5fc
4
- data.tar.gz: 283d79fe43753535b16469e15bf2413055713698
3
+ metadata.gz: cc488d6deade84992853796d2e3e315e23a2bb32
4
+ data.tar.gz: 4f671bc5963d4002509d54a90dc41024a9efa676
5
5
  SHA512:
6
- metadata.gz: 82a3e76586a5a45335a2838c11d108a875b2d5ff2ac9a7e92141017eac240c9c8c0e136c6c0e7fe007d889b6da92d3f78f73d878ba964cda665e714b0a101edc
7
- data.tar.gz: a104e1756ebf9caa6621e4fc890238248e1a814dfc1ace32e36a725f3370809accb0b7fbf7354a356004af59b0b9da6a4fd4564f0c8077551274ecca1016fdd0
6
+ metadata.gz: 96553f167a0dc42ce8c556ef92e3542940bd6093ab1b5e368c58e7627e3f83ed479368bc5b552be845ee84c68ee52e254781ab42eb44777ad53d75e20c19108f
7
+ data.tar.gz: 5ca6dc072b0ecf10503271b7d18ab2bee23efdf1663050f59a9c38e5c68409a19636ea9979986542848f11a960132361575e3b5142fdf225525b27e559ab3986
@@ -69,6 +69,43 @@ module Corefines
69
69
  end
70
70
  end
71
71
 
72
+ ##
73
+ # @!method flat_map(&block)
74
+ # Returns a new hash with the merged results of running the _block_ once
75
+ # for every entry in +self+.
76
+ #
77
+ # @example
78
+ # hash = { a: 1, b: 2, c: 3 }
79
+ # hash.flat_map { |k, v| {k => v * 2, k.upcase => v} if v % 2 == 1 }
80
+ # # => { a: 2, A: 1, c: 6, C: 3 }
81
+ # hash.flat_map { |k, v| [[k, v * 2], [k.upcase => v]] if v % 2 == 1 }
82
+ # # => { a: 2, A: 1, c: 6, C: 3 }
83
+ #
84
+ # @yield [key, value] gives every key-value pair to the block.
85
+ # @yieldreturn [#to_h, Array, nil] an object that will be interpreted as
86
+ # a Hash and merged into the result, or nil to omit this key-value.
87
+ # @return [Hash] a new hash.
88
+ module FlatMap
89
+ refine ::Hash do
90
+ def flat_map
91
+ each_with_object({}) do |(key, value), hash|
92
+ yielded = yield(key, value)
93
+
94
+ if yielded.is_a? ::Hash
95
+ hash.merge!(yielded)
96
+ elsif yielded.is_a? ::Array
97
+ # Array#to_h exists since Ruby 2.1.
98
+ yielded.each do |pair|
99
+ hash.store(*pair)
100
+ end
101
+ elsif yielded
102
+ hash.merge!(yielded.to_h)
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
108
+
72
109
  ##
73
110
  # @!method only(*keys)
74
111
  # @example
@@ -132,6 +169,35 @@ module Corefines
132
169
  end
133
170
  end
134
171
 
172
+ ##
173
+ # @!method recurse(&block)
174
+ # Transforms this hash and each of its sub-hashes recursively using the
175
+ # given _block_.
176
+ #
177
+ # It does not mutate the hash if the given _block_ is pure (i.e. does not
178
+ # modify given hashes, but returns new ones).
179
+ #
180
+ # @example
181
+ # hash = {"a" => 1, "b" => {"c" => {"e" => 5}, "d" => 4}}
182
+ # hash.recurse!(&:symbolize_keys!) # => {a: 1, b: {c: {e: 5}, d: 4}}
183
+ # hash # => {a: 1, b: {c: {e: 5}, d: 4}}
184
+ #
185
+ # @yield [Hash] gives this hash and every sub-hash (recursively).
186
+ # The return value replaces the old value.
187
+ # @return [Hash] a result of applying _block_ to this hash and each of
188
+ # its sub-hashes (recursively).
189
+ #
190
+ module Recurse
191
+ refine ::Hash do
192
+ def recurse(&block)
193
+ h = yield(self)
194
+ h.each do |key, value|
195
+ h[key] = value.recurse(&block) if value.is_a? ::Hash
196
+ end
197
+ end
198
+ end
199
+ end
200
+
135
201
  ##
136
202
  # @!method rekey(key_map = nil, &block)
137
203
  # Returns a new hash with keys transformed according to the given
@@ -1,3 +1,3 @@
1
1
  module Corefines
2
- VERSION = '1.10.0'
2
+ VERSION = '1.11.0'.freeze
3
3
  end
@@ -0,0 +1,61 @@
1
+ require 'ostruct'
2
+
3
+ describe Hash do
4
+ describe '#flat_map' do
5
+ using Corefines::Hash::flat_map
6
+
7
+ let(:hash) { {a: 1, b: 2, c: 3} }
8
+ let!(:original) { hash.dup }
9
+
10
+ context "with block" do
11
+ it "returns a new hash, does not mutate self" do
12
+ expect( hash.flat_map { |k, v| {k => v * 2} } ).to be_a Hash
13
+ expect( hash ).to eq original
14
+ end
15
+
16
+ context "that yields Hash" do
17
+ it "returns merged results of running block for each entry" do
18
+ expect( hash.flat_map { |k, v| {k => v * 2, k.upcase => v * 3} } )
19
+ .to eq({a: 2, A: 3, b: 4, B: 6, c: 6, C: 9})
20
+ end
21
+
22
+ it "does not flatten yielded hashes" do
23
+ expect( hash.flat_map { |k, v| {k => {k.upcase => v}} } )
24
+ .to eq({a: {A: 1}, b: {B: 2}, c: {C: 3}})
25
+ end
26
+
27
+ it "omits entries for which the block yielded nil" do
28
+ expect( hash.flat_map { |k, v| {k.upcase => v * 2} if k != :b } )
29
+ .to eq({A: 2, C: 6})
30
+ end
31
+
32
+ it "handles duplicated keys by method the last wins" do
33
+ expect( hash.flat_map { |k, v| {k => v * 2, b: v * 6} } )
34
+ .to eq({a: 2, b: 18, c: 6})
35
+ end
36
+ end
37
+
38
+ context "that yields Array" do
39
+ it "interprets array of pairs as Hash" do
40
+ expect( hash.flat_map { |k, v| [[k, v * 2], [k.upcase, v * 3]] } )
41
+ .to eq({a: 2, A: 3, b: 4, B: 6, c: 6, C: 9})
42
+ end
43
+
44
+ it "raises ArgumentError if nested array has more than 2 elements" do
45
+ expect { hash.flat_map { |k, v| [[k, v, v]] } }.to raise_error(ArgumentError)
46
+ end
47
+ end
48
+
49
+ # There's no usable class in 1.9.3 implementing #to_h and I'd like to
50
+ # keep this simple...
51
+ if RUBY_VERSION.to_f >= 2
52
+ context "that yields object responding to #to_h" do
53
+ it "calls #to_h on yielded value" do
54
+ expect( hash.flat_map { |k, v| OpenStruct.new(k => v * 2) } )
55
+ .to eq({a: 2, b: 4, c: 6})
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,36 @@
1
+ describe Hash do
2
+ describe '#recurse' do
3
+ using Corefines::Hash::recurse
4
+
5
+ subject(:hash) { {a: 1, b: {d: {f: 6}, e: 5}, c: 3} }
6
+ let(:expected) { {a: 1, b: {d: {f: 6, x: 42}, e: 5, x: 42}, c: 3, x: 42} }
7
+ let!(:original) { Marshal.load(Marshal.dump(hash)) } # deep clone
8
+
9
+ shared_examples :common do
10
+ it "returns a result of calling block on the hash and sub-hashes recursively" do
11
+ is_expected.to eq expected
12
+ end
13
+ end
14
+
15
+ context "with pure block" do
16
+ subject!(:result) { hash.recurse { |h| h.merge(x: 42) } }
17
+
18
+ include_examples :common
19
+
20
+ it "does not mutate the original hash" do
21
+ expect( hash ).to eq original
22
+ end
23
+ end
24
+
25
+ context "with impure block" do
26
+ subject!(:result) { hash.recurse { |h| h.merge!(x: 42) } }
27
+
28
+ include_examples :common
29
+
30
+ it "modifies the hash in-place" do
31
+ expect( hash ).to eq expected
32
+ expect( hash ).to_not eq original
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,6 +1,3 @@
1
- require 'simplecov' unless RUBY_ENGINE == 'jruby'
2
- require 'corefines'
3
-
4
1
  RSpec.configure do |config|
5
2
 
6
3
  # rspec-expectations config
@@ -28,3 +25,13 @@ RSpec.configure do |config|
28
25
 
29
26
  config.color = true
30
27
  end
28
+
29
+ unless RUBY_ENGINE == 'jruby'
30
+ require 'simplecov'
31
+
32
+ SimpleCov.start do
33
+ add_filter '/spec/'
34
+ end
35
+ end
36
+
37
+ require 'corefines'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corefines
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jakub Jirutka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-25 00:00:00.000000000 Z
11
+ date: 2017-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.4'
33
+ version: '1.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.4'
40
+ version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -128,8 +128,10 @@ files:
128
128
  - spec/enumerable/map_to_spec.rb
129
129
  - spec/hash/compact_spec.rb
130
130
  - spec/hash/except_spec.rb
131
+ - spec/hash/flat_map_spec.rb
131
132
  - spec/hash/only_spec.rb
132
133
  - spec/hash/op_add_spec.rb
134
+ - spec/hash/recurse_spec.rb
133
135
  - spec/hash/rekey_spec.rb
134
136
  - spec/hash/symbolize_keys_spec.rb
135
137
  - spec/module/alias_class_method_spec.rb
@@ -179,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
181
  version: '0'
180
182
  requirements: []
181
183
  rubyforge_project:
182
- rubygems_version: 2.6.11
184
+ rubygems_version: 2.6.13
183
185
  signing_key:
184
186
  specification_version: 4
185
187
  summary: A collection of refinements for Ruby core classes.