diff options
Diffstat (limited to 'spec/ruby/core/array')
27 files changed, 446 insertions, 5 deletions
diff --git a/spec/ruby/core/array/all_spec.rb b/spec/ruby/core/array/all_spec.rb new file mode 100644 index 0000000000..680e8c26fa --- /dev/null +++ b/spec/ruby/core/array/all_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' + +describe "Array#all?" do + @value_to_return = -> _ { true } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :all? + + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].all?(/bar/) { false }.should == true + }.should complain(/given block not used/) + end +end diff --git a/spec/ruby/core/array/any_spec.rb b/spec/ruby/core/array/any_spec.rb index 09d949fe6e..b51ce62f0f 100644 --- a/spec/ruby/core/array/any_spec.rb +++ b/spec/ruby/core/array/any_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#any?" do describe 'with no block given (a default block of { |x| x } is implicit)' do @@ -19,6 +20,9 @@ describe "Array#any?" do end describe 'with a block given' do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :any? + it 'is false if the array is empty' do empty_array = [] empty_array.any? {|v| 1 == 1 }.should == false @@ -34,4 +38,12 @@ describe "Array#any?" do array_with_members.any? {|v| v == 42 }.should == false end end + + describe 'when given a pattern argument' do + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].any?(/bar/) { false }.should == true + }.should complain(/given block not used/) + end + end end diff --git a/spec/ruby/core/array/count_spec.rb b/spec/ruby/core/array/count_spec.rb index eaf275aeb7..e778233c16 100644 --- a/spec/ruby/core/array/count_spec.rb +++ b/spec/ruby/core/array/count_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#count" do it "returns the number of elements" do @@ -12,4 +13,14 @@ describe "Array#count" do it "returns the number of element for which the block evaluates to true" do [:a, :b, :c].count { |s| s != :b }.should == 2 end + + it "ignores the block if there is an argument" do + -> { + [:a, :b, :b, :c].count(:b) { |e| e.size > 10 }.should == 2 + }.should complain(/given block not used/) + end + + context "when a block argument given" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :count + end end diff --git a/spec/ruby/core/array/delete_if_spec.rb b/spec/ruby/core/array/delete_if_spec.rb index 1459cc8d04..10972eee0e 100644 --- a/spec/ruby/core/array/delete_if_spec.rb +++ b/spec/ruby/core/array/delete_if_spec.rb @@ -2,6 +2,7 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' require_relative 'shared/delete_if' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' describe "Array#delete_if" do @@ -47,6 +48,35 @@ describe "Array#delete_if" do -> { ArraySpecs.empty_frozen_array.delete_if {} }.should raise_error(FrozenError) end + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.delete_if { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "only removes elements for which the block returns true, keeping the element which raised an error." do + a = [1, 2, 3, 4] + begin + a.delete_if do |e| + case e + when 2 then true + when 3 then raise StandardError, 'Oops' + else false + end + end + rescue StandardError + end + + a.should == [1, 3, 4] + end + it_behaves_like :enumeratorized_with_origin_size, :delete_if, [1,2,3] it_behaves_like :delete_if, :delete_if + + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :delete_if end diff --git a/spec/ruby/core/array/drop_while_spec.rb b/spec/ruby/core/array/drop_while_spec.rb index bb783d22a5..94064528aa 100644 --- a/spec/ruby/core/array/drop_while_spec.rb +++ b/spec/ruby/core/array/drop_while_spec.rb @@ -1,7 +1,11 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#drop_while" do + @value_to_return = -> _ { true } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :drop_while + it "removes elements from the start of the array while the block evaluates to true" do [1, 2, 3, 4].drop_while { |n| n < 4 }.should == [4] end diff --git a/spec/ruby/core/array/each_index_spec.rb b/spec/ruby/core/array/each_index_spec.rb index 75ab61b6f9..3a4bca9251 100644 --- a/spec/ruby/core/array/each_index_spec.rb +++ b/spec/ruby/core/array/each_index_spec.rb @@ -40,3 +40,19 @@ describe "Array#each_index" do it_behaves_like :enumeratorize, :each_index it_behaves_like :enumeratorized_with_origin_size, :each_index, [1,2,3] end + +describe "Array#each_index" do + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.each_index do |index| + ScratchPad << index + array << i if i < 100 + i += 1 + end + + ScratchPad.recorded.should == (0..102).to_a # element indices + end +end diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb index cf8e9da6d8..57d6082f01 100644 --- a/spec/ruby/core/array/each_spec.rb +++ b/spec/ruby/core/array/each_spec.rb @@ -1,6 +1,7 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' # Mutating the array while it is being iterated is discouraged as it can result in confusing behavior. @@ -75,3 +76,7 @@ describe "Array#each" do it_behaves_like :enumeratorize, :each it_behaves_like :enumeratorized_with_origin_size, :each, [1,2,3] end + +describe "Array#each" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :each +end diff --git a/spec/ruby/core/array/fill_spec.rb b/spec/ruby/core/array/fill_spec.rb index 524728233b..a591444bab 100644 --- a/spec/ruby/core/array/fill_spec.rb +++ b/spec/ruby/core/array/fill_spec.rb @@ -72,6 +72,48 @@ describe "Array#fill" do -> { [].fill(1, 2) {|i|} }.should_not raise_error(ArgumentError) -> { [].fill(1, 2, true) {|i|} }.should raise_error(ArgumentError) end + + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.fill { 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.fill do |i| + case i + when 0 then -1 + when 1 then -2 + when 2 then raise StandardError, 'Oops' + else 0 + end + end + rescue StandardError + end + + a.should == [-1, -2, 3, 4] + end + + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.fill do |index| + ScratchPad << index + array << i if i < 100 + i++ + index + end + + ScratchPad.recorded.should == [0, 1, 2] + end end describe "Array#fill with (filler, index, length)" do diff --git a/spec/ruby/core/array/initialize_spec.rb b/spec/ruby/core/array/initialize_spec.rb index a8deed2b84..b9fa77b16e 100644 --- a/spec/ruby/core/array/initialize_spec.rb +++ b/spec/ruby/core/array/initialize_spec.rb @@ -53,7 +53,9 @@ describe "Array#initialize with no arguments" do end it "does not use the given block" do - ->{ [1, 2, 3].send(:initialize) { raise } }.should_not raise_error + -> { + -> { [1, 2, 3].send(:initialize) { raise } }.should_not raise_error + }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true) end end diff --git a/spec/ruby/core/array/intersect_spec.rb b/spec/ruby/core/array/intersect_spec.rb index b8c5b1e69a..62ac157278 100644 --- a/spec/ruby/core/array/intersect_spec.rb +++ b/spec/ruby/core/array/intersect_spec.rb @@ -1,17 +1,66 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe 'Array#intersect?' do ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/15198 describe 'when at least one element in two Arrays is the same' do it 'returns true' do - [1, 2].intersect?([2, 3]).should == true + [1, 2].intersect?([2, 3, 4]).should == true + [2, 3, 4].intersect?([1, 2]).should == true end end describe 'when there are no elements in common between two Arrays' do it 'returns false' do - [1, 2].intersect?([3, 4]).should == false + [0, 1, 2].intersect?([3, 4]).should == false + [3, 4].intersect?([0, 1, 2]).should == false + [3, 4].intersect?([]).should == false + [].intersect?([0, 1, 2]).should == false end end + + it "tries to convert the passed argument to an Array using #to_ary" do + obj = mock('[1,2,3]') + obj.should_receive(:to_ary).and_return([1, 2, 3]) + + [1, 2].intersect?(obj).should == true + end + + it "determines equivalence between elements in the sense of eql?" do + obj1 = mock('1') + obj2 = mock('2') + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) + obj1.stub!(:eql?).and_return(true) + obj2.stub!(:eql?).and_return(true) + + [obj1].intersect?([obj2]).should == true + + obj1 = mock('3') + obj2 = mock('4') + obj1.stub!(:hash).and_return(0) + obj2.stub!(:hash).and_return(0) + obj1.stub!(:eql?).and_return(false) + obj2.stub!(:eql?).and_return(false) + + [obj1].intersect?([obj2]).should == false + end + + it "does not call to_ary on array subclasses" do + [5, 6].intersect?(ArraySpecs::ToAryArray[1, 2, 5, 6]).should == true + end + + it "properly handles an identical item even when its #eql? isn't reflexive" do + x = mock('x') + x.stub!(:hash).and_return(42) + x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI. + + [x].intersect?([x]).should == true + end + + it "has semantic of !(a & b).empty?" do + [].intersect?([]).should == false + [nil].intersect?([nil]).should == true + end end end diff --git a/spec/ruby/core/array/new_spec.rb b/spec/ruby/core/array/new_spec.rb index 96ec6b8198..b50a4857b0 100644 --- a/spec/ruby/core/array/new_spec.rb +++ b/spec/ruby/core/array/new_spec.rb @@ -26,7 +26,9 @@ describe "Array.new with no arguments" do end it "does not use the given block" do - ->{ Array.new { raise } }.should_not raise_error + -> { + -> { Array.new { raise } }.should_not raise_error + }.should complain(/warning: given block not used/, verbose: true) end end diff --git a/spec/ruby/core/array/none_spec.rb b/spec/ruby/core/array/none_spec.rb new file mode 100644 index 0000000000..31cd8c46d6 --- /dev/null +++ b/spec/ruby/core/array/none_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' + +describe "Array#none?" do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :none? + + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].none?(/baz/) { true }.should == true + }.should complain(/given block not used/) + end +end diff --git a/spec/ruby/core/array/one_spec.rb b/spec/ruby/core/array/one_spec.rb new file mode 100644 index 0000000000..0c61907881 --- /dev/null +++ b/spec/ruby/core/array/one_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' + +describe "Array#one?" do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :one? + + it "ignores the block if there is an argument" do + -> { + ['bar', 'foobar'].one?(/foo/) { false }.should == true + }.should complain(/given block not used/) + end +end diff --git a/spec/ruby/core/array/reject_spec.rb b/spec/ruby/core/array/reject_spec.rb index fcf43fabde..81a467e364 100644 --- a/spec/ruby/core/array/reject_spec.rb +++ b/spec/ruby/core/array/reject_spec.rb @@ -2,6 +2,7 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/enumeratorize' require_relative 'shared/delete_if' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' describe "Array#reject" do @@ -47,6 +48,10 @@ describe "Array#reject" do it_behaves_like :enumeratorized_with_origin_size, :reject, [1,2,3] end +describe "Array#reject" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :reject +end + describe "Array#reject!" do it "removes elements for which block is true" do a = [3, 4, 5, 6, 7, 8, 9, 10, 11] @@ -111,6 +116,11 @@ describe "Array#reject!" do -> { ArraySpecs.empty_frozen_array.reject! {} }.should raise_error(FrozenError) end + it "raises a FrozenError on a frozen array only during iteration if called without a block" do + enum = ArraySpecs.frozen_array.reject! + -> { enum.each {} }.should raise_error(FrozenError) + end + it "does not truncate the array is the block raises an exception" do a = [1, 2, 3] begin @@ -141,3 +151,8 @@ describe "Array#reject!" do it_behaves_like :enumeratorized_with_origin_size, :reject!, [1,2,3] it_behaves_like :delete_if, :reject! end + +describe "Array#reject!" do + @value_to_return = -> _ { false } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :reject! +end diff --git a/spec/ruby/core/array/reverse_each_spec.rb b/spec/ruby/core/array/reverse_each_spec.rb index 97c84a2c2e..59dabcd33d 100644 --- a/spec/ruby/core/array/reverse_each_spec.rb +++ b/spec/ruby/core/array/reverse_each_spec.rb @@ -38,6 +38,20 @@ describe "Array#reverse_each" do [1, 2, 3].reverse_each.size.should == 3 end + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.reverse_each do |e| + ScratchPad << e + array.prepend i if i < 100 + i += 1 + end + + ScratchPad.recorded.should == [:c, :a, 1] + end + it_behaves_like :enumeratorize, :reverse_each it_behaves_like :enumeratorized_with_origin_size, :reverse_each, [1,2,3] end diff --git a/spec/ruby/core/array/rindex_spec.rb b/spec/ruby/core/array/rindex_spec.rb index a75099e390..13de88818c 100644 --- a/spec/ruby/core/array/rindex_spec.rb +++ b/spec/ruby/core/array/rindex_spec.rb @@ -68,6 +68,21 @@ describe "Array#rindex" do seen.should == [3] end + it "tolerates increasing an array size during iteration" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.rindex do |e| + ScratchPad << e + array.prepend i if i < 100 + i += 1 + false + end + + ScratchPad.recorded.should == [:c, :a, 1] + end + describe "given no argument and no block" do it "produces an Enumerator" do enum = [4, 2, 1, 5, 1, 3].rindex diff --git a/spec/ruby/core/array/shared/collect.rb b/spec/ruby/core/array/shared/collect.rb index 8d75f7db9a..030302ced6 100644 --- a/spec/ruby/core/array/shared/collect.rb +++ b/spec/ruby/core/array/shared/collect.rb @@ -1,4 +1,5 @@ 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 @@ -46,6 +47,8 @@ describe :array_collect, shared: true 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 @@ -102,8 +105,37 @@ describe :array_collect_b, shared: true do 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/index.rb b/spec/ruby/core/array/shared/index.rb index a9896554f2..a4a0adbab6 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') @@ -34,4 +36,6 @@ describe :array_index, shared: true do [].send(@method).should be_an_instance_of(Enumerator) end end + + it_should_behave_like :array_iterable_and_tolerating_size_increasing end diff --git a/spec/ruby/core/array/shared/intersection.rb b/spec/ruby/core/array/shared/intersection.rb index 49849b08c2..0b4166ab63 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 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/keep_if.rb b/spec/ruby/core/array/shared/keep_if.rb index f26aff028c..43a047c0a7 100644 --- a/spec/ruby/core/array/shared/keep_if.rb +++ b/spec/ruby/core/array/shared/keep_if.rb @@ -1,4 +1,5 @@ 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 @@ -56,5 +57,39 @@ describe :keep_if, shared: true do -> { @frozen.send(@method) { false } }.should raise_error(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_error(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/select.rb b/spec/ruby/core/array/shared/select.rb index 09101e8ab5..9c2cbf76c4 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 diff --git a/spec/ruby/core/array/sort_by_spec.rb b/spec/ruby/core/array/sort_by_spec.rb index 7cea6ec6d3..0334f953f6 100644 --- a/spec/ruby/core/array/sort_by_spec.rb +++ b/spec/ruby/core/array/sort_by_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' require_relative '../enumerable/shared/enumeratorized' describe "Array#sort_by!" do @@ -31,6 +32,11 @@ describe "Array#sort_by!" do -> { ArraySpecs.empty_frozen_array.sort_by! {}}.should raise_error(FrozenError) end + it "raises a FrozenError on a frozen array only during iteration if called without a block" do + enum = ArraySpecs.frozen_array.sort_by! + -> { enum.each {} }.should raise_error(FrozenError) + end + it "returns the specified value when it would break in the given block" do [1, 2, 3].sort_by!{ break :a }.should == :a end @@ -48,5 +54,32 @@ describe "Array#sort_by!" do [1].sort_by!(&:to_s).should == [1] end + it "does not truncate the array is the block raises an exception" do + a = [1, 2, 3] + begin + a.sort_by! { raise StandardError, 'Oops' } + rescue + end + + a.should == [1, 2, 3] + end + + it "doesn't change array if error is raised" do + a = [4, 3, 2, 1] + begin + a.sort_by! do |e| + raise StandardError, 'Oops' if e == 1 + e + end + rescue StandardError + end + + a.should == [4, 3, 2, 1] + end + it_behaves_like :enumeratorized_with_origin_size, :sort_by!, [1,2,3] end + +describe "Array#sort_by!" do + it_behaves_like :array_iterable_and_tolerating_size_increasing, :sort_by! +end diff --git a/spec/ruby/core/array/sum_spec.rb b/spec/ruby/core/array/sum_spec.rb index 34635d9bc0..1f1d6b2f14 100644 --- a/spec/ruby/core/array/sum_spec.rb +++ b/spec/ruby/core/array/sum_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#sum" do it "returns the sum of elements" do @@ -69,3 +70,8 @@ describe "Array#sum" do [b].sum(a).should == 42 end end + +describe "Array#sum" do + @value_to_return = -> _ { 1 } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :sum +end diff --git a/spec/ruby/core/array/take_while_spec.rb b/spec/ruby/core/array/take_while_spec.rb index 363419b265..73f25493c8 100644 --- a/spec/ruby/core/array/take_while_spec.rb +++ b/spec/ruby/core/array/take_while_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#take_while" do it "returns all elements until the block returns false" do @@ -26,3 +27,8 @@ describe "Array#take_while" do end end end + +describe "Array#take_while" do + @value_to_return = -> _ { true } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :take_while +end diff --git a/spec/ruby/core/array/to_h_spec.rb b/spec/ruby/core/array/to_h_spec.rb index f5a7e546e6..f4578211a1 100644 --- a/spec/ruby/core/array/to_h_spec.rb +++ b/spec/ruby/core/array/to_h_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#to_h" do it "converts empty array to empty hash" do @@ -77,3 +78,8 @@ describe "Array#to_h" do end end end + +describe "Array#to_h" do + @value_to_return = -> e { [e, e.to_s] } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :to_h +end diff --git a/spec/ruby/core/array/uniq_spec.rb b/spec/ruby/core/array/uniq_spec.rb index 4461cae16b..905ab59634 100644 --- a/spec/ruby/core/array/uniq_spec.rb +++ b/spec/ruby/core/array/uniq_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/iterable_and_tolerating_size_increasing' describe "Array#uniq" do it "returns an array with no duplicates" do @@ -131,6 +132,11 @@ describe "Array#uniq" do end end +describe "Array#uniq" do + @value_to_return = -> e { e } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :uniq +end + describe "Array#uniq!" do it "modifies the array in place" do a = [ "a", "a", "b", "b", "c" ] @@ -214,4 +220,32 @@ describe "Array#uniq!" do a.uniq! a.should == [x] 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 "doesn't change array if error is raised" do + a = [1, 1, 2, 2, 3, 3, 4, 4] + begin + a.send(@method) do |e| + raise StandardError, 'Oops' if e == 3 + e + end + rescue StandardError + end + + a.should == [1, 1, 2, 2, 3, 3, 4, 4] + end +end + +describe "Array#uniq!" do + @value_to_return = -> e { e } + it_behaves_like :array_iterable_and_tolerating_size_increasing, :uniq! end |