mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Move spec/rubyspec to spec/ruby for consistency
* Other ruby implementations use the spec/ruby directory. [Misc #13792] [ruby-core:82287] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
75bfc6440d
commit
1d15d5f080
4370 changed files with 0 additions and 0 deletions
221
spec/ruby/core/array/uniq_spec.rb
Normal file
221
spec/ruby/core/array/uniq_spec.rb
Normal file
|
@ -0,0 +1,221 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../fixtures/classes', __FILE__)
|
||||
|
||||
describe "Array#uniq" do
|
||||
it "returns an array with no duplicates" do
|
||||
["a", "a", "b", "b", "c"].uniq.should == ["a", "b", "c"]
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty.uniq.should == [empty]
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
array.uniq.should == [1, 'two', 3.0, array]
|
||||
end
|
||||
|
||||
it "uses eql? semantics" do
|
||||
[1.0, 1].uniq.should == [1.0, 1]
|
||||
end
|
||||
|
||||
it "compares elements first with hash" do
|
||||
x = mock('0')
|
||||
x.should_receive(:hash).at_least(1).and_return(0)
|
||||
y = mock('0')
|
||||
y.should_receive(:hash).at_least(1).and_return(0)
|
||||
|
||||
[x, y].uniq.should == [x, y]
|
||||
end
|
||||
|
||||
it "does not compare elements with different hash codes via eql?" do
|
||||
x = mock('0')
|
||||
x.should_not_receive(:eql?)
|
||||
y = mock('1')
|
||||
y.should_not_receive(:eql?)
|
||||
|
||||
x.should_receive(:hash).at_least(1).and_return(0)
|
||||
y.should_receive(:hash).at_least(1).and_return(1)
|
||||
|
||||
[x, y].uniq.should == [x, y]
|
||||
end
|
||||
|
||||
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].tainted?.should == true
|
||||
a[1].tainted?.should == true
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
a.uniq.size.should == 1
|
||||
a[0].tainted?.should == true
|
||||
a[1].tainted?.should == true
|
||||
end
|
||||
|
||||
it "compares elements based on the value returned from the block" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.uniq { |x| x >= 2 ? 1 : 0 }.should == [1, 2]
|
||||
end
|
||||
|
||||
it "yields items in order" do
|
||||
a = [1, 2, 3]
|
||||
yielded = []
|
||||
a.uniq { |v| yielded << v }
|
||||
yielded.should == a
|
||||
end
|
||||
|
||||
it "handles nil and false like any other values" do
|
||||
[nil, false, 42].uniq { :foo }.should == [nil]
|
||||
[false, nil, 42].uniq { :bar }.should == [false]
|
||||
end
|
||||
|
||||
it "returns subclass instance on Array subclasses" do
|
||||
ArraySpecs::MyArray[1, 2, 3].uniq.should be_an_instance_of(ArraySpecs::MyArray)
|
||||
end
|
||||
|
||||
it "properly handles an identical item even when its #eql? isn't reflexive" do
|
||||
x = mock('x')
|
||||
x.should_receive(:hash).at_least(1).and_return(42)
|
||||
x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
|
||||
|
||||
[x, x].uniq.should == [x]
|
||||
end
|
||||
|
||||
describe "given an array of BasicObject subclasses that define ==, eql?, and hash" do
|
||||
# jruby/jruby#3227
|
||||
it "filters equivalent elements using those definitions" do
|
||||
|
||||
basic = Class.new(BasicObject) do
|
||||
attr_reader :x
|
||||
|
||||
def initialize(x)
|
||||
@x = x
|
||||
end
|
||||
|
||||
def ==(rhs)
|
||||
@x == rhs.x
|
||||
end
|
||||
alias_method :eql?, :==
|
||||
|
||||
def hash
|
||||
@x.hash
|
||||
end
|
||||
end
|
||||
|
||||
a = [basic.new(3), basic.new(2), basic.new(1), basic.new(4), basic.new(1), basic.new(2), basic.new(3)]
|
||||
a.uniq.should == [basic.new(3), basic.new(2), basic.new(1), basic.new(4)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Array#uniq!" do
|
||||
it "modifies the array in place" do
|
||||
a = [ "a", "a", "b", "b", "c" ]
|
||||
a.uniq!
|
||||
a.should == ["a", "b", "c"]
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
a = [ "a", "a", "b", "b", "c" ]
|
||||
a.should equal(a.uniq!)
|
||||
end
|
||||
|
||||
it "properly handles recursive arrays" do
|
||||
empty = ArraySpecs.empty_recursive_array
|
||||
empty_dup = empty.dup
|
||||
empty.uniq!
|
||||
empty.should == empty_dup
|
||||
|
||||
array = ArraySpecs.recursive_array
|
||||
expected = array[0..3]
|
||||
array.uniq!
|
||||
array.should == expected
|
||||
end
|
||||
|
||||
it "compares elements first with hash" do
|
||||
x = mock('0')
|
||||
x.should_receive(:hash).at_least(1).and_return(0)
|
||||
y = mock('0')
|
||||
y.should_receive(:hash).at_least(1).and_return(0)
|
||||
|
||||
a = [x, y]
|
||||
a.uniq!
|
||||
a.should == [x, y]
|
||||
end
|
||||
|
||||
it "does not compare elements with different hash codes via eql?" do
|
||||
x = mock('0')
|
||||
x.should_not_receive(:eql?)
|
||||
y = mock('1')
|
||||
y.should_not_receive(:eql?)
|
||||
|
||||
x.should_receive(:hash).at_least(1).and_return(0)
|
||||
y.should_receive(:hash).at_least(1).and_return(1)
|
||||
|
||||
a = [x, y]
|
||||
a.uniq!
|
||||
a.should == [x, y]
|
||||
end
|
||||
|
||||
it "returns nil if no changes are made to the array" do
|
||||
[ "a", "b", "c" ].uniq!.should == nil
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen array when the array is modified" do
|
||||
dup_ary = [1, 1, 2]
|
||||
dup_ary.freeze
|
||||
lambda { dup_ary.uniq! }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23666]
|
||||
it "raises a RuntimeError on a frozen array when the array would not be modified" do
|
||||
lambda { ArraySpecs.frozen_array.uniq!}.should raise_error(RuntimeError)
|
||||
lambda { ArraySpecs.empty_frozen_array.uniq!}.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "doesn't yield to the block on a frozen array" do
|
||||
lambda { ArraySpecs.frozen_array.uniq!{ raise RangeError, "shouldn't yield"}}.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "compares elements based on the value returned from the block" do
|
||||
a = [1, 2, 3, 4]
|
||||
a.uniq! { |x| x >= 2 ? 1 : 0 }.should == [1, 2]
|
||||
end
|
||||
|
||||
it "properly handles an identical item even when its #eql? isn't reflexive" do
|
||||
x = mock('x')
|
||||
x.should_receive(:hash).at_least(1).and_return(42)
|
||||
x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
|
||||
|
||||
a = [x, x]
|
||||
a.uniq!
|
||||
a.should == [x]
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue