backports 1.3.1 → 1.5.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.
@@ -1,5 +1,34 @@
1
1
  = Packable --- History
2
2
 
3
+ == Version 1.5 - April 24, 2009
4
+
5
+ * Array (completed)
6
+ * +combination+
7
+ * +try_convert+
8
+ * Optional block for collect!, :map!, :each, :each_index, :reject, :reject!, :delete_if
9
+ * +pop+, +shift+
10
+ * +product+
11
+
12
+ * Fixnum (completed)
13
+ * +div+, +fdiv+
14
+ * +succ+
15
+ * +magnitude+
16
+
17
+ * Enumerable (completed)
18
+ * +each_with_object+
19
+ * +inject+
20
+ * +max_by+, +min_by+, +minmax+, +minmax_by+
21
+ * +reduce+
22
+ * +to_a+
23
+
24
+ == Version 1.4 - April 21, 2009
25
+
26
+ * String
27
+ * +rpartition+
28
+
29
+ * Proc
30
+ * +yield+
31
+
3
32
  == Version 1.3 - April 17, 2009
4
33
 
5
34
  * Enumerable
@@ -47,28 +47,20 @@ Compatible with Ruby 1.8 & 1.9.
47
47
  * +constantize+
48
48
  * +partition+, +rpartition+
49
49
  * Hash
50
- * <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
51
- * +key+
52
50
  * +symbolize_keys+, <tt>symbolize_keys!</tt>
53
51
  * +reverse_merge+, <tt>reverse_merge!</tt>
52
+ * <tt>Hash[[[:foo, :bar],[:hello, "world"]]] ==> {:foo => :bar, :hello => "world"}</tt> (see _note_)
53
+ * +key+
54
54
  * <tt>default_proc=</tt>
55
55
  * Enumerable
56
56
  * +sum+
57
- * +find_index+
58
- * +take+, +take_while+, +drop+, +drop_while+
59
- * +first+
60
- * +reverse_each+
61
- * +count+
62
- * +cycle+
63
- * +group_by+
64
- * <tt>none?</tt>
57
+ * complete Ruby 1.8.7 backport
65
58
  * Array
66
- * +flatten+, <tt>flatten!</tt>
67
- * +find_index+, +find+
68
- * +reverse_each+
69
- * +cycle+
59
+ * complete Ruby 1.8.7 backport
70
60
  * Fixnum
71
- * <tt>odd?</tt>, <tt>even?</tt>
61
+ * complete Ruby 1.8.7 backport
62
+ * Proc
63
+ * +yield+
72
64
 
73
65
  Finally, there is no need to <tt>require 'enumerator'</tt> in older Ruby, and +Enumerator+ can be accessed directly (instead of <tt>Enumerable::Enumerator</tt>)
74
66
 
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
- :minor: 3
4
- :patch: 1
3
+ :minor: 5
4
+ :patch: 0
@@ -10,6 +10,6 @@ module Kernel
10
10
  end unless method_defined? :require_relative
11
11
  end
12
12
 
13
- %w(object module array enumerable string symbol fixnum hash).each do |lib|
13
+ %w(object module array enumerable string symbol fixnum hash proc).each do |lib|
14
14
  require_relative "backports/#{lib}"
15
15
  end
@@ -1,4 +1,52 @@
1
1
  class Array
