diff options
Diffstat (limited to 'spec/ruby/core/array/shared')
| -rw-r--r-- | spec/ruby/core/array/shared/clone.rb | 32 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/collect.rb | 85 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/difference.rb | 8 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/enumeratorize.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/eql.rb | 66 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/index.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/inspect.rb | 36 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/intersection.rb | 9 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb | 25 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/join.rb | 96 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/keep_if.rb | 49 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/push.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/replace.rb | 8 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/select.rb | 5 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/slice.rb | 572 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/union.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/array/shared/unshift.rb | 26 |
17 files changed, 533 insertions, 504 deletions
diff --git a/spec/ruby/core/array/shared/clone.rb b/spec/ruby/core/array/shared/clone.rb index 3c17b1f10f..1a45c2fe2c 100644 --- a/spec/ruby/core/array/shared/clone.rb +++ b/spec/ruby/core/array/shared/clone.rb @@ -1,14 +1,14 @@ describe :array_clone, shared: true do it "returns an Array or a subclass instance" do - [].send(@method).should be_an_instance_of(Array) - ArraySpecs::MyArray[1, 2].send(@method).should be_an_instance_of(ArraySpecs::MyArray) + [].send(@method).should.instance_of?(Array) + ArraySpecs::MyArray[1, 2].send(@method).should.instance_of?(ArraySpecs::MyArray) end it "produces a shallow copy where the references are directly copied" do a = [mock('1'), mock('2')] b = a.send @method - b.first.should equal a.first - b.last.should equal a.last + b.first.should.equal? a.first + b.last.should.equal? a.last end it "creates a new array containing all elements or the original" do @@ -17,28 +17,4 @@ describe :array_clone, shared: true do b.should == a b.__id__.should_not == a.__id__ end - - ruby_version_is ''...'2.7' do - it "copies taint status from the original" do - a = [1, 2, 3, 4] - b = [1, 2, 3, 4] - a.taint - aa = a.send @method - bb = b.send @method - - aa.should.tainted? - bb.should_not.tainted? - end - - it "copies untrusted status from the original" do - a = [1, 2, 3, 4] - b = [1, 2, 3, 4] - a.untrust - aa = a.send @method - bb = b.send @method - - aa.should.untrusted? - bb.should_not.untrusted? - end - end end diff --git a/spec/ruby/core/array/shared/collect.rb b/spec/ruby/core/array/shared/collect.rb index d84432734a..aec51c9dc9 100644 --- a/spec/ruby/core/array/shared/collect.rb +++ b/spec/ruby/core/array/shared/collect.rb @@ -1,15 +1,16 @@ require_relative '../../enumerable/shared/enumeratorized' +require_relative '../shared/iterable_and_tolerating_size_increasing' describe :array_collect, shared: true do it "returns a copy of array with each element replaced by the value returned by block" do a = ['a', 'b', 'c', 'd'] b = a.send(@method) { |i| i + '!' } b.should == ["a!", "b!", "c!", "d!"] - b.should_not equal a + b.should_not.equal? a end it "does not return subclass instance" do - ArraySpecs::MyArray[1, 2, 3].send(@method) { |x| x + 1 }.should be_an_instance_of(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method) { |x| x + 1 }.should.instance_of?(Array) end it "does not change self" do @@ -32,47 +33,35 @@ describe :array_collect, shared: true do it "returns an Enumerator when no block given" do a = [1, 2, 3] - a.send(@method).should be_an_instance_of(Enumerator) + a.send(@method).should.instance_of?(Enumerator) end it "raises an ArgumentError when no block and with arguments" do a = [1, 2, 3] -> { a.send(@method, :foo) - }.should raise_error(ArgumentError) - end - - ruby_version_is ''...'2.7' do - it "does not copy tainted status" do - a = [1, 2, 3] - a.taint - a.send(@method){|x| x}.tainted?.should be_false - end - - it "does not copy untrusted status" do - a = [1, 2, 3] - a.untrust - a.send(@method){|x| x}.untrusted?.should be_false - end + }.should.raise(ArgumentError) end before :all do @object = [1, 2, 3, 4] end it_should_behave_like :enumeratorized_with_origin_size + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end describe :array_collect_b, shared: true do it "replaces each element with the value returned by block" do a = [7, 9, 3, 5] - a.send(@method) { |i| i - 1 }.should equal(a) + a.send(@method) { |i| i - 1 }.should.equal?(a) a.should == [6, 8, 2, 4] end it "returns self" do a = [1, 2, 3, 4, 5] b = a.send(@method) {|i| i+1 } - a.should equal b + a.should.equal? b end it "returns the evaluated value of block but its contents is partially modified, if it broke in the block" do @@ -91,50 +80,62 @@ describe :array_collect_b, shared: true do it "returns an Enumerator when no block given, and the enumerator can modify the original array" do a = [1, 2, 3] enum = a.send(@method) - enum.should be_an_instance_of(Enumerator) + enum.should.instance_of?(Enumerator) enum.each{|i| "#{i}!" } a.should == ["1!", "2!", "3!"] end - ruby_version_is ''...'2.7' do - it "keeps tainted status" do - a = [1, 2, 3] - a.taint - a.tainted?.should be_true - a.send(@method){|x| x} - a.tainted?.should be_true - end - - it "keeps untrusted status" do - a = [1, 2, 3] - a.untrust - a.send(@method){|x| x} - a.untrusted?.should be_true - end - end - describe "when frozen" do it "raises a FrozenError" do - -> { ArraySpecs.frozen_array.send(@method) {} }.should raise_error(FrozenError) + -> { ArraySpecs.frozen_array.send(@method) {} }.should.raise(FrozenError) end it "raises a FrozenError when empty" do - -> { ArraySpecs.empty_frozen_array.send(@method) {} }.should raise_error(FrozenError) + -> { ArraySpecs.empty_frozen_array.send(@method) {} }.should.raise(FrozenError) end it "raises a FrozenError when calling #each on the returned Enumerator" do enumerator = ArraySpecs.frozen_array.send(@method) - -> { enumerator.each {|x| x } }.should raise_error(FrozenError) + -> { enumerator.each {|x| x } }.should.raise(FrozenError) end it "raises a FrozenError when calling #each on the returned Enumerator when empty" do enumerator = ArraySpecs.empty_frozen_array.send(@method) - -> { enumerator.each {|x| x } }.should raise_error(FrozenError) + -> { enumerator.each {|x| x } }.should.raise(FrozenError) end end + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.send(@method) { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "only changes elements before error is raised, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.send(@method) do |e| + case e + when 1 then -1 + when 2 then -2 + when 3 then raise StandardError, 'Oops' + else 0 + end + end + rescue StandardError + end + + a.should == [-1, -2, 3, 4] + end + before :all do @object = [1, 2, 3, 4] end it_should_behave_like :enumeratorized_with_origin_size + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/difference.rb b/spec/ruby/core/array/shared/difference.rb index 3e69050d82..3fe22331bd 100644 --- a/spec/ruby/core/array/shared/difference.rb +++ b/spec/ruby/core/array/shared/difference.rb @@ -27,13 +27,13 @@ describe :array_binary_difference, shared: true do it "raises a TypeError if the argument cannot be coerced to an Array by calling #to_ary" do obj = mock('not an array') - -> { [1, 2, 3].send(@method, obj) }.should raise_error(TypeError) + -> { [1, 2, 3].send(@method, obj) }.should.raise(TypeError) end it "does not return subclass instance for Array subclasses" do - ArraySpecs::MyArray[1, 2, 3].send(@method, []).should be_an_instance_of(Array) - ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[]).should be_an_instance_of(Array) - [1, 2, 3].send(@method, ArraySpecs::MyArray[]).should be_an_instance_of(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method, []).should.instance_of?(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[]).should.instance_of?(Array) + [1, 2, 3].send(@method, ArraySpecs::MyArray[]).should.instance_of?(Array) end it "does not call to_ary on array subclasses" do diff --git a/spec/ruby/core/array/shared/enumeratorize.rb b/spec/ruby/core/array/shared/enumeratorize.rb index a19a5d3b9b..5beab5c4c4 100644 --- a/spec/ruby/core/array/shared/enumeratorize.rb +++ b/spec/ruby/core/array/shared/enumeratorize.rb @@ -1,5 +1,5 @@ describe :enumeratorize, shared: true do it "returns an Enumerator if no block given" do - [1,2].send(@method).should be_an_instance_of(Enumerator) + [1,2].send(@method).should.instance_of?(Enumerator) end end diff --git a/spec/ruby/core/array/shared/eql.rb b/spec/ruby/core/array/shared/eql.rb index b5d9128434..5e770bf167 100644 --- a/spec/ruby/core/array/shared/eql.rb +++ b/spec/ruby/core/array/shared/eql.rb @@ -1,59 +1,59 @@ describe :array_eql, shared: true do it "returns true if other is the same array" do a = [1] - a.send(@method, a).should be_true + a.send(@method, a).should == true end it "returns true if corresponding elements are #eql?" do - [].send(@method, []).should be_true - [1, 2, 3, 4].send(@method, [1, 2, 3, 4]).should be_true + [].send(@method, []).should == true + [1, 2, 3, 4].send(@method, [1, 2, 3, 4]).should == true end it "returns false if other is shorter than self" do - [1, 2, 3, 4].send(@method, [1, 2, 3]).should be_false + [1, 2, 3, 4].send(@method, [1, 2, 3]).should == false end it "returns false if other is longer than self" do - [1, 2, 3, 4].send(@method, [1, 2, 3, 4, 5]).should be_false + [1, 2, 3, 4].send(@method, [1, 2, 3, 4, 5]).should == false end it "returns false immediately when sizes of the arrays differ" do obj = mock('1') obj.should_not_receive(@method) - [] .send(@method, [obj] ).should be_false - [obj] .send(@method, [] ).should be_false + [] .send(@method, [obj] ).should == false + [obj] .send(@method, [] ).should == false end it "handles well recursive arrays" do a = ArraySpecs.empty_recursive_array - a .send(@method, [a] ).should be_true - a .send(@method, [[a]] ).should be_true - [a] .send(@method, a ).should be_true - [[a]] .send(@method, a ).should be_true + a .send(@method, [a] ).should == true + a .send(@method, [[a]] ).should == true + [a] .send(@method, a ).should == true + [[a]] .send(@method, a ).should == true # These may be surprising, but no difference can be # found between these arrays, so they are ==. # There is no "path" that will lead to a difference # (contrary to other examples below) a2 = ArraySpecs.empty_recursive_array - a .send(@method, a2 ).should be_true - a .send(@method, [a2] ).should be_true - a .send(@method, [[a2]] ).should be_true - [a] .send(@method, a2 ).should be_true - [[a]] .send(@method, a2 ).should be_true + a .send(@method, a2 ).should == true + a .send(@method, [a2] ).should == true + a .send(@method, [[a2]] ).should == true + [a] .send(@method, a2 ).should == true + [[a]] .send(@method, a2 ).should == true back = [] forth = [back]; back << forth; - back .send(@method, a ).should be_true + back .send(@method, a ).should == true x = []; x << x << x - x .send(@method, a ).should be_false # since x.size != a.size - x .send(@method, [a, a] ).should be_false # since x[0].size != [a, a][0].size - x .send(@method, [x, a] ).should be_false # since x[1].size != [x, a][1].size - [x, a] .send(@method, [a, x] ).should be_false # etc... - x .send(@method, [x, x] ).should be_true - x .send(@method, [[x, x], [x, x]] ).should be_true + x .send(@method, a ).should == false # since x.size != a.size + x .send(@method, [a, a] ).should == false # since x[0].size != [a, a][0].size + x .send(@method, [x, a] ).should == false # since x[1].size != [x, a][1].size + [x, a] .send(@method, [a, x] ).should == false # etc... + x .send(@method, [x, x] ).should == true + x .send(@method, [[x, x], [x, x]] ).should == true tree = []; branch = []; branch << tree << tree; tree << branch @@ -62,31 +62,31 @@ describe :array_eql, shared: true do forest = [tree, branch, :bird, a]; forest << forest forest2 = [tree2, branch2, :bird, a2]; forest2 << forest2 - forest .send(@method, forest2 ).should be_true - forest .send(@method, [tree2, branch, :bird, a, forest2]).should be_true + forest .send(@method, forest2 ).should == true + forest .send(@method, [tree2, branch, :bird, a, forest2]).should == true diffforest = [branch2, tree2, :bird, a2]; diffforest << forest2 - forest .send(@method, diffforest ).should be_false # since forest[0].size == 1 != 3 == diffforest[0] - forest .send(@method, [nil] ).should be_false - forest .send(@method, [forest] ).should be_false + forest .send(@method, diffforest ).should == false # since forest[0].size == 1 != 3 == diffforest[0] + forest .send(@method, [nil] ).should == false + forest .send(@method, [forest] ).should == false end it "does not call #to_ary on its argument" do obj = mock('to_ary') obj.should_not_receive(:to_ary) - [1, 2, 3].send(@method, obj).should be_false + [1, 2, 3].send(@method, obj).should == false end it "does not call #to_ary on Array subclasses" do ary = ArraySpecs::ToAryArray[5, 6, 7] ary.should_not_receive(:to_ary) - [5, 6, 7].send(@method, ary).should be_true + [5, 6, 7].send(@method, ary).should == true end it "ignores array class differences" do - ArraySpecs::MyArray[1, 2, 3].send(@method, [1, 2, 3]).should be_true - ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_true - [1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_true + ArraySpecs::MyArray[1, 2, 3].send(@method, [1, 2, 3]).should == true + ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should == true + [1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should == true end end diff --git a/spec/ruby/core/array/shared/index.rb b/spec/ruby/core/array/shared/index.rb index a9896554f2..cc6d6cfb5b 100644 --- a/spec/ruby/core/array/shared/index.rb +++ b/spec/ruby/core/array/shared/index.rb @@ -1,3 +1,5 @@ +require_relative '../shared/iterable_and_tolerating_size_increasing' + describe :array_index, shared: true do it "returns the index of the first element == to object" do x = mock('3') @@ -31,7 +33,9 @@ describe :array_index, shared: true do describe "given no argument and no block" do it "produces an Enumerator" do - [].send(@method).should be_an_instance_of(Enumerator) + [].send(@method).should.instance_of?(Enumerator) end end + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/inspect.rb b/spec/ruby/core/array/shared/inspect.rb index 736f8d946b..7197cd7f26 100644 --- a/spec/ruby/core/array/shared/inspect.rb +++ b/spec/ruby/core/array/shared/inspect.rb @@ -2,7 +2,7 @@ require_relative '../fixtures/encoded_strings' describe :array_inspect, shared: true do it "returns a string" do - [1, 2, 3].send(@method).should be_an_instance_of(String) + [1, 2, 3].send(@method).should.instance_of?(String) end it "returns '[]' for an empty Array" do @@ -19,7 +19,7 @@ describe :array_inspect, shared: true do end it "does not call #to_s on a String returned from #inspect" do - str = "abc" + str = +"abc" str.should_not_receive(:to_s) [str].send(@method).should == '["abc"]' @@ -55,7 +55,7 @@ describe :array_inspect, shared: true do obj.should_receive(:inspect).and_return(obj) obj.should_receive(:to_s).and_raise(Exception) - -> { [obj].send(@method) }.should raise_error(Exception) + -> { [obj].send(@method) }.should.raise(Exception) end it "represents a recursive element with '[...]'" do @@ -64,32 +64,6 @@ describe :array_inspect, shared: true do ArraySpecs.empty_recursive_array.send(@method).should == "[[...]]" end - ruby_version_is ''...'2.7' do - it "taints the result if the Array is non-empty and tainted" do - [1, 2].taint.send(@method).tainted?.should be_true - end - - it "does not taint the result if the Array is tainted but empty" do - [].taint.send(@method).tainted?.should be_false - end - - it "taints the result if an element is tainted" do - ["str".taint].send(@method).tainted?.should be_true - end - - it "untrusts the result if the Array is untrusted" do - [1, 2].untrust.send(@method).untrusted?.should be_true - end - - it "does not untrust the result if the Array is untrusted but empty" do - [].untrust.send(@method).untrusted?.should be_false - end - - it "untrusts the result if an element is untrusted" do - ["str".untrust].send(@method).untrusted?.should be_true - end - end - describe "with encoding" do before :each do @default_external_encoding = Encoding.default_external @@ -124,8 +98,8 @@ describe :array_inspect, shared: true do end it "does not raise if inspected result is not default external encoding" do - utf_16be = mock("utf_16be") - utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode!(Encoding::UTF_16BE)) + utf_16be = mock(+"utf_16be") + utf_16be.should_receive(:inspect).and_return(%<"utf_16be \u3042">.encode(Encoding::UTF_16BE)) [utf_16be].send(@method).should == '["utf_16be \u3042"]' end diff --git a/spec/ruby/core/array/shared/intersection.rb b/spec/ruby/core/array/shared/intersection.rb index 49849b08c2..dda72e8bd7 100644 --- a/spec/ruby/core/array/shared/intersection.rb +++ b/spec/ruby/core/array/shared/intersection.rb @@ -11,7 +11,8 @@ describe :array_intersection, shared: true do end it "creates an array with elements in order they are first encountered" do - [ 1, 2, 3, 2, 5 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5] + [ 1, 2, 3, 2, 5, 6, 7, 8 ].send(@method, [ 5, 2, 3, 4 ]).should == [2, 3, 5] # array > other + [ 5, 2, 3, 4 ].send(@method, [ 1, 2, 3, 2, 5, 6, 7, 8 ]).should == [5, 2, 3] # array < other end it "does not modify the original Array" do @@ -65,9 +66,9 @@ describe :array_intersection, shared: true do end it "does return subclass instances for Array subclasses" do - ArraySpecs::MyArray[1, 2, 3].send(@method, []).should be_an_instance_of(Array) - ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array) - [].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method, []).should.instance_of?(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should.instance_of?(Array) + [].send(@method, ArraySpecs::MyArray[1, 2, 3]).should.instance_of?(Array) end it "does not call to_ary on array subclasses" do diff --git a/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb b/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb new file mode 100644 index 0000000000..3e73bad44b --- /dev/null +++ b/spec/ruby/core/array/shared/iterable_and_tolerating_size_increasing.rb @@ -0,0 +1,25 @@ +describe :array_iterable_and_tolerating_size_increasing, shared: true do + before do + @value_to_return ||= -> _ { nil } + end + + it "tolerates increasing an array size during iteration" do + # The goal is to trigger potential reallocation of internal array storage, so we: + # - use elements of different types, starting with the less generic (Integer) + # - add reasonably big number of new elements (~ 100) + array = [1, 2, 3] # to test some methods we need several uniq elements + array_to_join = [:a, :b, :c] + (4..100).to_a + + ScratchPad.record [] + i = 0 + + array.send(@method) do |e| + ScratchPad << e + array << array_to_join[i] if i < array_to_join.size + i += 1 + @value_to_return.call(e) + end + + ScratchPad.recorded.should == [1, 2, 3] + array_to_join + end +end diff --git a/spec/ruby/core/array/shared/join.rb b/spec/ruby/core/array/shared/join.rb index dfdb4ae1e4..2be60a4dbc 100644 --- a/spec/ruby/core/array/shared/join.rb +++ b/spec/ruby/core/array/shared/join.rb @@ -49,43 +49,13 @@ describe :array_join_with_default_separator, shared: true do it "raises a NoMethodError if an element does not respond to #to_str, #to_ary, or #to_s" do obj = mock('o') class << obj; undef :to_s; end - -> { [1, obj].send(@method) }.should raise_error(NoMethodError) + -> { [1, obj].send(@method) }.should.raise(NoMethodError) end it "raises an ArgumentError when the Array is recursive" do - -> { ArraySpecs.recursive_array.send(@method) }.should raise_error(ArgumentError) - -> { ArraySpecs.head_recursive_array.send(@method) }.should raise_error(ArgumentError) - -> { ArraySpecs.empty_recursive_array.send(@method) }.should raise_error(ArgumentError) - end - - ruby_version_is ''...'2.7' do - it "taints the result if the Array is tainted and non-empty" do - [1, 2].taint.send(@method).tainted?.should be_true - end - - it "does not taint the result if the Array is tainted but empty" do - [].taint.send(@method).tainted?.should be_false - end - - it "taints the result if the result of coercing an element is tainted" do - s = mock("taint") - s.should_receive(:to_s).and_return("str".taint) - [s].send(@method).tainted?.should be_true - end - - it "untrusts the result if the Array is untrusted and non-empty" do - [1, 2].untrust.send(@method).untrusted?.should be_true - end - - it "does not untrust the result if the Array is untrusted but empty" do - [].untrust.send(@method).untrusted?.should be_false - end - - it "untrusts the result if the result of coercing an element is untrusted" do - s = mock("untrust") - s.should_receive(:to_s).and_return("str".untrust) - [s].send(@method).untrusted?.should be_true - end + -> { ArraySpecs.recursive_array.send(@method) }.should.raise(ArgumentError) + -> { ArraySpecs.head_recursive_array.send(@method) }.should.raise(ArgumentError) + -> { ArraySpecs.empty_recursive_array.send(@method) }.should.raise(ArgumentError) end it "uses the first encoding when other strings are compatible" do @@ -111,21 +81,19 @@ describe :array_join_with_default_separator, shared: true do it "fails for arrays with incompatibly-encoded strings" do ary_utf8_bad_binary = ArraySpecs.array_with_utf8_and_binary_strings - -> { ary_utf8_bad_binary.send(@method) }.should raise_error(EncodingError) + -> { ary_utf8_bad_binary.send(@method) }.should.raise(EncodingError) end - ruby_version_is "2.7" do - context "when $, is not nil" do - before do - suppress_warning do - $, = '*' - end + context "when $, is not nil" do + before do + suppress_warning do + $, = '*' end + end - it "warns" do - -> { [].join }.should complain(/warning: \$, is set to non-nil value/) - -> { [].join(nil) }.should complain(/warning: \$, is set to non-nil value/) - end + it "warns" do + -> { [].join }.should complain(/warning: \$, is set to non-nil value/) + -> { [].join(nil) }.should complain(/warning: \$, is set to non-nil value/) end end end @@ -141,42 +109,4 @@ describe :array_join_with_string_separator, shared: true do [1, [2, [3, 4], 5], 6].send(@method, ":").should == "1:2:3:4:5:6" [1, [2, ArraySpecs::MyArray[3, 4], 5], 6].send(@method, ":").should == "1:2:3:4:5:6" end - - ruby_version_is ''...'2.7' do - describe "with a tainted separator" do - before :each do - @sep = ":".taint - end - - it "does not taint the result if the array is empty" do - [].send(@method, @sep).tainted?.should be_false - end - - it "does not taint the result if the array has only one element" do - [1].send(@method, @sep).tainted?.should be_false - end - - it "taints the result if the array has two or more elements" do - [1, 2].send(@method, @sep).tainted?.should be_true - end - end - - describe "with an untrusted separator" do - before :each do - @sep = ":".untrust - end - - it "does not untrust the result if the array is empty" do - [].send(@method, @sep).untrusted?.should be_false - end - - it "does not untrust the result if the array has only one element" do - [1].send(@method, @sep).untrusted?.should be_false - end - - it "untrusts the result if the array has two or more elements" do - [1, 2].send(@method, @sep).untrusted?.should be_true - end - end - end end diff --git a/spec/ruby/core/array/shared/keep_if.rb b/spec/ruby/core/array/shared/keep_if.rb index f26aff028c..44625eebd1 100644 --- a/spec/ruby/core/array/shared/keep_if.rb +++ b/spec/ruby/core/array/shared/keep_if.rb @@ -1,14 +1,15 @@ require_relative '../../enumerable/shared/enumeratorized' +require_relative '../shared/iterable_and_tolerating_size_increasing' describe :keep_if, shared: true do it "deletes elements for which the block returns a false value" do array = [1, 2, 3, 4, 5] - array.send(@method) {|item| item > 3 }.should equal(array) + array.send(@method) {|item| item > 3 }.should.equal?(array) array.should == [4, 5] end it "returns an enumerator if no block is given" do - [1, 2, 3].send(@method).should be_an_instance_of(Enumerator) + [1, 2, 3].send(@method).should.instance_of?(Enumerator) end it "updates the receiver after all blocks" do @@ -32,29 +33,63 @@ describe :keep_if, shared: true do end it "returns an Enumerator if no block is given" do - @frozen.send(@method).should be_an_instance_of(Enumerator) + @frozen.send(@method).should.instance_of?(Enumerator) end describe "with truthy block" do it "keeps elements after any exception" do - -> { @frozen.send(@method) { true } }.should raise_error(Exception) + -> { @frozen.send(@method) { true } }.should.raise(Exception) @frozen.should == @origin end it "raises a FrozenError" do - -> { @frozen.send(@method) { true } }.should raise_error(FrozenError) + -> { @frozen.send(@method) { true } }.should.raise(FrozenError) end end describe "with falsy block" do it "keeps elements after any exception" do - -> { @frozen.send(@method) { false } }.should raise_error(Exception) + -> { @frozen.send(@method) { false } }.should.raise(Exception) @frozen.should == @origin end it "raises a FrozenError" do - -> { @frozen.send(@method) { false } }.should raise_error(FrozenError) + -> { @frozen.send(@method) { false } }.should.raise(FrozenError) end end + + it "raises a FrozenError on a frozen array only during iteration if called without a block" do + enum = @frozen.send(@method) + -> { enum.each {} }.should.raise(FrozenError) + end + end + + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.send(@method) { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] end + + it "only changes elements before error is raised, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.send(@method) do |e| + case e + when 2 then false + when 3 then raise StandardError, 'Oops' + else true + end + end + rescue StandardError + end + + a.should == [1, 3, 4] + end + + @value_to_return = -> _ { true } + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/push.rb b/spec/ruby/core/array/shared/push.rb index ac790fb6a4..ec406e506e 100644 --- a/spec/ruby/core/array/shared/push.rb +++ b/spec/ruby/core/array/shared/push.rb @@ -1,7 +1,7 @@ describe :array_push, shared: true do it "appends the arguments to the array" do a = [ "a", "b", "c" ] - a.send(@method, "d", "e", "f").should equal(a) + a.send(@method, "d", "e", "f").should.equal?(a) a.send(@method).should == ["a", "b", "c", "d", "e", "f"] a.send(@method, 5) a.should == ["a", "b", "c", "d", "e", "f", 5] @@ -27,7 +27,7 @@ describe :array_push, shared: true do end it "raises a FrozenError on a frozen array" do - -> { ArraySpecs.frozen_array.send(@method, 1) }.should raise_error(FrozenError) - -> { ArraySpecs.frozen_array.send(@method) }.should raise_error(FrozenError) + -> { ArraySpecs.frozen_array.send(@method, 1) }.should.raise(FrozenError) + -> { ArraySpecs.frozen_array.send(@method) }.should.raise(FrozenError) end end diff --git a/spec/ruby/core/array/shared/replace.rb b/spec/ruby/core/array/shared/replace.rb index 9a6e60c1b0..06bfd00795 100644 --- a/spec/ruby/core/array/shared/replace.rb +++ b/spec/ruby/core/array/shared/replace.rb @@ -2,9 +2,9 @@ describe :array_replace, shared: true do it "replaces the elements with elements from other array" do a = [1, 2, 3, 4, 5] b = ['a', 'b', 'c'] - a.send(@method, b).should equal(a) + a.send(@method, b).should.equal?(a) a.should == b - a.should_not equal(b) + a.should_not.equal?(b) a.send(@method, [4] * 10) a.should == [4] * 10 @@ -27,7 +27,7 @@ describe :array_replace, shared: true do it "returns self" do ary = [1, 2, 3] other = [:a, :b, :c] - ary.send(@method, other).should equal(ary) + ary.send(@method, other).should.equal?(ary) end it "does not make self dependent to the original array" do @@ -55,6 +55,6 @@ describe :array_replace, shared: true do it "raises a FrozenError on a frozen array" do -> { ArraySpecs.frozen_array.send(@method, ArraySpecs.frozen_array) - }.should raise_error(FrozenError) + }.should.raise(FrozenError) end end diff --git a/spec/ruby/core/array/shared/select.rb b/spec/ruby/core/array/shared/select.rb index 09101e8ab5..cb4f9acbb7 100644 --- a/spec/ruby/core/array/shared/select.rb +++ b/spec/ruby/core/array/shared/select.rb @@ -2,11 +2,14 @@ require_relative '../../../spec_helper' require_relative '../fixtures/classes' require_relative '../shared/enumeratorize' require_relative '../shared/keep_if' +require_relative '../shared/iterable_and_tolerating_size_increasing' require_relative '../../enumerable/shared/enumeratorized' describe :array_select, shared: true do it_should_behave_like :enumeratorize + it_should_behave_like :array_iterable_and_tolerating_size_increasing + before :each do @object = [1,2,3] end @@ -17,7 +20,7 @@ describe :array_select, shared: true do end it "does not return subclass instance on Array subclasses" do - ArraySpecs::MyArray[1, 2, 3].send(@method) { true }.should be_an_instance_of(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method) { true }.should.instance_of?(Array) end it "properly handles recursive arrays" do diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb index 540a050130..b838d86118 100644 --- a/spec/ruby/core/array/shared/slice.rb +++ b/spec/ruby/core/array/shared/slice.rb @@ -130,12 +130,12 @@ describe :array_slice, shared: true do def from.to_int() 'cat' end def to.to_int() -2 end - -> { a.send(@method, from..to) }.should raise_error(TypeError) + -> { a.send(@method, from..to) }.should.raise(TypeError) def from.to_int() 1 end def to.to_int() 'cat' end - -> { a.send(@method, from..to) }.should raise_error(TypeError) + -> { a.send(@method, from..to) }.should.raise(TypeError) end it "returns the elements specified by Range indexes with [m..n]" do @@ -287,10 +287,10 @@ describe :array_slice, shared: true do a.send(@method, 1..0).should == [] a.send(@method, 1...0).should == [] - -> { a.send(@method, "a" .. "b") }.should raise_error(TypeError) - -> { a.send(@method, "a" ... "b") }.should raise_error(TypeError) - -> { a.send(@method, from .. "b") }.should raise_error(TypeError) - -> { a.send(@method, from ... "b") }.should raise_error(TypeError) + -> { a.send(@method, "a" .. "b") }.should.raise(TypeError) + -> { a.send(@method, "a" ... "b") }.should.raise(TypeError) + -> { a.send(@method, from .. "b") }.should.raise(TypeError) + -> { a.send(@method, from ... "b") }.should.raise(TypeError) end it "returns the same elements as [m..n] and [m...n] with Range subclasses" do @@ -397,92 +397,64 @@ describe :array_slice, shared: true do @array = ArraySpecs::MyArray[1, 2, 3, 4, 5] end - ruby_version_is ''...'3.0' do - it "returns a subclass instance with [n, m]" do - @array.send(@method, 0, 2).should be_an_instance_of(ArraySpecs::MyArray) - end - - it "returns a subclass instance with [-n, m]" do - @array.send(@method, -3, 2).should be_an_instance_of(ArraySpecs::MyArray) - end - - it "returns a subclass instance with [n..m]" do - @array.send(@method, 1..3).should be_an_instance_of(ArraySpecs::MyArray) - end - - it "returns a subclass instance with [n...m]" do - @array.send(@method, 1...3).should be_an_instance_of(ArraySpecs::MyArray) - end - - it "returns a subclass instance with [-n..-m]" do - @array.send(@method, -3..-1).should be_an_instance_of(ArraySpecs::MyArray) - end - - it "returns a subclass instance with [-n...-m]" do - @array.send(@method, -3...-1).should be_an_instance_of(ArraySpecs::MyArray) - end + it "returns a Array instance with [n, m]" do + @array.send(@method, 0, 2).should.instance_of?(Array) end - ruby_version_is '3.0' do - it "returns a Array instance with [n, m]" do - @array.send(@method, 0, 2).should be_an_instance_of(Array) - end - - it "returns a Array instance with [-n, m]" do - @array.send(@method, -3, 2).should be_an_instance_of(Array) - end + it "returns a Array instance with [-n, m]" do + @array.send(@method, -3, 2).should.instance_of?(Array) + end - it "returns a Array instance with [n..m]" do - @array.send(@method, 1..3).should be_an_instance_of(Array) - end + it "returns a Array instance with [n..m]" do + @array.send(@method, 1..3).should.instance_of?(Array) + end - it "returns a Array instance with [n...m]" do - @array.send(@method, 1...3).should be_an_instance_of(Array) - end + it "returns a Array instance with [n...m]" do + @array.send(@method, 1...3).should.instance_of?(Array) + end - it "returns a Array instance with [-n..-m]" do - @array.send(@method, -3..-1).should be_an_instance_of(Array) - end + it "returns a Array instance with [-n..-m]" do + @array.send(@method, -3..-1).should.instance_of?(Array) + end - it "returns a Array instance with [-n...-m]" do - @array.send(@method, -3...-1).should be_an_instance_of(Array) - end + it "returns a Array instance with [-n...-m]" do + @array.send(@method, -3...-1).should.instance_of?(Array) end it "returns an empty array when m == n with [m...n]" do @array.send(@method, 1...1).should == [] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "returns an empty array with [0...0]" do @array.send(@method, 0...0).should == [] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "returns an empty array when m > n and m, n are positive with [m..n]" do @array.send(@method, 3..2).should == [] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "returns an empty array when m > n and m, n are negative with [m..n]" do @array.send(@method, -2..-3).should == [] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "returns [] if index == array.size with [index, length]" do @array.send(@method, 5, 2).should == [] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "returns [] if the index is valid but length is zero with [index, length]" do @array.send(@method, 0, 0).should == [] @array.send(@method, 2, 0).should == [] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "does not call #initialize on the subclass instance" do @array.send(@method, 0, 3).should == [1, 2, 3] - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end end @@ -490,13 +462,13 @@ describe :array_slice, shared: true do array = [1, 2, 3, 4, 5, 6] obj = mock('large value') obj.should_receive(:to_int).and_return(bignum_value) - -> { array.send(@method, obj) }.should raise_error(RangeError) + -> { array.send(@method, obj) }.should.raise(RangeError) obj = 8e19 - -> { array.send(@method, obj) }.should raise_error(RangeError) + -> { array.send(@method, obj) }.should.raise(RangeError) # boundary value when longs are 64 bits - -> { array.send(@method, 2.0**63) }.should raise_error(RangeError) + -> { array.send(@method, 2.0**63) }.should.raise(RangeError) # just under the boundary value when longs are 64 bits array.send(@method, max_long.to_f.prev_float).should == nil @@ -506,20 +478,20 @@ describe :array_slice, shared: true do array = [1, 2, 3, 4, 5, 6] obj = mock('large value') obj.should_receive(:to_int).and_return(bignum_value) - -> { array.send(@method, 1, obj) }.should raise_error(RangeError) + -> { array.send(@method, 1, obj) }.should.raise(RangeError) obj = 8e19 - -> { array.send(@method, 1, obj) }.should raise_error(RangeError) + -> { array.send(@method, 1, obj) }.should.raise(RangeError) end it "raises a type error if a range is passed with a length" do - ->{ [1, 2, 3].send(@method, 1..2, 1) }.should raise_error(TypeError) + ->{ [1, 2, 3].send(@method, 1..2, 1) }.should.raise(TypeError) end it "raises a RangeError if passed a range with a bound that is too large" do array = [1, 2, 3, 4, 5, 6] - -> { array.send(@method, bignum_value..(bignum_value + 1)) }.should raise_error(RangeError) - -> { array.send(@method, 0..bignum_value) }.should raise_error(RangeError) + -> { array.send(@method, bignum_value..(bignum_value + 1)) }.should.raise(RangeError) + -> { array.send(@method, 0..bignum_value) }.should.raise(RangeError) end it "can accept endless ranges" do @@ -534,262 +506,352 @@ describe :array_slice, shared: true do a.send(@method, eval("(-9...)")).should == nil end - ruby_version_is "3.0" do - describe "can be sliced with Enumerator::ArithmeticSequence" do - before :each do - @array = [0, 1, 2, 3, 4, 5] - end + describe "can be sliced with Enumerator::ArithmeticSequence" do + before :each do + @array = [0, 1, 2, 3, 4, 5] + end - it "has endless range and positive steps" do - @array.send(@method, eval("(0..).step(1)")).should == [0, 1, 2, 3, 4, 5] - @array.send(@method, eval("(0..).step(2)")).should == [0, 2, 4] - @array.send(@method, eval("(0..).step(10)")).should == [0] + it "has endless range and positive steps" do + @array.send(@method, eval("(0..).step(1)")).should == [0, 1, 2, 3, 4, 5] + @array.send(@method, eval("(0..).step(2)")).should == [0, 2, 4] + @array.send(@method, eval("(0..).step(10)")).should == [0] - @array.send(@method, eval("(2..).step(1)")).should == [2, 3, 4, 5] - @array.send(@method, eval("(2..).step(2)")).should == [2, 4] - @array.send(@method, eval("(2..).step(10)")).should == [2] + @array.send(@method, eval("(2..).step(1)")).should == [2, 3, 4, 5] + @array.send(@method, eval("(2..).step(2)")).should == [2, 4] + @array.send(@method, eval("(2..).step(10)")).should == [2] - @array.send(@method, eval("(-3..).step(1)")).should == [3, 4, 5] - @array.send(@method, eval("(-3..).step(2)")).should == [3, 5] - @array.send(@method, eval("(-3..).step(10)")).should == [3] - end + @array.send(@method, eval("(-3..).step(1)")).should == [3, 4, 5] + @array.send(@method, eval("(-3..).step(2)")).should == [3, 5] + @array.send(@method, eval("(-3..).step(10)")).should == [3] + end - it "has beginless range and positive steps" do - # end with zero index - @array.send(@method, eval("(..0).step(1)")).should == [0] - @array.send(@method, eval("(...0).step(1)")).should == [] + it "has beginless range and positive steps" do + # end with zero index + @array.send(@method, (..0).step(1)).should == [0] + @array.send(@method, (...0).step(1)).should == [] - @array.send(@method, eval("(..0).step(2)")).should == [0] - @array.send(@method, eval("(...0).step(2)")).should == [] + @array.send(@method, (..0).step(2)).should == [0] + @array.send(@method, (...0).step(2)).should == [] - @array.send(@method, eval("(..0).step(10)")).should == [0] - @array.send(@method, eval("(...0).step(10)")).should == [] + @array.send(@method, (..0).step(10)).should == [0] + @array.send(@method, (...0).step(10)).should == [] - # end with positive index - @array.send(@method, eval("(..3).step(1)")).should == [0, 1, 2, 3] - @array.send(@method, eval("(...3).step(1)")).should == [0, 1, 2] + # end with positive index + @array.send(@method, (..3).step(1)).should == [0, 1, 2, 3] + @array.send(@method, (...3).step(1)).should == [0, 1, 2] - @array.send(@method, eval("(..3).step(2)")).should == [0, 2] - @array.send(@method, eval("(...3).step(2)")).should == [0, 2] + @array.send(@method, (..3).step(2)).should == [0, 2] + @array.send(@method, (...3).step(2)).should == [0, 2] - @array.send(@method, eval("(..3).step(10)")).should == [0] - @array.send(@method, eval("(...3).step(10)")).should == [0] + @array.send(@method, (..3).step(10)).should == [0] + @array.send(@method, (...3).step(10)).should == [0] - # end with negative index - @array.send(@method, eval("(..-2).step(1)")).should == [0, 1, 2, 3, 4,] - @array.send(@method, eval("(...-2).step(1)")).should == [0, 1, 2, 3] + # end with negative index + @array.send(@method, (..-2).step(1)).should == [0, 1, 2, 3, 4,] + @array.send(@method, (...-2).step(1)).should == [0, 1, 2, 3] - @array.send(@method, eval("(..-2).step(2)")).should == [0, 2, 4] - @array.send(@method, eval("(...-2).step(2)")).should == [0, 2] + @array.send(@method, (..-2).step(2)).should == [0, 2, 4] + @array.send(@method, (...-2).step(2)).should == [0, 2] - @array.send(@method, eval("(..-2).step(10)")).should == [0] - @array.send(@method, eval("(...-2).step(10)")).should == [0] - end + @array.send(@method, (..-2).step(10)).should == [0] + @array.send(@method, (...-2).step(10)).should == [0] + end - it "has endless range and negative steps" do - @array.send(@method, eval("(0..).step(-1)")).should == [0] - @array.send(@method, eval("(0..).step(-2)")).should == [0] - @array.send(@method, eval("(0..).step(-10)")).should == [0] + it "has endless range and negative steps" do + @array.send(@method, eval("(0..).step(-1)")).should == [0] + @array.send(@method, eval("(0..).step(-2)")).should == [0] + @array.send(@method, eval("(0..).step(-10)")).should == [0] - @array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0] - @array.send(@method, eval("(2..).step(-2)")).should == [2, 0] + @array.send(@method, eval("(2..).step(-1)")).should == [2, 1, 0] + @array.send(@method, eval("(2..).step(-2)")).should == [2, 0] - @array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0] - @array.send(@method, eval("(-3..).step(-2)")).should == [3, 1] - end + @array.send(@method, eval("(-3..).step(-1)")).should == [3, 2, 1, 0] + @array.send(@method, eval("(-3..).step(-2)")).should == [3, 1] + end - it "has closed range and positive steps" do - # start and end with 0 - @array.send(@method, eval("(0..0).step(1)")).should == [0] - @array.send(@method, eval("(0...0).step(1)")).should == [] + it "has closed range and positive steps" do + # start and end with 0 + @array.send(@method, eval("(0..0).step(1)")).should == [0] + @array.send(@method, eval("(0...0).step(1)")).should == [] - @array.send(@method, eval("(0..0).step(2)")).should == [0] - @array.send(@method, eval("(0...0).step(2)")).should == [] + @array.send(@method, eval("(0..0).step(2)")).should == [0] + @array.send(@method, eval("(0...0).step(2)")).should == [] - @array.send(@method, eval("(0..0).step(10)")).should == [0] - @array.send(@method, eval("(0...0).step(10)")).should == [] + @array.send(@method, eval("(0..0).step(10)")).should == [0] + @array.send(@method, eval("(0...0).step(10)")).should == [] - # start and end with positive index - @array.send(@method, eval("(1..3).step(1)")).should == [1, 2, 3] - @array.send(@method, eval("(1...3).step(1)")).should == [1, 2] + # start and end with positive index + @array.send(@method, eval("(1..3).step(1)")).should == [1, 2, 3] + @array.send(@method, eval("(1...3).step(1)")).should == [1, 2] - @array.send(@method, eval("(1..3).step(2)")).should == [1, 3] - @array.send(@method, eval("(1...3).step(2)")).should == [1] + @array.send(@method, eval("(1..3).step(2)")).should == [1, 3] + @array.send(@method, eval("(1...3).step(2)")).should == [1] - @array.send(@method, eval("(1..3).step(10)")).should == [1] - @array.send(@method, eval("(1...3).step(10)")).should == [1] + @array.send(@method, eval("(1..3).step(10)")).should == [1] + @array.send(@method, eval("(1...3).step(10)")).should == [1] - # start with positive index, end with negative index - @array.send(@method, eval("(1..-2).step(1)")).should == [1, 2, 3, 4] - @array.send(@method, eval("(1...-2).step(1)")).should == [1, 2, 3] + # start with positive index, end with negative index + @array.send(@method, eval("(1..-2).step(1)")).should == [1, 2, 3, 4] + @array.send(@method, eval("(1...-2).step(1)")).should == [1, 2, 3] - @array.send(@method, eval("(1..-2).step(2)")).should == [1, 3] - @array.send(@method, eval("(1...-2).step(2)")).should == [1, 3] + @array.send(@method, eval("(1..-2).step(2)")).should == [1, 3] + @array.send(@method, eval("(1...-2).step(2)")).should == [1, 3] - @array.send(@method, eval("(1..-2).step(10)")).should == [1] - @array.send(@method, eval("(1...-2).step(10)")).should == [1] + @array.send(@method, eval("(1..-2).step(10)")).should == [1] + @array.send(@method, eval("(1...-2).step(10)")).should == [1] - # start with negative index, end with positive index - @array.send(@method, eval("(-4..4).step(1)")).should == [2, 3, 4] - @array.send(@method, eval("(-4...4).step(1)")).should == [2, 3] + # start with negative index, end with positive index + @array.send(@method, eval("(-4..4).step(1)")).should == [2, 3, 4] + @array.send(@method, eval("(-4...4).step(1)")).should == [2, 3] - @array.send(@method, eval("(-4..4).step(2)")).should == [2, 4] - @array.send(@method, eval("(-4...4).step(2)")).should == [2] + @array.send(@method, eval("(-4..4).step(2)")).should == [2, 4] + @array.send(@method, eval("(-4...4).step(2)")).should == [2] - @array.send(@method, eval("(-4..4).step(10)")).should == [2] - @array.send(@method, eval("(-4...4).step(10)")).should == [2] + @array.send(@method, eval("(-4..4).step(10)")).should == [2] + @array.send(@method, eval("(-4...4).step(10)")).should == [2] - # start with negative index, end with negative index - @array.send(@method, eval("(-4..-2).step(1)")).should == [2, 3, 4] - @array.send(@method, eval("(-4...-2).step(1)")).should == [2, 3] + # start with negative index, end with negative index + @array.send(@method, eval("(-4..-2).step(1)")).should == [2, 3, 4] + @array.send(@method, eval("(-4...-2).step(1)")).should == [2, 3] - @array.send(@method, eval("(-4..-2).step(2)")).should == [2, 4] - @array.send(@method, eval("(-4...-2).step(2)")).should == [2] + @array.send(@method, eval("(-4..-2).step(2)")).should == [2, 4] + @array.send(@method, eval("(-4...-2).step(2)")).should == [2] - @array.send(@method, eval("(-4..-2).step(10)")).should == [2] - @array.send(@method, eval("(-4...-2).step(10)")).should == [2] - end + @array.send(@method, eval("(-4..-2).step(10)")).should == [2] + @array.send(@method, eval("(-4...-2).step(10)")).should == [2] + end - it "has closed range and negative steps" do - # start and end with 0 - @array.send(@method, eval("(0..0).step(-1)")).should == [0] - @array.send(@method, eval("(0...0).step(-1)")).should == [] + it "has closed range and negative steps" do + # start and end with 0 + @array.send(@method, eval("(0..0).step(-1)")).should == [0] + @array.send(@method, eval("(0...0).step(-1)")).should == [] - @array.send(@method, eval("(0..0).step(-2)")).should == [0] - @array.send(@method, eval("(0...0).step(-2)")).should == [] + @array.send(@method, eval("(0..0).step(-2)")).should == [0] + @array.send(@method, eval("(0...0).step(-2)")).should == [] - @array.send(@method, eval("(0..0).step(-10)")).should == [0] - @array.send(@method, eval("(0...0).step(-10)")).should == [] + @array.send(@method, eval("(0..0).step(-10)")).should == [0] + @array.send(@method, eval("(0...0).step(-10)")).should == [] - # start and end with positive index - @array.send(@method, eval("(1..3).step(-1)")).should == [] - @array.send(@method, eval("(1...3).step(-1)")).should == [] + # start and end with positive index + @array.send(@method, eval("(1..3).step(-1)")).should == [] + @array.send(@method, eval("(1...3).step(-1)")).should == [] - @array.send(@method, eval("(1..3).step(-2)")).should == [] - @array.send(@method, eval("(1...3).step(-2)")).should == [] + @array.send(@method, eval("(1..3).step(-2)")).should == [] + @array.send(@method, eval("(1...3).step(-2)")).should == [] - @array.send(@method, eval("(1..3).step(-10)")).should == [] - @array.send(@method, eval("(1...3).step(-10)")).should == [] + @array.send(@method, eval("(1..3).step(-10)")).should == [] + @array.send(@method, eval("(1...3).step(-10)")).should == [] - # start with positive index, end with negative index - @array.send(@method, eval("(1..-2).step(-1)")).should == [] - @array.send(@method, eval("(1...-2).step(-1)")).should == [] + # start with positive index, end with negative index + @array.send(@method, eval("(1..-2).step(-1)")).should == [] + @array.send(@method, eval("(1...-2).step(-1)")).should == [] - @array.send(@method, eval("(1..-2).step(-2)")).should == [] - @array.send(@method, eval("(1...-2).step(-2)")).should == [] + @array.send(@method, eval("(1..-2).step(-2)")).should == [] + @array.send(@method, eval("(1...-2).step(-2)")).should == [] - @array.send(@method, eval("(1..-2).step(-10)")).should == [] - @array.send(@method, eval("(1...-2).step(-10)")).should == [] + @array.send(@method, eval("(1..-2).step(-10)")).should == [] + @array.send(@method, eval("(1...-2).step(-10)")).should == [] - # start with negative index, end with positive index - @array.send(@method, eval("(-4..4).step(-1)")).should == [] - @array.send(@method, eval("(-4...4).step(-1)")).should == [] + # start with negative index, end with positive index + @array.send(@method, eval("(-4..4).step(-1)")).should == [] + @array.send(@method, eval("(-4...4).step(-1)")).should == [] - @array.send(@method, eval("(-4..4).step(-2)")).should == [] - @array.send(@method, eval("(-4...4).step(-2)")).should == [] + @array.send(@method, eval("(-4..4).step(-2)")).should == [] + @array.send(@method, eval("(-4...4).step(-2)")).should == [] - @array.send(@method, eval("(-4..4).step(-10)")).should == [] - @array.send(@method, eval("(-4...4).step(-10)")).should == [] + @array.send(@method, eval("(-4..4).step(-10)")).should == [] + @array.send(@method, eval("(-4...4).step(-10)")).should == [] - # start with negative index, end with negative index - @array.send(@method, eval("(-4..-2).step(-1)")).should == [] - @array.send(@method, eval("(-4...-2).step(-1)")).should == [] + # start with negative index, end with negative index + @array.send(@method, eval("(-4..-2).step(-1)")).should == [] + @array.send(@method, eval("(-4...-2).step(-1)")).should == [] - @array.send(@method, eval("(-4..-2).step(-2)")).should == [] - @array.send(@method, eval("(-4...-2).step(-2)")).should == [] + @array.send(@method, eval("(-4..-2).step(-2)")).should == [] + @array.send(@method, eval("(-4...-2).step(-2)")).should == [] - @array.send(@method, eval("(-4..-2).step(-10)")).should == [] - @array.send(@method, eval("(-4...-2).step(-10)")).should == [] - end + @array.send(@method, eval("(-4..-2).step(-10)")).should == [] + @array.send(@method, eval("(-4...-2).step(-10)")).should == [] + end - it "has inverted closed range and positive steps" do - # start and end with positive index - @array.send(@method, eval("(3..1).step(1)")).should == [] - @array.send(@method, eval("(3...1).step(1)")).should == [] + it "has inverted closed range and positive steps" do + # start and end with positive index + @array.send(@method, eval("(3..1).step(1)")).should == [] + @array.send(@method, eval("(3...1).step(1)")).should == [] - @array.send(@method, eval("(3..1).step(2)")).should == [] - @array.send(@method, eval("(3...1).step(2)")).should == [] + @array.send(@method, eval("(3..1).step(2)")).should == [] + @array.send(@method, eval("(3...1).step(2)")).should == [] - @array.send(@method, eval("(3..1).step(10)")).should == [] - @array.send(@method, eval("(3...1).step(10)")).should == [] + @array.send(@method, eval("(3..1).step(10)")).should == [] + @array.send(@method, eval("(3...1).step(10)")).should == [] - # start with negative index, end with positive index - @array.send(@method, eval("(-2..1).step(1)")).should == [] - @array.send(@method, eval("(-2...1).step(1)")).should == [] + # start with negative index, end with positive index + @array.send(@method, eval("(-2..1).step(1)")).should == [] + @array.send(@method, eval("(-2...1).step(1)")).should == [] - @array.send(@method, eval("(-2..1).step(2)")).should == [] - @array.send(@method, eval("(-2...1).step(2)")).should == [] + @array.send(@method, eval("(-2..1).step(2)")).should == [] + @array.send(@method, eval("(-2...1).step(2)")).should == [] - @array.send(@method, eval("(-2..1).step(10)")).should == [] - @array.send(@method, eval("(-2...1).step(10)")).should == [] + @array.send(@method, eval("(-2..1).step(10)")).should == [] + @array.send(@method, eval("(-2...1).step(10)")).should == [] - # start with positive index, end with negative index - @array.send(@method, eval("(4..-4).step(1)")).should == [] - @array.send(@method, eval("(4...-4).step(1)")).should == [] + # start with positive index, end with negative index + @array.send(@method, eval("(4..-4).step(1)")).should == [] + @array.send(@method, eval("(4...-4).step(1)")).should == [] - @array.send(@method, eval("(4..-4).step(2)")).should == [] - @array.send(@method, eval("(4...-4).step(2)")).should == [] + @array.send(@method, eval("(4..-4).step(2)")).should == [] + @array.send(@method, eval("(4...-4).step(2)")).should == [] - @array.send(@method, eval("(4..-4).step(10)")).should == [] - @array.send(@method, eval("(4...-4).step(10)")).should == [] + @array.send(@method, eval("(4..-4).step(10)")).should == [] + @array.send(@method, eval("(4...-4).step(10)")).should == [] - # start with negative index, end with negative index - @array.send(@method, eval("(-2..-4).step(1)")).should == [] - @array.send(@method, eval("(-2...-4).step(1)")).should == [] + # start with negative index, end with negative index + @array.send(@method, eval("(-2..-4).step(1)")).should == [] + @array.send(@method, eval("(-2...-4).step(1)")).should == [] - @array.send(@method, eval("(-2..-4).step(2)")).should == [] - @array.send(@method, eval("(-2...-4).step(2)")).should == [] + @array.send(@method, eval("(-2..-4).step(2)")).should == [] + @array.send(@method, eval("(-2...-4).step(2)")).should == [] - @array.send(@method, eval("(-2..-4).step(10)")).should == [] - @array.send(@method, eval("(-2...-4).step(10)")).should == [] - end + @array.send(@method, eval("(-2..-4).step(10)")).should == [] + @array.send(@method, eval("(-2...-4).step(10)")).should == [] + end - it "has range with bounds outside of array" do - # end is equal to array's length - @array.send(@method, (0..6).step(1)).should == [0, 1, 2, 3, 4, 5] - -> { @array.send(@method, (0..6).step(2)) }.should raise_error(RangeError) + it "has range with bounds outside of array" do + # end is equal to array's length + @array.send(@method, (0..6).step(1)).should == [0, 1, 2, 3, 4, 5] + -> { @array.send(@method, (0..6).step(2)) }.should.raise(RangeError) - # end is greater than length with positive steps - @array.send(@method, (1..6).step(2)).should == [1, 3, 5] - @array.send(@method, (2..7).step(2)).should == [2, 4] - -> { @array.send(@method, (2..8).step(2)) }.should raise_error(RangeError) + # end is greater than length with positive steps + @array.send(@method, (1..6).step(2)).should == [1, 3, 5] + @array.send(@method, (2..7).step(2)).should == [2, 4] + -> { @array.send(@method, (2..8).step(2)) }.should.raise(RangeError) - # begin is greater than length with negative steps - @array.send(@method, (6..1).step(-2)).should == [5, 3, 1] - @array.send(@method, (7..2).step(-2)).should == [5, 3] - -> { @array.send(@method, (8..2).step(-2)) }.should raise_error(RangeError) - end + # begin is greater than length with negative steps + @array.send(@method, (6..1).step(-2)).should == [5, 3, 1] + @array.send(@method, (7..2).step(-2)).should == [5, 3] + -> { @array.send(@method, (8..2).step(-2)) }.should.raise(RangeError) + end - it "has endless range with start outside of array's bounds" do - @array.send(@method, eval("(6..).step(1)")).should == [] - @array.send(@method, eval("(7..).step(1)")).should == nil + it "has endless range with start outside of array's bounds" do + @array.send(@method, eval("(6..).step(1)")).should == [] + @array.send(@method, eval("(7..).step(1)")).should == nil - @array.send(@method, eval("(6..).step(2)")).should == [] - -> { @array.send(@method, eval("(7..).step(2)")) }.should raise_error(RangeError) - end + @array.send(@method, eval("(6..).step(2)")).should == [] + -> { @array.send(@method, eval("(7..).step(2)")) }.should.raise(RangeError) end end - ruby_version_is "2.7" do - it "can accept beginless ranges" do - a = [0, 1, 2, 3, 4, 5] - a.send(@method, eval("(..3)")).should == [0, 1, 2, 3] - a.send(@method, eval("(...3)")).should == [0, 1, 2] - a.send(@method, eval("(..-3)")).should == [0, 1, 2, 3] - a.send(@method, eval("(...-3)")).should == [0, 1, 2] - a.send(@method, eval("(..0)")).should == [0] - a.send(@method, eval("(...0)")).should == [] - a.send(@method, eval("(..9)")).should == [0, 1, 2, 3, 4, 5] - a.send(@method, eval("(...9)")).should == [0, 1, 2, 3, 4, 5] - a.send(@method, eval("(..-9)")).should == [] - a.send(@method, eval("(...-9)")).should == [] + it "can accept beginless ranges" do + a = [0, 1, 2, 3, 4, 5] + a.send(@method, (..3)).should == [0, 1, 2, 3] + a.send(@method, (...3)).should == [0, 1, 2] + a.send(@method, (..-3)).should == [0, 1, 2, 3] + a.send(@method, (...-3)).should == [0, 1, 2] + a.send(@method, (..0)).should == [0] + a.send(@method, (...0)).should == [] + a.send(@method, (..9)).should == [0, 1, 2, 3, 4, 5] + a.send(@method, (...9)).should == [0, 1, 2, 3, 4, 5] + a.send(@method, (..-9)).should == [] + a.send(@method, (...-9)).should == [] + end + + describe "can be sliced with Enumerator::ArithmeticSequence" do + it "with infinite/inverted ranges and negative steps" do + @array = [0, 1, 2, 3, 4, 5] + @array.send(@method, (2..).step(-1)).should == [2, 1, 0] + @array.send(@method, (2..).step(-2)).should == [2, 0] + @array.send(@method, (2..).step(-3)).should == [2] + @array.send(@method, (2..).step(-4)).should == [2] + + @array.send(@method, (-3..).step(-1)).should == [3, 2, 1, 0] + @array.send(@method, (-3..).step(-2)).should == [3, 1] + @array.send(@method, (-3..).step(-3)).should == [3, 0] + @array.send(@method, (-3..).step(-4)).should == [3] + @array.send(@method, (-3..).step(-5)).should == [3] + + @array.send(@method, (..0).step(-1)).should == [5, 4, 3, 2, 1, 0] + @array.send(@method, (..0).step(-2)).should == [5, 3, 1] + @array.send(@method, (..0).step(-3)).should == [5, 2] + @array.send(@method, (..0).step(-4)).should == [5, 1] + @array.send(@method, (..0).step(-5)).should == [5, 0] + @array.send(@method, (..0).step(-6)).should == [5] + @array.send(@method, (..0).step(-7)).should == [5] + + @array.send(@method, (...0).step(-1)).should == [5, 4, 3, 2, 1] + @array.send(@method, (...0).step(-2)).should == [5, 3, 1] + @array.send(@method, (...0).step(-3)).should == [5, 2] + @array.send(@method, (...0).step(-4)).should == [5, 1] + @array.send(@method, (...0).step(-5)).should == [5] + @array.send(@method, (...0).step(-6)).should == [5] + + @array.send(@method, (...1).step(-1)).should == [5, 4, 3, 2] + @array.send(@method, (...1).step(-2)).should == [5, 3] + @array.send(@method, (...1).step(-3)).should == [5, 2] + @array.send(@method, (...1).step(-4)).should == [5] + @array.send(@method, (...1).step(-5)).should == [5] + + @array.send(@method, (..-5).step(-1)).should == [5, 4, 3, 2, 1] + @array.send(@method, (..-5).step(-2)).should == [5, 3, 1] + @array.send(@method, (..-5).step(-3)).should == [5, 2] + @array.send(@method, (..-5).step(-4)).should == [5, 1] + @array.send(@method, (..-5).step(-5)).should == [5] + @array.send(@method, (..-5).step(-6)).should == [5] + + @array.send(@method, (...-5).step(-1)).should == [5, 4, 3, 2] + @array.send(@method, (...-5).step(-2)).should == [5, 3] + @array.send(@method, (...-5).step(-3)).should == [5, 2] + @array.send(@method, (...-5).step(-4)).should == [5] + @array.send(@method, (...-5).step(-5)).should == [5] + + @array.send(@method, (4..1).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (4..1).step(-2)).should == [4, 2] + @array.send(@method, (4..1).step(-3)).should == [4, 1] + @array.send(@method, (4..1).step(-4)).should == [4] + @array.send(@method, (4..1).step(-5)).should == [4] + + @array.send(@method, (4...1).step(-1)).should == [4, 3, 2] + @array.send(@method, (4...1).step(-2)).should == [4, 2] + @array.send(@method, (4...1).step(-3)).should == [4] + @array.send(@method, (4...1).step(-4)).should == [4] + + @array.send(@method, (-2..1).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (-2..1).step(-2)).should == [4, 2] + @array.send(@method, (-2..1).step(-3)).should == [4, 1] + @array.send(@method, (-2..1).step(-4)).should == [4] + @array.send(@method, (-2..1).step(-5)).should == [4] + + @array.send(@method, (-2...1).step(-1)).should == [4, 3, 2] + @array.send(@method, (-2...1).step(-2)).should == [4, 2] + @array.send(@method, (-2...1).step(-3)).should == [4] + @array.send(@method, (-2...1).step(-4)).should == [4] + + @array.send(@method, (4..-5).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (4..-5).step(-2)).should == [4, 2] + @array.send(@method, (4..-5).step(-3)).should == [4, 1] + @array.send(@method, (4..-5).step(-4)).should == [4] + @array.send(@method, (4..-5).step(-5)).should == [4] + + @array.send(@method, (4...-5).step(-1)).should == [4, 3, 2] + @array.send(@method, (4...-5).step(-2)).should == [4, 2] + @array.send(@method, (4...-5).step(-3)).should == [4] + @array.send(@method, (4...-5).step(-4)).should == [4] + + @array.send(@method, (-2..-5).step(-1)).should == [4, 3, 2, 1] + @array.send(@method, (-2..-5).step(-2)).should == [4, 2] + @array.send(@method, (-2..-5).step(-3)).should == [4, 1] + @array.send(@method, (-2..-5).step(-4)).should == [4] + @array.send(@method, (-2..-5).step(-5)).should == [4] + + @array.send(@method, (-2...-5).step(-1)).should == [4, 3, 2] + @array.send(@method, (-2...-5).step(-2)).should == [4, 2] + @array.send(@method, (-2...-5).step(-3)).should == [4] + @array.send(@method, (-2...-5).step(-4)).should == [4] end + end - it "can accept nil...nil ranges" do - a = [0, 1, 2, 3, 4, 5] - a.send(@method, eval("(nil...nil)")).should == a - a.send(@method, eval("(...nil)")).should == a - a.send(@method, eval("(nil..)")).should == a - end + it "can accept nil...nil ranges" do + a = [0, 1, 2, 3, 4, 5] + a.send(@method, eval("(nil...nil)")).should == a + a.send(@method, (...nil)).should == a + a.send(@method, eval("(nil..)")).should == a end end diff --git a/spec/ruby/core/array/shared/union.rb b/spec/ruby/core/array/shared/union.rb index 0b60df9ca4..0b225b9a31 100644 --- a/spec/ruby/core/array/shared/union.rb +++ b/spec/ruby/core/array/shared/union.rb @@ -60,9 +60,9 @@ describe :array_binary_union, shared: true do end it "does not return subclass instances for Array subclasses" do - ArraySpecs::MyArray[1, 2, 3].send(@method, []).should be_an_instance_of(Array) - ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array) - [].send(@method, ArraySpecs::MyArray[1, 2, 3]).should be_an_instance_of(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method, []).should.instance_of?(Array) + ArraySpecs::MyArray[1, 2, 3].send(@method, ArraySpecs::MyArray[1, 2, 3]).should.instance_of?(Array) + [].send(@method, ArraySpecs::MyArray[1, 2, 3]).should.instance_of?(Array) end it "does not call to_ary on array subclasses" do diff --git a/spec/ruby/core/array/shared/unshift.rb b/spec/ruby/core/array/shared/unshift.rb index fc82e19e2a..b636347cd3 100644 --- a/spec/ruby/core/array/shared/unshift.rb +++ b/spec/ruby/core/array/shared/unshift.rb @@ -1,9 +1,9 @@ describe :array_unshift, shared: true do it "prepends object to the original array" do a = [1, 2, 3] - a.send(@method, "a").should equal(a) + a.send(@method, "a").should.equal?(a) a.should == ['a', 1, 2, 3] - a.send(@method).should equal(a) + a.send(@method).should.equal?(a) a.should == ['a', 1, 2, 3] a.send(@method, 5, 4, 3) a.should == [5, 4, 3, 'a', 1, 2, 3] @@ -22,6 +22,11 @@ describe :array_unshift, shared: true do a.should == [3, 4] end + it "returns self" do + a = [1, 2, 3] + a.send(@method, "a").should.equal?(a) + end + it "quietly ignores unshifting nothing" do [].send(@method).should == [] end @@ -36,11 +41,24 @@ describe :array_unshift, shared: true do end it "raises a FrozenError on a frozen array when the array is modified" do - -> { ArraySpecs.frozen_array.send(@method, 1) }.should raise_error(FrozenError) + -> { ArraySpecs.frozen_array.send(@method, 1) }.should.raise(FrozenError) end # see [ruby-core:23666] it "raises a FrozenError on a frozen array when the array would not be modified" do - -> { ArraySpecs.frozen_array.send(@method) }.should raise_error(FrozenError) + -> { ArraySpecs.frozen_array.send(@method) }.should.raise(FrozenError) + end + + # https://github.com/truffleruby/truffleruby/issues/2772 + it "doesn't rely on Array#[]= so it can be overridden" do + subclass = Class.new(Array) do + def []=(*) + raise "[]= is called" + end + end + + array = subclass.new + array.send(@method, 1) + array.should == [1] end end |
