1require_relative '../../spec_helper' 2require_relative 'fixtures/classes' 3 4describe "Array#[]=" do 5 it "sets the value of the element at index" do 6 a = [1, 2, 3, 4] 7 a[2] = 5 8 a[-1] = 6 9 a[5] = 3 10 a.should == [1, 2, 5, 6, nil, 3] 11 12 a = [] 13 a[4] = "e" 14 a.should == [nil, nil, nil, nil, "e"] 15 a[3] = "d" 16 a.should == [nil, nil, nil, "d", "e"] 17 a[0] = "a" 18 a.should == ["a", nil, nil, "d", "e"] 19 a[-3] = "C" 20 a.should == ["a", nil, "C", "d", "e"] 21 a[-1] = "E" 22 a.should == ["a", nil, "C", "d", "E"] 23 a[-5] = "A" 24 a.should == ["A", nil, "C", "d", "E"] 25 a[5] = "f" 26 a.should == ["A", nil, "C", "d", "E", "f"] 27 a[1] = [] 28 a.should == ["A", [], "C", "d", "E", "f"] 29 a[-1] = nil 30 a.should == ["A", [], "C", "d", "E", nil] 31 end 32 33 it "sets the section defined by [start,length] to other" do 34 a = [1, 2, 3, 4, 5, 6] 35 a[0, 1] = 2 36 a[3, 2] = ['a', 'b', 'c', 'd'] 37 a.should == [2, 2, 3, "a", "b", "c", "d", 6] 38 end 39 it "replaces the section defined by [start,length] with the given values" do 40 a = [1, 2, 3, 4, 5, 6] 41 a[3, 2] = 'a', 'b', 'c', 'd' 42 a.should == [1, 2, 3, "a", "b", "c", "d", 6] 43 end 44 45 it "just sets the section defined by [start,length] to other even if other is nil" do 46 a = ['a', 'b', 'c', 'd', 'e'] 47 a[1, 3] = nil 48 a.should == ["a", nil, "e"] 49 end 50 51 it "returns nil if the rhs is nil" do 52 a = [1, 2, 3] 53 (a[1, 3] = nil).should == nil 54 (a[1..3] = nil).should == nil 55 end 56 57 it "sets the section defined by range to other" do 58 a = [6, 5, 4, 3, 2, 1] 59 a[1...2] = 9 60 a[3..6] = [6, 6, 6] 61 a.should == [6, 9, 4, 6, 6, 6] 62 end 63 64 it "replaces the section defined by range with the given values" do 65 a = [6, 5, 4, 3, 2, 1] 66 a[3..6] = :a, :b, :c 67 a.should == [6, 5, 4, :a, :b, :c] 68 end 69 70 it "just sets the section defined by range to other even if other is nil" do 71 a = [1, 2, 3, 4, 5] 72 a[0..1] = nil 73 a.should == [nil, 3, 4, 5] 74 end 75 76 it 'expands and nil-pads the array if section assigned by range is outside array boundaries' do 77 a = ['a'] 78 a[3..4] = ['b', 'c'] 79 a.should == ['a', nil, nil, 'b', 'c'] 80 end 81 82 it "calls to_int on its start and length arguments" do 83 obj = mock('to_int') 84 obj.stub!(:to_int).and_return(2) 85 86 a = [1, 2, 3, 4] 87 a[obj, 0] = [9] 88 a.should == [1, 2, 9, 3, 4] 89 a[obj, obj] = [] 90 a.should == [1, 2, 4] 91 a[obj] = -1 92 a.should == [1, 2, -1] 93 end 94 95 it "checks frozen before attempting to coerce arguments" do 96 a = [1,2,3,4].freeze 97 lambda {a[:foo] = 1}.should raise_error(frozen_error_class) 98 lambda {a[:foo, :bar] = 1}.should raise_error(frozen_error_class) 99 end 100 101 it "sets elements in the range arguments when passed ranges" do 102 ary = [1, 2, 3] 103 rhs = [nil, [], ["x"], ["x", "y"]] 104 (0 .. ary.size + 2).each do |a| 105 (a .. ary.size + 3).each do |b| 106 rhs.each do |c| 107 ary1 = ary.dup 108 ary1[a .. b] = c 109 ary2 = ary.dup 110 ary2[a, 1 + b-a] = c 111 ary1.should == ary2 112 113 ary1 = ary.dup 114 ary1[a ... b] = c 115 ary2 = ary.dup 116 ary2[a, b-a] = c 117 ary1.should == ary2 118 end 119 end 120 end 121 end 122 123 it "inserts the given elements with [range] which the range is zero-width" do 124 ary = [1, 2, 3] 125 ary[1...1] = 0 126 ary.should == [1, 0, 2, 3] 127 ary[1...1] = [5] 128 ary.should == [1, 5, 0, 2, 3] 129 ary[1...1] = :a, :b, :c 130 ary.should == [1, :a, :b, :c, 5, 0, 2, 3] 131 end 132 133 it "inserts the given elements with [start, length] which length is zero" do 134 ary = [1, 2, 3] 135 ary[1, 0] = 0 136 ary.should == [1, 0, 2, 3] 137 ary[1, 0] = [5] 138 ary.should == [1, 5, 0, 2, 3] 139 ary[1, 0] = :a, :b, :c 140 ary.should == [1, :a, :b, :c, 5, 0, 2, 3] 141 end 142 143 # Now we only have to test cases where the start, length interface would 144 # have raise an exception because of negative size 145 it "inserts the given elements with [range] which the range has negative width" do 146 ary = [1, 2, 3] 147 ary[1..0] = 0 148 ary.should == [1, 0, 2, 3] 149 ary[1..0] = [4, 3] 150 ary.should == [1, 4, 3, 0, 2, 3] 151 ary[1..0] = :a, :b, :c 152 ary.should == [1, :a, :b, :c, 4, 3, 0, 2, 3] 153 end 154 155 it "just inserts nil if the section defined by range is zero-width and the rhs is nil" do 156 ary = [1, 2, 3] 157 ary[1...1] = nil 158 ary.should == [1, nil, 2, 3] 159 end 160 161 it "just inserts nil if the section defined by range has negative width and the rhs is nil" do 162 ary = [1, 2, 3] 163 ary[1..0] = nil 164 ary.should == [1, nil, 2, 3] 165 end 166 167 it "does nothing if the section defined by range is zero-width and the rhs is an empty array" do 168 ary = [1, 2, 3] 169 ary[1...1] = [] 170 ary.should == [1, 2, 3] 171 end 172 it "does nothing if the section defined by range has negative width and the rhs is an empty array" do 173 ary = [1, 2, 3, 4, 5] 174 ary[1...0] = [] 175 ary.should == [1, 2, 3, 4, 5] 176 ary[-2..2] = [] 177 ary.should == [1, 2, 3, 4, 5] 178 end 179 180 it "tries to convert Range elements to Integers using #to_int with [m..n] and [m...n]" do 181 from = mock('from') 182 to = mock('to') 183 184 # So we can construct a range out of them... 185 def from.<=>(o) 0 end 186 def to.<=>(o) 0 end 187 188 def from.to_int() 1 end 189 def to.to_int() -2 end 190 191 a = [1, 2, 3, 4] 192 193 a[from .. to] = ["a", "b", "c"] 194 a.should == [1, "a", "b", "c", 4] 195 196 a[to .. from] = ["x"] 197 a.should == [1, "a", "b", "x", "c", 4] 198 lambda { a["a" .. "b"] = [] }.should raise_error(TypeError) 199 lambda { a[from .. "b"] = [] }.should raise_error(TypeError) 200 end 201 202 it "raises an IndexError when passed indexes out of bounds" do 203 a = [1, 2, 3, 4] 204 lambda { a[-5] = "" }.should raise_error(IndexError) 205 lambda { a[-5, -1] = "" }.should raise_error(IndexError) 206 lambda { a[-5, 0] = "" }.should raise_error(IndexError) 207 lambda { a[-5, 1] = "" }.should raise_error(IndexError) 208 lambda { a[-5, 2] = "" }.should raise_error(IndexError) 209 lambda { a[-5, 10] = "" }.should raise_error(IndexError) 210 211 lambda { a[-5..-5] = "" }.should raise_error(RangeError) 212 lambda { a[-5...-5] = "" }.should raise_error(RangeError) 213 lambda { a[-5..-4] = "" }.should raise_error(RangeError) 214 lambda { a[-5...-4] = "" }.should raise_error(RangeError) 215 lambda { a[-5..10] = "" }.should raise_error(RangeError) 216 lambda { a[-5...10] = "" }.should raise_error(RangeError) 217 218 # ok 219 a[0..-9] = [1] 220 a.should == [1, 1, 2, 3, 4] 221 end 222 223 it "calls to_ary on its rhs argument for multi-element sets" do 224 obj = mock('to_ary') 225 def obj.to_ary() [1, 2, 3] end 226 ary = [1, 2] 227 ary[0, 0] = obj 228 ary.should == [1, 2, 3, 1, 2] 229 ary[1, 10] = obj 230 ary.should == [1, 1, 2, 3] 231 end 232 233 it "does not call to_ary on rhs array subclasses for multi-element sets" do 234 ary = [] 235 ary[0, 0] = ArraySpecs::ToAryArray[5, 6, 7] 236 ary.should == [5, 6, 7] 237 end 238 239 it "raises a #{frozen_error_class} on a frozen array" do 240 lambda { ArraySpecs.frozen_array[0, 0] = [] }.should raise_error(frozen_error_class) 241 end 242end 243 244describe "Array#[]= with [index]" do 245 it "returns value assigned if idx is inside array" do 246 a = [1, 2, 3, 4, 5] 247 (a[3] = 6).should == 6 248 end 249 250 it "returns value assigned if idx is right beyond right array boundary" do 251 a = [1, 2, 3, 4, 5] 252 (a[5] = 6).should == 6 253 end 254 255 it "returns value assigned if idx far beyond right array boundary" do 256 a = [1, 2, 3, 4, 5] 257 (a[10] = 6).should == 6 258 end 259 260 it "sets the value of the element at index" do 261 a = [1, 2, 3, 4] 262 a[2] = 5 263 a[-1] = 6 264 a[5] = 3 265 a.should == [1, 2, 5, 6, nil, 3] 266 end 267 268 it "sets the value of the element if it is right beyond the array boundary" do 269 a = [1, 2, 3, 4] 270 a[4] = 8 271 a.should == [1, 2, 3, 4, 8] 272 end 273 274end 275 276describe "Array#[]= with [index, count]" do 277 it "returns non-array value if non-array value assigned" do 278 a = [1, 2, 3, 4, 5] 279 (a[2, 3] = 10).should == 10 280 end 281 282 it "returns array if array assigned" do 283 a = [1, 2, 3, 4, 5] 284 (a[2, 3] = [4, 5]).should == [4, 5] 285 end 286 287 it "just sets the section defined by [start,length] to nil even if the rhs is nil" do 288 a = ['a', 'b', 'c', 'd', 'e'] 289 a[1, 3] = nil 290 a.should == ["a", nil, "e"] 291 end 292 293 it "just sets the section defined by [start,length] to nil if negative index within bounds, cnt > 0 and the rhs is nil" do 294 a = ['a', 'b', 'c', 'd', 'e'] 295 a[-3, 2] = nil 296 a.should == ["a", "b", nil, "e"] 297 end 298 299 it "replaces the section defined by [start,length] to other" do 300 a = [1, 2, 3, 4, 5, 6] 301 a[0, 1] = 2 302 a[3, 2] = ['a', 'b', 'c', 'd'] 303 a.should == [2, 2, 3, "a", "b", "c", "d", 6] 304 end 305 306 it "replaces the section to other if idx < 0 and cnt > 0" do 307 a = [1, 2, 3, 4, 5, 6] 308 a[-3, 2] = ["x", "y", "z"] 309 a.should == [1, 2, 3, "x", "y", "z", 6] 310 end 311 312 it "replaces the section to other even if cnt spanning beyond the array boundary" do 313 a = [1, 2, 3, 4, 5] 314 a[-1, 3] = [7, 8] 315 a.should == [1, 2, 3, 4, 7, 8] 316 end 317 318 it "pads the Array with nils if the span is past the end" do 319 a = [1, 2, 3, 4, 5] 320 a[10, 1] = [1] 321 a.should == [1, 2, 3, 4, 5, nil, nil, nil, nil, nil, 1] 322 323 b = [1, 2, 3, 4, 5] 324 b[10, 0] = [1] 325 a.should == [1, 2, 3, 4, 5, nil, nil, nil, nil, nil, 1] 326 end 327 328 it "inserts other section in place defined by idx" do 329 a = [1, 2, 3, 4, 5] 330 a[3, 0] = [7, 8] 331 a.should == [1, 2, 3, 7, 8, 4, 5] 332 333 b = [1, 2, 3, 4, 5] 334 b[1, 0] = b 335 b.should == [1, 1, 2, 3, 4, 5, 2, 3, 4, 5] 336 end 337 338 it "raises an IndexError when passed start and negative length" do 339 a = [1, 2, 3, 4] 340 lambda { a[-2, -1] = "" }.should raise_error(IndexError) 341 lambda { a[0, -1] = "" }.should raise_error(IndexError) 342 lambda { a[2, -1] = "" }.should raise_error(IndexError) 343 lambda { a[4, -1] = "" }.should raise_error(IndexError) 344 lambda { a[10, -1] = "" }.should raise_error(IndexError) 345 lambda { [1, 2, 3, 4, 5][2, -1] = [7, 8] }.should raise_error(IndexError) 346 end 347end 348 349describe "Array#[]= with [m..n]" do 350 it "returns non-array value if non-array value assigned" do 351 a = [1, 2, 3, 4, 5] 352 (a[2..4] = 10).should == 10 353 (a.[]=(2..4, 10)).should == 10 354 end 355 356 it "returns array if array assigned" do 357 a = [1, 2, 3, 4, 5] 358 (a[2..4] = [7, 8]).should == [7, 8] 359 (a.[]=(2..4, [7, 8])).should == [7, 8] 360 end 361 362 it "just sets the section defined by range to nil even if the rhs is nil" do 363 a = [1, 2, 3, 4, 5] 364 a[0..1] = nil 365 a.should == [nil, 3, 4, 5] 366 end 367 368 it "just sets the section defined by range to nil if m and n < 0 and the rhs is nil" do 369 a = [1, 2, 3, 4, 5] 370 a[-3..-2] = nil 371 a.should == [1, 2, nil, 5] 372 end 373 374 it "replaces the section defined by range" do 375 a = [6, 5, 4, 3, 2, 1] 376 a[1...2] = 9 377 a[3..6] = [6, 6, 6] 378 a.should == [6, 9, 4, 6, 6, 6] 379 end 380 381 it "replaces the section if m and n < 0" do 382 a = [1, 2, 3, 4, 5] 383 a[-3..-2] = [7, 8, 9] 384 a.should == [1, 2, 7, 8, 9, 5] 385 end 386 387 it "replaces the section if m < 0 and n > 0" do 388 a = [1, 2, 3, 4, 5] 389 a[-4..3] = [8] 390 a.should == [1, 8, 5] 391 end 392 393 it "inserts the other section at m if m > n" do 394 a = [1, 2, 3, 4, 5] 395 a[3..1] = [8] 396 a.should == [1, 2, 3, 8, 4, 5] 397 end 398 399 describe "Range subclasses" do 400 before :each do 401 @range_incl = ArraySpecs::MyRange.new(1, 2) 402 @range_excl = ArraySpecs::MyRange.new(-3, -1, true) 403 end 404 405 it "accepts Range subclasses" do 406 a = [1, 2, 3, 4] 407 408 a[@range_incl] = ["a", "b"] 409 a.should == [1, "a", "b", 4] 410 a[@range_excl] = ["A", "B"] 411 a.should == [1, "A", "B", 4] 412 end 413 414 it "returns non-array value if non-array value assigned" do 415 a = [1, 2, 3, 4, 5] 416 (a[@range_incl] = 10).should == 10 417 (a.[]=(@range_incl, 10)).should == 10 418 end 419 420 it "returns array if array assigned" do 421 a = [1, 2, 3, 4, 5] 422 (a[@range_incl] = [7, 8]).should == [7, 8] 423 a.[]=(@range_incl, [7, 8]).should == [7, 8] 424 end 425 end 426end 427 428describe "Array#[] after a shift" do 429 it "works for insertion" do 430 a = [1,2] 431 a.shift 432 a.shift 433 a[0,0] = [3,4] 434 a.should == [3,4] 435 end 436end 437