summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb2
-rw-r--r--test/date/test_date.rb4
-rw-r--r--test/date/test_switch_hitter.rb5
-rw-r--r--test/net/http/test_http.rb14
-rw-r--r--test/net/http/utils.rb13
-rw-r--r--test/prism/fixtures/strings.txt4
-rw-r--r--test/ruby/namespace/instance_variables.rb21
-rw-r--r--test/ruby/test_ast.rb18
-rw-r--r--test/ruby/test_compile_prism.rb3
-rw-r--r--test/ruby/test_data.rb6
-rw-r--r--test/ruby/test_gc.rb8
-rw-r--r--test/ruby/test_io_buffer.rb10
-rw-r--r--test/ruby/test_namespace.rb20
-rw-r--r--test/ruby/test_object.rb13
-rw-r--r--test/ruby/test_object_id.rb46
-rw-r--r--test/ruby/test_ractor.rb35
-rw-r--r--test/ruby/test_rubyoptions.rb29
-rw-r--r--test/ruby/test_set.rb6
-rw-r--r--test/ruby/test_struct.rb6
-rw-r--r--test/ruby/test_thread_queue.rb8
-rw-r--r--test/ruby/test_variable.rb14
-rw-r--r--test/ruby/test_vm_dump.rb2
-rw-r--r--test/ruby/test_zjit.rb136
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb32
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb54
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder.rb52
-rw-r--r--test/socket/test_socket.rb26
27 files changed, 536 insertions, 51 deletions
diff --git a/test/-ext-/bug_reporter/test_bug_reporter.rb b/test/-ext-/bug_reporter/test_bug_reporter.rb
index 8293408518..d402ab1382 100644
--- a/test/-ext-/bug_reporter/test_bug_reporter.rb
+++ b/test/-ext-/bug_reporter/test_bug_reporter.rb
@@ -6,8 +6,6 @@ require_relative '../../lib/parser_support'
class TestBugReporter < Test::Unit::TestCase
def test_bug_reporter_add
- pend "macOS 15 is not working with this test" if macos?(15)
-
description = RUBY_DESCRIPTION
description = description.sub(/\+PRISM /, '') unless ParserSupport.prism_enabled_in_subprocess?
expected_stderr = [
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/net/http/test_http.rb b/test/net/http/test_http.rb
index c9a27d87cb..366b4cd12c 100644
--- a/test/net/http/test_http.rb
+++ b/test/net/http/test_http.rb
@@ -494,12 +494,10 @@ module TestNetHTTP_version_1_1_methods
def test_s_post
url = "http://#{config('host')}:#{config('port')}/?q=a"
- res = assert_warning(/Content-Type did not set/) do
- Net::HTTP.post(
- URI.parse(url),
- "a=x")
- end
- assert_equal "application/x-www-form-urlencoded", res["Content-Type"]
+ res = Net::HTTP.post(
+ URI.parse(url),
+ "a=x")
+ assert_equal "application/octet-stream", res["Content-Type"]
assert_equal "a=x", res.body
assert_equal url, res["X-request-uri"]
@@ -570,9 +568,7 @@ module TestNetHTTP_version_1_1_methods
th = Thread.new do
err = !windows? ? Net::WriteTimeout : Net::ReadTimeout
assert_raise(err) do
- assert_warning(/Content-Type did not set/) do
- conn.post('/', "a"*50_000_000)
- end
+ conn.post('/', "a"*50_000_000)
end
end
assert th.join(EnvUtil.apply_timeout_scale(10))
diff --git a/test/net/http/utils.rb b/test/net/http/utils.rb
index b41341d0a0..067cca02e3 100644
--- a/test/net/http/utils.rb
+++ b/test/net/http/utils.rb
@@ -71,6 +71,11 @@ module TestNetHTTPUtils
socket.write "HTTP/1.1 100 Continue\r\n\r\n"
end
+ # Set default Content-Type if not provided
+ if !headers['Content-Type'] && (method == 'POST' || method == 'PUT' || method == 'PATCH')
+ headers['Content-Type'] = 'application/octet-stream'
+ end
+
req = Request.new(method, path, headers, socket)
if @procs.key?(req.path) || @procs.key?("#{req.path}/")
proc = @procs[req.path] || @procs["#{req.path}/"]
@@ -306,16 +311,18 @@ module TestNetHTTPUtils
scheme = headers['X-Request-Scheme'] || 'http'
host = @config['host']
port = socket.addr[1]
- charset = parse_content_type(headers['Content-Type'])[1]
+ content_type = headers['Content-Type'] || 'application/octet-stream'
+ charset = parse_content_type(content_type)[1]
path = "#{scheme}://#{host}:#{port}#{path}"
path = path.encode(charset) if charset
- response = "HTTP/1.1 200 OK\r\nContent-Type: #{headers['Content-Type']}\r\nContent-Length: #{body.bytesize}\r\nX-request-uri: #{path}\r\n\r\n#{body}"
+ response = "HTTP/1.1 200 OK\r\nContent-Type: #{content_type}\r\nContent-Length: #{body.bytesize}\r\nX-request-uri: #{path}\r\n\r\n#{body}"
socket.print(response)
end
def handle_patch(path, headers, socket)
body = socket.read(headers['Content-Length'].to_i)
- response = "HTTP/1.1 200 OK\r\nContent-Type: #{headers['Content-Type']}\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
+ content_type = headers['Content-Type'] || 'application/octet-stream'
+ response = "HTTP/1.1 200 OK\r\nContent-Type: #{content_type}\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
socket.print(response)
end
diff --git a/test/prism/fixtures/strings.txt b/test/prism/fixtures/strings.txt
index 0787152786..77e1e4acff 100644
--- a/test/prism/fixtures/strings.txt
+++ b/test/prism/fixtures/strings.txt
@@ -146,6 +146,10 @@ baz
%Q{abc}
+%Q(\«)
+
+%q(\«)
+
%^#$^#
%@#@#
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_io_buffer.rb b/test/ruby/test_io_buffer.rb
index 55296c1f23..70c5ef061d 100644
--- a/test/ruby/test_io_buffer.rb
+++ b/test/ruby/test_io_buffer.rb
@@ -121,6 +121,16 @@ class TestIOBuffer < Test::Unit::TestCase
end
end
+ def test_string_mapped_buffer_frozen
+ string = "Hello World".freeze
+ IO::Buffer.for(string) do |buffer|
+ assert_raise IO::Buffer::AccessError, "Buffer is not writable!" do
+ buffer.set_string("abc")
+ end
+ assert_equal "H".ord, buffer.get_value(:U8, 0)
+ end
+ end
+
def test_non_string
not_string = Object.new
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.rb b/test/ruby/test_object.rb
index 7d00422629..9074e54df5 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -950,6 +950,19 @@ class TestObject < Test::Unit::TestCase
assert_match(/\bInspect\u{3042}:.* @\u{3044}=42\b/, x.inspect)
x.instance_variable_set("@\u{3046}".encode(Encoding::EUC_JP), 6)
assert_match(/@\u{3046}=6\b/, x.inspect)
+
+ x = Object.new
+ x.singleton_class.class_eval do
+ private def instance_variables_to_inspect = [:@host, :@user]
+ end
+
+ x.instance_variable_set(:@host, "localhost")
+ x.instance_variable_set(:@user, "root")
+ x.instance_variable_set(:@password, "hunter2")
+ s = x.inspect
+ assert_include(s, "@host=\"localhost\"")
+ assert_include(s, "@user=\"root\"")
+ assert_not_include(s, "@password=")
end
def test_singleton_methods
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_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 833b6a3b7d..54ad953ee9 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -787,6 +787,12 @@ class TestRubyOptions < Test::Unit::TestCase
unless /mswin|mingw/ =~ RUBY_PLATFORM
opts[:rlimit_core] = 0
end
+ opts[:failed] = proc do |status, message = "", out = ""|
+ if (sig = status.termsig) && Signal.list["SEGV"] == sig
+ out = ""
+ end
+ Test::Unit::CoreAssertions::FailDesc[status, message]
+ end
ExecOptions = opts.freeze
# The regexp list that should match the entire stderr output.
@@ -836,8 +842,6 @@ class TestRubyOptions < Test::Unit::TestCase
end
def assert_segv(args, message=nil, list: SEGVTest::ExpectedStderrList, **opt, &block)
- pend "macOS 15 is not working with this assertion" if macos?(15)
-
# We want YJIT to be enabled in the subprocess if it's enabled for us
# so that the Ruby description matches.
env = Hash === args.first ? args.shift : {}
@@ -849,7 +853,11 @@ class TestRubyOptions < Test::Unit::TestCase
args.unshift(env)
test_stdin = ""
- tests = [//, list] unless block
+ if !block
+ tests = [//, list, message]
+ elsif message
+ tests = [[], [], message]
+ end
assert_in_out_err(args, test_stdin, *tests, encoding: "ASCII-8BIT",
**SEGVTest::ExecOptions, **opt, &block)
@@ -862,13 +870,12 @@ class TestRubyOptions < Test::Unit::TestCase
def test_segv_loaded_features
bug7402 = '[ruby-core:49573]'
- status = assert_segv(['-e', "END {#{SEGVTest::KILL_SELF}}",
- '-e', 'class Bogus; def to_str; exit true; end; end',
- '-e', '$".clear',
- '-e', '$".unshift Bogus.new',
- '-e', '(p $"; abort) unless $".size == 1',
- ])
- assert_not_predicate(status, :success?, "segv but success #{bug7402}")
+ assert_segv(['-e', "END {#{SEGVTest::KILL_SELF}}",
+ '-e', 'class Bogus; def to_str; exit true; end; end',
+ '-e', '$".clear',
+ '-e', '$".unshift Bogus.new',
+ '-e', '(p $"; abort) unless $".size == 1',
+ ], success: false)
end
def test_segv_setproctitle
@@ -881,8 +888,6 @@ class TestRubyOptions < Test::Unit::TestCase
end
def assert_crash_report(path, cmd = nil, &block)
- pend "macOS 15 is not working with this assertion" if macos?(15)
-
Dir.mktmpdir("ruby_crash_report") do |dir|
list = SEGVTest::ExpectedStderrList
if cmd
diff --git a/test/ruby/test_set.rb b/test/ruby/test_set.rb
index 2bb7858eb2..3a8568762a 100644
--- a/test/ruby/test_set.rb
+++ b/test/ruby/test_set.rb
@@ -130,6 +130,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)
}
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_thread_queue.rb b/test/ruby/test_thread_queue.rb
index 545bf98888..9485528977 100644
--- a/test/ruby/test_thread_queue.rb
+++ b/test/ruby/test_thread_queue.rb
@@ -235,8 +235,14 @@ class TestThreadQueue < Test::Unit::TestCase
end
_eom
rescue Timeout::Error
+ # record load average:
+ uptime = `uptime` rescue nil
+ if uptime && /(load average: [\d.]+),/ =~ uptime
+ la = " (#{$1})"
+ end
+
count = File.read("#{d}/test_thr_kill_count").to_i
- flunk "only #{count}/#{total_count} done in #{timeout} seconds."
+ flunk "only #{count}/#{total_count} done in #{timeout} seconds.#{la}"
end
}
end
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_vm_dump.rb b/test/ruby/test_vm_dump.rb
index 709fd5eadf..a3e7b69913 100644
--- a/test/ruby/test_vm_dump.rb
+++ b/test/ruby/test_vm_dump.rb
@@ -5,8 +5,6 @@ return unless /darwin/ =~ RUBY_PLATFORM
class TestVMDump < Test::Unit::TestCase
def assert_darwin_vm_dump_works(args, timeout=nil)
- pend "macOS 15 is not working with this assertion" if macos?(15)
-
assert_in_out_err(args, "", [], /^\[IMPORTANT\]/, timeout: timeout || 300)
end
diff --git a/test/ruby/test_zjit.rb b/test/ruby/test_zjit.rb
index 3b64887f92..d7249053e5 100644
--- a/test/ruby/test_zjit.rb
+++ b/test/ruby/test_zjit.rb
@@ -31,6 +31,20 @@ class TestZJIT < Test::Unit::TestCase
}
end
+ def test_putstring
+ assert_compiles '""', %q{
+ def test = "#{""}"
+ test
+ }, insns: [:putstring]
+ end
+
+ def test_putchilldedstring
+ assert_compiles '""', %q{
+ def test = ""
+ test
+ }, insns: [:putchilledstring]
+ end
+
def test_leave_param
assert_compiles '5', %q{
def test(n) = n
@@ -102,12 +116,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 +171,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
@@ -205,6 +245,48 @@ class TestZJIT < Test::Unit::TestCase
}, insns: [:opt_gt], call_threshold: 2
end
+ def test_opt_empty_p
+ assert_compiles('[false, false, true]', <<~RUBY, insns: [:opt_empty_p])
+ def test(x) = x.empty?
+ return test([1]), test("1"), test({})
+ RUBY
+ end
+
+ def test_opt_succ
+ assert_compiles('[0, "B"]', <<~RUBY, insns: [:opt_succ])
+ def test(obj) = obj.succ
+ return test(-1), test("A")
+ RUBY
+ end
+
+ def test_opt_and
+ assert_compiles('[1, [3, 2, 1]]', <<~RUBY, insns: [:opt_and])
+ def test(x, y) = x & y
+ return test(0b1101, 3), test([3, 2, 1, 4], [8, 1, 2, 3])
+ RUBY
+ end
+
+ def test_opt_or
+ assert_compiles('[11, [3, 2, 1]]', <<~RUBY, insns: [:opt_or])
+ def test(x, y) = x | y
+ return test(0b1000, 3), test([3, 2, 1], [1, 2, 3])
+ RUBY
+ end
+
+ def test_opt_not
+ assert_compiles('[true, true, false]', <<~RUBY, insns: [:opt_not])
+ def test(obj) = !obj
+ return test(nil), test(false), test(0)
+ RUBY
+ end
+
+ def test_opt_regexpmatch2
+ assert_compiles('[1, nil]', <<~RUBY, insns: [:opt_regexpmatch2])
+ def test(haystack) = /needle/ =~ haystack
+ return test("kneedle"), test("")
+ RUBY
+ end
+
def test_opt_ge
assert_compiles '[false, true, true]', %q{
def test(a, b) = a >= b
@@ -568,6 +650,48 @@ 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
+
+ def test_putspecialobject_vm_core_and_cbase
+ assert_compiles '10', %q{
+ def test
+ alias bar test
+ 10
+ end
+
+ test
+ bar
+ }, insns: [:putspecialobject]
+ end
+
+ def test_putspecialobject_const_base
+ assert_compiles '1', %q{
+ Foo = 1
+
+ def test = Foo
+
+ # First call: populates the constant cache
+ test
+ # Second call: triggers ZJIT compilation with warm cache
+ # RubyVM::ZJIT.assert_compiles will panic if this fails to compile
+ test
+ }, 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
@@ -589,11 +713,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/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb
index 468aecde56..77525aed2c 100644
--- a/test/rubygems/test_gem_commands_install_command.rb
+++ b/test/rubygems/test_gem_commands_install_command.rb
@@ -1005,6 +1005,38 @@ ERROR: Possible alternatives: non_existent_with_hint
assert_equal %W[a-3-#{local}], @cmd.installed_specs.map(&:full_name)
end
+ def test_install_gem_platform_specificity_match
+ util_set_arch "arm64-darwin-20"
+
+ spec_fetcher do |fetcher|
+ %w[ruby universal-darwin universal-darwin-20 x64-darwin-20 arm64-darwin-20].each do |platform|
+ fetcher.download "a", 3 do |s|
+ s.platform = platform
+ end
+ end
+ end
+
+ @cmd.install_gem "a", ">= 0"
+
+ assert_equal %w[a-3-arm64-darwin-20], @cmd.installed_specs.map(&:full_name)
+ end
+
+ def test_install_gem_platform_specificity_match_reverse_order
+ util_set_arch "arm64-darwin-20"
+
+ spec_fetcher do |fetcher|
+ %w[ruby universal-darwin universal-darwin-20 x64-darwin-20 arm64-darwin-20].reverse_each do |platform|
+ fetcher.download "a", 3 do |s|
+ s.platform = platform
+ end
+ end
+ end
+
+ @cmd.install_gem "a", ">= 0"
+
+ assert_equal %w[a-3-arm64-darwin-20], @cmd.installed_specs.map(&:full_name)
+ end
+
def test_install_gem_ignore_dependencies_specific_file
spec = util_spec "a", 2
diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb
index 46c06db014..e9c4d32945 100644
--- a/test/rubygems/test_gem_commands_pristine_command.rb
+++ b/test/rubygems/test_gem_commands_pristine_command.rb
@@ -125,8 +125,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase
@cmd.execute
end
- assert File.exist?(gem_bin)
- assert File.exist?(gem_stub)
+ assert_path_exist gem_bin
+ assert_path_exist gem_stub
out = @ui.output.split "\n"
@@ -537,8 +537,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase
@cmd.execute
end
- assert File.exist? gem_exec
- refute File.exist? gem_lib
+ assert_path_exist gem_exec
+ assert_path_not_exist gem_lib
end
def test_execute_only_plugins
@@ -572,9 +572,9 @@ class TestGemCommandsPristineCommand < Gem::TestCase
@cmd.execute
end
- refute File.exist? gem_exec
- assert File.exist? gem_plugin
- refute File.exist? gem_lib
+ assert_path_not_exist gem_exec
+ assert_path_exist gem_plugin
+ assert_path_not_exist gem_lib
end
def test_execute_bindir
@@ -606,8 +606,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase
@cmd.execute
end
- refute File.exist? gem_exec
- assert File.exist? gem_bindir
+ assert_path_not_exist gem_exec
+ assert_path_exist gem_bindir
end
def test_execute_unknown_gem_at_remote_source
@@ -659,6 +659,42 @@ class TestGemCommandsPristineCommand < Gem::TestCase
refute_includes "ruby_executable_hooks", File.read(exe)
end
+ def test_execute_default_gem_and_regular_gem
+ a_default = new_default_spec("a", "1.2.0")
+
+ a = util_spec "a" do |s|
+ s.extensions << "ext/a/extconf.rb"
+ end
+
+ ext_path = File.join @tempdir, "ext", "a", "extconf.rb"
+ write_file ext_path do |io|
+ io.write <<-'RUBY'
+ File.open "Makefile", "w" do |f|
+ f.puts "clean:\n\techo cleaned\n"
+ f.puts "all:\n\techo built\n"
+ f.puts "install:\n\techo installed\n"
+ end
+ RUBY
+ end
+
+ install_default_gems a_default
+ install_gem a
+
+ # Remove the extension files for a
+ FileUtils.rm_rf a.gem_build_complete_path
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_includes @ui.output, "Restored #{a.full_name}"
+
+ # Check extension files for a were restored
+ assert_path_exist a.gem_build_complete_path
+ end
+
def test_execute_multi_platform
a = util_spec "a" do |s|
s.extensions << "ext/a/extconf.rb"
diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb
index 5035937544..b970e442c2 100644
--- a/test/rubygems/test_gem_ext_cargo_builder.rb
+++ b/test/rubygems/test_gem_ext_cargo_builder.rb
@@ -141,6 +141,58 @@ class TestGemExtCargoBuilder < Gem::TestCase
end
end
+ def test_linker_args
+ orig_cc = RbConfig::MAKEFILE_CONFIG["CC"]
+ RbConfig::MAKEFILE_CONFIG["CC"] = "clang"
+
+ builder = Gem::Ext::CargoBuilder.new
+ args = builder.send(:linker_args)
+
+ assert args[1], "linker=clang"
+ assert_nil args[2]
+ ensure
+ RbConfig::MAKEFILE_CONFIG["CC"] = orig_cc
+ end
+
+ def test_linker_args_with_options
+ orig_cc = RbConfig::MAKEFILE_CONFIG["CC"]
+ RbConfig::MAKEFILE_CONFIG["CC"] = "gcc -Wl,--no-undefined"
+
+ builder = Gem::Ext::CargoBuilder.new
+ args = builder.send(:linker_args)
+
+ assert args[1], "linker=clang"
+ assert args[3], "link-args=-Wl,--no-undefined"
+ ensure
+ RbConfig::MAKEFILE_CONFIG["CC"] = orig_cc
+ end
+
+ def test_linker_args_with_cachetools
+ orig_cc = RbConfig::MAKEFILE_CONFIG["CC"]
+ RbConfig::MAKEFILE_CONFIG["CC"] = "sccache clang"
+
+ builder = Gem::Ext::CargoBuilder.new
+ args = builder.send(:linker_args)
+
+ assert args[1], "linker=clang"
+ assert_nil args[2]
+ ensure
+ RbConfig::MAKEFILE_CONFIG["CC"] = orig_cc
+ end
+
+ def test_linker_args_with_cachetools_and_options
+ orig_cc = RbConfig::MAKEFILE_CONFIG["CC"]
+ RbConfig::MAKEFILE_CONFIG["CC"] = "ccache gcc -Wl,--no-undefined"
+
+ builder = Gem::Ext::CargoBuilder.new
+ args = builder.send(:linker_args)
+
+ assert args[1], "linker=clang"
+ assert args[3], "link-args=-Wl,--no-undefined"
+ ensure
+ RbConfig::MAKEFILE_CONFIG["CC"] = orig_cc
+ end
+
private
def skip_unsupported_platforms!
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