corefines 1.6.0 → 1.7.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: 6ff01826fd1321effe7725bd8de106831ae6400c
4
- data.tar.gz: 6441dd63f2e8896861f092fce7c3001258aefdb1
3
+ metadata.gz: ea0feea695c1bc742c15a3ca74b9e4aa98d1d632
4
+ data.tar.gz: cce9dd830c78ddec528b274c8a42119dd79bf51d
5
5
  SHA512:
6
- metadata.gz: 4e3b8f57a51c0c947e9ae175481676b4b2c9423f687533a8d549069d39a3d35cd66b4830fff0430c83f821b15ac312b61db3e99d2de9271bae5dda2f181a0132
7
- data.tar.gz: e5d5affb24e366e957d40894bfaec32bd1cd1f59693816fd8777e2cddcf19f5981080a2d5abe0ab6a1e07398d0ad98fe7c7f3aa9ac3d82b39ef3eb9416875db4
6
+ metadata.gz: 36952b5e7ac736ae14986a44737fd7232a7ead39091ac4075b67b470dee862e260876511b757b316e326e95aa869fac6415adf6a7c775e7da9f34c72fe43bdcf
7
+ data.tar.gz: b70e5551f42ad5f19f44e65427bbf9d09c59b78a167e46e022ee1c33a65b81ae283fd497cd52b0acbd83ad5e416b8c3ba6932e0993e0900b47120d3a7cabd547
@@ -3,6 +3,13 @@
3
3
  :doc-base-url: http://www.rubydoc.info/github/jirutka/corefines/Corefines
4
4
  :issue-uri: {repo-uri}/issues
5
5
 