2
+ class << self
3
+ # Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
4
+ def try_convert(x)
5
+ x.to_ary if x.respond_to? :to_ary
6
+ end unless method_defined? :try_convert
7
+ end
8
+
9
+ # Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
10
+ unless ([42].map! rescue false)
11
+ # Make block optional for...
12
+ [:collect!, :map!, :each, :each_index, :reverse_each, :reject, :reject!, :delete_if].each do |selector|
13
+ alias_method_chain(selector, :optional_block) do |aliased_target, punctuation|
14
+ module_eval <<-end_eval
15
+ def #{aliased_target}_with_optional_block#{punctuation}(*args, &block)
16
+ return to_enum(:#{aliased_target}_without_optional_block#{punctuation}, *args) unless block_given?
17
+ #{aliased_target}_without_optional_block#{punctuation}(*args, &block)
18
+ end
19
+ end_eval
20
+ end
21
+ end
22
+ end
23
+
24
+ # Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
25
+ def combination(num)
26
+ num = num.to_i
27
+ return to_enum(:combination, num) unless block_given?
28
+ return self unless (0..size).include? num
29
+ # Implementation note: slightly tricky.
30
+ # Example: self = 1..7, num = 3
31
+ picks = (0...num).to_a # picks start at 0, 1, 2
32
+ max = ((size-num)...size).to_a # max (index for a given pick) is [4, 5, 6]
33
+ pick_max_pairs = picks.zip(max).reverse # pick_max_pairs = [[2, 6], [1, 5], [0, 4]]
34
+ lookup = pick_max_pairs.find(Proc.new{return self})
35
+ loop do
36
+ yield values_at(*picks)
37
+ move = lookup.each{|pick, max| picks[pick] < max}.first
38
+ new_index = picks[move] + 1
39
+ picks[move...num] = (new_index...(new_index+num-move)).to_a
40
+ end
41
+ end unless method_defined? :combination
42
+
43
+ # Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
44
+ def cycle(*arg, &block)
45
+ return to_enum(:cycle, *arg) unless block_given?
46
+ nb = arg.empty? ? (1/0.0) : arg.first
47
+ nb.to_i.times{each(&block)}
48
+ end unless method_defined? :cycle
49
+
2
50
  # flatten & flatten!, standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
3
51
  unless ([[]].flatten(1) rescue false)
4
52
 
@@ -57,6 +105,30 @@ class Array
57
105
  alias_method :find_index, :index
58
106
  end
59
107
 
108
+ # pop. Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
109
+ unless ([1].pop(1) rescue false)
110
+ def pop_with_optional_argument(*arg)
111
+ return pop_without_optional_argument if arg.empty?
112
+ n = arg.first.to_i
113
+ slice!([0,size-n].max, size)
114
+ end
115
+ alias_method_chain :pop, :optional_argument
116
+ end
117
+
118
+ def product(*arg)
119
+ arg.unshift(self)
120
+ arg._partial_cartesian_product(arg.size-1, Array.new(arg.size), [])
121
+ end unless method_defined? :product
122
+
123
+ def _partial_cartesian_product(combi, iterate_index, result)
124
+ action = iterate_index.zero? ? Proc.new(result << combi.dup) : Proc.new(_sub(combi, iterate_index-1, &block))
125
+ self[iterate_index].each do |obj|
126
+ combi[iterate_index] = obj
127
+ action.call
128
+ end
129
+ end
130
+ private :_partial_cartesian_product
131
+
60
132
  # rindex
61
133
  unless ([1].rindex{true} rescue false)
62
134
  def rindex_with_block(*arg)
@@ -66,20 +138,17 @@ class Array
66
138
  end
67
139
  alias_method_chain :rindex, :block
68
140
  end
69
-
70
- unless ([1].reverse_each rescue false)
71
- def reverse_each_with_optional_block(&block)
72
- return reverse_each_without_optional_block(&block) if block_given?
73
- to_enum(:reverse_each)
141
+
142
+ # shift. Standard in Ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Array.html]
143
+ unless ([1].shift(1) rescue false)
144
+ def shift_with_optional_argument(*arg)
145
+ return shift_without_optional_argument if arg.empty?
146
+ n = arg.first.to_i
147
+ slice!(0, n)
74
148
  end
75
- alias_method_chain :reverse_each, :optional_block
149
+ alias_method_chain :shift, :optional_argument
76
150
  end
77
151
 
78
- def cycle(*arg, &block)
79
- return to_enum(:cycle, *arg) unless block_given?
80
- nb = arg.empty? ? (1/0.0) : arg.first
81
- nb.to_i.times{each(&block)}
82
- end unless method_defined? :cycle
83
152
 
84
153
  def sample(*arg)
85
154
  return self[rand(size)] if arg.empty?
@@ -10,42 +10,35 @@ module Enumerable
10
10
  end unless method_defined? :sum
11
11
 
12
12
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
13
- def find_index(*args)
14
- if args.size == 1
15
- obj = args.first
16
- each_with_index do |element, i|
17
- return i if element == obj
18
- end
19
- elsif block_given?
20
- each_with_index do |element, i|
21
- return i if yield element
22
- end
23
- each_with_index{|o,i| return i if yield o}
13
+ def count(*arg)
14
+ result = 0
15
+ if block_given?
16
+ each{|o| result += 1 if yield o}
17
+ elsif arg.empty?
18
+ each{|o| result += 1}
24
19
  else
25
- raise ArgumentError, "Wrong number of arguments (#{args.size} for 1)"
20
+ obj = arg.first
21
+ each{|o| result += 1 if obj == o}
26
22
  end
27
- nil
28
- end unless method_defined? :find_index
23
+ result
24
+ end unless method_defined? :count
29
25
 
30
26
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
31
- def take(n)
32
- returning([]) do |array|
33
- each do |elem|
34
- array << elem
35
- break if array.size >= n
36
- end unless n <= 0
37
- end
38
- end unless method_defined? :take
27
+ def cycle(*arg, &block)
28
+ return to_enum(:cycle, *arg) unless block_given?
29
+ to_a.cycle(*arg, &block)
30
+ end unless method_defined? :cycle
39
31
 
40
32
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
41
- def take_while
42
- return to_enum(:take_while) unless block_given?
43
- inject([]) do |array, elem|
44
- return array unless yield elem
45
- array << elem
33
+ unless ([].detect rescue false)
34
+ def detect_with_optional_block(ifnone = nil, &block)
35
+ return to_enum(:detect, ifnone) unless block_given?
36
+ detect_without_optional_block(ifnone, &block)
46
37
  end
47
- end unless method_defined? :take_while
48
-
38
+ alias_method_chain :detect, :optional_block
39
+ alias_method :find, :detect
40
+ end
41
+
49
42
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
50
43
  def drop(n)
51
44
  array = to_a
@@ -63,18 +56,15 @@ module Enumerable
63
56
  end unless method_defined? :drop_while
64
57
 
65
58
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
66
- def first(*arg)
67
- arg.empty? ? take(1)[0] : take(arg.first)
68
- end unless method_defined? :first
59
+ unless ((1..2).each_cons(1) rescue false)
60
+ def each_cons_with_optional_block(len, &block)
61
+ raise ArgumentError, "invalid size" if len <= 0
62
+ return to_enum(:each_cons, len) unless block_given?
63
+ each_cons_without_optional_block(len, &block)
64
+ end
65
+ alias_method_chain :each_cons, :optional_block
66
+ end
69
67
 
70
- # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
71
- def reverse_each(&block)
72
- return to_enum(:reverse_each) unless block_given?
73
- # There is no other way then to convert to an array first... see 1.9's source.
74
- to_a.reverse_each(&block)
75
- self
76
- end unless method_defined? :reverse_each
77
-
78
68
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
79
69
  unless ((1..2).each_slice(1) rescue false)
80
70
  def each_slice_with_optional_block(len, &block)
@@ -84,36 +74,45 @@ module Enumerable
84
74
  end
85
75
  alias_method_chain :each_slice, :optional_block
86
76
  end
87
-
77
+
88
78
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
89
- def count(*arg)
90
- result = 0
91
- if block_given?
92
- each{|o| result += 1 if yield o}
93
- elsif arg.empty?
94
- each{|o| result += 1}
95
- else
96
- obj = arg.first
97
- each{|o| result += 1 if obj == o}
79
+ if instance_method(:each_with_index).arity.zero?
80
+ def each_with_index_with_optional_args_and_block(*args, &block)
81
+ return to_enum(:each_with_index, *args) unless block_given?
82
+ to_enum(:each, *args).each_with_index_without_optional_args_and_block(&block)
98
83
  end
99
- result
100
- end unless method_defined? :count
84
+ alias_method_chain :each_with_index, :optional_args_and_block
85
+ end
101
86
 
102
87
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
103
- def cycle(*arg, &block)
104
- return to_enum(:cycle, *arg) unless block_given?
105
- to_a.cycle(*arg, &block)
106
- end unless method_defined? :cycle
107
-
88
+ def each_with_object(memo, &block)
89
+ return to_enum(:each_with_object, memo) unless block_given?
90
+ each {|obj| block.call(obj, memo)}
91
+ memo
92
+ end unless method_defined? :each_with_object
93
+
108
94
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
109
- unless ((1..2).each_cons(1) rescue false)
110
- def each_cons_with_optional_block(len, &block)
111
- raise ArgumentError, "invalid size" if len <= 0
112
- return to_enum(:each_cons, len) unless block_given?
113
- each_cons_without_optional_block(len, &block)
95
+ def find_index(*args)
96
+ if args.size == 1
97
+ obj = args.first
98
+ each_with_index do |element, i|
99
+ return i if element == obj
100
+ end
101
+ elsif block_given?
102
+ each_with_index do |element, i|
103
+ return i if yield element
104
+ end
105
+ each_with_index{|o,i| return i if yield o}
106
+ else
107
+ raise ArgumentError, "Wrong number of arguments (#{args.size} for 1)"
114
108
  end
115
- alias_method_chain :each_cons, :optional_block
116
- end
109
+ nil
110
+ end unless method_defined? :find_index
111
+
112
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
113
+ def first(*arg)
114
+ arg.empty? ? take(1)[0] : take(arg.first)
115
+ end unless method_defined? :first
117
116
 
118
117
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
119
118
  def group_by
@@ -125,9 +124,122 @@ module Enumerable
125
124
  end
126
125
  end unless method_defined? :group_by
127
126
 
127
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
128
+ unless ((1..2).inject(:+) rescue false)
129
+ def inject_with_symbol(*args, &block)
130
+ return inject_without_symbol(*args, &block) if block_given?
131
+ method = args.pop
132
+ raise TypeError, "#{method} is not a symbol" unless method.respond_to? :to_sym
133
+ method = method.to_sym
134
+ inject_without_symbol(*args) {|memo, obj| memo.send(method, obj)}
135
+ end
136
+ alias_method_chain :inject, :symbol
137
+ end
138
+
139
+ MOST_EXTREME_OBJECT_EVER = Object.new # :nodoc:
140
+ class << MOST_EXTREME_OBJECT_EVER
141
+ def < (whatever)
142
+ true
143
+ end
144
+
145
+ def > (whatever)
146
+ true
147
+ end
148
+ end
149
+
150
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
151
+ def max_by(&block)
152
+ return to_enum(:max_by) unless block_given?
153
+ minmax_by(&block)[1]
154
+ end unless method_defined? :max_by
155
+
156
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
157
+ def min_by(&block)
158
+ return to_enum(:min_by) unless block_given?
159
+ minmax_by(&block).first
160
+ end unless method_defined? :min_by
161
+
162
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
163
+ def minmax
164
+ return minmax{|a,b| a <=> b} unless block_given?
165
+ first_time = true
166
+ min, max = nil
167
+ each do |object|
168
+ if first_time
169
+ min = max = object
170
+ first_time = false
171
+ else
172
+ min = object if yield(min, object) > 0
173
+ max = object if yield(max, object) < 0
174
+ end
175
+ end
176
+ [min, max]
177
+ end unless method_defined? :minmax
178
+
179
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
180
+ def minmax_by(&block)
181
+ return to_enum(:minmax_by) unless block_given?
182
+ min_object, min_result = nil, MOST_EXTREME_OBJECT_EVER
183
+ max_object, max_result = nil, MOST_EXTREME_OBJECT_EVER
184
+ each do |object|
185
+ result = yield object
186
+ min_object, min_result = object, result if min_result > result
187
+ max_object, max_result = object, result if max_result < result
188
+ end
189
+ [min_object, max_object]
190
+ end unless method_defined? :minmax_by
191
+
128
192
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
129
193
  def none?(&block)
130
194
  !any?(&block)
131
195
  end unless method_defined? :none?
132
196
 
197
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
198
+ def one?(&block)
199
+ return one?{|o| o} unless block_given?
200
+ 1 == count(&block)
201
+ end unless method_defined? :one?
202
+
203
+ alias_method :reduce, :inject unless method_defined? :reduce
204
+
205
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
206
+ def reverse_each(&block)
207
+ return to_enum(:reverse_each) unless block_given?
208
+ # There is no other way then to convert to an array first... see 1.9's source.
209
+ to_a.reverse_each(&block)
210
+ self
211
+ end unless method_defined? :reverse_each
212
+
213
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
214
+ def take(n)
215
+ returning([]) do |array|
216
+ each do |elem|
217
+ array << elem
218
+ break if array.size >= n
219
+ end unless n <= 0
220
+ end
221
+ end unless method_defined? :take
222
+
223
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
224
+ def take_while
225
+ return to_enum(:take_while) unless block_given?
226
+ inject([]) do |array, elem|
227
+ return array unless yield elem
228
+ array << elem
229
+ end
230
+ end unless method_defined? :take_while
231
+
232
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Enumerable.html]
233
+ if instance_method(:to_a).arity.zero?
234
+ def to_a_with_optional_arguments(*args)
235
+ return to_a_without_optional_arguments if args.empty?
236
+ to_enum(:each, *args).to_a
237
+ end
238
+ alias_method_chain :to_a, :optional_arguments
239
+ end
240
+
133
241
  end
