1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
require 'test/minirunit'
require 'enumerator'
test_ok defined?(Enumerable::Enumerator)
######################
# Everything in the right place
######################
test_ok(Object.instance_methods.include?("enum_for"))
test_ok(Object.instance_methods.include?("to_enum"))
test_ok(Enumerable.instance_methods.include?("each_slice"))
test_ok(Enumerable.instance_methods.include?("each_cons"))
test_ok(Enumerable.instance_methods.include?("enum_with_index"))
test_ok(Enumerable.instance_methods.include?("enum_slice"))
test_ok(Enumerable.instance_methods.include?("enum_cons"))
test_ok(Enumerable::Enumerator.public_methods.include?("new"))
test_ok(!Enumerable::Enumerator.instance_methods.include?("initialize"))
test_ok(Enumerable::Enumerator.instance_methods.include?("each"))
test_ok(Enumerable::Enumerator.ancestors.include?(Enumerable))
######################
# Object#enum_for & Object#to_enum
######################
test_ok([97, 98, 99], "abc".enum_for(:each_byte).map { |b| b })
test_ok([97, 98, 99], "abc".to_enum(:each_byte).map { |b| b })
class Wobble
def each
3.times do |index|
yield(1) if block_given?
end
end
def each_with_args(count, multiplier)
count.times do |index|
yield(index * multiplier) if block_given?
end
end
def each_needing_block
yield(123)
end
def each_not_needing_block
end
end
#defaults to enumerating over :each
test_ok([1, 1, 1], Wobble.new.enum_for.map { |b| b })
test_ok([1, 1, 1], Wobble.new.to_enum.map { |b| b })
#parameters passed to enumerator method
test_ok([0, 10, 20], Wobble.new.enum_for(:each_with_args, 3, 10).map { |b| b })
test_ok([0, 10, 20], Wobble.new.to_enum(:each_with_args, 3, 10).map { |b| b })
######################
# Enumerable#enum_with_index
######################
test_equal(
[['a', 0], ['b', 1], ['c', 2]],
['a', 'b', 'c'].enum_with_index.map { |item| item })
test_equal([], [].enum_with_index.map { |item| item })
######################
# Enumerable#enum_slice and Enumerable#each_slice
######################
#It does what it says on the tin!
test_equal([[1], [2], [3]], Enumerable::Enumerator.new([1,2,3], :each_slice, 1).map { |item| item })
test_equal([[1], [2], [3]], [1,2,3].enum_slice(1).map { |item| item })
test_equal([[1,2], [3,4]], Enumerable::Enumerator.new([1,2,3,4], :each_slice, 2).map { |item| item })
test_equal([[1,2], [3,4]], [1,2,3,4].enum_slice(2).map { |item| item })
test_equal([[1,2], [3,4], [5]], Enumerable::Enumerator.new([1,2,3,4,5], :each_slice, 2).map { |item| item })
test_equal([[1,2], [3,4], [5]], [1,2,3,4,5].enum_slice(2).map { |item| item })
#Jagged array not flattened
test_equal([[[1,2],3],[4,5]], Enumerable::Enumerator.new([[1,2],3,4,5], :each_slice, 2).map { |item| item })
test_equal([[[1,2],3],[4,5]], [[1,2],3,4,5].enum_slice(2).map { |item| item })
#empty array
test_equal([], Enumerable::Enumerator.new([], :each_slice, 3).map { |item| item })
test_equal([], [].enum_slice(3).map { |item| item })
#slice count == array count yields
test_equal([[1,2,3]], Enumerable::Enumerator.new([1,2,3], :each_slice, 3).map { |item| item })
test_equal([[1,2,3]], [1,2,3].enum_slice(3).map { |item| item })
#slice count > array count yields array
test_equal([[1,2,3]], Enumerable::Enumerator.new([1,2,3], :each_slice, 4).map { |item| item })
test_equal([[1,2,3]], [1,2,3].enum_slice(4).map { |item| item })
#slice size must be specified
test_exception(ArgumentError) { [].each_cons {} }
test_exception(ArgumentError) { [].enum_cons }
#slice size must be > 0 but error only raised on each
test_exception(ArgumentError) { [1,2,3].each_slice(0) {} }
test_no_exception { [1,2,3].enum_slice(0) }
test_exception(ArgumentError) { [1,2,3].enum_slice(0).each {} }
test_exception(ArgumentError) { [1,2,3].each_slice(-1) {} }
test_no_exception { [1,2,3].enum_slice(-1) }
test_exception(ArgumentError) { [1,2,3].enum_slice(-1).each {} }
#slice size must convertible to integer but error only raised on each
test_exception(TypeError) { [].each_slice(Object.new) {} }
test_no_exception { [].enum_slice(Object.new) }
test_exception(TypeError) { [].enum_slice(Object.new).each {} }
#enum_slice & each_slice always return nil
test_equal(nil, [0,1,2].each_slice(2) { 123 })
test_equal(nil, [0,1,2].enum_slice(2).each { 123 })
######################
# Enumerable#enum_cons and Enumerable#each_const
######################
#It does what it says on the tin!
test_equal([[1,2], [2,3], [3,4], [4,5]], Enumerable::Enumerator.new([1,2,3,4,5], :each_cons, 2).map { |item| item })
test_equal([[1,2], [2,3], [3,4], [4,5]], [1,2,3,4,5].enum_cons(2).map { |item| item })
#Jagged array not flattened
test_equal([[[1,2],3], [3,4], [4,5]], Enumerable::Enumerator.new([[1,2],3,4,5], :each_cons, 2).map { |item| item })
test_equal([[[1,2],3], [3,4], [4,5]], [[1,2],3,4,5].enum_cons(2).map { |item| item })
#cons count == array size yields once
test_equal([[1,2,3]], Enumerable::Enumerator.new([1,2,3], :each_cons, 3).map { |item| item })
test_equal([[1,2,3]], [1,2,3].enum_cons(3).map { |item| item })
#cons count > array size yields nothing
test_equal([], Enumerable::Enumerator.new([1,2,3], :each_cons, 4).map { |item| item.to_s })
test_equal([], [1,2,3].enum_cons(4).map { |item| item.to_s })
#cons size must be specified
test_exception(ArgumentError) { [].each_cons {} }
test_exception(ArgumentError) { [].enum_cons }
#cons size must be > 0 but error only raised on each
test_exception(ArgumentError) { [].each_cons(0) {} }
test_no_exception { [].enum_cons(0) }
test_exception(ArgumentError) { [].enum_slice(0).each {} }
test_exception(ArgumentError) { [].each_slice(-1) {} }
test_no_exception { [].enum_cons(-1) }
test_exception(ArgumentError) { [].enum_slice(-1).each {} }
#cons size must convertible to integer but error only raised on each
test_exception(TypeError) { [].each_cons(Object.new) {} }
test_no_exception { [].enum_cons(Object.new) }
test_exception(TypeError) { [].enum_cons(Object.new).each {} }
#enum_cons & each_cons always returns nil
test_equal(nil, [0,1,2].enum_cons(2).each { })
test_equal(nil, [0,1,2].each_cons(2) { })
######################
# Enumerable::Enumerator
######################
test_exception(ArgumentError) { Enumerable::Enumerator.new }
test_no_exception { Enumerable::Enumerator.new("somestring") }
#NoMethodError if enumeration method doesn't exist
test_exception(NoMethodError) { Enumerable::Enumerator.new(Object.new).each {} }
test_exception(NoMethodError) { Enumerable::Enumerator.new("abc", :each_BYTE).each {} }
#each works!
test_equal([97, 98, 99], Enumerable::Enumerator.new("abc", :each_byte).map { |b| b })
#no block results in LocalJumpError only if enumerating method requires it
test_exception(LocalJumpError) { Enumerable::Enumerator.new(Wobble.new, :each_needing_block).each }
test_no_exception { Enumerable::Enumerator.new(Wobble.new, :each_not_needing_block).each }
# JRUBY-3492: wrong # args when calling super without args in subclass of Enumerable::Enumerator
class JRuby3492 < Enumerable::Enumerator
def initialize(x, y, *z)
super
end
end
test_no_exception {
JRuby3492.new("foo", :each_byte)
}
|