1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
require_relative '../../spec_helper'
require 'set'
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.should.compare_by_identity?
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 FrozenError on frozen sets" do
set = Set.new.freeze
-> {
set.compare_by_identity
}.should raise_error(FrozenError, /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
end
end
describe "Set#compare_by_identity?" do
it "returns false by default" do
Set.new.should_not.compare_by_identity?
end
it "returns true once #compare_by_identity has been invoked on self" do
set = Set.new
set.compare_by_identity
set.should.compare_by_identity?
end
it "returns true when called multiple times on the same set" do
set = Set.new
set.compare_by_identity
set.should.compare_by_identity?
set.should.compare_by_identity?
set.should.compare_by_identity?
end
end
|