242
+
243
+ class Enumerator
244
+ alias_method :with_object, :each_with_object unless method_defined? :with_object
245
+ end
@@ -1,11 +1,33 @@
1
1
  class Fixnum
2
2
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
3
- def odd?
4
- self & 1 == 1
5
- end unless method_defined? :odd?
6
-
3
+ def div(n)
4
+ (self / n).round
5
+ end unless method_defined? :div
6
+
7
7
  # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
8
8
  def even?
9
9
  self & 1 == 0
10
10
  end unless method_defined? :even?
11
+
12
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
13
+ def fdiv(n)
14
+ to_f / n
15
+ end unless method_defined? :fdiv
16
+
17
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
18
+ def odd?
19
+ self & 1 == 1
20
+ end unless method_defined? :odd?
21
+
22
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Fixnum.html]
23
+ def succ
24
+ self + 1
25
+ end unless method_defined? :succ
26
+
27
+ alias_method :magnitude, :abs unless method_defined? :magnitude
28
+
29
+
30
+
31
+
32
+
11
33
  end
@@ -9,6 +9,11 @@ class Hash
9
9
  arg.first.each{|key, value| h[key] = value}
10
10
  end
11
11
  end unless (Hash[[[:test, :test]]] rescue false)
12
+
13
+ def try_convert(x)
14
+ return nil unless x.respond_to? :to_hash
15
+ x.to_hash
16
+ end unless method_defined? :to_hash
12
17
  end
