backports 1.3.1 → 1.5.0

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