diff options
Diffstat (limited to 'spec/ruby/core/enumerable')
20 files changed, 255 insertions, 200 deletions
diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb index b782f94a3e..160cd52628 100644 --- a/spec/ruby/core/enumerable/all_spec.rb +++ b/spec/ruby/core/enumerable/all_spec.rb @@ -131,7 +131,6 @@ describe "Enumerable#all?" do pattern.yielded.should == [[0], [1], [2], [-1]] end - # may raise an exception in future versions it "always returns true on empty enumeration" do @empty.all?(Integer).should == true [].all?(Integer).should == true @@ -178,5 +177,11 @@ describe "Enumerable#all?" do multi.all?(pattern).should == true pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).all?(String) { true }.should == false + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb index 636b1fa450..243f8735d5 100644 --- a/spec/ruby/core/enumerable/any_spec.rb +++ b/spec/ruby/core/enumerable/any_spec.rb @@ -145,7 +145,6 @@ describe "Enumerable#any?" do pattern.yielded.should == [[0], [1], [2]] end - # may raise an exception in future versions it "always returns false on empty enumeration" do @empty.any?(Integer).should == false [].any?(Integer).should == false @@ -191,5 +190,11 @@ describe "Enumerable#any?" do multi.any?(pattern).should == false pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).any?(String) { true }.should == false + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/chunk_spec.rb b/spec/ruby/core/enumerable/chunk_spec.rb index c5579d67fa..ed6304307f 100644 --- a/spec/ruby/core/enumerable/chunk_spec.rb +++ b/spec/ruby/core/enumerable/chunk_spec.rb @@ -29,6 +29,11 @@ describe "Enumerable#chunk" do result.should == [[1, [1, 2]], [0, [3]], [1, [2]], [0, [3]], [1, [2, 1]]] end + it "returns a partitioned Array of values" do + e = EnumerableSpecs::Numerous.new(1,2,3) + e.chunk { |x| x > 2 }.map(&:last).should == [[1, 2], [3]] + end + it "returns elements for which the block returns :_alone in separate Arrays" do e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1) result = e.chunk { |x| x < 2 && :_alone }.to_a diff --git a/spec/ruby/core/enumerable/compact_spec.rb b/spec/ruby/core/enumerable/compact_spec.rb new file mode 100644 index 0000000000..86e95dce08 --- /dev/null +++ b/spec/ruby/core/enumerable/compact_spec.rb @@ -0,0 +1,11 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is '3.1' do + describe "Enumerable#compact" do + it 'returns array without nil elements' do + arr = EnumerableSpecs::Numerous.new(nil, 1, 2, nil, true) + arr.compact.should == [1, 2, true] + end + end +end diff --git a/spec/ruby/core/enumerable/each_cons_spec.rb b/spec/ruby/core/enumerable/each_cons_spec.rb index ba658203a2..8fb31fb925 100644 --- a/spec/ruby/core/enumerable/each_cons_spec.rb +++ b/spec/ruby/core/enumerable/each_cons_spec.rb @@ -56,6 +56,12 @@ describe "Enumerable#each_cons" do multi.each_cons(2).to_a.should == [[[1, 2], [3, 4, 5]], [[3, 4, 5], [6, 7, 8, 9]]] end + ruby_version_is "3.1" do + it "returns self when a block is given" do + @enum.each_cons(3){}.should == @enum + end + end + describe "when no block is given" do it "returns an enumerator" do e = @enum.each_cons(3) diff --git a/spec/ruby/core/enumerable/each_slice_spec.rb b/spec/ruby/core/enumerable/each_slice_spec.rb index 2ea89f5e72..a57a1dba81 100644 --- a/spec/ruby/core/enumerable/each_slice_spec.rb +++ b/spec/ruby/core/enumerable/each_slice_spec.rb @@ -57,6 +57,12 @@ describe "Enumerable#each_slice" do e.to_a.should == @sliced end + ruby_version_is "3.1" do + it "returns self when a block is given" do + @enum.each_slice(3){}.should == @enum + end + end + it "gathers whole arrays as elements when each yields multiple" do multi = EnumerableSpecs::YieldsMulti.new multi.each_slice(2).to_a.should == [[[1, 2], [3, 4, 5]], [[6, 7, 8, 9]]] diff --git a/spec/ruby/core/enumerable/filter_map_spec.rb b/spec/ruby/core/enumerable/filter_map_spec.rb index 31acc277b4..aa4894230b 100644 --- a/spec/ruby/core/enumerable/filter_map_spec.rb +++ b/spec/ruby/core/enumerable/filter_map_spec.rb @@ -1,26 +1,24 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is '2.7' do - describe 'Enumerable#filter_map' do - before :each do - @numerous = EnumerableSpecs::Numerous.new(*(1..8).to_a) - end +describe 'Enumerable#filter_map' do + before :each do + @numerous = EnumerableSpecs::Numerous.new(*(1..8).to_a) + end - it 'returns an empty array if there are no elements' do - EnumerableSpecs::Empty.new.filter_map { true }.should == [] - end + it 'returns an empty array if there are no elements' do + EnumerableSpecs::Empty.new.filter_map { true }.should == [] + end - it 'returns an array with truthy results of passing each element to block' do - @numerous.filter_map { |i| i * 2 if i.even? }.should == [4, 8, 12, 16] - @numerous.filter_map { |i| i * 2 }.should == [2, 4, 6, 8, 10, 12, 14, 16] - @numerous.filter_map { 0 }.should == [0, 0, 0, 0, 0, 0, 0, 0] - @numerous.filter_map { false }.should == [] - @numerous.filter_map { nil }.should == [] - end + it 'returns an array with truthy results of passing each element to block' do + @numerous.filter_map { |i| i * 2 if i.even? }.should == [4, 8, 12, 16] + @numerous.filter_map { |i| i * 2 }.should == [2, 4, 6, 8, 10, 12, 14, 16] + @numerous.filter_map { 0 }.should == [0, 0, 0, 0, 0, 0, 0, 0] + @numerous.filter_map { false }.should == [] + @numerous.filter_map { nil }.should == [] + end - it 'returns an enumerator when no block given' do - @numerous.filter_map.should be_an_instance_of(Enumerator) - end + it 'returns an enumerator when no block given' do + @numerous.filter_map.should be_an_instance_of(Enumerator) end end diff --git a/spec/ruby/core/enumerable/fixtures/classes.rb b/spec/ruby/core/enumerable/fixtures/classes.rb index fb4951c6e6..2701c6999c 100644 --- a/spec/ruby/core/enumerable/fixtures/classes.rb +++ b/spec/ruby/core/enumerable/fixtures/classes.rb @@ -342,4 +342,10 @@ module EnumerableSpecs @block.call(*args) end end + + # Set is a core class since Ruby 3.2 + ruby_version_is '3.2' do + class SetSubclass < Set + end + end end # EnumerableSpecs utility classes diff --git a/spec/ruby/core/enumerable/grep_spec.rb b/spec/ruby/core/enumerable/grep_spec.rb index b81075291f..989358f01b 100644 --- a/spec/ruby/core/enumerable/grep_spec.rb +++ b/spec/ruby/core/enumerable/grep_spec.rb @@ -40,43 +40,28 @@ describe "Enumerable#grep" do $~.should == nil end - ruby_version_is ""..."3.0.0" do - it "sets $~ to the last match when given no block" do - "z" =~ /z/ # Reset $~ - ["abc", "def"].grep(/b/).should == ["abc"] - - # Set by the failed match of "def" - $~.should == nil - - ["abc", "def"].grep(/e/) - $&.should == "e" - end + it "does not set $~ when given no block" do + "z" =~ /z/ # Reset $~ + ["abc", "def"].grep(/b/).should == ["abc"] + $&.should == "z" end - ruby_version_is "3.0.0" do - it "does not set $~ when given no block" do - "z" =~ /z/ # Reset $~ - ["abc", "def"].grep(/b/).should == ["abc"] - $&.should == "z" - end - - it "does not modify Regexp.last_match without block" do - "z" =~ /z/ # Reset last match - ["abc", "def"].grep(/b/).should == ["abc"] - Regexp.last_match[0].should == "z" - end + it "does not modify Regexp.last_match without block" do + "z" =~ /z/ # Reset last match + ["abc", "def"].grep(/b/).should == ["abc"] + Regexp.last_match[0].should == "z" + end - it "correctly handles non-string elements" do - 'set last match' =~ /set last (.*)/ - [:a, 'b', 'z', :c, 42, nil].grep(/[a-d]/).should == [:a, 'b', :c] - $1.should == 'match' + it "correctly handles non-string elements" do + 'set last match' =~ /set last (.*)/ + [:a, 'b', 'z', :c, 42, nil].grep(/[a-d]/).should == [:a, 'b', :c] + $1.should == 'match' - o = Object.new - def o.to_str - 'hello' - end - [o].grep(/ll/).first.should.equal?(o) + o = Object.new + def o.to_str + 'hello' end + [o].grep(/ll/).first.should.equal?(o) end describe "with a block" do diff --git a/spec/ruby/core/enumerable/grep_v_spec.rb b/spec/ruby/core/enumerable/grep_v_spec.rb index 35fde27eb6..ba19216968 100644 --- a/spec/ruby/core/enumerable/grep_v_spec.rb +++ b/spec/ruby/core/enumerable/grep_v_spec.rb @@ -20,43 +20,28 @@ describe "Enumerable#grep_v" do $&.should == "e" end - ruby_version_is ""..."3.0.0" do - it "sets $~ to the last match when given no block" do - "z" =~ /z/ # Reset $~ - ["abc", "def"].grep_v(/e/).should == ["abc"] - - # Set by the match of "def" - $&.should == "e" - - ["abc", "def"].grep_v(/b/) - $&.should == nil - end + it "does not set $~ when given no block" do + "z" =~ /z/ # Reset $~ + ["abc", "def"].grep_v(/e/).should == ["abc"] + $&.should == "z" end - ruby_version_is "3.0.0" do - it "does not set $~ when given no block" do - "z" =~ /z/ # Reset $~ - ["abc", "def"].grep_v(/e/).should == ["abc"] - $&.should == "z" - end - - it "does not modify Regexp.last_match without block" do - "z" =~ /z/ # Reset last match - ["abc", "def"].grep_v(/e/).should == ["abc"] - Regexp.last_match[0].should == "z" - end + it "does not modify Regexp.last_match without block" do + "z" =~ /z/ # Reset last match + ["abc", "def"].grep_v(/e/).should == ["abc"] + Regexp.last_match[0].should == "z" + end - it "correctly handles non-string elements" do - 'set last match' =~ /set last (.*)/ - [:a, 'b', 'z', :c, 42, nil].grep_v(/[a-d]/).should == ['z', 42, nil] - $1.should == 'match' + it "correctly handles non-string elements" do + 'set last match' =~ /set last (.*)/ + [:a, 'b', 'z', :c, 42, nil].grep_v(/[a-d]/).should == ['z', 42, nil] + $1.should == 'match' - o = Object.new - def o.to_str - 'hello' - end - [o].grep_v(/mm/).first.should.equal?(o) + o = Object.new + def o.to_str + 'hello' end + [o].grep_v(/mm/).first.should.equal?(o) end describe "without block" do diff --git a/spec/ruby/core/enumerable/group_by_spec.rb b/spec/ruby/core/enumerable/group_by_spec.rb index 52b5a68d64..4fd1603819 100644 --- a/spec/ruby/core/enumerable/group_by_spec.rb +++ b/spec/ruby/core/enumerable/group_by_spec.rb @@ -33,15 +33,5 @@ describe "Enumerable#group_by" do [3, 4, 5] => [[3, 4, 5]] } end - ruby_version_is ''...'2.7' do - it "returns a tainted hash if self is tainted" do - EnumerableSpecs::Empty.new.taint.group_by {}.tainted?.should be_true - end - - it "returns an untrusted hash if self is untrusted" do - EnumerableSpecs::Empty.new.untrust.group_by {}.untrusted?.should be_true - end - end - it_behaves_like :enumerable_enumeratorized_with_origin_size, :group_by end diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb index b898d00063..fb42f13386 100644 --- a/spec/ruby/core/enumerable/none_spec.rb +++ b/spec/ruby/core/enumerable/none_spec.rb @@ -100,7 +100,6 @@ describe "Enumerable#none?" do pattern.yielded.should == [[0], [1], [2], [-1]] end - # may raise an exception in future versions it "always returns true on empty enumeration" do @empty.none?(Integer).should == true [].none?(Integer).should == true @@ -144,5 +143,11 @@ describe "Enumerable#none?" do multi.none?(pattern).should == true pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, 5).none?(String) { true }.should == true + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb index d54dd4a527..4bf8623d2e 100644 --- a/spec/ruby/core/enumerable/one_spec.rb +++ b/spec/ruby/core/enumerable/one_spec.rb @@ -83,7 +83,6 @@ describe "Enumerable#one?" do end end - describe 'when given a pattern argument' do it "calls `===` on the pattern the return value " do pattern = EnumerableSpecs::Pattern.new { |x| x == 1 } @@ -91,7 +90,6 @@ describe "Enumerable#one?" do pattern.yielded.should == [[0], [1], [2], [-1]] end - # may raise an exception in future versions it "always returns false on empty enumeration" do @empty.one?(Integer).should == false [].one?(Integer).should == false @@ -146,5 +144,11 @@ describe "Enumerable#one?" do multi.one?(pattern).should == false pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]] end + + it "ignores the block if there is an argument" do + -> { + EnumerableSpecs::Numerous.new(1, 2, 3, 4, "5").one?(String) { false }.should == true + }.should complain(/given block not used/) + end end end diff --git a/spec/ruby/core/enumerable/shared/entries.rb b/spec/ruby/core/enumerable/shared/entries.rb index 590ce73bcf..e32eb23d2a 100644 --- a/spec/ruby/core/enumerable/shared/entries.rb +++ b/spec/ruby/core/enumerable/shared/entries.rb @@ -13,14 +13,4 @@ describe :enumerable_entries, shared: true do count.send(@method, :hello, "world").should == [1, 2, 3] count.arguments_passed.should == [:hello, "world"] end - - ruby_version_is ''...'2.7' do - it "returns a tainted array if self is tainted" do - EnumerableSpecs::Empty.new.taint.send(@method).tainted?.should be_true - end - - it "returns an untrusted array if self is untrusted" do - EnumerableSpecs::Empty.new.untrust.send(@method).untrusted?.should be_true - end - end end diff --git a/spec/ruby/core/enumerable/shared/inject.rb b/spec/ruby/core/enumerable/shared/inject.rb index 12e0665dda..693d34d675 100644 --- a/spec/ruby/core/enumerable/shared/inject.rb +++ b/spec/ruby/core/enumerable/shared/inject.rb @@ -1,3 +1,5 @@ +require_relative '../../array/shared/iterable_and_tolerating_size_increasing' + describe :enumerable_inject, shared: true do it "with argument takes a block with an accumulator (with argument as initial value) and the current element. Value of block becomes new accumulator" do a = [] @@ -17,7 +19,22 @@ describe :enumerable_inject, shared: true do end it "ignores the block if two arguments" do - EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-){ raise "we never get here"}.should == 4 + -> { + EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-) { raise "we never get here"}.should == 4 + }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true) + + -> { + [1, 2, 3].send(@method, 10, :-) { raise "we never get here"}.should == 4 + }.should complain(/#{__FILE__}:#{__LINE__-1}: warning: given block not used/, verbose: true) + end + + it "does not warn when given a Symbol with $VERBOSE true" do + -> { + [1, 2].send(@method, 0, :+) + [1, 2].send(@method, :+) + EnumerableSpecs::Numerous.new(1, 2).send(@method, 0, :+) + EnumerableSpecs::Numerous.new(1, 2).send(@method, :+) + }.should_not complain(verbose: true) end it "can take a symbol argument" do @@ -30,10 +47,10 @@ describe :enumerable_inject, shared: true do a.should == [[2, 5], [5, 3], [3, 6], [6, 1], [1, 4]] end - it "gathers whole arrays as elements when each yields multiple" do - multi = EnumerableSpecs::YieldsMulti.new - multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]] - end + it "gathers whole arrays as elements when each yields multiple" do + multi = EnumerableSpecs::YieldsMulti.new + multi.send(@method, []) {|acc, e| acc << e }.should == [[1, 2], [3, 4, 5], [6, 7, 8, 9]] + end it "with inject arguments(legacy rubycon)" do # with inject argument @@ -66,4 +83,27 @@ describe :enumerable_inject, shared: true do it "returns nil when fails(legacy rubycon)" do EnumerableSpecs::EachDefiner.new().send(@method) {|acc,x| 999 }.should == nil end + + it "tolerates increasing a collection size during iterating Array" do + array = [:a, :b, :c] + ScratchPad.record [] + i = 0 + + array.send(@method, nil) do |_, e| + ScratchPad << e + array << i if i < 100 + i += 1 + end + + actual = ScratchPad.recorded + expected = [:a, :b, :c] + (0..99).to_a + actual.sort_by(&:to_s).should == expected.sort_by(&:to_s) + end + + ruby_bug '#18635', ''...'3.2' do + it "raises an ArgumentError when no parameters or block is given" do + -> { [1,2].send(@method) }.should raise_error(ArgumentError) + -> { {one: 1, two: 2}.send(@method) }.should raise_error(ArgumentError) + end + end end diff --git a/spec/ruby/core/enumerable/sum_spec.rb b/spec/ruby/core/enumerable/sum_spec.rb index 4a978794e5..2eb74db6ac 100644 --- a/spec/ruby/core/enumerable/sum_spec.rb +++ b/spec/ruby/core/enumerable/sum_spec.rb @@ -22,12 +22,25 @@ describe 'Enumerable#sum' do @enum.sum.should == 5/3r end - it 'takes a block to transform the elements' do - @enum.sum { |element| element * 2 }.should == 10/3r + context 'with a block' do + it 'transforms the elements' do + @enum.sum { |element| element * 2 }.should == 10/3r + end + + it 'does not destructure array elements' do + class << @enum + def each + yield [1,2] + yield [3] + end + end + + @enum.sum(&:last).should == 5 + end end # https://bugs.ruby-lang.org/issues/12217 - # https://github.com/ruby/ruby/blob/master/doc/ChangeLog-2.4.0#L6208-L6214 + # https://github.com/ruby/ruby/blob/master/doc/ChangeLog/ChangeLog-2.4.0#L6208-L6214 it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do floats = [2.7800000000000002, 5.0, 2.5, 4.44, 3.89, 3.89, 4.44, 7.78, 5.0, 2.7800000000000002, 5.0, 2.5].to_enum naive_sum = floats.reduce { |sum, e| sum + e } diff --git a/spec/ruby/core/enumerable/tally_spec.rb b/spec/ruby/core/enumerable/tally_spec.rb index 92aac507ff..e0edc8dc75 100644 --- a/spec/ruby/core/enumerable/tally_spec.rb +++ b/spec/ruby/core/enumerable/tally_spec.rb @@ -1,36 +1,34 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is "2.7" do - describe "Enumerable#tally" do - before :each do - ScratchPad.record [] - end +describe "Enumerable#tally" do + before :each do + ScratchPad.record [] + end - it "returns a hash with counts according to the value" do - enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') - enum.tally.should == { 'foo' => 2, 'bar' => 1, 'baz' => 1} - end + it "returns a hash with counts according to the value" do + enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') + enum.tally.should == { 'foo' => 2, 'bar' => 1, 'baz' => 1} + end - it "returns a hash without default" do - hash = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz').tally - hash.default_proc.should be_nil - hash.default.should be_nil - end + it "returns a hash without default" do + hash = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz').tally + hash.default_proc.should be_nil + hash.default.should be_nil + end - it "returns an empty hash for empty enumerables" do - EnumerableSpecs::Empty.new.tally.should == {} - end + it "returns an empty hash for empty enumerables" do + EnumerableSpecs::Empty.new.tally.should == {} + end - it "counts values as gathered array when yielded with multiple arguments" do - EnumerableSpecs::YieldsMixed2.new.tally.should == EnumerableSpecs::YieldsMixed2.gathered_yields.group_by(&:itself).transform_values(&:size) - end + it "counts values as gathered array when yielded with multiple arguments" do + EnumerableSpecs::YieldsMixed2.new.tally.should == EnumerableSpecs::YieldsMixed2.gathered_yields.group_by(&:itself).transform_values(&:size) + end - it "does not call given block" do - enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') - enum.tally { |v| ScratchPad << v } - ScratchPad.recorded.should == [] - end + it "does not call given block" do + enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') + enum.tally { |v| ScratchPad << v } + ScratchPad.recorded.should == [] end end @@ -51,6 +49,13 @@ ruby_version_is "3.1" do enum.tally(hash).should equal(hash) end + it "calls #to_hash to convert argument to Hash implicitly if passed not a Hash" do + enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') + object = Object.new + def object.to_hash; { 'foo' => 1 }; end + enum.tally(object).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1} + end + it "raises a FrozenError and does not update the given hash when the hash is frozen" do enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') hash = { 'foo' => 1 }.freeze @@ -58,6 +63,12 @@ ruby_version_is "3.1" do hash.should == { 'foo' => 1 } end + it "raises a FrozenError even if enumerable is empty" do + enum = EnumerableSpecs::Numerous.new() + hash = { 'foo' => 1 }.freeze + -> { enum.tally(hash) }.should raise_error(FrozenError) + end + it "does not call given block" do enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz') enum.tally({ 'foo' => 1 }) { |v| ScratchPad << v } diff --git a/spec/ruby/core/enumerable/to_set_spec.rb b/spec/ruby/core/enumerable/to_set_spec.rb new file mode 100644 index 0000000000..c21a2772c4 --- /dev/null +++ b/spec/ruby/core/enumerable/to_set_spec.rb @@ -0,0 +1,29 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "3.2" do + describe "Enumerable#to_set" do + it "returns a new Set created from self" do + [1, 2, 3].to_set.should == Set[1, 2, 3] + {a: 1, b: 2}.to_set.should == Set[[:b, 2], [:a, 1]] + end + + it "passes down passed blocks" do + [1, 2, 3].to_set { |x| x * x }.should == Set[1, 4, 9] + end + + it "instantiates an object of provided as the first argument set class" do + set = [1, 2, 3].to_set(EnumerableSpecs::SetSubclass) + set.should be_kind_of(EnumerableSpecs::SetSubclass) + set.to_a.sort.should == [1, 2, 3] + end + + it "does not need explicit `require 'set'`" do + output = ruby_exe(<<~RUBY, options: '--disable-gems', args: '2>&1') + puts [1, 2, 3].to_set + RUBY + + output.chomp.should == "#<Set: {1, 2, 3}>" + end + end +end diff --git a/spec/ruby/core/enumerable/uniq_spec.rb b/spec/ruby/core/enumerable/uniq_spec.rb index e58dd36366..a1ed44796f 100644 --- a/spec/ruby/core/enumerable/uniq_spec.rb +++ b/spec/ruby/core/enumerable/uniq_spec.rb @@ -31,76 +31,32 @@ describe 'Enumerable#uniq' do [x, y].to_enum.uniq.should == [x, y] end - ruby_version_is '2.7' do - it "compares elements with matching hash codes with #eql?" do - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) - - def obj.eql?(o) - false - end - - obj - end - - a.uniq.should == a + it "compares elements with matching hash codes with #eql?" do + a = Array.new(2) do + obj = mock('0') + obj.should_receive(:hash).at_least(1).and_return(0) - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) - - def obj.eql?(o) - true - end - - obj + def obj.eql?(o) + false end - a.to_enum.uniq.size.should == 1 + obj end - end - ruby_version_is ''...'2.7' do - it "compares elements with matching hash codes with #eql?" do - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) - - def obj.eql?(o) - # It's undefined whether the impl does a[0].eql?(a[1]) or - # a[1].eql?(a[0]) so we taint both. - taint - o.taint - false - end - - obj - end - - a.uniq.should == a - a[0].should.tainted? - a[1].should.tainted? + a.uniq.should == a - a = Array.new(2) do - obj = mock('0') - obj.should_receive(:hash).at_least(1).and_return(0) + a = Array.new(2) do + obj = mock('0') + obj.should_receive(:hash).at_least(1).and_return(0) - def obj.eql?(o) - # It's undefined whether the impl does a[0].eql?(a[1]) or - # a[1].eql?(a[0]) so we taint both. - taint - o.taint - true - end - - obj + def obj.eql?(o) + true end - a.to_enum.uniq.size.should == 1 - a[0].should.tainted? - a[1].should.tainted? + obj end + + a.to_enum.uniq.size.should == 1 end context 'when yielded with multiple arguments' do diff --git a/spec/ruby/core/enumerable/zip_spec.rb b/spec/ruby/core/enumerable/zip_spec.rb index 9ec15aa030..ab148f2a6e 100644 --- a/spec/ruby/core/enumerable/zip_spec.rb +++ b/spec/ruby/core/enumerable/zip_spec.rb @@ -38,4 +38,9 @@ describe "Enumerable#zip" do multi.zip(multi).should == [[[1, 2], [1, 2]], [[3, 4, 5], [3, 4, 5]], [[6, 7, 8, 9], [6, 7, 8, 9]]] end + it "raises TypeError when some argument isn't Array and doesn't respond to #to_ary and #to_enum" do + -> { EnumerableSpecs::Numerous.new(1,2,3).zip(Object.new) }.should raise_error(TypeError, "wrong argument type Object (must respond to :each)") + -> { EnumerableSpecs::Numerous.new(1,2,3).zip(1) }.should raise_error(TypeError, "wrong argument type Integer (must respond to :each)") + -> { EnumerableSpecs::Numerous.new(1,2,3).zip(true) }.should raise_error(TypeError, "wrong argument type TrueClass (must respond to :each)") + end end |