13
18
 
14
19
  # Standard in rails. See official documentation[http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/Keys.html]
@@ -0,0 +1,4 @@
1
+ class Proc
2
+ # Standard in ruby 1.9. See official documentation[http://ruby-doc.org/core-1.9/classes/Proc.html]
3
+ alias_method :yield, :call unless method_defined? :yield
4
+ end
@@ -2,17 +2,21 @@ require 'test_helper'
2
2
 
3
3
  class ArrayTest < Test::Unit::TestCase
4
4
  context "Array" do
5
- context "#reverse_each" do
6
- should "return an enumerator when no block is given" do
7
- assert_equal [4,3,2], [1,2,3,4].reverse_each.take(3)
5
+ context "#combination" do
6
+ should "conform to doc" do
7
+ a = [ "a", "b", "c" ]
8
+ assert_equal [["a"], ["b"], ["c"]], a.combination(1).to_a
9
+ assert_equal [["a", "b"], ["a", "c"], ["b", "c"]], a.combination(2).to_a
10
+ assert_equal [["a", "b", "c"]], a.combination(3).to_a
11
+ assert_equal [], a.combination(4).to_a
8
12
  end
9
13
  end
10
-
14
+
11
15
  context "#flatten" do
12
16
  should "conform to doc" do
13
- s = [ 1, 2, 3 ] #=> [1, 2, 3]
14
- t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
15
- a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
17
+ s = [ 1, 2, 3 ]
18
+ t = [ 4, 5, 6, [7, 8] ]
19
+ a = [ s, t, 9, 10 ]
16
20
  assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], a.flatten
