2018-03-04 10:09:32 -05:00
|
|
|
require_relative '../../spec_helper'
|
2017-10-28 11:15:48 -04:00
|
|
|
require 'set'
|
|
|
|
|
2019-04-27 12:53:23 -04:00
|
|
|
describe "Set#compare_by_identity" do
|
|
|
|
it "compares its members by identity" do
|
|
|
|
a = "a"
|
|
|
|
b1 = "b"
|
|
|
|
b2 = "b"
|
|
|
|
|
|
|
|
set = Set.new
|
|
|
|
set.compare_by_identity
|
|
|
|
set.merge([a, a, b1, b2])
|
|
|
|
set.to_a.sort.should == [a, b1, b2].sort
|
|
|
|
end
|
|
|
|
|
|
|
|
it "causes future comparisons on the receiver to be made by identity" do
|
|
|
|
elt = [1]
|
|
|
|
set = Set.new
|
|
|
|
set << elt
|
|
|
|
set.member?(elt.dup).should be_true
|
|
|
|
set.compare_by_identity
|
|
|
|
set.member?(elt.dup).should be_false
|
|
|
|
end
|
|
|
|
|
|
|
|
it "rehashes internally so that old members can be looked up" do
|
|
|
|
set = Set.new
|
|
|
|
(1..10).each { |k| set << k }
|
|
|
|
o = Object.new
|
|
|
|
def o.hash; 123; end
|
|
|
|
set << o
|
|
|
|
set.compare_by_identity
|
|
|
|
set.member?(o).should be_true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns self" do
|
|
|
|
set = Set.new
|
|
|
|
result = set.compare_by_identity
|
|
|
|
result.should equal(set)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "is idempotent and has no effect on an already compare_by_identity set" do
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
set << :foo
|
|
|
|
set.compare_by_identity.should equal(set)
|
|
|
|
set.compare_by_identity?.should == true
|
|
|
|
set.to_a.should == [:foo]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "uses the semantics of BasicObject#equal? to determine members identity" do
|
|
|
|
:a.equal?(:a).should == true
|
|
|
|
Set.new.compare_by_identity.merge([:a, :a]).to_a.should == [:a]
|
|
|
|
|
|
|
|
ary1 = [1]
|
|
|
|
ary2 = [1]
|
|
|
|
ary1.equal?(ary2).should == false
|
|
|
|
Set.new.compare_by_identity.merge([ary1, ary2]).to_a.sort.should == [ary1, ary2].sort
|
|
|
|
end
|
|
|
|
|
|
|
|
it "uses #equal? semantics, but doesn't actually call #equal? to determine identity" do
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
obj = mock("equal")
|
|
|
|
obj.should_not_receive(:equal?)
|
|
|
|
set << :foo
|
|
|
|
set << obj
|
|
|
|
set.to_a.should == [:foo, obj]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "does not call #hash on members" do
|
|
|
|
elt = mock("element")
|
|
|
|
elt.should_not_receive(:hash)
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
set << elt
|
|
|
|
set.member?(elt).should be_true
|
|
|
|
end
|
|
|
|
|
|
|
|
it "regards #dup'd objects as having different identities" do
|
|
|
|
a1 = "a"
|
|
|
|
a2 = a1.dup
|
|
|
|
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
set.merge([a1, a2])
|
|
|
|
set.to_a.sort.should == [a1, a2].sort
|
|
|
|
end
|
|
|
|
|
|
|
|
it "regards #clone'd objects as having different identities" do
|
|
|
|
a1 = "a"
|
|
|
|
a2 = a1.clone
|
|
|
|
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
set.merge([a1, a2])
|
|
|
|
set.to_a.sort.should == [a1, a2].sort
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises a #{frozen_error_class} on frozen sets" do
|
|
|
|
set = Set.new.freeze
|
2019-07-27 06:40:09 -04:00
|
|
|
-> {
|
2017-10-28 11:15:48 -04:00
|
|
|
set.compare_by_identity
|
2019-04-27 12:53:23 -04:00
|
|
|
}.should raise_error(frozen_error_class, /frozen Hash/)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "persists over #dups" do
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
set << :a
|
|
|
|
set_dup = set.dup
|
|
|
|
set_dup.should == set
|
|
|
|
set_dup << :a
|
|
|
|
set_dup.to_a.should == [:a]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "persists over #clones" do
|
|
|
|
set = Set.new.compare_by_identity
|
|
|
|
set << :a
|
|
|
|
set_clone = set.clone
|
|
|
|
set_clone.should == set
|
|
|
|
set_clone << :a
|
|
|
|
set_clone.to_a.should == [:a]
|
|
|
|
end
|
|
|
|
|
|
|
|
it "is not equal to set what does not compare by identity" do
|
|
|
|
Set.new([1, 2]).should == Set.new([1, 2])
|
|
|
|
Set.new([1, 2]).should_not == Set.new([1, 2]).compare_by_identity
|
2017-10-28 11:15:48 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-04-27 12:53:23 -04:00
|
|
|
describe "Set#compare_by_identity?" do
|
|
|
|
it "returns false by default" do
|
|
|
|
Set.new.compare_by_identity?.should == false
|
|
|
|
end
|
2017-10-28 11:15:48 -04:00
|
|
|
|
2019-04-27 12:53:23 -04:00
|
|
|
it "returns true once #compare_by_identity has been invoked on self" do
|
|
|
|
set = Set.new
|
|
|
|
set.compare_by_identity
|
|
|
|
set.compare_by_identity?.should == true
|
|
|
|
end
|
2017-10-28 11:15:48 -04:00
|
|
|
|
2019-04-27 12:53:23 -04:00
|
|
|
it "returns true when called multiple times on the same set" do
|
|
|
|
set = Set.new
|
|
|
|
set.compare_by_identity
|
|
|
|
set.compare_by_identity?.should == true
|
|
|
|
set.compare_by_identity?.should == true
|
|
|
|
set.compare_by_identity?.should == true
|
2017-10-28 11:15:48 -04:00
|
|
|
end
|
|
|
|
end
|