require "spec" require "set" require "spec/helpers/iterate" describe "Set" do describe "an empty set" do it "is empty" do Set(Nil).new.empty?.should be_true end it "has size 0" do Set(Nil).new.size.should eq(0) end end describe "new" do it "creates new set with enumerable without block" do set_from_array = Set.new([2, 4, 6, 4]) set_from_array.size.should eq(3) set_from_array.to_a.sort.should eq([2, 4, 6]) set_from_tuple = Set.new({1, "hello", 'x'}) set_from_tuple.size.should eq(3) set_from_tuple.to_a.should contain(1) set_from_tuple.to_a.should contain("hello") set_from_tuple.to_a.should contain('x') end end describe "add" do it "adds and includes" do set = Set(Int32).new set.add 1 set.includes?(1).should be_true set.size.should eq(1) end it "returns self" do set = Set(Int32).new set.add(1).should be(set) end end describe "add?" do it "returns true when object is not in the set" do set = Set(Int32).new set.add?(1).should be_true end it "returns false when object is in the set" do set = Set(Int32).new set.add?(1).should be_true set.should contain(1) set.add?(1).should be_false end end describe "delete" do it "deletes an object" do set = Set{1, 2, 3} set.delete 2 set.size.should eq(2) set.should contain(1) set.should contain(3) end it "returns true when the object was present" do set = Set{1, 2, 3} set.delete(2).should be_true end it "returns false when the object was absent" do set = Set{1, 2, 3} set.delete(0).should be_false end end describe "dup" do it "creates a dup" do set1 = Set{[1, 2]} set2 = set1.dup set1.should eq(set2) set1.should_not be(set2) set1.to_a.first.should be(set2.to_a.first) set1 << [3] set2 << [4] set2.should eq(Set{[1, 2], [4]}) end end describe "clone" do it "creates a clone" do set1 = Set{[1, 2]} set2 = set1.clone set1.should eq(set2) set1.should_not be(set2) set1.to_a.first.should_not be(set2.to_a.first) set1 << [3] set2 << [4] set2.should eq(Set{[1, 2], [4]}) end end describe "==" do it "compares two sets" do set1 = Set{1, 2, 3} set2 = Set{1, 2, 3} set3 = Set{1, 2, 3, 4} set1.should eq(set1) set1.should eq(set2) set1.should_not eq(set3) end end describe "concat" do it "adds all the other elements" do set = Set{1, 4, 8} set.concat [1, 9, 10] set.should eq(Set{1, 4, 8, 9, 10}) end it "returns self" do set = Set{1, 4, 8} set.concat([1, 9, 10]).should be(set) end end it "does &" do set1 = Set{1, 2, 3} set2 = Set{4, 2, 5, 3} set3 = set1 & set2 set3.should eq(Set{2, 3}) end it "does |" do set1 = Set{1, 2, 3} set2 = Set{4, 2, 5, "3"} set3 = set1 | set2 set3.should eq(Set{1, 2, 3, 4, 5, "3"}) end it "aliases + to |" do set1 = Set{1, 1, 2, 3} set2 = Set{3, 4, 5} set3 = set1 + set2 set4 = set1 | set2 set3.should eq(set4) end it "does -" do set1 = Set{1, 2, 3, 4, 5} set2 = Set{2, 4, 6} set3 = set1 - set2 set3.should eq(Set{1, 3, 5}) end it "does -" do set1 = Set{1, 2, 3, 4, 5} set2 = Set{2, 4, 'a'} set3 = set1 - set2 set3.should eq(Set{1, 3, 5}) end it "does -" do set1 = Set{1, 2, 3, 4, 'b'} set2 = Set{2, 4, 5} set3 = set1 - set2 set3.should eq(Set{1, 3, 'b'}) end it "does -" do set1 = Set{1, 2, 3, 4, 5} set2 = [2, 4, 6] set3 = set1 - set2 set3.should eq(Set{1, 3, 5}) end it "does -" do set1 = Set{1, 2, 3, 4, 5} set2 = [2, 4, 'a'] set3 = set1 - set2 set3.should eq(Set{1, 3, 5}) end it "does -" do set1 = Set{1, 2, 3, 4, 'b'} set2 = [2, 4, 5] set3 = set1 - set2 set3.should eq(Set{1, 3, 'b'}) end it "does ^" do set1 = Set{1, 2, 3, 4, 5} set2 = Set{2, 4, 6} set3 = set1 ^ set2 set3.should eq(Set{1, 3, 5, 6}) end it "does ^" do set1 = Set{1, 2, 3, 4, 5} set2 = Set{2, 4, 'a'} set3 = set1 ^ set2 set3.should eq(Set{1, 3, 5, 'a'}) end it "does ^" do set1 = Set{1, 2, 3, 4, 'b'} set2 = Set{2, 4, 5} set3 = set1 ^ set2 set3.should eq(Set{1, 3, 5, 'b'}) end it "does ^" do set1 = Set{1, 2, 3, 4, 5} set2 = [2, 4, 6] set3 = set1 ^ set2 set3.should eq(Set{1, 3, 5, 6}) end it "does ^" do set1 = Set{1, 2, 3, 4, 5} set2 = [2, 4, 'a'] set3 = set1 ^ set2 set3.should eq(Set{1, 3, 5, 'a'}) end it "does ^" do set1 = Set{1, 2, 3, 4, 'b'} set2 = [2, 4, 5] set3 = set1 ^ set2 set3.should eq(Set{1, 3, 5, 'b'}) end it "does subtract" do set1 = Set{1, 2, 3, 4, 5} set2 = Set{2, 4, 6} set1.subtract set2 set1.should eq(Set{1, 3, 5}) end it "does subtract" do set1 = Set{1, 2, 3, 4, 5} set2 = Set{2, 4, 'a'} set1.subtract set2 set1.should eq(Set{1, 3, 5}) end it "does subtract" do set1 = Set{1, 2, 3, 4, 'b'} set2 = Set{2, 4, 5} set1.subtract set2 set1.should eq(Set{1, 3, 'b'}) end it "does subtract" do set1 = Set{1, 2, 3, 4, 5} set2 = [2, 4, 6] set1.subtract set2 set1.should eq(Set{1, 3, 5}) end it "does subtract" do set1 = Set{1, 2, 3, 4, 5} set2 = [2, 4, 'a'] set1.subtract set2 set1.should eq(Set{1, 3, 5}) end it "does subtract" do set1 = Set{1, 2, 3, 4, 'b'} set2 = [2, 4, 5] set1.subtract set2 set1.should eq(Set{1, 3, 'b'}) end it "does to_a" do Set{1, 2, 3}.to_a.should eq([1, 2, 3]) end it "does support giving a block to to_a" do Set{1, 2, 3}.to_a { |x| x + 1 }.should eq([2, 3, 4]) end it "does to_s" do Set{1, 2, 3}.to_s.should eq("Set{1, 2, 3}") Set{"foo"}.to_s.should eq(%(Set{"foo"})) end it "does clear" do x = Set{1, 2, 3} x.to_a.should eq([1, 2, 3]) x.clear.should be(x) x << 1 x.to_a.should eq([1]) end it "checks intersects" do set = Set{3, 4, 5} empty_set = Set(Int32).new set.intersects?(set).should be_true set.intersects?(Set{2, 4}).should be_true set.intersects?(Set{5, 6, 7}).should be_true set.intersects?(Set{1, 2, 6, 8, 4}).should be_true set.intersects?(empty_set).should be_false set.intersects?(Set{0, 2}).should be_false set.intersects?(Set{0, 2, 6}).should be_false set.intersects?(Set{0, 2, 6, 8, 10}).should be_false # Make sure set hasn't changed set.should eq(Set{3, 4, 5}) end it "compares hashes of sets" do h1 = {Set{1, 2, 3} => 1} h2 = {Set{1, 2, 3} => 1} h1.should eq(h2) end it "does each" do set = Set{1, 2, 3} i = 1 set.each do |v| v.should eq(i) i += 1 end.should be_nil i.should eq(4) end it_iterates "#each", [1, 2, 3], Set{1, 2, 3}.each it "#subset_of?" do set = Set{1, 2, 3} empty_set = Set(Int32).new set.subset_of?(Set{1, 2, 3, 4}).should be_true set.subset_of?(Set{1, 2, 3, "4"}).should be_true set.subset_of?(Set{1, 2, 3}).should be_true set.subset_of?(Set{1, 2}).should be_false set.subset_of?(empty_set).should be_false empty_set.subset_of?(Set{1}).should be_true empty_set.subset_of?(empty_set).should be_true end it "#proper_subset_of?" do set = Set{1, 2, 3} empty_set = Set(Int32).new set.proper_subset_of?(Set{1, 2, 3, 4}).should be_true set.proper_subset_of?(Set{1, 2, 3, "4"}).should be_true set.proper_subset_of?(Set{1, 2, 3}).should be_false set.proper_subset_of?(Set{1, 2}).should be_false set.proper_subset_of?(empty_set).should be_false empty_set.proper_subset_of?(Set{1}).should be_true empty_set.proper_subset_of?(empty_set).should be_false end it "#superset_of?" do set = Set{1, 2, "3"} empty_set = Set(Int32).new set.superset_of?(empty_set).should be_true set.superset_of?(Set{1, 2}).should be_true set.superset_of?(Set{1, 2, "3"}).should be_true set.superset_of?(Set{1, 2, 3}).should be_false set.superset_of?(Set{1, 2, 3, 4}).should be_false set.superset_of?(Set{1, 4}).should be_false empty_set.superset_of?(empty_set).should be_true end it "#proper_superset_of?" do set = Set{1, 2, "3"} empty_set = Set(Int32).new set.proper_superset_of?(empty_set).should be_true set.proper_superset_of?(Set{1, 2}).should be_true set.proper_superset_of?(Set{1, 2, "3"}).should be_false set.proper_superset_of?(Set{1, 2, 3}).should be_false set.proper_superset_of?(Set{1, 2, 3, 4}).should be_false set.proper_superset_of?(Set{1, 4}).should be_false empty_set.proper_superset_of?(empty_set).should be_false end it "has object_id" do Set(Int32).new.object_id.should be > 0 end typeof(Set(Int32).new(initial_capacity: 1234)) describe "compare_by_identity" do it "compares by identity" do string = "foo" set = Set{string, "bar", "baz"} set.compare_by_identity?.should be_false set.should contain(string) set.compare_by_identity set.compare_by_identity?.should be_true set.should_not contain("fo" + "o") set.should contain(string) end it "retains compare_by_identity on dup" do set = Set(String).new.compare_by_identity set.dup.compare_by_identity?.should be_true end it "retains compare_by_identity on clone" do set = Set(String).new.compare_by_identity set.clone.compare_by_identity?.should be_true end end describe "#map!" do it "replaces elements with the block's return values" do set = Set{1, 2, 3} set.map! { |n| n * -1 }.should be(set) set.should eq(Set{-1, -2, -3}) end it "exhibits reference semantic" do set = Set{1, 2, 3} copy = set set.map! { |n| n * -1 } set.should eq(copy) end end describe "#select!" do it "keeps only elements that evaluate to true" do set = Set{1, 2, 3} set.select! { |n| n < 2 }.should be(set) set.should eq(Set{1}) end end describe "#reject!" do it "returns self if changes were made" do set = Set{1, 2, 3} set.reject! { |n| n < 2 }.should be(set) set.should eq(Set{2, 3}) end end describe "#rehash" do it "rehashes" do a = [1] s = Set{a} (10..100).each do |i| s << [i] end a << 2 s.should_not contain(a) s.rehash s.should contain(a) end end end