17
21
  a = [ 1, 2, [3, [4, 5] ] ]
18
22
  assert_equal [1, 2, 3, [4, 5]], a.flatten(1)
@@ -28,6 +32,30 @@ class ArrayTest < Test::Unit::TestCase
28
32
  end
29
33
  end
30
34
 
35
+ context "#reverse_each" do
36
+ should "return an enumerator when no block is given" do
37
+ assert_equal [4,3,2], [1,2,3,4].reverse_each.take(3)
38
+ end
39
+ end
40
+
41
+ context "#pop" do
42
+ should "conform to doc" do
43
+ a = %w{ f r a b j o u s }
44
+ assert_equal "s", a.pop
45
+ assert_equal ["f", "r", "a", "b", "j", "o", "u"] , a
46
+ assert_equal ["j", "o", "u"], a.pop(3)
47
+ assert_equal ["f", "r", "a", "b"] , a
48
+ end
49
+ end
50
+
51
+ context "#product" do
52
+ should "conform to doc" do
53
+ assert_equal [[1, 3], [1, 4], [2, 3], [2, 4]], [1, 2].product([3, 4])
54
+ assert_equal [[1, 3, 5], [1, 4, 5], [2, 3, 5], [2, 4, 5]], [1, 2].product([3, 4], [5])
55
+ assert_equal [[1], [2]], [1, 2].product
56
+ end
57
+ end
58
+
31
59
  context "#sample" do
