diff options
Diffstat (limited to 'test/ruby/test_set.rb')
| -rw-r--r-- | test/ruby/test_set.rb | 195 |
1 files changed, 175 insertions, 20 deletions
diff --git a/test/ruby/test_set.rb b/test/ruby/test_set.rb index 565946096e..70a61aa3b5 100644 --- a/test/ruby/test_set.rb +++ b/test/ruby/test_set.rb @@ -3,7 +3,36 @@ require 'test/unit' require 'set' class TC_Set < Test::Unit::TestCase - class Set2 < Set + class SetSubclass < Set + end + class CoreSetSubclass < Set::CoreSet + end + ALL_SET_CLASSES = [Set, SetSubclass, CoreSetSubclass].freeze + + def test_marshal + set = Set[1, 2, 3] + mset = Marshal.load(Marshal.dump(set)) + assert_equal(set, mset) + assert_equal(set.compare_by_identity?, mset.compare_by_identity?) + + set.compare_by_identity + mset = Marshal.load(Marshal.dump(set)) + assert_equal(set, mset) + assert_equal(set.compare_by_identity?, mset.compare_by_identity?) + + set.instance_variable_set(:@a, 1) + mset = Marshal.load(Marshal.dump(set)) + assert_equal(set, mset) + assert_equal(set.compare_by_identity?, mset.compare_by_identity?) + assert_equal(1, mset.instance_variable_get(:@a)) + + old_stdlib_set_data = "\x04\bo:\bSet\x06:\n@hash}\bi\x06Ti\aTi\bTF".b + set = Marshal.load(old_stdlib_set_data) + assert_equal(Set[1, 2, 3], set) + + old_stdlib_set_cbi_data = "\x04\bo:\bSet\x06:\n@hashC:\tHash}\ai\x06Ti\aTF".b + set = Marshal.load(old_stdlib_set_cbi_data) + assert_equal(Set[1, 2].compare_by_identity, set) end def test_aref @@ -104,6 +133,12 @@ class TC_Set < Test::Unit::TestCase assert_equal(Set['a','b','c'], set) set = Set[1,2] + ret = set.replace(Set.new('a'..'c')) + + assert_same(set, ret) + assert_equal(Set['a','b','c'], set) + + set = Set[1,2] assert_raise(ArgumentError) { set.replace(3) } @@ -232,7 +267,7 @@ class TC_Set < Test::Unit::TestCase set.superset?([2]) } - [Set, Set2].each { |klass| + ALL_SET_CLASSES.each { |klass| assert_equal(true, set.superset?(klass[]), klass.name) assert_equal(true, set.superset?(klass[1,2]), klass.name) assert_equal(true, set.superset?(klass[1,2,3]), klass.name) @@ -261,7 +296,7 @@ class TC_Set < Test::Unit::TestCase set.proper_superset?([2]) } - [Set, Set2].each { |klass| + ALL_SET_CLASSES.each { |klass| assert_equal(true, set.proper_superset?(klass[]), klass.name) assert_equal(true, set.proper_superset?(klass[1,2]), klass.name) assert_equal(false, set.proper_superset?(klass[1,2,3]), klass.name) @@ -290,7 +325,7 @@ class TC_Set < Test::Unit::TestCase set.subset?([2]) } - [Set, Set2].each { |klass| + ALL_SET_CLASSES.each { |klass| assert_equal(true, set.subset?(klass[1,2,3,4]), klass.name) assert_equal(true, set.subset?(klass[1,2,3]), klass.name) assert_equal(false, set.subset?(klass[1,2]), klass.name) @@ -319,7 +354,7 @@ class TC_Set < Test::Unit::TestCase set.proper_subset?([2]) } - [Set, Set2].each { |klass| + ALL_SET_CLASSES.each { |klass| assert_equal(true, set.proper_subset?(klass[1,2,3,4]), klass.name) assert_equal(false, set.proper_subset?(klass[1,2,3]), klass.name) assert_equal(false, set.proper_subset?(klass[1,2]), klass.name) @@ -339,7 +374,7 @@ class TC_Set < Test::Unit::TestCase assert_nil(set <=> set.to_a) - [Set, Set2].each { |klass| + ALL_SET_CLASSES.each { |klass| assert_equal(-1, set <=> klass[1,2,3,4], klass.name) assert_equal( 0, set <=> klass[3,2,1] , klass.name) assert_equal(nil, set <=> klass[1,2,4] , klass.name) @@ -606,6 +641,22 @@ class TC_Set < Test::Unit::TestCase } end + def test_merge_mutating_hash_bug_21305 + a = (1..100).to_a + o = Object.new + o.define_singleton_method(:hash) do + a.clear + 0 + end + a.unshift o + assert_equal([o], Set.new.merge(a).to_a) + end + + def test_initialize_mutating_array_bug_21306 + a = (1..100).to_a + assert_equal(Set[0], Set.new(a){a.clear; 0}) + end + def test_subtract set = Set[1,2,3] @@ -639,15 +690,28 @@ class TC_Set < Test::Unit::TestCase end def test_xor - set = Set[1,2,3,4] - ret = set ^ [2,4,5,5] - assert_not_same(set, ret) - assert_equal(Set[1,3,5], ret) + ALL_SET_CLASSES.each { |klass| + set = klass[1,2,3,4] + ret = set ^ [2,4,5,5] + assert_not_same(set, ret) + assert_equal(klass[1,3,5], ret) + + set2 = klass[1,2,3,4] + ret2 = set2 ^ [2,4,5,5] + assert_instance_of(klass, ret2) + assert_equal(klass[1,3,5], ret2) + } + end + + def test_xor_does_not_mutate_other_set + a = Set[1] + b = Set[1, 2] + original_b = b.dup - set2 = Set2[1,2,3,4] - ret2 = set2 ^ [2,4,5,5] - assert_instance_of(Set2, ret2) - assert_equal(Set2[1,3,5], ret2) + result = a ^ b + + assert_equal(original_b, b) + assert_equal(Set[2], result) end def test_eq @@ -733,6 +797,10 @@ class TC_Set < Test::Unit::TestCase ret.each { |s| n += s.size } assert_equal(set.size, n) assert_equal(set, ret.flatten) + + set = Set[2,12,9,11,13,4,10,15,3,8,5,0,1,7,14] + ret = set.divide { |a,b| (a - b).abs == 1 } + assert_equal(2, ret.size) end def test_freeze @@ -787,24 +855,32 @@ class TC_Set < Test::Unit::TestCase def test_inspect set1 = Set[1, 2] - assert_equal('#<Set: {1, 2}>', set1.inspect) + assert_equal('Set[1, 2]', set1.inspect) set2 = Set[Set[0], 1, 2, set1] - assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2}>}>', set2.inspect) + assert_equal('Set[Set[0], 1, 2, Set[1, 2]]', set2.inspect) set1.add(set2) - assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2, #<Set: {...}>}>}>', set2.inspect) + assert_equal('Set[Set[0], 1, 2, Set[1, 2, Set[...]]]', set2.inspect) + + c = Class.new(Set::CoreSet) + c.set_temporary_name("_MySet") + assert_equal('_MySet[1, 2]', c[1, 2].inspect) + + c = Class.new(Set) + c.set_temporary_name("_MySet") + assert_equal('#<_MySet: {1, 2}>', c[1, 2].inspect) end def test_to_s set1 = Set[1, 2] - assert_equal('#<Set: {1, 2}>', set1.to_s) + assert_equal('Set[1, 2]', set1.to_s) set2 = Set[Set[0], 1, 2, set1] - assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2}>}>', set2.to_s) + assert_equal('Set[Set[0], 1, 2, Set[1, 2]]', set2.to_s) set1.add(set2) - assert_equal('#<Set: {#<Set: {0}>, 1, 2, #<Set: {1, 2, #<Set: {...}>}>}>', set2.to_s) + assert_equal('Set[Set[0], 1, 2, Set[1, 2, Set[...]]]', set2.to_s) end def test_compare_by_identity @@ -838,6 +914,55 @@ class TC_Set < Test::Unit::TestCase assert_equal(klass.new([a]), set, klass.name) } end + + def test_set_gc_compact_does_not_allocate + assert_in_out_err([], <<-"end;", [], []) + def x + s = Set.new + s << Object.new + s + end + + x + begin + GC.compact + rescue NotImplementedError + end + end; + end + + def test_larger_sets + set = Set.new + 10_000.times do |i| + set << i + end + set = set.dup + + 10_000.times do |i| + assert_includes set, i + end + end + + def test_subclass_new_calls_add + c = Class.new(Set) do + def add(o) + super + super(o+1) + end + end + assert_equal([1, 2], c.new([1]).to_a) + end + + def test_subclass_aref_calls_initialize + c = Class.new(Set) do + def initialize(enum) + super + add(1) + end + end + assert_equal([2, 1], c[2].to_a) + end + end class TC_Enumerable < Test::Unit::TestCase @@ -855,6 +980,36 @@ class TC_Enumerable < Test::Unit::TestCase assert_same set, set.to_set assert_not_same set, set.to_set { |o| o } end + + class MyEnum + include Enumerable + + def initialize(array) + @array = array + end + + def each(&block) + @array.each(&block) + end + + def size + raise "should not be called" + end + end + + def test_to_set_not_calling_size + enum = MyEnum.new([1,2,3]) + + set = assert_nothing_raised { enum.to_set } + assert(set.is_a?(Set)) + assert_equal(Set[1,2,3], set) + + enumerator = enum.to_enum + + set = assert_nothing_raised { enumerator.to_set } + assert(set.is_a?(Set)) + assert_equal(Set[1,2,3], set) + end end class TC_Set_Builtin < Test::Unit::TestCase |