6
+ == 1.7.0 (2015-07-05)
7
+
8
+ * Add new refinement {doc-base-url}/Enumerable/MapTo[Enumerable#map_to].
9
+ * Add new refinement {doc-base-url}/Array/Wrap[Array#wrap].
10
+ * Add new refinement {doc-base-url}/Enumerable/Many[Enumerable#many?].
11
+
12
+
6
13
  == 1.6.0 (2015-05-16)
7
14
 
8
15
  * Add new refinement {doc-base-url}/String/Camelcase[String#camelcase].
@@ -11,14 +11,14 @@ ifdef::env-github[:idprefix: user-content-]
11
11
  :gh-name: jirutka/{gem-name}
12
12
  :gh-branch: master
13
13
  :badge-style: flat
14
- :doc-base-url: http://www.rubydoc.info/github/jirutka/corefines/Corefines
14
+ :doc-base-url: http://www.rubydoc.info/github/{gh-name}/{gh-branch}/Corefines
15
15
 
16
16
  ifdef::env-github[]
17
17
  image:https://img.shields.io/travis/{gh-name}/{gh-branch}.svg?style={badge-style}[Build Status, link="https://travis-ci.org/{gh-name}"]
18
18
  image:https://img.shields.io/codeclimate/coverage/github/{gh-name}.svg?style={badge-style}[Test Coverage, link="https://codeclimate.com/github/{gh-name}"]
19
19
  image:https://img.shields.io/codeclimate/github/{gh-name}.svg?style={badge-style}[Code Climate, link="https://codeclimate.com/github/{gh-name}"]
20
20
  image:https://img.shields.io/gem/v/{gem-name}.svg?style={badge-style}[Gem Version, link="https://rubygems.org/gems/{gem-name}"]
21
- image:https://img.shields.io/badge/yard-docs-blue.svg?style={badge-style}[Yard Docs, link="http://www.rubydoc.info/github/{gh-name}/frames"]
21
+ image:https://img.shields.io/badge/yard-docs-blue.svg?style={badge-style}[Yard Docs, link="http://www.rubydoc.info/github/{gh-name}/{gh-branch}"]
22
22
  endif::env-github[]
23
23
 
24
24
  Corefines is a collection of general purpose _refinements_ for extending the core capabilities of Ruby’s built-in classes.
@@ -41,12 +41,12 @@ TODO
41
41
  Add this line to your application’s Gemfile:
42
42
 
43
43
  [source]
44
- gem 'corefines', '~> 1.6'
44
+ gem 'corefines', '~> 1.7'
45
45
 
46
46
  or to your gemspec:
47
47
 
48
48
  [source]
49
- s.add_runtime_dependency 'corefines', '~> 1.6'
49
+ s.add_runtime_dependency 'corefines', '~> 1.7'
50
50
 
51
51
  and then execute:
52
52
 
@@ -132,9 +132,12 @@ Not ideal indeed, but probably the best of what we can achieve.
132
132
  * {doc-base-url}/Array[Array]
133
133
  ** {doc-base-url}/Array/Second[#second]
134
134
  ** {doc-base-url}/Array/Third[#third]
135
+ ** {doc-base-url}/Array/Wrap[.wrap]
135
136
  * {doc-base-url}/Enumerable[Enumerable]
136
137
  ** {doc-base-url}/Enumerable/IndexBy[#index_by]
138
+ ** {doc-base-url}/Enumerable/Many[#many?]
137
139
  ** {doc-base-url}/Enumerable/MapSend[#map_send]
140
+ ** {doc-base-url}/Enumerable/MapTo[#map_to]
138
141
  * {doc-base-url}/Hash[Hash]
139
142
  ** {doc-base-url}/Hash/OpAdd[#+]
140
143
  ** {doc-base-url}/Hash/Compact[#compact]
@@ -25,6 +25,66 @@ module Corefines
25
25
  end
26
26
  end
27
27
 
28
+ ##
29
+ # @!method self.wrap(object)
30
+ # Wraps its argument in an array unless it is already an array (or
31
+ # array-like).
32
+ #
33
+ # Specifically:
34
+ #
35
+ # * If the argument is +nil+ an empty list is returned.
36
+ # * Otherwise, if the argument responds to +to_ary+ it is invoked, and
37
+ # its result returned.
38
+ # * Otherwise, returns an array with the argument as its single element.
39
+ #
40
+ # @example
41
+ # Array.wrap(nil) # => []
42
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
43
+ # Array.wrap(0) # => [0]
44
+ #
45
+ # This method is similar in purpose to <tt>Kernel#Array</tt>, but there
46
+ # are some differences:
47
+ #
48
+ # * If the argument responds to +to_ary+ the method is invoked.
49
+ # <tt>Kernel#Array</tt> moves on to try +to_a+ if the returned value is
50
+ # +nil+, but <tt>Array.wrap</tt> returns +nil+ right away.
51
+ # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+
52
+ # object, <tt>Kernel#Array</tt> raises an exception, while
53
+ # <tt>Array.wrap</tt> does not, it just returns the value.
54
+ # * It does not call +to_a+ on the argument, but returns an empty array
55
+ # if argument is +nil+.
56
+ #
57
+ # The second point is easily explained with some enumerables:
58
+ #
59
+ # Array(foo: :bar) # => [[:foo, :bar]]
60
+ # Array.wrap(foo: :bar) # => [{:foo=>:bar}]
61
+ #
62
+ # There's also a related idiom that uses the splat operator:
63
+ #
64
+ # [*object]
65
+ #
66
+ # which returns <tt>[]</tt> for +nil+, but calls to
67
+ # <tt>Array(object)</tt> otherwise.
68
+ #
69
+ # The differences with <tt>Kernel#Array</tt> explained above apply to the
70
+ # rest of <tt>object</tt>s.
71
+ #
72
+ # @return [Array]
73
+ #
74
+ module Wrap
75
+ refine ::Array.singleton_class do
76
+ def wrap(object)
77
+ if object.nil?
78
+ []
79
+ elsif object.respond_to? :to_ary
80
+ object.to_ary || [object]
81
+ else
82
+ [object]
83
+ end
84
+ end
85
+ end
86
+ end
87
+
28
88
  include Support::AliasSubmodules
29
89
  end
30
90
  end
@@ -36,6 +36,47 @@ module Corefines
36
36
  end
37
37
  end
38
38
 
39
+ ##
40
+ # @!method many?
41
+ # Returns +true+ if the enumerable has more than one element.
42
+ #
43
+ # This method is functionally equivalent to <tt>enum.to_a.size > 1</tt>,
44
+ # or <tt>enum.select { ... }.length > 1</tt> when the block is given.
45
+ #
46
+ # @example
47
+ # [1].many? # => false
48
+ # [1, 2].many? # => true
49
+ # [1, 2, 3].many? # => true
50
+ # [1, nil].many? # => true
51
+ # [1, 2, 3].many? { |n| n > 2 } # => false
52
+ #
53
+ # @overload many?
54
+ # @return [Boolean] +true+ if the enumerable has more than one element.
55
+ #
56
+ # @overload many?(&block)
57
+ # @yield [obj] gives each element to the block.
58
+ # @return [Boolean] +true+ if the block returns a truthy value (i.e.
59
+ # other than +nil+ and +false+) more than once.
60
+ #
61
+ module Many
62
+ Support.classes_including_module(::Enumerable) do |klass|
63
+
64
+ refine klass do
65
+ def many?
66
+ cnt = 0
67
+ if block_given?
68
+ any? do |element|
69
+ cnt += 1 if yield element
70
+ cnt > 1
71
+ end
72
+ else
73
+ any? { (cnt += 1) > 1 }
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+
39
80
  ##
40
81
  # @!method map_send(method_name, *args, &block)
41
82
  # Sends a message to each element and collects the result.
@@ -59,6 +100,32 @@ module Corefines
59
100
  end
60
101
  end
61
102
 
103
+ ##
104
+ # @!method map_to(klass)
105
+ # Maps each element of this _enum_ into the _klass_ via constructor.
106
+ #
107
+ # @example
108
+ # ['/tmp', '/var/tmp'].map_to(Pathname) # => [#<Pathname:/tmp>, #<Pathname:/var/tmp>]
109
+ #
110
+ # @param klass [#new] the klass to map each element to.
111
+ # @return [Enumerable] a new array with instances of the _klass_ for
112
+ # every element in _enum_.
113
+ #
114
+ module MapTo
115
+ Support.classes_including_module(::Enumerable) do |klass|
116
+
117
+ refine klass do
118
+ def map_to(klass)
119
+ map { |e| klass.new(e) }
120
+ end
121
+ end
122
+ end
123
+ end
124
+
62
125
  include Support::AliasSubmodules
126
+
127
+ class << self
128
+ alias_method :many?, :many
129
+ end
63
130
  end
64
131
  end
@@ -25,6 +25,10 @@ module Corefines
25
25
  # "camel::ca-se-y".camelcase(':', '-') # => "camelCaSeY"
26
26
  # "camel42case".camelcase(/[0-9]+/) # => "camelCase"
27
27
  #
28
+ # @param *separators [String, Regexp] the patterns used to determine
29
+ # where capitalization should occur. Defaults to <tt>/_+/</tt> and
30
+ # <tt>\s+</tt>.
31
+ #
28
32
  # @overload camelcase(first_letter, *separators)
29
33
  # @example
30
34
  # "camel case".camelcase(:upper) # => "CamelCase"
@@ -33,10 +37,10 @@ module Corefines
33
37
  # @param first_letter [:upper, :lower] desired case of the first
34
38
  # character of a word - +:upper+ to be upcased, or +:lower+ to
35
39
  # be downcased.
40
+ # @param *separators [String, Regexp] the patterns used to determine
41
+ # where capitalization should occur. Defaults to <tt>/_+/</tt> and
42
+ # <tt>\s+</tt>.
36
43
  #
37
- # @param *separators [String, Regexp] the patterns used to determine
38
- # where capitalization should occur. Defaults to <tt>/_+/</tt> and
39
- # <tt>\s+</tt>.
40
44
  # @return [String] a copy of the _str_ converted to camelcase.
41
45
  #
42
46
  module Camelcase
@@ -1,3 +1,3 @@
1
1
  module Corefines
2
- VERSION = '1.6.0'
2
+ VERSION = '1.7.0'
3
3
  end
@@ -0,0 +1,50 @@
1
+ describe Array do
2
+ using Corefines::Array::wrap
3
+
4
+ describe '.wrap' do
5
+
6
+ context "array" do
7
+ it "returns the given array unchanged" do
8
+ ary = ['foo', 'bar']
9
+ expect( Array.wrap(ary) ).to be ary
10
+ end
11
+ end
12
+
13
+ context "nil" do
14
+ it "returns an empty array" do
15
+ expect( Array.wrap(nil) ).to eq []
16
+ end
17
+ end
18
+
19
+ context "an object" do
20
+ it "returns it wrapped in an array" do
21
+ o = Object.new
22
+ expect( Array.wrap(o) ).to eq [o]
23
+ end
24
+ end
25
+
26
+ context "string" do
27
+ it "returns it wrapped in an array" do
28
+ expect( Array.wrap("foo\nbar") ).to eq ["foo\nbar"]
29
+ end
30
+ end
31
+
32
+ context "object with #to_ary" do
33
+
34
+ it "returns result of #to_ary" do
35
+ o = Class.new { def to_ary; ['foo', 'bar'] end }.new
36
+ expect( Array.wrap(o) ).to eq o.to_ary
37
+ end
38
+
39
+ it "returns wrapped if #to_ary returns nil" do
40
+ o = Class.new { def to_ary; nil end }.new
41
+ expect( Array.wrap(o) ).to eq [o]
42
+ end
43
+
44
+ it "doesn't complain if #to_ary doesn't return an array" do
45
+ o = Class.new { def to_ary; :not_an_array end }.new
46
+ expect( Array.wrap(o) ).to eq o.to_ary
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,66 @@
1
+ describe Enumerable do
2
+ using Corefines::Enumerable::many?
3
+
4
+ describe '#many?' do
5
+
6
+ shared_examples :without_block do |enum, expected|
7
+ context enum.class do
8
+ it { expect( enum.many? ).to be expected }
9
+ end
10
+ end
11
+
12
+ context "when empty" do
13
+ [ [], Set.new, {} ].each do |enum|
14
+ include_examples :without_block, enum, false
15
+ end
16
+ end
17
+
18
+ context "when one element" do
19
+ [ [42], Set.new([42]), {a: 42} ].each do |enum|
20
+ include_examples :without_block, enum, false
21
+ end
22
+ end
23
+
24
+ context "when two elements" do
25
+ [ [1, 2], Set.new([1, 2]), {a: 1, b: 2} ].each do |enum|
26
+ include_examples :without_block, enum, true
27
+ end
28
+ end
29
+
30
+ context "when two nil elements" do
31
+ [ [nil, nil], {a: nil, b: nil} ].each do |enum|
32
+ include_examples :without_block, enum, true
33
+ end
34
+ end
35
+
36
+ context "when more than two elements" do
37
+ [ [1, 2, 3], Set.new([1, 2, 3]), {a: 1, b: 2, c: 3} ].each do |enum|
38
+ include_examples :without_block, enum, true
39
+ end
40
+ end
41
+
42
+
43
+ context "with block" do
44
+
45
+ context "that yields true for one element" do
46
+ context Array do
47
+ it { expect( [1, 2].many? { |n| n > 1 } ).to eq false }
48
+ end
49
+
50
+ context Hash do
51
+ it { expect( {a: 1, b: 2}.many? { |k, v| v > 1 } ).to eq false }
52
+ end
53
+ end
54
+
55
+ context "that yield true for two elements" do
56
+ context Array do
57
+ it { expect( [1, 2].many? { |n| n > 0 } ).to eq true }
58
+ end
59
+
60
+ context Hash do
61
+ it { expect( {a: 1, b: 2}.many? { |k, v| k.is_a?(Symbol) } ).to eq true }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,15 @@
1
+ require 'pathname'
2
+
3
+ describe Enumerable do
4
+ using Corefines::Enumerable::map_to
5
+
6
+ describe '#map_to' do
7
+
8
+ context Array do
9
+ it "creates instance of the klass for every element and collects the result" do
10
+ ary = ['/tmp', '/var/tmp']
11
+ expect( ary.map_to(Pathname) ).to eq ary.map { |e| Pathname.new(e) }
12
+ end
13
+ end
14
+ end
15
+ end
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.6.0
4
+ version: 1.7.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: 2015-05-16 00:00:00.000000000 Z
11
+ date: 2015-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: asciidoctor
@@ -122,8 +122,11 @@ files:
122
122
  - lib/corefines/version.rb
123
123
  - spec/array/second_spec.rb
124
124
  - spec/array/third_spec.rb
125
+ - spec/array/wrap_spec.rb
125
126
  - spec/enumerable/index_by_spec.rb
127
+ - spec/enumerable/many_spec.rb
126
128
  - spec/enumerable/map_send_spec.rb
129
+ - spec/enumerable/map_to_spec.rb
127
130
  - spec/hash/compact_spec.rb
128
131
  - spec/hash/except_spec.rb
129
132
  - spec/hash/only_spec.rb