32
60
  should "conform to doc" do
33
61
  assert_equal nil, [].sample
@@ -38,7 +66,16 @@ class ArrayTest < Test::Unit::TestCase
38
66
  s = a.sample(2)
39
67
  assert_equal 2, s.size
40
68
  assert_equal 1, (a-s).size
41
- assert_equal [], a-(0..20).sum{a.sample(2)} # ~ 3e-10
69
+ assert_equal [], a-(0..20).sum{a.sample(2)}
70
+ end
71
+ end
72
+
73
+ context "#shift" do
74
+ should "conform to doc" do
75
+ args = [ "-m", "-q", "-v", "filename" ]
76
+ assert_equal "-m", args.shift
77
+ assert_equal ["-q", "-v"], args.shift(2)
78
+ assert_equal ["filename"], args
42
79
  end
43
80
  end
44
81
  end
@@ -1,41 +1,22 @@
1
1
  require 'test_helper'
2
+ require 'stringio'
2
3
 
3
4
  class EnumerableTest < Test::Unit::TestCase
4
5
  context "Enumerable" do
5
- context "#find_index" do
6
+ context "#count" do
6
7
  should "conform to doc" do
7
- assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
8
- assert_equal nil, %w{ant bat cat dog}.find_index {|item| item =~ /h/ }
9
- end
10
-
11
- should "#work for enumerables too" do
12
- assert_equal 69-42, (42..666).find_index(69)
8
+ assert_equal 4, (1..4).count
9
+ assert_equal 1, (1..4).count(3)
10
+ assert_equal 2, (1..4).count{|obj| obj > 2 }
13
11
  end
