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