corefines 1.10.0 → 1.11.0

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