14
12
  end
15
13
 
16
- context "#take" do
17
- should "conform to doc" do
18
- assert_equal [1, 2, 3], (1..7).take(3)
19
- assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
20
- end
21
-
22
- should "only consume what's needed" do
23
- assert_equal [], Enumerator.new(nil).take(0)
24
- assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
25
- end
26
- end
27
-
28
- context "#take_while" do
14
+ context "#cycle" do
29
15
  should "conform to doc" do
30
- assert_equal [1,2], (1..7).take_while {|item| item < 3 }
31
- assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
32
- end
33
-
34
- should "work with infinite enumerables" do
35
- assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
16
+ assert_equal ["a", "b", "c", "a", "b", "c"], ('a'..'c').cycle(2).to_a
36
17
  end
37
18
  end
38
-
19
+
39
20
  context "#drop" do
40
21
  should "conform to doc" do
41
22
  assert_equal [5, 8, 13], [ 1, 1, 2, 3, 5, 8, 13 ].drop(4)
@@ -62,9 +43,9 @@ class EnumerableTest < Test::Unit::TestCase
62
43
  end
63
44
  end
64
45
 
65
- context "#reverse_each" do
66
- should "work as expected" do
67
- assert_equal [4,3,2], (1..4).reverse_each.take(3)
46
+ context "#each_cons" do
47
+ should "conform to doc" do
48
+ assert_equal [[1,2],[2,3],[3,4]], (1..4).each_cons(2).to_a
68
49
  end
69
50
  end
70
51
 
@@ -76,27 +57,43 @@ class EnumerableTest < Test::Unit::TestCase
76
57
  assert_equal [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10]], (1..10).each_slice(4).to_a
77
58
  end
78
59
  end
79
-
80
- context "#count" do
60
+
61
+ context "#each_with_index" do
81
62
  should "conform to doc" do
82
- assert_equal 4, (1..4).count
83
- assert_equal 1, (1..4).count(3)
84
- assert_equal 2, (1..4).count{|obj| obj > 2 }
63
+ hash = Hash.new
64
+ %w(cat dog wombat).each_with_index do |item, index|
65
+ hash[item] = index
66
+ end
67
+ assert_equal({"cat"=>0, "wombat"=>2, "dog"=>1}, hash)
85
68
  end
69
+
70
+ should "be ok with arguments and no block" do
71
+ s = StringIO.new("Hello world!")
72
+ assert_equal [["Hello",0], [" wo",1], ["rld!",2]], s.each_with_index("o").to_a
73
+ end
74
+
86
75
  end
87
76
 
88
- context "#cycle" do
77
+ context "#each_with_object" do
89
78
  should "conform to doc" do
90
- assert_equal ["a", "b", "c", "a", "b", "c"], ('a'..'c').cycle(2).to_a
79
+ hash = %w(cat dog wombat).each_with_object({}) do |item, memo|
80
+ memo[item] = item.upcase.reverse
81
+ end
82
+ assert_equal({"cat"=>"TAC", "dog"=>"GOD", "wombat"=>"TABMOW"}, hash)
91
83
  end
92
84
  end
93
-
94
- context "#each_cons" do
85
+
86
+ context "#find_index" do
95
87
  should "conform to doc" do
96
- assert_equal [[1,2],[2,3],[3,4]], (1..4).each_cons(2).to_a
88
+ assert_equal 3, %w{ant bat cat dog}.find_index {|item| item =~ /g/ }
89
+ assert_equal nil, %w{ant bat cat dog}.find_index {|item| item =~ /h/ }
90
+ end
91
+
92
+ should "#work for enumerables too" do
93
+ assert_equal 69-42, (42..666).find_index(69)
97
94
  end
98
95
  end
99
-
96
+
100
97
  context "#group_by" do
101
98
  should "conform to doc" do
