1require_relative '../../spec_helper' 2require_relative 'fixtures/classes' 3 4describe "Array#fill" do 5 before :all do 6 @never_passed = lambda do |i| 7 raise ExpectationNotMetError, "the control path should not pass here" 8 end 9 end 10 11 it "returns self" do 12 ary = [1, 2, 3] 13 ary.fill(:a).should equal(ary) 14 end 15 16 it "is destructive" do 17 ary = [1, 2, 3] 18 ary.fill(:a) 19 ary.should == [:a, :a, :a] 20 end 21 22 it "does not replicate the filler" do 23 ary = [1, 2, 3, 4] 24 str = "x" 25 ary.fill(str).should == [str, str, str, str] 26 str << "y" 27 ary.should == [str, str, str, str] 28 ary[0].should equal(str) 29 ary[1].should equal(str) 30 ary[2].should equal(str) 31 ary[3].should equal(str) 32 end 33 34 it "replaces all elements in the array with the filler if not given a index nor a length" do 35 ary = ['a', 'b', 'c', 'duh'] 36 ary.fill(8).should == [8, 8, 8, 8] 37 38 str = "x" 39 ary.fill(str).should == [str, str, str, str] 40 end 41 42 it "replaces all elements with the value of block (index given to block)" do 43 [nil, nil, nil, nil].fill { |i| i * 2 }.should == [0, 2, 4, 6] 44 end 45 46 it "raises a #{frozen_error_class} on a frozen array" do 47 lambda { ArraySpecs.frozen_array.fill('x') }.should raise_error(frozen_error_class) 48 end 49 50 it "raises a #{frozen_error_class} on an empty frozen array" do 51 lambda { ArraySpecs.empty_frozen_array.fill('x') }.should raise_error(frozen_error_class) 52 end 53 54 it "raises an ArgumentError if 4 or more arguments are passed when no block given" do 55 lambda { [].fill('a') }.should_not raise_error(ArgumentError) 56 57 lambda { [].fill('a', 1) }.should_not raise_error(ArgumentError) 58 59 lambda { [].fill('a', 1, 2) }.should_not raise_error(ArgumentError) 60 lambda { [].fill('a', 1, 2, true) }.should raise_error(ArgumentError) 61 end 62 63 it "raises an ArgumentError if no argument passed and no block given" do 64 lambda { [].fill }.should raise_error(ArgumentError) 65 end 66 67 it "raises an ArgumentError if 3 or more arguments are passed when a block given" do 68 lambda { [].fill() {|i|} }.should_not raise_error(ArgumentError) 69 70 lambda { [].fill(1) {|i|} }.should_not raise_error(ArgumentError) 71 72 lambda { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError) 73 lambda { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError) 74 end 75end 76 77describe "Array#fill with (filler, index, length)" do 78 it "replaces length elements beginning with the index with the filler if given an index and a length" do 79 ary = [1, 2, 3, 4, 5, 6] 80 ary.fill('x', 2, 3).should == [1, 2, 'x', 'x', 'x', 6] 81 end 82 83 it "replaces length elements beginning with the index with the value of block" do 84 [true, false, true, false, true, false, true].fill(1, 4) { |i| i + 3 }.should == [true, 4, 5, 6, 7, false, true] 85 end 86 87 it "replaces all elements after the index if given an index and no length" do 88 ary = [1, 2, 3] 89 ary.fill('x', 1).should == [1, 'x', 'x'] 90 ary.fill(1){|i| i*2}.should == [1, 2, 4] 91 end 92 93 it "replaces all elements after the index if given an index and nil as a length" do 94 a = [1, 2, 3] 95 a.fill('x', 1, nil).should == [1, 'x', 'x'] 96 a.fill(1, nil){|i| i*2}.should == [1, 2, 4] 97 a.fill('y', nil).should == ['y', 'y', 'y'] 98 end 99 100 it "replaces the last (-n) elements if given an index n which is negative and no length" do 101 a = [1, 2, 3, 4, 5] 102 a.fill('x', -2).should == [1, 2, 3, 'x', 'x'] 103 a.fill(-2){|i| i.to_s}.should == [1, 2, 3, '3', '4'] 104 end 105 106 it "replaces the last (-n) elements if given an index n which is negative and nil as a length" do 107 a = [1, 2, 3, 4, 5] 108 a.fill('x', -2, nil).should == [1, 2, 3, 'x', 'x'] 109 a.fill(-2, nil){|i| i.to_s}.should == [1, 2, 3, '3', '4'] 110 end 111 112 it "makes no modifications if given an index greater than end and no length" do 113 [1, 2, 3, 4, 5].fill('a', 5).should == [1, 2, 3, 4, 5] 114 [1, 2, 3, 4, 5].fill(5, &@never_passed).should == [1, 2, 3, 4, 5] 115 end 116 117 it "makes no modifications if given an index greater than end and nil as a length" do 118 [1, 2, 3, 4, 5].fill('a', 5, nil).should == [1, 2, 3, 4, 5] 119 [1, 2, 3, 4, 5].fill(5, nil, &@never_passed).should == [1, 2, 3, 4, 5] 120 end 121 122 it "replaces length elements beginning with start index if given an index >= 0 and a length >= 0" do 123 [1, 2, 3, 4, 5].fill('a', 2, 0).should == [1, 2, 3, 4, 5] 124 [1, 2, 3, 4, 5].fill('a', 2, 2).should == [1, 2, "a", "a", 5] 125 126 [1, 2, 3, 4, 5].fill(2, 0, &@never_passed).should == [1, 2, 3, 4, 5] 127 [1, 2, 3, 4, 5].fill(2, 2){|i| i*2}.should == [1, 2, 4, 6, 5] 128 end 129 130 it "increases the Array size when necessary" do 131 a = [1, 2, 3] 132 a.size.should == 3 133 a.fill 'a', 0, 10 134 a.size.should == 10 135 end 136 137 it "pads between the last element and the index with nil if given an index which is greater than size of the array" do 138 [1, 2, 3, 4, 5].fill('a', 8, 5).should == [1, 2, 3, 4, 5, nil, nil, nil, 'a', 'a', 'a', 'a', 'a'] 139 [1, 2, 3, 4, 5].fill(8, 5){|i| 'a'}.should == [1, 2, 3, 4, 5, nil, nil, nil, 'a', 'a', 'a', 'a', 'a'] 140 end 141 142 it "replaces length elements beginning with the (-n)th if given an index n < 0 and a length > 0" do 143 [1, 2, 3, 4, 5].fill('a', -2, 2).should == [1, 2, 3, "a", "a"] 144 [1, 2, 3, 4, 5].fill('a', -2, 4).should == [1, 2, 3, "a", "a", "a", "a"] 145 146 [1, 2, 3, 4, 5].fill(-2, 2){|i| 'a'}.should == [1, 2, 3, "a", "a"] 147 [1, 2, 3, 4, 5].fill(-2, 4){|i| 'a'}.should == [1, 2, 3, "a", "a", "a", "a"] 148 end 149 150 it "starts at 0 if the negative index is before the start of the array" do 151 [1, 2, 3, 4, 5].fill('a', -25, 3).should == ['a', 'a', 'a', 4, 5] 152 [1, 2, 3, 4, 5].fill('a', -10, 10).should == %w|a a a a a a a a a a| 153 154 [1, 2, 3, 4, 5].fill(-25, 3){|i| 'a'}.should == ['a', 'a', 'a', 4, 5] 155 [1, 2, 3, 4, 5].fill(-10, 10){|i| 'a'}.should == %w|a a a a a a a a a a| 156 end 157 158 it "makes no modifications if the given length <= 0" do 159 [1, 2, 3, 4, 5].fill('a', 2, 0).should == [1, 2, 3, 4, 5] 160 [1, 2, 3, 4, 5].fill('a', -2, 0).should == [1, 2, 3, 4, 5] 161 162 [1, 2, 3, 4, 5].fill('a', 2, -2).should == [1, 2, 3, 4, 5] 163 [1, 2, 3, 4, 5].fill('a', -2, -2).should == [1, 2, 3, 4, 5] 164 165 [1, 2, 3, 4, 5].fill(2, 0, &@never_passed).should == [1, 2, 3, 4, 5] 166 [1, 2, 3, 4, 5].fill(-2, 0, &@never_passed).should == [1, 2, 3, 4, 5] 167 168 [1, 2, 3, 4, 5].fill(2, -2, &@never_passed).should == [1, 2, 3, 4, 5] 169 [1, 2, 3, 4, 5].fill(-2, -2, &@never_passed).should == [1, 2, 3, 4, 5] 170 end 171 172 # See: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/17481 173 it "does not raise an exception if the given length is negative and its absolute value does not exceed the index" do 174 lambda { [1, 2, 3, 4].fill('a', 3, -1)}.should_not raise_error(ArgumentError) 175 lambda { [1, 2, 3, 4].fill('a', 3, -2)}.should_not raise_error(ArgumentError) 176 lambda { [1, 2, 3, 4].fill('a', 3, -3)}.should_not raise_error(ArgumentError) 177 178 lambda { [1, 2, 3, 4].fill(3, -1, &@never_passed)}.should_not raise_error(ArgumentError) 179 lambda { [1, 2, 3, 4].fill(3, -2, &@never_passed)}.should_not raise_error(ArgumentError) 180 lambda { [1, 2, 3, 4].fill(3, -3, &@never_passed)}.should_not raise_error(ArgumentError) 181 end 182 183 it "does not raise an exception even if the given length is negative and its absolute value exceeds the index" do 184 lambda { [1, 2, 3, 4].fill('a', 3, -4)}.should_not raise_error(ArgumentError) 185 lambda { [1, 2, 3, 4].fill('a', 3, -5)}.should_not raise_error(ArgumentError) 186 lambda { [1, 2, 3, 4].fill('a', 3, -10000)}.should_not raise_error(ArgumentError) 187 188 lambda { [1, 2, 3, 4].fill(3, -4, &@never_passed)}.should_not raise_error(ArgumentError) 189 lambda { [1, 2, 3, 4].fill(3, -5, &@never_passed)}.should_not raise_error(ArgumentError) 190 lambda { [1, 2, 3, 4].fill(3, -10000, &@never_passed)}.should_not raise_error(ArgumentError) 191 end 192 193 it "tries to convert the second and third arguments to Integers using #to_int" do 194 obj = mock('to_int') 195 obj.should_receive(:to_int).and_return(2, 2) 196 filler = mock('filler') 197 filler.should_not_receive(:to_int) 198 [1, 2, 3, 4, 5].fill(filler, obj, obj).should == [1, 2, filler, filler, 5] 199 end 200 201 it "raises a TypeError if the index is not numeric" do 202 lambda { [].fill 'a', true }.should raise_error(TypeError) 203 204 obj = mock('nonnumeric') 205 lambda { [].fill('a', obj) }.should raise_error(TypeError) 206 end 207 208 not_supported_on :opal do 209 it "raises an ArgumentError or RangeError for too-large sizes" do 210 arr = [1, 2, 3] 211 lambda { arr.fill(10, 1, fixnum_max) }.should raise_error(ArgumentError) 212 lambda { arr.fill(10, 1, bignum_value) }.should raise_error(RangeError) 213 end 214 end 215end 216 217describe "Array#fill with (filler, range)" do 218 it "replaces elements in range with object" do 219 [1, 2, 3, 4, 5, 6].fill(8, 0..3).should == [8, 8, 8, 8, 5, 6] 220 [1, 2, 3, 4, 5, 6].fill(8, 0...3).should == [8, 8, 8, 4, 5, 6] 221 [1, 2, 3, 4, 5, 6].fill('x', 4..6).should == [1, 2, 3, 4, 'x', 'x', 'x'] 222 [1, 2, 3, 4, 5, 6].fill('x', 4...6).should == [1, 2, 3, 4, 'x', 'x'] 223 [1, 2, 3, 4, 5, 6].fill('x', -2..-1).should == [1, 2, 3, 4, 'x', 'x'] 224 [1, 2, 3, 4, 5, 6].fill('x', -2...-1).should == [1, 2, 3, 4, 'x', 6] 225 [1, 2, 3, 4, 5, 6].fill('x', -2...-2).should == [1, 2, 3, 4, 5, 6] 226 [1, 2, 3, 4, 5, 6].fill('x', -2..-2).should == [1, 2, 3, 4, 'x', 6] 227 [1, 2, 3, 4, 5, 6].fill('x', -2..0).should == [1, 2, 3, 4, 5, 6] 228 [1, 2, 3, 4, 5, 6].fill('x', 0...0).should == [1, 2, 3, 4, 5, 6] 229 [1, 2, 3, 4, 5, 6].fill('x', 1..1).should == [1, 'x', 3, 4, 5, 6] 230 end 231 232 it "replaces all elements in range with the value of block" do 233 [1, 1, 1, 1, 1, 1].fill(1..6) { |i| i + 1 }.should == [1, 2, 3, 4, 5, 6, 7] 234 end 235 236 it "increases the Array size when necessary" do 237 [1, 2, 3].fill('x', 1..6).should == [1, 'x', 'x', 'x', 'x', 'x', 'x'] 238 [1, 2, 3].fill(1..6){|i| i+1}.should == [1, 2, 3, 4, 5, 6, 7] 239 end 240 241 it "raises a TypeError with range and length argument" do 242 lambda { [].fill('x', 0 .. 2, 5) }.should raise_error(TypeError) 243 end 244 245 it "replaces elements between the (-m)th to the last and the (n+1)th from the first if given an range m..n where m < 0 and n >= 0" do 246 [1, 2, 3, 4, 5, 6].fill('x', -4..4).should == [1, 2, 'x', 'x', 'x', 6] 247 [1, 2, 3, 4, 5, 6].fill('x', -4...4).should == [1, 2, 'x', 'x', 5, 6] 248 249 [1, 2, 3, 4, 5, 6].fill(-4..4){|i| (i+1).to_s}.should == [1, 2, '3', '4', '5', 6] 250 [1, 2, 3, 4, 5, 6].fill(-4...4){|i| (i+1).to_s}.should == [1, 2, '3', '4', 5, 6] 251 end 252 253 it "replaces elements between the (-m)th and (-n)th to the last if given an range m..n where m < 0 and n < 0" do 254 [1, 2, 3, 4, 5, 6].fill('x', -4..-2).should == [1, 2, 'x', 'x', 'x', 6] 255 [1, 2, 3, 4, 5, 6].fill('x', -4...-2).should == [1, 2, 'x', 'x', 5, 6] 256 257 [1, 2, 3, 4, 5, 6].fill(-4..-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', '5', 6] 258 [1, 2, 3, 4, 5, 6].fill(-4...-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', 5, 6] 259 end 260 261 it "replaces elements between the (m+1)th from the first and (-n)th to the last if given an range m..n where m >= 0 and n < 0" do 262 [1, 2, 3, 4, 5, 6].fill('x', 2..-2).should == [1, 2, 'x', 'x', 'x', 6] 263 [1, 2, 3, 4, 5, 6].fill('x', 2...-2).should == [1, 2, 'x', 'x', 5, 6] 264 265 [1, 2, 3, 4, 5, 6].fill(2..-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', '5', 6] 266 [1, 2, 3, 4, 5, 6].fill(2...-2){|i| (i+1).to_s}.should == [1, 2, '3', '4', 5, 6] 267 end 268 269 it "makes no modifications if given an range which implies a section of zero width" do 270 [1, 2, 3, 4, 5, 6].fill('x', 2...2).should == [1, 2, 3, 4, 5, 6] 271 [1, 2, 3, 4, 5, 6].fill('x', -4...2).should == [1, 2, 3, 4, 5, 6] 272 [1, 2, 3, 4, 5, 6].fill('x', -4...-4).should == [1, 2, 3, 4, 5, 6] 273 [1, 2, 3, 4, 5, 6].fill('x', 2...-4).should == [1, 2, 3, 4, 5, 6] 274 275 [1, 2, 3, 4, 5, 6].fill(2...2, &@never_passed).should == [1, 2, 3, 4, 5, 6] 276 [1, 2, 3, 4, 5, 6].fill(-4...2, &@never_passed).should == [1, 2, 3, 4, 5, 6] 277 [1, 2, 3, 4, 5, 6].fill(-4...-4, &@never_passed).should == [1, 2, 3, 4, 5, 6] 278 [1, 2, 3, 4, 5, 6].fill(2...-4, &@never_passed).should == [1, 2, 3, 4, 5, 6] 279 end 280 281 it "makes no modifications if given an range which implies a section of negative width" do 282 [1, 2, 3, 4, 5, 6].fill('x', 2..1).should == [1, 2, 3, 4, 5, 6] 283 [1, 2, 3, 4, 5, 6].fill('x', -4..1).should == [1, 2, 3, 4, 5, 6] 284 [1, 2, 3, 4, 5, 6].fill('x', -2..-4).should == [1, 2, 3, 4, 5, 6] 285 [1, 2, 3, 4, 5, 6].fill('x', 2..-5).should == [1, 2, 3, 4, 5, 6] 286 287 [1, 2, 3, 4, 5, 6].fill(2..1, &@never_passed).should == [1, 2, 3, 4, 5, 6] 288 [1, 2, 3, 4, 5, 6].fill(-4..1, &@never_passed).should == [1, 2, 3, 4, 5, 6] 289 [1, 2, 3, 4, 5, 6].fill(-2..-4, &@never_passed).should == [1, 2, 3, 4, 5, 6] 290 [1, 2, 3, 4, 5, 6].fill(2..-5, &@never_passed).should == [1, 2, 3, 4, 5, 6] 291 end 292 293 it "raises an exception if some of the given range lies before the first of the array" do 294 lambda { [1, 2, 3].fill('x', -5..-3) }.should raise_error(RangeError) 295 lambda { [1, 2, 3].fill('x', -5...-3) }.should raise_error(RangeError) 296 lambda { [1, 2, 3].fill('x', -5..-4) }.should raise_error(RangeError) 297 298 lambda { [1, 2, 3].fill(-5..-3, &@never_passed) }.should raise_error(RangeError) 299 lambda { [1, 2, 3].fill(-5...-3, &@never_passed) }.should raise_error(RangeError) 300 lambda { [1, 2, 3].fill(-5..-4, &@never_passed) }.should raise_error(RangeError) 301 end 302 303 it "tries to convert the start and end of the passed range to Integers using #to_int" do 304 obj = mock('to_int') 305 def obj.<=>(rhs); rhs == self ? 0 : nil end 306 obj.should_receive(:to_int).twice.and_return(2) 307 filler = mock('filler') 308 filler.should_not_receive(:to_int) 309 [1, 2, 3, 4, 5].fill(filler, obj..obj).should == [1, 2, filler, 4, 5] 310 end 311 312 it "raises a TypeError if the start or end of the passed range is not numeric" do 313 obj = mock('nonnumeric') 314 def obj.<=>(rhs); rhs == self ? 0 : nil end 315 lambda { [].fill('a', obj..obj) }.should raise_error(TypeError) 316 end 317end 318