diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/date/test_date.rb | 4 | ||||
-rw-r--r-- | test/date/test_switch_hitter.rb | 5 | ||||
-rw-r--r-- | test/ruby/namespace/instance_variables.rb | 21 | ||||
-rw-r--r-- | test/ruby/test_ast.rb | 18 | ||||
-rw-r--r-- | test/ruby/test_compile_prism.rb | 3 | ||||
-rw-r--r-- | test/ruby/test_data.rb | 6 | ||||
-rw-r--r-- | test/ruby/test_gc.rb | 8 | ||||
-rw-r--r-- | test/ruby/test_namespace.rb | 20 | ||||
-rw-r--r-- | test/ruby/test_object_id.rb | 46 | ||||
-rw-r--r-- | test/ruby/test_ractor.rb | 35 | ||||
-rw-r--r-- | test/ruby/test_struct.rb | 6 | ||||
-rw-r--r-- | test/ruby/test_variable.rb | 14 | ||||
-rw-r--r-- | test/ruby/test_zjit.rb | 54 | ||||
-rw-r--r-- | test/socket/test_socket.rb | 26 |
14 files changed, 253 insertions, 13 deletions
diff --git a/test/date/test_date.rb b/test/date/test_date.rb index 3f9c893efa..7e37fc94d2 100644 --- a/test/date/test_date.rb +++ b/test/date/test_date.rb @@ -135,6 +135,10 @@ class TestDate < Test::Unit::TestCase assert_equal(9, h[DateTime.new(1999,5,25)]) h = {} + h[Date.new(3171505571716611468830131104691,2,19)] = 0 + assert_equal(true, h.key?(Date.new(3171505571716611468830131104691,2,19))) + + h = {} h[DateTime.new(1999,5,23)] = 0 h[DateTime.new(1999,5,24)] = 1 h[DateTime.new(1999,5,25)] = 2 diff --git a/test/date/test_switch_hitter.rb b/test/date/test_switch_hitter.rb index bdf299e030..cc75782537 100644 --- a/test/date/test_switch_hitter.rb +++ b/test/date/test_switch_hitter.rb @@ -97,6 +97,11 @@ class TestSH < Test::Unit::TestCase [d.year, d.mon, d.mday, d.hour, d.min, d.sec, d.offset]) end + def test_ajd + assert_equal(Date.civil(2008, 1, 16).ajd, 4908963r/2) + assert_equal(Date.civil(-11082381539297990, 2, 19).ajd, -8095679714453739481r/2) + end + def test_ordinal d = Date.ordinal assert_equal([-4712, 1], [d.year, d.yday]) diff --git a/test/ruby/namespace/instance_variables.rb b/test/ruby/namespace/instance_variables.rb new file mode 100644 index 0000000000..1562ad5d45 --- /dev/null +++ b/test/ruby/namespace/instance_variables.rb @@ -0,0 +1,21 @@ +class String + class << self + attr_reader :str_ivar1 + + def str_ivar2 + @str_ivar2 + end + end + + @str_ivar1 = 111 + @str_ivar2 = 222 +end + +class StringDelegator < BasicObject +private + def method_missing(...) + ::String.public_send(...) + end +end + +StringDelegatorObj = StringDelegator.new diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 72a0d821a0..d22823470b 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -1397,6 +1397,24 @@ dummy assert_locations(node.children[-1].locations, [[1, 0, 1, 16], [1, 0, 1, 5], [1, 8, 1, 9], [1, 13, 1, 16]]) end + def test_colon2_locations + node = ast_parse("A::B") + assert_locations(node.children[-1].locations, [[1, 0, 1, 4], [1, 1, 1, 3], [1, 3, 1, 4]]) + + node = ast_parse("A::B::C") + assert_locations(node.children[-1].locations, [[1, 0, 1, 7], [1, 4, 1, 6], [1, 6, 1, 7]]) + assert_locations(node.children[-1].children[0].locations, [[1, 0, 1, 4], [1, 1, 1, 3], [1, 3, 1, 4]]) + end + + def test_colon3_locations + node = ast_parse("::A") + assert_locations(node.children[-1].locations, [[1, 0, 1, 3], [1, 0, 1, 2], [1, 2, 1, 3]]) + + node = ast_parse("::A::B") + assert_locations(node.children[-1].locations, [[1, 0, 1, 6], [1, 3, 1, 5], [1, 5, 1, 6]]) + assert_locations(node.children[-1].children[0].locations, [[1, 0, 1, 3], [1, 0, 1, 2], [1, 2, 1, 3]]) + end + def test_dot2_locations node = ast_parse("1..2") assert_locations(node.children[-1].locations, [[1, 0, 1, 4], [1, 1, 1, 3]]) diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index 819d0d35aa..86f7f0b14f 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -1053,6 +1053,9 @@ module Prism assert_prism_eval("for foo, in [1,2,3] do end") assert_prism_eval("for i, j in {a: 'b'} do; i; j; end") + + # Test splat node as index in for loop + assert_prism_eval("for *x in [[1,2], [3,4]] do; x; end") end ############################################################################ diff --git a/test/ruby/test_data.rb b/test/ruby/test_data.rb index bb38f8ec91..dd698fdcc4 100644 --- a/test/ruby/test_data.rb +++ b/test/ruby/test_data.rb @@ -280,4 +280,10 @@ class TestData < Test::Unit::TestCase assert_not_same(test, loaded) assert_predicate(loaded, :frozen?) end + + def test_frozen_subclass + test = Class.new(Data.define(:a)).freeze.new(a: 0) + assert_kind_of(Data, test) + assert_equal([:a], test.members) + end end diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index daa645b349..3516cefedf 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -393,12 +393,10 @@ class TestGc < Test::Unit::TestCase # Create some objects and place it in a WeakMap wmap = ObjectSpace::WeakMap.new - ary = Array.new(count) - enum = count.times - enum.each.with_index do |i| + ary = Array.new(count) do |i| obj = Object.new - ary[i] = obj wmap[obj] = nil + obj end # Run full GC to collect stats about weak references @@ -421,7 +419,7 @@ class TestGc < Test::Unit::TestCase GC.start # Sometimes the WeakMap has a few elements, which might be held on by registers. - assert_operator(wmap.size, :<=, 2) + assert_operator(wmap.size, :<=, count / 1000) assert_operator(GC.latest_gc_info(:weak_references_count), :<=, before_weak_references_count - count + error_tolerance) assert_operator(GC.latest_gc_info(:retained_weak_references_count), :<=, before_retained_weak_references_count - count + error_tolerance) diff --git a/test/ruby/test_namespace.rb b/test/ruby/test_namespace.rb index 395f244c8e..f13063be48 100644 --- a/test/ruby/test_namespace.rb +++ b/test/ruby/test_namespace.rb @@ -222,6 +222,26 @@ class TestNamespace < Test::Unit::TestCase end; end + def test_instance_variable + pend unless Namespace.enabled? + + @n.require_relative('namespace/instance_variables') + + assert_equal [], String.instance_variables + assert_equal [:@str_ivar1, :@str_ivar2], @n::StringDelegatorObj.instance_variables + assert_equal 111, @n::StringDelegatorObj.str_ivar1 + assert_equal 222, @n::StringDelegatorObj.str_ivar2 + assert_equal 222, @n::StringDelegatorObj.instance_variable_get(:@str_ivar2) + + @n::StringDelegatorObj.instance_variable_set(:@str_ivar3, 333) + assert_equal 333, @n::StringDelegatorObj.instance_variable_get(:@str_ivar3) + @n::StringDelegatorObj.remove_instance_variable(:@str_ivar1) + assert_nil @n::StringDelegatorObj.str_ivar1 + assert_equal [:@str_ivar2, :@str_ivar3], @n::StringDelegatorObj.instance_variables + + assert_equal [], String.instance_variables + end + def test_methods_added_in_namespace_are_invisible_globally pend unless Namespace.enabled? diff --git a/test/ruby/test_object_id.rb b/test/ruby/test_object_id.rb index 44421ea256..9c0099517b 100644 --- a/test/ruby/test_object_id.rb +++ b/test/ruby/test_object_id.rb @@ -198,3 +198,49 @@ class TestObjectIdTooComplexGeneric < TestObjectId end end end + +class TestObjectIdRactor < Test::Unit::TestCase + def test_object_id_race_free + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + Warning[:experimental] = false + class MyClass + attr_reader :a, :b, :c + def initialize + @a = @b = @c = nil + end + end + N = 10_000 + objs = Ractor.make_shareable(N.times.map { MyClass.new }) + results = 4.times.map{ + Ractor.new(objs) { |objs| + vars = [] + ids = [] + objs.each do |obj| + vars << obj.a << obj.b << obj.c + ids << obj.object_id + end + [vars, ids] + } + }.map(&:value) + assert_equal 1, results.uniq.size + end; + end + + def test_external_object_id_ractor_move + assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + Warning[:experimental] = false + class MyClass + attr_reader :a, :b, :c + def initialize + @a = @b = @c = nil + end + end + obj = Ractor.make_shareable(MyClass.new) + object_id = obj.object_id + obj = Ractor.new { Ractor.receive }.send(obj, move: true).value + assert_equal object_id, obj.object_id + end; + end +end diff --git a/test/ruby/test_ractor.rb b/test/ruby/test_ractor.rb index b423993df1..3fc891da23 100644 --- a/test/ruby/test_ractor.rb +++ b/test/ruby/test_ractor.rb @@ -79,6 +79,26 @@ class TestRactor < Test::Unit::TestCase end; end + def test_class_instance_variables + assert_ractor(<<~'RUBY') + # Once we're in multi-ractor mode, the codepaths + # for class instance variables are a bit different. + Ractor.new {}.value + + class TestClass + @a = 1 + @b = 2 + @c = 3 + @d = 4 + end + + assert_equal 4, TestClass.remove_instance_variable(:@d) + assert_nil TestClass.instance_variable_get(:@d) + assert_equal 4, TestClass.instance_variable_set(:@d, 4) + assert_equal 4, TestClass.instance_variable_get(:@d) + RUBY + end + def test_require_raises_and_no_ractor_belonging_issue assert_ractor(<<~'RUBY') require "tempfile" @@ -98,6 +118,21 @@ class TestRactor < Test::Unit::TestCase RUBY end + def test_require_non_string + assert_ractor(<<~'RUBY') + require "tempfile" + require "pathname" + f = Tempfile.new(["file_to_require_from_ractor", ".rb"]) + f.write("") + f.flush + result = Ractor.new(f.path) do |path| + require Pathname.new(path) + "success" + end.value + assert_equal "success", result + RUBY + end + def assert_make_shareable(obj) refute Ractor.shareable?(obj), "object was already shareable" Ractor.make_shareable(obj) diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb index ecd8ed196c..db591c306e 100644 --- a/test/ruby/test_struct.rb +++ b/test/ruby/test_struct.rb @@ -550,6 +550,12 @@ module TestStruct CODE end + def test_frozen_subclass + test = Class.new(@Struct.new(:a)).freeze.new(a: 0) + assert_kind_of(@Struct, test) + assert_equal([:a], test.members) + end + class TopStruct < Test::Unit::TestCase include TestStruct diff --git a/test/ruby/test_variable.rb b/test/ruby/test_variable.rb index 49fec2d40e..984045e05d 100644 --- a/test/ruby/test_variable.rb +++ b/test/ruby/test_variable.rb @@ -407,6 +407,20 @@ class TestVariable < Test::Unit::TestCase } end + def test_exivar_resize_with_compaction_stress + omit "compaction doesn't work well on s390x" if RUBY_PLATFORM =~ /s390x/ # https://github.com/ruby/ruby/pull/5077 + objs = 10_000.times.map do + ExIvar.new + end + EnvUtil.under_gc_compact_stress do + 10.times do + x = ExIvar.new + x.instance_variable_set(:@resize, 1) + x + end + end + end + def test_local_variables_with_kwarg bug11674 = '[ruby-core:71437] [Bug #11674]' v = with_kwargs_11(v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8,v9:9,v10:10,v11:11) diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb index 47a9f6f7dc..6095b0b734 100644 --- a/test/ruby/test_zjit.rb +++ b/test/ruby/test_zjit.rb @@ -102,12 +102,39 @@ class TestZJIT < Test::Unit::TestCase }, call_threshold: 2 end + def test_opt_plus_type_guard_exit_with_locals + assert_compiles '[6, 6.0]', %q{ + def test(a) + local = 3 + 1 + a + local + end + test(1) # profile opt_plus + [test(2), test(2.0)] + }, call_threshold: 2 + end + def test_opt_plus_type_guard_nested_exit - omit 'rewind_caller_frames is not implemented yet' - assert_compiles '[3, 3.0]', %q{ + assert_compiles '[4, 4.0]', %q{ def side_exit(n) = 1 + n def jit_frame(n) = 1 + side_exit(n) def entry(n) = jit_frame(n) + entry(2) # profile send + [entry(2), entry(2.0)] + }, call_threshold: 2 + end + + def test_opt_plus_type_guard_nested_exit_with_locals + assert_compiles '[9, 9.0]', %q{ + def side_exit(n) + local = 2 + 1 + n + local + end + def jit_frame(n) + local = 3 + 1 + side_exit(n) + local + end + def entry(n) = jit_frame(n) + entry(2) # profile send [entry(2), entry(2.0)] }, call_threshold: 2 end @@ -130,7 +157,6 @@ class TestZJIT < Test::Unit::TestCase end def test_opt_mult_overflow - omit 'side exits are not implemented yet' assert_compiles '[6, -6, 9671406556917033397649408, -9671406556917033397649408, 21267647932558653966460912964485513216]', %q{ def test(a, b) a * b @@ -610,6 +636,22 @@ class TestZJIT < Test::Unit::TestCase } end + def test_send_backtrace + backtrace = [ + "-e:2:in 'Object#jit_frame1'", + "-e:3:in 'Object#entry'", + "-e:5:in 'block in <main>'", + "-e:6:in '<main>'", + ] + assert_compiles backtrace.inspect, %q{ + def jit_frame2 = caller # 1 + def jit_frame1 = jit_frame2 # 2 + def entry = jit_frame1 # 3 + entry # profile send # 4 + entry # 5 + }, call_threshold: 2 + end + # tool/ruby_vm/views/*.erb relies on the zjit instructions a) being contiguous and # b) being reliably ordered after all the other instructions. def test_instruction_order @@ -631,11 +673,7 @@ class TestZJIT < Test::Unit::TestCase pipe_fd = 3 script = <<~RUBY - _test_proc = -> { - RubyVM::ZJIT.assert_compiles - #{test_script} - } - ret_val = _test_proc.call + ret_val = (_test_proc = -> { RubyVM::ZJIT.assert_compiles; #{test_script.lstrip} }).call result = { ret_val:, #{ unless insns.empty? diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb index 165990dd64..4b85d43291 100644 --- a/test/socket/test_socket.rb +++ b/test/socket/test_socket.rb @@ -937,6 +937,32 @@ class TestSocket < Test::Unit::TestCase RUBY end + def test_tcp_socket_open_timeout + opts = %w[-rsocket -W1] + assert_separately opts, <<~RUBY + Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_| + if family == Socket::AF_INET6 + sleep + else + [Addrinfo.tcp("127.0.0.1", 12345)] + end + end + + assert_raise(Errno::ETIMEDOUT) do + Socket.tcp("localhost", 12345, open_timeout: 0.01) + end + RUBY + end + + def test_tcp_socket_open_timeout_with_other_timeouts + opts = %w[-rsocket -W1] + assert_separately opts, <<~RUBY + assert_raise(ArgumentError) do + Socket.tcp("localhost", 12345, open_timeout: 0.01, resolv_timout: 0.01) + end + RUBY + end + def test_tcp_socket_one_hostname_resolution_succeeded_at_least opts = %w[-rsocket -W1] assert_separately opts, <<~RUBY |