102
99
  x = (1..5).group_by{|item| item.even? ? :even : :odd }
@@ -104,5 +101,83 @@ class EnumerableTest < Test::Unit::TestCase
104
101
  assert_equal nil, x[:xyz]
105
102
  end
106
103
  end
104
+
105
+ context "#inject" do
106
+ should "conform to doc" do
107
+ assert_equal 45, (5..10).inject(0) {|sum, n| sum + n }
108
+ assert_equal 45, (5..10).inject {|sum, n| sum + n }
109
+ assert_equal 45, (5..10).inject(0, :+)
110
+ assert_equal 45, (5..10).inject(:+)
111
+ end
112
+ end
113
+
114
+ context "#max_by" do
115
+ should "conform to doc" do
116
+ a = %w(albatross dog horse fox)
117
+ assert_equal "albatross" , a.max_by {|item| item.length }
118
+ assert_equal "fox", a.max_by {|item| item.reverse }
119
+ end
120
+ end
121
+
122
+ context "#min_by" do
123
+ should "conform to doc" do
124
+ a = %w(albatross dog horse fox)
125
+ assert_equal "dog" , a.min_by {|item| item.length }
126
+ assert_equal "horse", a.min_by {|item| item.reverse }
127
+ end
128
+ end
129
+
130
+ context "#minmax" do
131
+ should "conform to doc" do
132
+ a = %w(albatross dog horse)
133
+ assert_equal ["albatross", "horse"], a.minmax
134
+ assert_equal ["dog", "albatross"], a.minmax {|a,b| a.length <=> b.length }
135
+ end
136
+ end
137
+
138
+ context "#one" do
139
+ should "conform to doc" do
140
+ assert_equal false, %w{ ant bear cat}.one? {|word| word.length >= 3}
141
+ assert_equal true, %w{ ant bear cat}.one? {|word| word.length >= 4}
142
+ assert_equal true, [ nil, nil, 99 ].one?
143
+ end
144
+ end
145
+
146
+ context "#reverse_each" do
147
+ should "work as expected" do
148
+ assert_equal [4,3,2], (1..4).reverse_each.take(3)
149
+ end
150
+ end
151
+
152
+ context "#take" do
153
+ should "conform to doc" do
154
+ assert_equal [1, 2, 3], (1..7).take(3)
155
+ assert_equal [["a", 1], ["b", 2]], { 'a'=>1, 'b'=>2, 'c'=>3 }.take(2)
156
+ end
157
+
158
+ should "only consume what's needed" do
159
+ assert_equal [], Enumerator.new(nil).take(0)
160
+ assert_raises(NoMethodError) { Enumerator.new(nil).take(1) }
161
+ end
162
+ end
163
+
164
+ context "#take_while" do
165
+ should "conform to doc" do
166
+ assert_equal [1,2], (1..7).take_while {|item| item < 3 }
167
+ assert_equal [2,4,6], [ 2, 4, 6, 9, 11, 16 ].take_while(&:even?)
168
+ end
169
+
170
+ should "work with infinite enumerables" do
171
+ assert_equal [1,2], (1..(1/0.0)).take_while {|item| item < 3 }
172
+ end
173
+ end
174
+
175
+ context "#to_a" do
176
+ should "work with arguments" do
177
+ s = StringIO.new("Hello world!")
178
+ assert_equal ["Hello", " wo", "rld!"], s.to_a("o")
179
+ end
180
+ end
181
+
107
182
  end
108
183
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backports
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Marc-Andr\xC3\xA9 Lafortune"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-20 00:00:00 -04:00
12
+ date: 2009-04-24 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -35,6 +35,7 @@ files:
35
35
  - lib/backports/hash.rb
36
36
  - lib/backports/module.rb
37
37
  - lib/backports/object.rb
38
+ - lib/backports/proc.rb
38
39
  - lib/backports/string.rb
39
40
  - lib/backports/symbol.rb
40
41
  - test/array_test.rb