nutella 0.8 → 0.9
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.
- data/lib/nutella/core_ext/enumerable/apply.rb +29 -0
- data/lib/nutella/core_ext/enumerable/group.rb +30 -0
- data/lib/nutella/core_ext/enumerable/map.rb +30 -0
- data/lib/nutella/core_ext/enumerable/search.rb +13 -0
- data/lib/nutella/core_ext/enumerable/sum.rb +24 -0
- data/lib/nutella/core_ext/enumerable.rb +1 -65
- data/lib/nutella/core_ext/hash.rb +2 -2
- data/lib/nutella/core_ext/integer/format.rb +2 -6
- data/lib/nutella/core_ext/integer/multiples.rb +2 -2
- data/lib/nutella/core_ext/numeric/bytes.rb +43 -0
- data/lib/nutella/core_ext/numeric/sanity_check.rb +23 -0
- data/lib/nutella/core_ext/numeric.rb +1 -43
- data/lib/nutella/core_ext/object/aliases.rb +1 -1
- data/lib/nutella/core_ext/string.rb +6 -6
- data/lib/nutella/version.rb +1 -1
- data/spec/nutella/core_ext/enumerable_spec.rb +72 -6
- data/spec/nutella/core_ext/hash_spec.rb +7 -9
- data/spec/nutella/core_ext/integer_spec.rb +29 -29
- data/spec/nutella/core_ext/numeric_spec.rb +28 -0
- data/spec/nutella/core_ext/object_spec.rb +14 -14
- data/spec/nutella/core_ext/string_spec.rb +3 -9
- data/spec/support/apply_tester.rb +11 -0
- metadata +12 -3
@@ -0,0 +1,29 @@
|
|
1
|
+
module Enumerable
|
2
|
+
# Applies a method to the collection of various arguments.
|
3
|
+
#
|
4
|
+
# @example Requires multiple files
|
5
|
+
# # Without Nutella:
|
6
|
+
# %w[several libs to include].each { |r| require r }
|
7
|
+
# # With Nutella:
|
8
|
+
# %w[several libs to include].apply :require
|
9
|
+
#
|
10
|
+
# @example Passes in multiple arguments
|
11
|
+
# # Without Nutella:
|
12
|
+
# [1, 2, 3].each { |n| foo n, 5 }
|
13
|
+
# # With Nutella:
|
14
|
+
# [1, 2, 3].apply :foo, 5
|
15
|
+
#
|
16
|
+
# @example Uses a multi-dimensional array to get the extra arguments
|
17
|
+
# arr = [[1, 2], [3, 4], [5, 6]]
|
18
|
+
# # Without Nutella:
|
19
|
+
# arr.each { |a, b| foo a, b }
|
20
|
+
# # With Nutella:
|
21
|
+
# arr.apply :foo
|
22
|
+
#
|
23
|
+
# @param [Symbol] method the method to apply
|
24
|
+
# @param [*Object] args any extra arguments to use
|
25
|
+
# @return [Array] a list of the return values of the method calls
|
26
|
+
def apply(method, *args)
|
27
|
+
map { |elem| method(method).(*elem, *args) }
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Enumerable
|
2
|
+
# Groups an array into smaller arrays of +size+ elements. Remaining elements
|
3
|
+
# at the end will be put into a smaller group if necessary, unless
|
4
|
+
# +discard_excess+ is true, in which case they will be discarded.
|
5
|
+
#
|
6
|
+
# @example Groups numbers 1..4 into groups of 2
|
7
|
+
# (1..4).group(2) # => [[1, 2], [3, 4]]
|
8
|
+
# @example Groups numbers 1..8 into groups of 3
|
9
|
+
# (1..8).group(3) # => [[1, 2, 3], [4, 5, 6], [7, 8]]
|
10
|
+
# @example Groups numbers 1..8 into groups of 3, discarding excess elements
|
11
|
+
# (1..8).group(3, true) # => [[1, 2, 3], [4, 5, 6]]
|
12
|
+
#
|
13
|
+
# @param [Integer] size the size of the groups to create
|
14
|
+
# @param [Boolean] discard_excess whether or not to discard extra elements
|
15
|
+
# @return [Array] an array of the groups
|
16
|
+
def group(size, discard_excess = false)
|
17
|
+
groups = each_slice(size).to_a
|
18
|
+
groups[0..(discard_excess && groups.last.size < size ? -2 : -1)]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Modifies the collection in place as described for
|
22
|
+
# <tt>Enumerable#group</tt>. Returns the modified collection, or nil if no
|
23
|
+
# modifications were made.
|
24
|
+
#
|
25
|
+
# @see Enumerable#group
|
26
|
+
def group!(size, discard_excess = false)
|
27
|
+
return nil if empty?
|
28
|
+
self.replace group(size, discard_excess)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Enumerable
|
2
|
+
alias old_map map
|
3
|
+
|
4
|
+
# Allows mapping of a method with parameters across a collection.
|
5
|
+
#
|
6
|
+
# You no longer have to open up a block just because the method that you're
|
7
|
+
# mapping needs parameters. This method is still behaves just as it used to
|
8
|
+
# otherwise.
|
9
|
+
#
|
10
|
+
# @example Replaces all vowels with <tt>"x"</tt> in a list of strings
|
11
|
+
# %w[Ann Mary Paul].map :gsub, /[aeiou]/i, "x" # => ["xnn", "Mxry", "Pxul"]
|
12
|
+
def map(*args, &block)
|
13
|
+
block_given? ? old_map(&block) : old_map { |elem| elem.send *args }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO: See if there is a DRYer way to make this work with Array also.
|
18
|
+
# Array doesn't inherit Enumerable's #map, so I'm forced to do this. Is there a
|
19
|
+
# better way to make Array inherit the modified #map?
|
20
|
+
|
21
|
+
class Array
|
22
|
+
alias old_map map
|
23
|
+
|
24
|
+
# Allows mapping of a method with parameters across an array.
|
25
|
+
#
|
26
|
+
# @see Enumerable#map
|
27
|
+
def map(*args, &block)
|
28
|
+
block_given? ? old_map(&block) : old_map { |elem| elem.send *args }
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Enumerable
|
2
|
+
alias contains? include?
|
3
|
+
alias includes? include?
|
4
|
+
|
5
|
+
# The inverse of <tt>Enumerable#include?</tt>.
|
6
|
+
#
|
7
|
+
# @param [Object] object the object to test for exclusion
|
8
|
+
# @return [Boolean] whether or not the collection excludes +object+
|
9
|
+
def exclude?(object)
|
10
|
+
!include? object
|
11
|
+
end
|
12
|
+
alias excludes? exclude?
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Enumerable
|
2
|
+
# Add together all numeric elements in the collection. When using a block,
|
3
|
+
# adds together all numeric elements that pass the predicate in that block.
|
4
|
+
#
|
5
|
+
# @example Sums up the elements of an array
|
6
|
+
# [1, 2, 3].sum # => 6
|
7
|
+
# @example Sums up the elements of a 2-dimensional array
|
8
|
+
# [[1, 2], [3, 4]].sum # => 10
|
9
|
+
# @example Sums up the numeric elements of a hash
|
10
|
+
# { a: 4, b: 5 }.sum # => 9
|
11
|
+
# @example Ignores the non-numeric element in the array
|
12
|
+
# [2, "string", 9].sum # => 11
|
13
|
+
# @example Sums up the even numbers from 1 to 10
|
14
|
+
# (1..10).sum &:even?
|
15
|
+
# @example Sums up the numbers from 1 to 100 that are multiples of 3
|
16
|
+
# (1..100).sum { |n| n % 3 == 0 }
|
17
|
+
#
|
18
|
+
# @return [Numeric] the sum of all numeric elements in the collection
|
19
|
+
def sum(&block)
|
20
|
+
# TODO: Two selects in a row, how to DRY this up?
|
21
|
+
flat = respond_to?(:flatten) ? flatten : self
|
22
|
+
flat.select { |e| e.is_a? Numeric }.select(&block).inject(:+) || 0
|
23
|
+
end
|
24
|
+
end
|
@@ -1,65 +1 @@
|
|
1
|
-
|
2
|
-
alias_method :contains?, :include?
|
3
|
-
alias_method :includes?, :include?
|
4
|
-
|
5
|
-
# The inverse of <tt>Enumerable#include?</tt>.
|
6
|
-
#
|
7
|
-
# @param [Object] object the object to test for exclusion
|
8
|
-
# @return [Boolean] whether or not the collection excludes +object+
|
9
|
-
def exclude?(object)
|
10
|
-
!include? object
|
11
|
-
end
|
12
|
-
alias_method :excludes?, :exclude?
|
13
|
-
|
14
|
-
# Groups an array into smaller arrays of +size+ elements. Remaining elements
|
15
|
-
# at the end will be put into a smaller group if necessary, unless
|
16
|
-
# +discard_excess+ is true, in which case they will be discarded.
|
17
|
-
#
|
18
|
-
# @example Groups numbers 1..4 into groups of 2
|
19
|
-
# (1..4).group(2) # => [[1, 2], [3, 4]]
|
20
|
-
# @example Groups numbers 1..8 into groups of 3
|
21
|
-
# (1..8).group(3) # => [[1, 2, 3], [4, 5, 6], [7, 8]]
|
22
|
-
# @example Groups numbers 1..8 into groups of 3, discarding excess elements
|
23
|
-
# (1..8).group(3, true) # => [[1, 2, 3], [4, 5, 6]]
|
24
|
-
#
|
25
|
-
# @param [Integer] size the size of the groups to create
|
26
|
-
# @param [Boolean] discard_excess whether or not to discard extra elements
|
27
|
-
# @return [Array] an array of the groups
|
28
|
-
def group(size, discard_excess = false)
|
29
|
-
groups = each_slice(size).to_a
|
30
|
-
groups[0..(discard_excess && groups.last.size < size ? -2 : -1)]
|
31
|
-
end
|
32
|
-
|
33
|
-
# Modifies the collection in place as described for
|
34
|
-
# <tt>Enumerable#group</tt>. Returns the modified collection, or nil if no
|
35
|
-
# modifications were made.
|
36
|
-
#
|
37
|
-
# @see Enumerable#group
|
38
|
-
def group!(size, discard_excess = false)
|
39
|
-
return nil if empty?
|
40
|
-
self.replace group(size, discard_excess)
|
41
|
-
end
|
42
|
-
|
43
|
-
# Add together all numeric elements in the collection. When using a block,
|
44
|
-
# adds together all numeric elements that pass the predicate in that block.
|
45
|
-
#
|
46
|
-
# @example Sums up the elements of an array
|
47
|
-
# [1, 2, 3].sum # => 6
|
48
|
-
# @example Sums up the elements of a 2-dimensional array
|
49
|
-
# [[1, 2], [3, 4]].sum # => 10
|
50
|
-
# @example Sums up the numeric elements of a hash
|
51
|
-
# { a: 4, b: 5 }.sum # => 9
|
52
|
-
# @example Ignores the non-numeric element in the array
|
53
|
-
# [2, "string", 9].sum # => 11
|
54
|
-
# @example Sums up the even numbers from 1 to 10
|
55
|
-
# (1..10).sum &:even?
|
56
|
-
# @example Sums up the numbers from 1 to 100 that are multiples of 3
|
57
|
-
# (1..100).sum { |n| n % 3 == 0 }
|
58
|
-
#
|
59
|
-
# @return [Numeric] the sum of all numeric elements in the collection
|
60
|
-
def sum(&block)
|
61
|
-
# TODO: Two selects in a row, how to DRY this up?
|
62
|
-
flat = respond_to?(:flatten) ? flatten : self
|
63
|
-
flat.select { |e| e.is_a? Numeric }.select(&block).inject(:+) || 0
|
64
|
-
end
|
65
|
-
end
|
1
|
+
Dir[File.expand_path("../enumerable/**/*.rb", __FILE__)].each { |f| require f }
|
@@ -20,7 +20,7 @@ class Hash
|
|
20
20
|
def slice(*keys)
|
21
21
|
select { |k, v| keys.include? k }
|
22
22
|
end
|
23
|
-
|
23
|
+
alias grab slice
|
24
24
|
|
25
25
|
# Acts on the hash as described in Hash#slice, but modifies the hash in
|
26
26
|
# place.
|
@@ -38,5 +38,5 @@ class Hash
|
|
38
38
|
end
|
39
39
|
# #grab! doesn't sound quite semantically correct, but keeping it for the
|
40
40
|
# sake of being consistent with #slice/#grab.
|
41
|
-
|
41
|
+
alias grab! slice!
|
42
42
|
end
|
@@ -8,12 +8,8 @@ class Integer
|
|
8
8
|
#
|
9
9
|
# @return [String] the ordinal form of the integer
|
10
10
|
def ordinalize
|
11
|
-
|
12
|
-
|
13
|
-
self.to_s + if (11..13).include?(self.abs % 100)
|
14
|
-
"th"
|
15
|
-
elsif suffixes.keys.include? (last_digit = self.abs % 10)
|
16
|
-
suffixes[last_digit]
|
11
|
+
self.to_s + if abs % 100 / 10 != 1 && (1..3).include?(last = abs % 10)
|
12
|
+
{1 => "st", 2 => "nd", 3 => "rd"}[last]
|
17
13
|
else
|
18
14
|
"th"
|
19
15
|
end
|
@@ -46,7 +46,7 @@ class Integer
|
|
46
46
|
def multiple_of?(*nums)
|
47
47
|
nums.all? { |n| (!n.zero? && self % n == 0) || zero? }
|
48
48
|
end
|
49
|
-
|
49
|
+
alias divisible_by? multiple_of?
|
50
50
|
|
51
51
|
# Checks whether the integer is evenly divisible by any of the arguments.
|
52
52
|
#
|
@@ -59,5 +59,5 @@ class Integer
|
|
59
59
|
def multiple_of_any?(*nums)
|
60
60
|
nums.any? { |n| multiple_of? n }
|
61
61
|
end
|
62
|
-
|
62
|
+
alias divisible_by_any? multiple_of_any?
|
63
63
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class Numeric
|
2
|
+
KILOBYTE = 1024
|
3
|
+
MEGABYTE = KILOBYTE * 1024
|
4
|
+
GIGABYTE = MEGABYTE * 1024
|
5
|
+
TERABYTE = GIGABYTE * 1024
|
6
|
+
PETABYTE = TERABYTE * 1024
|
7
|
+
EXABYTE = PETABYTE * 1024
|
8
|
+
|
9
|
+
def bytes
|
10
|
+
self
|
11
|
+
end
|
12
|
+
alias byte bytes
|
13
|
+
|
14
|
+
def kilobytes
|
15
|
+
self * KILOBYTE
|
16
|
+
end
|
17
|
+
alias kilobyte kilobytes
|
18
|
+
|
19
|
+
def megabytes
|
20
|
+
self * MEGABYTE
|
21
|
+
end
|
22
|
+
alias megabyte megabytes
|
23
|
+
|
24
|
+
def gigabytes
|
25
|
+
self * GIGABYTE
|
26
|
+
end
|
27
|
+
alias gigabyte gigabytes
|
28
|
+
|
29
|
+
def terabytes
|
30
|
+
self * TERABYTE
|
31
|
+
end
|
32
|
+
alias terabyte terabytes
|
33
|
+
|
34
|
+
def petabytes
|
35
|
+
self * PETABYTE
|
36
|
+
end
|
37
|
+
alias petabyte petabytes
|
38
|
+
|
39
|
+
def exabytes
|
40
|
+
self * EXABYTE
|
41
|
+
end
|
42
|
+
alias exabyte exabytes
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Numeric
|
2
|
+
# Checks that the number is at least a given minimum.
|
3
|
+
#
|
4
|
+
# @example Makes sure that a variable +num+ is a minimum of 5
|
5
|
+
# num = num.sanity_check_min 5
|
6
|
+
#
|
7
|
+
# @param [Numeric] minimum the minimum that the number can be
|
8
|
+
# @return [Numeric] what the number must be in order to satisfy the minimum
|
9
|
+
def sanity_check_min(minimum)
|
10
|
+
[self, minimum].max
|
11
|
+
end
|
12
|
+
|
13
|
+
# Checks that the number is at most a given maximum.
|
14
|
+
#
|
15
|
+
# @example Makes sure that a variable +num+ is a maximum of 5
|
16
|
+
# num = num.sanity_check_max 5
|
17
|
+
#
|
18
|
+
# @param [Numeric] maximum the maximum that the number can be
|
19
|
+
# @return [Numeric] what the number must be in order to satisfy the maximum
|
20
|
+
def sanity_check_max(maximum)
|
21
|
+
[self, maximum].min
|
22
|
+
end
|
23
|
+
end
|
@@ -1,43 +1 @@
|
|
1
|
-
|
2
|
-
KILOBYTE = 1024
|
3
|
-
MEGABYTE = KILOBYTE * 1024
|
4
|
-
GIGABYTE = MEGABYTE * 1024
|
5
|
-
TERABYTE = GIGABYTE * 1024
|
6
|
-
PETABYTE = TERABYTE * 1024
|
7
|
-
EXABYTE = PETABYTE * 1024
|
8
|
-
|
9
|
-
def bytes
|
10
|
-
self
|
11
|
-
end
|
12
|
-
alias_method :byte, :bytes
|
13
|
-
|
14
|
-
def kilobytes
|
15
|
-
self * KILOBYTE
|
16
|
-
end
|
17
|
-
alias_method :kilobyte, :kilobytes
|
18
|
-
|
19
|
-
def megabytes
|
20
|
-
self * MEGABYTE
|
21
|
-
end
|
22
|
-
alias_method :megabyte, :megabytes
|
23
|
-
|
24
|
-
def gigabytes
|
25
|
-
self * GIGABYTE
|
26
|
-
end
|
27
|
-
alias_method :gigabyte, :gigabytes
|
28
|
-
|
29
|
-
def terabytes
|
30
|
-
self * TERABYTE
|
31
|
-
end
|
32
|
-
alias_method :terabyte, :terabytes
|
33
|
-
|
34
|
-
def petabytes
|
35
|
-
self * PETABYTE
|
36
|
-
end
|
37
|
-
alias_method :petabyte, :petabytes
|
38
|
-
|
39
|
-
def exabytes
|
40
|
-
self * EXABYTE
|
41
|
-
end
|
42
|
-
alias_method :exabyte, :exabytes
|
43
|
-
end
|
1
|
+
Dir[File.expand_path("../numeric/**/*.rb", __FILE__)].each { |f| require f }
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class String
|
2
|
-
|
3
|
-
|
2
|
+
alias contains? include?
|
3
|
+
alias includes? include?
|
4
4
|
|
5
|
-
|
5
|
+
alias each each_char
|
6
6
|
|
7
7
|
# The inverse of <tt>String#include?</tt>.
|
8
8
|
#
|
@@ -11,7 +11,7 @@ class String
|
|
11
11
|
def exclude?(str)
|
12
12
|
!include? str
|
13
13
|
end
|
14
|
-
|
14
|
+
alias excludes? exclude?
|
15
15
|
|
16
16
|
# Left-aligns a heredoc by finding the least indented line in the string, and
|
17
17
|
# removing that amount of leading whitespace from each line.
|
@@ -29,6 +29,6 @@ class String
|
|
29
29
|
def heredoc
|
30
30
|
gsub /^[ \t]{#{scan(/^[ \t]*(?=\S)/).min.size}}/, ""
|
31
31
|
end
|
32
|
-
|
33
|
-
|
32
|
+
alias format_heredoc heredoc
|
33
|
+
alias strip_heredoc heredoc
|
34
34
|
end
|
data/lib/nutella/version.rb
CHANGED
@@ -8,6 +8,49 @@ describe Enumerable do
|
|
8
8
|
test_alias Enumerable, :excludes?, :exclude?
|
9
9
|
end
|
10
10
|
|
11
|
+
describe "#apply" do
|
12
|
+
let(:testers) do
|
13
|
+
5.times.map { ApplyTester.new(5) }
|
14
|
+
end
|
15
|
+
|
16
|
+
it "works for a function that takes one argument" do
|
17
|
+
testers.apply :increment_value
|
18
|
+
testers.map(&:value).should == [6] * 5
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with a function that takes two arguments" do
|
22
|
+
it "allows multi-dimensional arrays" do
|
23
|
+
multi = testers.zip([2] * 5)
|
24
|
+
multi.apply :increment_value
|
25
|
+
multi.each { |arr| arr.first.value.should == 7 }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows multiple arguments" do
|
29
|
+
testers.apply :increment_value, 2
|
30
|
+
testers.map(&:value).should == [7] * 5
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with a function that takes many arguments" do
|
35
|
+
it "allows multi-dimensional arrays" do
|
36
|
+
multi = testers.map { |elem| [elem, 2, 2] }
|
37
|
+
multi.apply :increment_value
|
38
|
+
multi.each { |arr| arr.first.value.should == 9 }
|
39
|
+
end
|
40
|
+
|
41
|
+
it "allows multiple arguments" do
|
42
|
+
testers.apply :increment_value, 2, 2
|
43
|
+
testers.map(&:value).should == [9] * 5
|
44
|
+
end
|
45
|
+
|
46
|
+
it "allows multi-dimensional arrays with multiple arguments" do
|
47
|
+
multi = testers.zip([2] * 5)
|
48
|
+
multi.apply :increment_value, 2
|
49
|
+
multi.each { |arr| arr.first.value.should == 9 }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
11
54
|
describe "#exclude?" do
|
12
55
|
it "returns true if the collection does not contain the input" do
|
13
56
|
[1, 2, 3].exclude?(4).should be_true
|
@@ -51,18 +94,41 @@ describe Enumerable do
|
|
51
94
|
let(:arr) { (1..10).to_a }
|
52
95
|
|
53
96
|
it "modifies in place" do
|
54
|
-
arr.group! 2
|
55
|
-
arr.should == (1..10).group(2)
|
97
|
+
expect { arr.group! 2 }.to change { arr }.to (1..10).group(2)
|
56
98
|
end
|
57
99
|
|
58
100
|
it "returns the modified string" do
|
59
|
-
|
60
|
-
return_catcher.should == arr
|
101
|
+
arr.group!(2).should == arr
|
61
102
|
end
|
62
103
|
|
63
104
|
it "returns nil if nothing was modified" do
|
64
|
-
|
65
|
-
|
105
|
+
[].group!(2).should be_nil
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe "#map" do
|
110
|
+
it "takes a symbol and maps that method" do
|
111
|
+
[1, 2, 3].map(:succ).should == [2, 3, 4]
|
112
|
+
(1..10).map(:succ).should == (2..11).to_a
|
113
|
+
end
|
114
|
+
|
115
|
+
it "passes additional arguments into the method in the first argument" do
|
116
|
+
arr = %w[Alice Bob Charlie Dennis]
|
117
|
+
alpha = ("a".."z")
|
118
|
+
args = [/[aeiou]/, "x"]
|
119
|
+
|
120
|
+
arr.map(:gsub, *args).should == arr.map { |e| e.gsub *args }
|
121
|
+
alpha.map(:gsub, *args).should == alpha.map { |e| e.gsub *args }
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when using as the original #map" do
|
125
|
+
it "doesn't break passing in blocks" do
|
126
|
+
[1, 2, 3].map { |n| n + 1 }.should == [2, 3, 4]
|
127
|
+
end
|
128
|
+
|
129
|
+
it "doesn't break when passing in Proc" do
|
130
|
+
[1, 2, 3].map(&:succ).should == [2, 3, 4]
|
131
|
+
end
|
66
132
|
end
|
67
133
|
end
|
68
134
|
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
require "nutella/core_ext/hash"
|
3
3
|
|
4
4
|
describe Hash do
|
5
|
-
let(:hash) { {
|
5
|
+
let(:hash) { {a: 1, b: 2, c: 3, d: 4} }
|
6
6
|
|
7
7
|
describe "aliases" do
|
8
8
|
test_alias Hash, :slice, :grab
|
@@ -11,11 +11,11 @@ describe Hash do
|
|
11
11
|
|
12
12
|
describe "#grab" do
|
13
13
|
it "selects the given items from a hash" do
|
14
|
-
hash.slice(:a, :c).should == {
|
14
|
+
hash.slice(:a, :c).should == {a: 1, c: 3}
|
15
15
|
end
|
16
16
|
|
17
17
|
it "skips items that do not exist in the hash" do
|
18
|
-
hash.slice(:a, :d, :f).should == {
|
18
|
+
hash.slice(:a, :d, :f).should == {a: 1, d: 4}
|
19
19
|
end
|
20
20
|
|
21
21
|
it "does not modify in place" do
|
@@ -27,17 +27,15 @@ describe Hash do
|
|
27
27
|
|
28
28
|
describe "#grab!" do
|
29
29
|
it "modifies in place" do
|
30
|
-
hash.slice! :a, :c
|
31
|
-
hash.should == { a: 1, c: 3 }
|
30
|
+
expect { hash.slice! :a, :c }.to change { hash }.to({a: 1, c: 3})
|
32
31
|
end
|
33
32
|
|
34
33
|
it "returns the removed pairs" do
|
35
|
-
hash.slice!(:a, :c).should == {
|
34
|
+
hash.slice!(:a, :c).should == {b: 2, d: 4}
|
36
35
|
end
|
37
36
|
|
38
|
-
it "
|
39
|
-
hash.slice!(:a, :c, :g).should == {
|
40
|
-
hash.should == { a: 1, c: 3 }
|
37
|
+
it "does not return pairs that did not affect the hash" do
|
38
|
+
hash.slice!(:a, :c, :g).should == {b: 2, d: 4}
|
41
39
|
end
|
42
40
|
end
|
43
41
|
end
|
@@ -8,8 +8,8 @@ describe Integer do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
describe "#ordinalize" do
|
11
|
-
|
12
|
-
|
11
|
+
NUMBER_FORMATS.each do |cardinal, ordinal|
|
12
|
+
it "returns the ordinal #{ordinal} for the integer #{cardinal}" do
|
13
13
|
cardinal.ordinalize.should == ordinal
|
14
14
|
end
|
15
15
|
end
|
@@ -76,66 +76,66 @@ describe Integer do
|
|
76
76
|
|
77
77
|
describe "#multiple_of?" do
|
78
78
|
it "returns true if the number is evenly divisible" do
|
79
|
-
5.
|
80
|
-
15.
|
81
|
-
10.
|
82
|
-
6000.
|
79
|
+
5.should be_multiple_of(5)
|
80
|
+
15.should be_multiple_of(5)
|
81
|
+
10.should be_multiple_of(2)
|
82
|
+
6000.should be_multiple_of(6)
|
83
83
|
end
|
84
84
|
|
85
85
|
it "returns false if the number is not evenly divisible" do
|
86
|
-
20.
|
87
|
-
4.
|
88
|
-
5.
|
89
|
-
100.
|
86
|
+
20.should_not be_multiple_of(7)
|
87
|
+
4.should_not be_multiple_of(3)
|
88
|
+
5.should_not be_multiple_of(15)
|
89
|
+
100.should_not be_multiple_of(3)
|
90
90
|
end
|
91
91
|
|
92
92
|
context "when passing in zero" do
|
93
93
|
it "returns false if one tries to divide by zero" do
|
94
|
-
20.
|
95
|
-
30.
|
94
|
+
20.should_not be_multiple_of(0)
|
95
|
+
30.should_not be_multiple_of(0)
|
96
96
|
end
|
97
97
|
|
98
98
|
it "allows zero to go into zero" do
|
99
|
-
0.
|
99
|
+
0.should be_multiple_of(0)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
103
|
context "with multiple arguments" do
|
104
104
|
it "returns true if evenly divisible by all arguments" do
|
105
|
-
15.
|
106
|
-
100.
|
107
|
-
0.
|
105
|
+
15.should be_multiple_of(3, 15)
|
106
|
+
100.should be_multiple_of(2, 5, 25)
|
107
|
+
0.should be_multiple_of(0, 1, 2)
|
108
108
|
end
|
109
109
|
|
110
110
|
it "returns false if evenly divisible by only some arguments" do
|
111
|
-
15.
|
112
|
-
12.
|
113
|
-
10.
|
111
|
+
15.should_not be_multiple_of(2, 3)
|
112
|
+
12.should_not be_multiple_of(3, 4, 6, 8)
|
113
|
+
10.should_not be_multiple_of(0, 5)
|
114
114
|
end
|
115
115
|
|
116
116
|
it "returns false if evenly divisible by none of the arguments" do
|
117
|
-
6.
|
118
|
-
17.
|
117
|
+
6.should_not be_multiple_of(4, 5)
|
118
|
+
17.should_not be_multiple_of(2, 4)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
123
|
describe "#multiple_of_any?" do
|
124
124
|
it "returns true if evenly divisible by all arguments" do
|
125
|
-
15.
|
126
|
-
100.
|
127
|
-
0.
|
125
|
+
15.should be_multiple_of_any(3, 15)
|
126
|
+
100.should be_multiple_of_any(2, 5, 25)
|
127
|
+
0.should be_multiple_of_any(0, 1, 2)
|
128
128
|
end
|
129
129
|
|
130
130
|
it "returns true if evenly divisible by only some arguments" do
|
131
|
-
15.
|
132
|
-
12.
|
133
|
-
10.
|
131
|
+
15.should be_multiple_of_any(2, 3)
|
132
|
+
12.should be_multiple_of_any(3, 4, 6, 8)
|
133
|
+
10.should be_multiple_of_any(0, 5)
|
134
134
|
end
|
135
135
|
|
136
136
|
it "returns false if evenly divisible by none of the arguments" do
|
137
|
-
6.
|
138
|
-
17.
|
137
|
+
6.should_not be_multiple_of_any(4, 5)
|
138
|
+
17.should_not be_multiple_of_any(2, 4)
|
139
139
|
end
|
140
140
|
end
|
141
141
|
end
|
@@ -8,4 +8,32 @@ describe Numeric do
|
|
8
8
|
test_alias Numeric, (name = "#{prefix}byte").to_sym, "#{name}s".to_sym
|
9
9
|
end
|
10
10
|
end
|
11
|
+
|
12
|
+
describe "#sanity_check_min" do
|
13
|
+
it "returns the parameter if the number is lower" do
|
14
|
+
5.sanity_check_min(7).should == 7
|
15
|
+
end
|
16
|
+
|
17
|
+
it "doesn't change anything if the number is equal" do
|
18
|
+
5.sanity_check_min(5).should == 5
|
19
|
+
end
|
20
|
+
|
21
|
+
it "returns the number if the number is higher" do
|
22
|
+
5.sanity_check_min(2).should == 5
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#sanity_check_max" do
|
27
|
+
it "returns the parameter if the number is higher" do
|
28
|
+
5.sanity_check_max(2).should == 2
|
29
|
+
end
|
30
|
+
|
31
|
+
it "doesn't change anything if the number is equal" do
|
32
|
+
5.sanity_check_max(5).should == 5
|
33
|
+
end
|
34
|
+
|
35
|
+
it "returns the number if the number is lower" do
|
36
|
+
5.sanity_check_max(7).should == 5
|
37
|
+
end
|
38
|
+
end
|
11
39
|
end
|
@@ -8,44 +8,44 @@ describe Object do
|
|
8
8
|
|
9
9
|
describe "#blank?" do
|
10
10
|
it "is blank when nil" do
|
11
|
-
nil.
|
11
|
+
nil.should be_blank
|
12
12
|
end
|
13
13
|
|
14
14
|
it "is blank when false" do
|
15
|
-
false.
|
15
|
+
false.should be_blank
|
16
16
|
end
|
17
17
|
|
18
18
|
it "is not blank when true" do
|
19
|
-
true.
|
19
|
+
true.should_not be_blank
|
20
20
|
end
|
21
21
|
|
22
22
|
it "is not blank when numeric" do
|
23
|
-
[0, 1].each { |n| n.
|
23
|
+
[0, 1].each { |n| n.should_not be_blank }
|
24
24
|
end
|
25
25
|
|
26
26
|
context "when a string" do
|
27
27
|
it "is blank if the string is empty" do
|
28
|
-
"".
|
28
|
+
"".should be_blank
|
29
29
|
end
|
30
30
|
|
31
31
|
it "is blank if only whitespace" do
|
32
|
-
[" ", "\n \t"].each { |str| str.
|
33
|
-
" something here ".
|
32
|
+
[" ", "\n \t"].each { |str| str.should be_blank }
|
33
|
+
" something here ".should_not be_blank
|
34
34
|
end
|
35
35
|
|
36
36
|
it "is not blank if the string has content" do
|
37
|
-
"string".
|
37
|
+
"string".should_not be_blank
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
context "when a collection" do
|
42
42
|
it "is blank if the collection is empty" do
|
43
|
-
[[], {}].each { |collection| collection.
|
43
|
+
[[], {}].each { |collection| collection.should be_blank }
|
44
44
|
end
|
45
45
|
|
46
46
|
it "is not blank if there are elements in the collection" do
|
47
47
|
[[1, 2, 3], { 1 => 2, 3 => 4 }].each do |collection|
|
48
|
-
collection.
|
48
|
+
collection.should_not be_blank
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
@@ -53,10 +53,10 @@ describe Object do
|
|
53
53
|
|
54
54
|
describe "#present?" do
|
55
55
|
it "is the inverse of #blank?" do
|
56
|
-
[0, 1].each { |n| n.
|
57
|
-
[[], {}].each { |collection| collection.
|
58
|
-
["", " "].each { |str| str.
|
59
|
-
["str", " str "].each { |str| str.
|
56
|
+
[0, 1].each { |n| n.should be_present }
|
57
|
+
[[], {}].each { |collection| collection.should_not be_present }
|
58
|
+
["", " "].each { |str| str.should_not be_present }
|
59
|
+
["str", " str "].each { |str| str.should be_present }
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -24,9 +24,8 @@ describe Enumerable do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
describe "#heredoc" do
|
27
|
-
|
28
|
-
|
29
|
-
let(:test) do <<-EOS.heredoc
|
27
|
+
it "strips all excess whitespace from the left" do
|
28
|
+
test = <<-EOS.heredoc
|
30
29
|
This is a test of String#heredoc.
|
31
30
|
This text should be left-aligned.
|
32
31
|
This text is indented by four spaces.
|
@@ -35,9 +34,8 @@ describe Enumerable do
|
|
35
34
|
now one space...
|
36
35
|
Left-aligned again.
|
37
36
|
EOS
|
38
|
-
end
|
39
37
|
|
40
|
-
|
38
|
+
test.should == <<EOS
|
41
39
|
This is a test of String#heredoc.
|
42
40
|
This text should be left-aligned.
|
43
41
|
This text is indented by four spaces.
|
@@ -47,9 +45,5 @@ This text should be left-aligned.
|
|
47
45
|
Left-aligned again.
|
48
46
|
EOS
|
49
47
|
end
|
50
|
-
|
51
|
-
it "strips all excess whitespace from the left" do
|
52
|
-
test.should == expected
|
53
|
-
end
|
54
48
|
end
|
55
49
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nutella
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.9'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fuubar
|
@@ -122,14 +122,22 @@ files:
|
|
122
122
|
- lib/nutella/core_ext/object.rb
|
123
123
|
- lib/nutella/core_ext/string.rb
|
124
124
|
- lib/nutella/core_ext/file.rb
|
125
|
+
- lib/nutella/core_ext/enumerable/group.rb
|
126
|
+
- lib/nutella/core_ext/enumerable/sum.rb
|
127
|
+
- lib/nutella/core_ext/enumerable/apply.rb
|
128
|
+
- lib/nutella/core_ext/enumerable/map.rb
|
129
|
+
- lib/nutella/core_ext/enumerable/search.rb
|
125
130
|
- lib/nutella/core_ext/integer.rb
|
126
131
|
- lib/nutella/core_ext/hash.rb
|
127
132
|
- lib/nutella/core_ext/object/blank.rb
|
128
133
|
- lib/nutella/core_ext/object/aliases.rb
|
134
|
+
- lib/nutella/core_ext/numeric/sanity_check.rb
|
135
|
+
- lib/nutella/core_ext/numeric/bytes.rb
|
129
136
|
- lib/nutella/core_ext/enumerable.rb
|
130
137
|
- lib/nutella/core_ext.rb
|
131
138
|
- spec/support/alias.rb
|
132
139
|
- spec/support/number_formats.rb
|
140
|
+
- spec/support/apply_tester.rb
|
133
141
|
- spec/nutella/core_ext/object_spec.rb
|
134
142
|
- spec/nutella/core_ext/hash_spec.rb
|
135
143
|
- spec/nutella/core_ext/numeric_spec.rb
|
@@ -164,7 +172,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
172
|
version: '0'
|
165
173
|
segments:
|
166
174
|
- 0
|
167
|
-
hash:
|
175
|
+
hash: 830849630549550428
|
168
176
|
requirements: []
|
169
177
|
rubyforge_project:
|
170
178
|
rubygems_version: 1.8.24
|
@@ -174,6 +182,7 @@ summary: Spread some Nutella on Ruby to sweeten up its functionality.
|
|
174
182
|
test_files:
|
175
183
|
- spec/support/alias.rb
|
176
184
|
- spec/support/number_formats.rb
|
185
|
+
- spec/support/apply_tester.rb
|
177
186
|
- spec/nutella/core_ext/object_spec.rb
|
178
187
|
- spec/nutella/core_ext/hash_spec.rb
|
179
188
|
- spec/nutella/core_ext/numeric_spec.rb
|