summaryrefslogtreecommitdiff
path: root/test/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby')
-rw-r--r--test/ruby/test_alias.rb29
-rw-r--r--test/ruby/test_arithmetic_sequence.rb5
-rw-r--r--test/ruby/test_array.rb14
-rw-r--r--test/ruby/test_class.rb47
-rw-r--r--test/ruby/test_enum.rb18
-rw-r--r--test/ruby/test_exception.rb21
-rw-r--r--test/ruby/test_fiber.rb6
-rw-r--r--test/ruby/test_float.rb18
-rw-r--r--test/ruby/test_hash.rb13
-rw-r--r--test/ruby/test_io.rb33
-rw-r--r--test/ruby/test_keyword.rb9
-rw-r--r--test/ruby/test_marshal.rb17
-rw-r--r--test/ruby/test_method.rb93
-rw-r--r--test/ruby/test_module.rb33
-rw-r--r--test/ruby/test_rational.rb7
-rw-r--r--test/ruby/test_regexp.rb24
-rw-r--r--test/ruby/test_require.rb29
-rw-r--r--test/ruby/test_rubyoptions.rb14
-rw-r--r--test/ruby/test_settracefunc.rb10
-rw-r--r--test/ruby/test_string.rb10
-rw-r--r--test/ruby/test_syntax.rb9
-rw-r--r--test/ruby/test_time.rb14
-rw-r--r--test/ruby/test_time_tz.rb33
-rw-r--r--test/ruby/test_weakmap.rb9
24 files changed, 495 insertions, 20 deletions
diff --git a/test/ruby/test_alias.rb b/test/ruby/test_alias.rb
index 33fb82e1d7..1acf12f7f3 100644
--- a/test/ruby/test_alias.rb
+++ b/test/ruby/test_alias.rb
@@ -227,4 +227,33 @@ class TestAlias < Test::Unit::TestCase
assert_equal(:foo, k.instance_method(:bar).original_name)
assert_equal(:foo, name)
end
+
+ def test_alias_suppressing_redefinition
+ assert_in_out_err(%w[-w], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ class A
+ def foo; end
+ alias foo foo
+ def foo; end
+ end
+ end;
+ end
+
+ def test_alias_memory_leak
+ assert_no_memory_leak([], "#{<<~"begin;"}", "#{<<~'end;'}", rss: true)
+ begin;
+ class A
+ 500.times do
+ 1000.times do |i|
+ define_method(:"foo_#{i}") {}
+
+ alias :"foo_#{i}" :"foo_#{i}"
+
+ remove_method :"foo_#{i}"
+ end
+ GC.start
+ end
+ end
+ end;
+ end
end
diff --git a/test/ruby/test_arithmetic_sequence.rb b/test/ruby/test_arithmetic_sequence.rb
index 45a0ab9222..755f54ac5a 100644
--- a/test/ruby/test_arithmetic_sequence.rb
+++ b/test/ruby/test_arithmetic_sequence.rb
@@ -284,6 +284,11 @@ class TestArithmeticSequence < Test::Unit::TestCase
'[ruby-core:90648] [Bug #15444]')
end
+ def test_last_bug17218
+ seq = (1.0997r .. 1.1r).step(0.0001r)
+ assert_equal([1.0997r, 1.0998r, 1.0999r, 1.1r], seq.to_a, '[ruby-core:100312] [Bug #17218]')
+ end
+
def test_slice
seq = 1.step(10, 2)
assert_equal([[1, 3, 5], [7, 9]], seq.each_slice(3).to_a)
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 476cf795f0..f2956a7fba 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -886,6 +886,17 @@ class TestArray < Test::Unit::TestCase
assert_raise(NoMethodError, bug12738) { a.flatten.m }
end
+ def test_flatten_recursive
+ a = []
+ a << a
+ assert_raise(ArgumentError) { a.flatten }
+ b = [1]; c = [2, b]; b << c
+ assert_raise(ArgumentError) { b.flatten }
+
+ assert_equal([1, 2, b], b.flatten(1))
+ assert_equal([1, 2, 1, 2, 1, c], b.flatten(4))
+ end
+
def test_flatten!
a1 = @cls[ 1, 2, 3]
a2 = @cls[ 5, 6 ]
@@ -2624,9 +2635,6 @@ class TestArray < Test::Unit::TestCase
def test_flatten_error
a = []
- a << a
- assert_raise(ArgumentError) { a.flatten }
-
f = [].freeze
assert_raise(ArgumentError) { a.flatten!(1, 2) }
assert_raise(TypeError) { a.flatten!(:foo) }
diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb
index ca78473026..46485c4fd2 100644
--- a/test/ruby/test_class.rb
+++ b/test/ruby/test_class.rb
@@ -483,6 +483,53 @@ class TestClass < Test::Unit::TestCase
assert_equal(:foo, d.foo)
end
+ def test_clone_singleton_class_exists
+ klass = Class.new do
+ def self.bar; :bar; end
+ end
+
+ o = klass.new
+ o.singleton_class
+ clone = o.clone
+
+ assert_empty(o.singleton_class.instance_methods(false))
+ assert_empty(clone.singleton_class.instance_methods(false))
+ assert_empty(o.singleton_class.singleton_class.instance_methods(false))
+ assert_empty(clone.singleton_class.singleton_class.instance_methods(false))
+ end
+
+ def test_clone_when_singleton_class_of_singleton_class_exists
+ klass = Class.new do
+ def self.bar; :bar; end
+ end
+
+ o = klass.new
+ o.singleton_class.singleton_class
+ clone = o.clone
+
+ assert_empty(o.singleton_class.instance_methods(false))
+ assert_empty(clone.singleton_class.instance_methods(false))
+ assert_empty(o.singleton_class.singleton_class.instance_methods(false))
+ assert_empty(clone.singleton_class.singleton_class.instance_methods(false))
+ end
+
+ def test_clone_when_method_exists_on_singleton_class_of_singleton_class
+ klass = Class.new do
+ def self.bar; :bar; end
+ end
+
+ o = klass.new
+ o.singleton_class.singleton_class.define_method(:s2_method) { :s2 }
+ clone = o.clone
+
+ assert_empty(o.singleton_class.instance_methods(false))
+ assert_empty(clone.singleton_class.instance_methods(false))
+ assert_equal(:s2, o.singleton_class.s2_method)
+ assert_equal(:s2, clone.singleton_class.s2_method)
+ assert_equal([:s2_method], o.singleton_class.singleton_class.instance_methods(false))
+ assert_equal([:s2_method], clone.singleton_class.singleton_class.instance_methods(false))
+ end
+
def test_singleton_class_p
feature7609 = '[ruby-core:51087] [Feature #7609]'
assert_predicate(self.singleton_class, :singleton_class?, feature7609)
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index 7b647231c8..ef732b9924 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -114,6 +114,11 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal([1, 2, 3, 1, 2], @obj.to_a)
end
+ def test_to_a_keywords
+ def @obj.each(foo:) yield foo end
+ assert_equal([1], @obj.to_a(foo: 1))
+ end
+
def test_to_a_size_symbol
sym = Object.new
class << sym
@@ -228,11 +233,13 @@ class TestEnumerable < Test::Unit::TestCase
assert_equal(15, [3, 5, 7].inject(:+))
assert_float_equal(15.0, [3, 5, 7.0].inject(:+))
assert_equal(2*FIXNUM_MAX, Array.new(2, FIXNUM_MAX).inject(:+))
+ assert_equal(3*FIXNUM_MAX, Array.new(3, FIXNUM_MAX).inject(:+))
assert_equal(2*(FIXNUM_MAX+1), Array.new(2, FIXNUM_MAX+1).inject(:+))
assert_equal(10*FIXNUM_MAX, Array.new(10, FIXNUM_MAX).inject(:+))
assert_equal(0, ([FIXNUM_MAX, 1, -FIXNUM_MAX, -1]*10).inject(:+))
assert_equal(FIXNUM_MAX*10, ([FIXNUM_MAX+1, -1]*10).inject(:+))
assert_equal(2*FIXNUM_MIN, Array.new(2, FIXNUM_MIN).inject(:+))
+ assert_equal(3*FIXNUM_MIN, Array.new(3, FIXNUM_MIN).inject(:+))
assert_equal((FIXNUM_MAX+1).to_f, [FIXNUM_MAX, 1, 0.0].inject(:+))
assert_float_equal(10.0, [3.0, 5].inject(2.0, :+))
assert_float_equal((FIXNUM_MAX+1).to_f, [0.0, FIXNUM_MAX+1].inject(:+))
@@ -319,6 +326,17 @@ class TestEnumerable < Test::Unit::TestCase
empty.first
empty.block.call
end;
+
+ bug18475 = '[ruby-dev:107059]'
+ assert_in_out_err([], <<-'end;', [], /unexpected break/, bug18475)
+ e = Enumerator.new do |g|
+ Thread.new do
+ g << 1
+ end.join
+ end
+
+ e.first
+ end;
end
def test_sort
diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb
index 69bf7ebf0e..9efcfc76cf 100644
--- a/test/ruby/test_exception.rb
+++ b/test/ruby/test_exception.rb
@@ -181,6 +181,27 @@ class TestException < Test::Unit::TestCase
}
end
+ def test_catch_throw_in_require_cant_be_rescued
+ bug18562 = '[ruby-core:107403]'
+ Tempfile.create(["dep", ".rb"]) {|t|
+ t.puts("throw :extdep, 42")
+ t.close
+
+ rescue_all = Class.new(Exception)
+ def rescue_all.===(_)
+ raise "should not reach here"
+ end
+
+ v = assert_throw(:extdep, bug18562) do
+ require t.path
+ rescue rescue_all => e
+ assert(false, "should not reach here")
+ end
+
+ assert_equal(42, v, bug18562)
+ }
+ end
+
def test_throw_false
bug12743 = '[ruby-core:77229] [Bug #12743]'
Thread.start {
diff --git a/test/ruby/test_fiber.rb b/test/ruby/test_fiber.rb
index a7ed9ac7e0..20436eca69 100644
--- a/test/ruby/test_fiber.rb
+++ b/test/ruby/test_fiber.rb
@@ -318,7 +318,7 @@ class TestFiber < Test::Unit::TestCase
Fiber.new {}.transfer
Fiber.new { Fiber.yield }
end
- exit!(0)
+ exit!(true)
end
}.transfer
_, status = Process.waitpid2(xpid)
@@ -327,8 +327,8 @@ class TestFiber < Test::Unit::TestCase
end.resume
end
pid, status = Process.waitpid2(pid)
- assert_equal(0, status.exitstatus, bug5700)
- assert_equal(false, status.signaled?, bug5700)
+ assert_not_predicate(status, :signaled?, bug5700)
+ assert_predicate(status, :success?, bug5700)
end
def test_exit_in_fiber
diff --git a/test/ruby/test_float.rb b/test/ruby/test_float.rb
index 7cbf3b5a8f..9c24dac8e6 100644
--- a/test/ruby/test_float.rb
+++ b/test/ruby/test_float.rb
@@ -171,6 +171,24 @@ class TestFloat < Test::Unit::TestCase
assert_raise(ArgumentError, n += z + "A") {Float(n)}
assert_raise(ArgumentError, n += z + ".0") {Float(n)}
end
+
+ x = nil
+ 2000.times do
+ x = Float("0x"+"0"*30)
+ break unless x == 0.0
+ end
+ assert_equal(0.0, x, ->{"%a" % x})
+ x = nil
+ 2000.times do
+ begin
+ x = Float("0x1."+"0"*270)
+ rescue ArgumentError => e
+ raise unless /"0x1\.0{270}"/ =~ e.message
+ else
+ break
+ end
+ end
+ assert_nil(x, ->{"%a" % x})
end
def test_divmod
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 046ea40f5d..d4af130a07 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -983,6 +983,19 @@ class TestHash < Test::Unit::TestCase
assert_equal("FOO", h.shift)
end
+ def test_shift_for_empty_hash
+ # [ruby-dev:51159]
+ h = @cls[]
+ 100.times{|n|
+ while h.size < n
+ k = Random.rand 0..1<<30
+ h[k] = 1
+ end
+ 0 while h.shift
+ assert_equal({}, h)
+ }
+ end
+
def test_reject_bang2
assert_equal({1=>2}, @cls[1=>2,3=>4].reject! {|k, v| k + v == 7 })
assert_nil(@cls[1=>2,3=>4].reject! {|k, v| k == 5 })
diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb
index 306f0bcce0..37f1477483 100644
--- a/test/ruby/test_io.rb
+++ b/test/ruby/test_io.rb
@@ -440,6 +440,18 @@ class TestIO < Test::Unit::TestCase
}
end
+ def test_copy_stream_append_to_nonempty
+ with_srccontent("foobar") {|src, content|
+ preface = 'preface'
+ File.write('dst', preface)
+ File.open('dst', 'ab') do |dst|
+ ret = IO.copy_stream(src, dst)
+ assert_equal(content.bytesize, ret)
+ assert_equal(preface + content, File.read("dst"))
+ end
+ }
+ end
+
def test_copy_stream_smaller
with_srccontent {|src, content|
@@ -1446,6 +1458,13 @@ class TestIO < Test::Unit::TestCase
end)
end
+ def test_readpartial_zero_size
+ File.open(IO::NULL) do |r|
+ assert_empty(r.readpartial(0, s = "01234567"))
+ assert_empty(s)
+ end
+ end
+
def test_readpartial_buffer_error
with_pipe do |r, w|
s = ""
@@ -1491,6 +1510,13 @@ class TestIO < Test::Unit::TestCase
end)
end
+ def test_read_zero_size
+ File.open(IO::NULL) do |r|
+ assert_empty(r.read(0, s = "01234567"))
+ assert_empty(s)
+ end
+ end
+
def test_read_buffer_error
with_pipe do |r, w|
s = ""
@@ -1528,6 +1554,13 @@ class TestIO < Test::Unit::TestCase
}
end
+ def test_read_nonblock_zero_size
+ File.open(IO::NULL) do |r|
+ assert_empty(r.read_nonblock(0, s = "01234567"))
+ assert_empty(s)
+ end
+ end
+
def test_write_nonblock_simple_no_exceptions
pipe(proc do |w|
w.write_nonblock('1', exception: false)
diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index e9be530754..ab3c11e149 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -2741,6 +2741,11 @@ class TestKeywordArguments < Test::Unit::TestCase
baz(*args)
end
+ define_method(:block_splat) {|*args| }
+ ruby2_keywords :block_splat, def foo_bar_after_bmethod(*args)
+ bar(*args)
+ end
+
ruby2_keywords def foo_baz2(*args)
baz(*args)
baz(*args)
@@ -2876,6 +2881,7 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([1, h1], o.foo(:foo_baz, 1, :a=>1))
assert_equal([[1], h1], o.foo_foo_bar(1, :a=>1))
assert_equal([1, h1], o.foo_foo_baz(1, :a=>1))
+ assert_equal([[1], h1], o.foo_bar_after_bmethod(1, :a=>1))
assert_equal([[1], h1], o.foo(:bar, 1, **h1))
assert_equal([1, h1], o.foo(:baz, 1, **h1))
@@ -2891,6 +2897,7 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([1, h1], o.foo(:foo_baz, 1, **h1))
assert_equal([[1], h1], o.foo_foo_bar(1, **h1))
assert_equal([1, h1], o.foo_foo_baz(1, **h1))
+ assert_equal([[1], h1], o.foo_bar_after_bmethod(1, **h1))
assert_equal([[h1], {}], o.foo(:bar, h1, **{}))
assert_equal([h1], o.foo(:baz, h1, **{}))
@@ -2906,6 +2913,7 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([h1], o.foo(:foo_baz, h1, **{}))
assert_equal([[h1], {}], o.foo_foo_bar(h1, **{}))
assert_equal([h1], o.foo_foo_baz(h1, **{}))
+ assert_equal([[h1], {}], o.foo_bar_after_bmethod(h1, **{}))
assert_warn(/Using the last argument as keyword parameters is deprecated.*The called method `bar'/m) do
assert_equal([[1], h1], o.foo(:bar, 1, h1))
@@ -2923,6 +2931,7 @@ class TestKeywordArguments < Test::Unit::TestCase
assert_equal([[1], h1], o.foo_bar(1, h1))
end
assert_equal([1, h1], o.foo_baz(1, h1))
+ assert_equal([[1], h1], o.foo_bar_after_bmethod(1, h1))
assert_equal([[1, h1, 1], {}], o.foo_mod(:bar, 1, :a=>1))
assert_equal([1, h1, 1], o.foo_mod(:baz, 1, :a=>1))
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index 850f467c10..90899fa83f 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -651,6 +651,23 @@ class TestMarshal < Test::Unit::TestCase
assert_equal(['X', 'X'], Marshal.load(Marshal.dump(obj), ->(v) { v == str ? v.upcase : v }))
end
+ def test_marshal_proc_string_encoding
+ string = "foo"
+ payload = Marshal.dump(string)
+ Marshal.load(payload, ->(v) {
+ if v.is_a?(String)
+ assert_equal(string, v)
+ assert_equal(string.encoding, v.encoding)
+ end
+ v
+ })
+ end
+
+ def test_marshal_proc_freeze
+ object = { foo: [42, "bar"] }
+ assert_equal object, Marshal.load(Marshal.dump(object), :freeze.to_proc)
+ end
+
def test_marshal_load_extended_class_crash
assert_separately([], "#{<<-"begin;"}\n#{<<-"end;"}")
begin;
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index bb506f1258..03a6c560e6 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -1064,6 +1064,99 @@ class TestMethod < Test::Unit::TestCase
'[ruby-core:85231] [Bug #14421]'
end
+ def test_super_method_alias
+ c0 = Class.new do
+ def m1
+ [:C0_m1]
+ end
+ def m2
+ [:C0_m2]
+ end
+ end
+
+ c1 = Class.new(c0) do
+ def m1
+ [:C1_m1] + super
+ end
+ alias m2 m1
+ end
+
+ c2 = Class.new(c1) do
+ def m2
+ [:C2_m2] + super
+ end
+ end
+ o1 = c2.new
+ assert_equal([:C2_m2, :C1_m1, :C0_m1], o1.m2)
+
+ m = o1.method(:m2)
+ assert_equal([:C2_m2, :C1_m1, :C0_m1], m.call)
+
+ m = m.super_method
+ assert_equal([:C1_m1, :C0_m1], m.call)
+
+ m = m.super_method
+ assert_equal([:C0_m1], m.call)
+
+ assert_nil(m.super_method)
+ end
+
+ def test_super_method_alias_to_prepended_module
+ m = Module.new do
+ def m1
+ [:P_m1] + super
+ end
+
+ def m2
+ [:P_m2] + super
+ end
+ end
+
+ c0 = Class.new do
+ def m1
+ [:C0_m1]
+ end
+ end
+
+ c1 = Class.new(c0) do
+ def m1
+ [:C1_m1] + super
+ end
+ prepend m
+ alias m2 m1
+ end
+
+ o1 = c1.new
+ assert_equal([:P_m2, :P_m1, :C1_m1, :C0_m1], o1.m2)
+
+ m = o1.method(:m2)
+ assert_equal([:P_m2, :P_m1, :C1_m1, :C0_m1], m.call)
+
+ m = m.super_method
+ assert_equal([:P_m1, :C1_m1, :C0_m1], m.call)
+
+ m = m.super_method
+ assert_equal([:C1_m1, :C0_m1], m.call)
+
+ m = m.super_method
+ assert_equal([:C0_m1], m.call)
+
+ assert_nil(m.super_method)
+ end
+
+ # Bug 17780
+ def test_super_method_module_alias
+ m = Module.new do
+ def foo
+ end
+ alias :f :foo
+ end
+
+ method = m.instance_method(:f)
+ super_method = method.super_method
+ assert_nil(super_method)
+ end
+
def rest_parameter(*rest)
rest
end
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index 69f03ae772..231ccd2072 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -472,6 +472,16 @@ class TestModule < Test::Unit::TestCase
assert_equal([Comparable, Kernel], String.included_modules - mixins)
end
+ def test_include_with_prepend
+ c = Class.new{def m; [:c] end}
+ p = Module.new{def m; [:p] + super end}
+ q = Module.new{def m; [:q] + super end; include p}
+ r = Module.new{def m; [:r] + super end; prepend q}
+ s = Module.new{def m; [:s] + super end; include r}
+ a = Class.new(c){def m; [:a] + super end; prepend p; include s}
+ assert_equal([:p, :a, :s, :q, :r, :c], a.new.m)
+ end
+
def test_instance_methods
assert_equal([:user, :user2], User.instance_methods(false).sort)
assert_equal([:user, :user2, :mixin].sort, User.instance_methods(true).sort)
@@ -1924,6 +1934,29 @@ class TestModule < Test::Unit::TestCase
assert_equal(0, 1 / 2)
end
+ def test_visibility_after_refine_and_visibility_change
+ m = Module.new
+ c = Class.new do
+ def x; :x end
+ end
+ c.prepend(m)
+ Module.new do
+ refine c do
+ def x; :y end
+ end
+ end
+
+ o1 = c.new
+ o2 = c.new
+ assert_equal(:x, o1.public_send(:x))
+ assert_equal(:x, o2.public_send(:x))
+ o1.singleton_class.send(:private, :x)
+ o2.singleton_class.send(:public, :x)
+
+ assert_raise(NoMethodError) { o1.public_send(:x) }
+ assert_equal(:x, o2.public_send(:x))
+ end
+
def test_prepend_visibility
bug8005 = '[ruby-core:53106] [Bug #8005]'
c = Class.new do
diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb
index 301890b620..5676b41445 100644
--- a/test/ruby/test_rational.rb
+++ b/test/ruby/test_rational.rb
@@ -598,6 +598,13 @@ class Rational_Test < Test::Unit::TestCase
assert_nothing_raised(TypeError, '[Bug #5020] [ruby-dev:44088]') do
Rational(1,2).coerce(Complex(1,1))
end
+
+ assert_raise(ZeroDivisionError) do
+ 1 / 0r.coerce(0+0i)[0]
+ end
+ assert_raise(ZeroDivisionError) do
+ 1 / 0r.coerce(0.0+0i)[0]
+ end
end
class ObjectX
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb
index b469d643f2..8709d05752 100644
--- a/test/ruby/test_regexp.rb
+++ b/test/ruby/test_regexp.rb
@@ -218,6 +218,17 @@ class TestRegexp < Test::Unit::TestCase
def test_assign_named_capture_to_reserved_word
/(?<nil>.)/ =~ "a"
assert_not_include(local_variables, :nil, "[ruby-dev:32675]")
+
+ def (obj = Object.new).test(s, nil: :ng)
+ /(?<nil>.)/ =~ s
+ binding.local_variable_get(:nil)
+ end
+ assert_equal("b", obj.test("b"))
+
+ tap do |nil: :ng|
+ /(?<nil>.)/ =~ "c"
+ assert_equal("c", binding.local_variable_get(:nil))
+ end
end
def test_assign_named_capture_to_const
@@ -680,11 +691,16 @@ class TestRegexp < Test::Unit::TestCase
test = proc {|&blk| "abc".sub("a", ""); blk.call($~) }
bug10877 = '[ruby-core:68209] [Bug #10877]'
+ bug18160 = '[Bug #18160]'
test.call {|m| assert_raise_with_message(IndexError, /foo/, bug10877) {m["foo"]} }
key = "\u{3042}"
[Encoding::UTF_8, Encoding::Shift_JIS, Encoding::EUC_JP].each do |enc|
idx = key.encode(enc)
- test.call {|m| assert_raise_with_message(IndexError, /#{idx}/, bug10877) {m[idx]} }
+ pat = /#{idx}/
+ test.call {|m| assert_raise_with_message(IndexError, pat, bug10877) {m[idx]} }
+ test.call {|m| assert_raise_with_message(IndexError, pat, bug18160) {m.offset(idx)} }
+ test.call {|m| assert_raise_with_message(IndexError, pat, bug18160) {m.begin(idx)} }
+ test.call {|m| assert_raise_with_message(IndexError, pat, bug18160) {m.end(idx)} }
end
test.call {|m| assert_equal(/a/, m.regexp) }
test.call {|m| assert_equal("abc", m.string) }
@@ -1277,6 +1293,12 @@ class TestRegexp < Test::Unit::TestCase
assert_nil($1)
end
+ def test_backref_overrun
+ assert_raise_with_message(SyntaxError, /invalid backref number/) do
+ eval(%["".match(/(())(?<X>)((?(90000)))/)])
+ end
+ end
+
# This assertion is for porting x2() tests in testpy.py of Onigmo.
def assert_match_at(re, str, positions, msg = nil)
re = Regexp.new(re) unless re.is_a?(Regexp)
diff --git a/test/ruby/test_require.rb b/test/ruby/test_require.rb
index a86ea356c5..a1adb4926f 100644
--- a/test/ruby/test_require.rb
+++ b/test/ruby/test_require.rb
@@ -368,15 +368,15 @@ class TestRequire < Test::Unit::TestCase
bug = '[ruby-list:49994] path in ospath'
base = "test_load\u{3042 3044 3046 3048 304a}".encode(Encoding::Windows_31J)
path = nil
- Tempfile.create([base, ".rb"]) do |t|
- path = t.path
-
+ Dir.mktmpdir do |dir|
+ path = File.join(dir, base+".rb")
assert_raise_with_message(LoadError, /#{base}/) {
- load(File.join(File.dirname(path), base))
+ load(File.join(dir, base))
}
- t.puts "warn 'ok'"
- t.close
+ File.open(path, "w+b") do |t|
+ t.puts "warn 'ok'"
+ end
assert_include(path, base)
assert_warn("ok\n", bug) {
assert_nothing_raised(LoadError, bug) {
@@ -831,6 +831,23 @@ class TestRequire < Test::Unit::TestCase
}
end
+ def test_provide_in_required_file
+ paths, loaded = $:.dup, $".dup
+ Dir.mktmpdir do |tmp|
+ provide = File.realdirpath("provide.rb", tmp)
+ File.write(File.join(tmp, "target.rb"), "raise __FILE__\n")
+ File.write(provide, '$" << '"'target.rb'\n")
+ $:.replace([tmp])
+ assert(require("provide"))
+ assert(!require("target"))
+ assert_equal($".pop, provide)
+ assert_equal($".pop, "target.rb")
+ end
+ ensure
+ $:.replace(paths)
+ $".replace(loaded)
+ end
+
if defined?($LOAD_PATH.resolve_feature_path)
def test_resolve_feature_path
paths, loaded = $:.dup, $".dup
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index fba53cd982..2842b63804 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -83,6 +83,15 @@ class TestRubyOptions < Test::Unit::TestCase
assert_in_out_err(%w(-w -e) + ['p Warning[:deprecated]'], "", %w(true), [])
assert_in_out_err(%w(-W -e) + ['p Warning[:deprecated]'], "", %w(true), [])
assert_in_out_err(%w(-e) + ['p Warning[:deprecated]'], "", %w(false), [])
+ code = 'puts "#{$VERBOSE}:#{Warning[:deprecated]}:#{Warning[:experimental]}"'
+ Tempfile.create(["test_ruby_test_rubyoption", ".rb"]) do |t|
+ t.puts code
+ t.close
+ assert_in_out_err(["-r#{t.path}", '-e', code], "", %w(false:false:true false:false:true), [])
+ assert_in_out_err(["-r#{t.path}", '-w', '-e', code], "", %w(true:true:true true:true:true), [])
+ assert_in_out_err(["-r#{t.path}", '-W:deprecated', '-e', code], "", %w(false:true:true false:true:true), [])
+ assert_in_out_err(["-r#{t.path}", '-W:no-experimental', '-e', code], "", %w(false:false:false false:false:false), [])
+ end
ensure
ENV['RUBYOPT'] = save_rubyopt
end
@@ -1060,6 +1069,11 @@ class TestRubyOptions < Test::Unit::TestCase
end
end
+ def test_rubylib_invalid_encoding
+ env = {"RUBYLIB"=>"\xFF", "LOCALE"=>"en_US.UTF-8", "LC_ALL"=>"en_US.UTF-8"}
+ assert_ruby_status([env, "-e;"])
+ end
+
def test_null_script
skip "#{IO::NULL} is not a character device" unless File.chardev?(IO::NULL)
assert_in_out_err([IO::NULL], success: true)
diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb
index e16a4fc01e..0c41f247be 100644
--- a/test/ruby/test_settracefunc.rb
+++ b/test/ruby/test_settracefunc.rb
@@ -555,6 +555,16 @@ class TestSetTraceFunc < Test::Unit::TestCase
}
end
+ # Bug #18264
+ def test_tracpoint_memory_leak
+ assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
+code = proc { TracePoint.new(:line) { } }
+1_000.times(&code)
+PREP
+1_000_000.times(&code)
+CODE
+ end
+
def trace_by_set_trace_func
events = []
trace = nil
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 746471553d..b6cb0321c8 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -107,6 +107,16 @@ PREP
CODE
end
+ # Bug #18154
+ def test_initialize_nofree_memory_leak
+ assert_no_memory_leak([], <<-PREP, <<-CODE, rss: true)
+code = proc {0.to_s.__send__(:initialize, capacity: 10000)}
+1_000.times(&code)
+PREP
+100_000.times(&code)
+CODE
+ end
+
def test_AREF # '[]'
assert_equal("A", S("AooBar")[0])
assert_equal("B", S("FooBaB")[-1])
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index f628dc3fba..86417ba12f 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -1374,6 +1374,15 @@ eom
assert_nil obj.test
end
+ def test_assignment_return_in_loop
+ obj = Object.new
+ def obj.test
+ x = nil
+ _y = (return until x unless x)
+ end
+ assert_nil obj.test, "[Bug #16695]"
+ end
+
def test_method_call_location
line = __LINE__+5
e = assert_raise(NoMethodError) do
diff --git a/test/ruby/test_time.rb b/test/ruby/test_time.rb
index ad8fe6c8cd..1749d92a17 100644
--- a/test/ruby/test_time.rb
+++ b/test/ruby/test_time.rb
@@ -1194,6 +1194,20 @@ class TestTime < Test::Unit::TestCase
}
end
+ def test_getlocal_utc_offset
+ t = Time.gm(2000)
+ assert_equal [00, 30, 21, 31, 12, 1999], t.getlocal("-02:30").to_a[0, 6]
+ assert_equal [00, 00, 9, 1, 1, 2000], t.getlocal("+09:00").to_a[0, 6]
+ assert_equal [20, 29, 21, 31, 12, 1999], t.getlocal("-02:30:40").to_a[0, 6]
+ assert_equal [35, 10, 9, 1, 1, 2000], t.getlocal("+09:10:35").to_a[0, 6]
+ assert_equal [00, 30, 21, 31, 12, 1999], t.getlocal("-0230").to_a[0, 6]
+ assert_equal [00, 00, 9, 1, 1, 2000], t.getlocal("+0900").to_a[0, 6]
+ assert_equal [20, 29, 21, 31, 12, 1999], t.getlocal("-023040").to_a[0, 6]
+ assert_equal [35, 10, 9, 1, 1, 2000], t.getlocal("+091035").to_a[0, 6]
+ assert_raise(ArgumentError) {t.getlocal("-02:3040")}
+ assert_raise(ArgumentError) {t.getlocal("+0910:35")}
+ end
+
def test_getlocal_nil
now = Time.now
now2 = nil
diff --git a/test/ruby/test_time_tz.rb b/test/ruby/test_time_tz.rb
index 7f0a306783..47f8c63077 100644
--- a/test/ruby/test_time_tz.rb
+++ b/test/ruby/test_time_tz.rb
@@ -7,9 +7,9 @@ class TestTimeTZ < Test::Unit::TestCase
has_lisbon_tz = true
force_tz_test = ENV["RUBY_FORCE_TIME_TZ_TEST"] == "yes"
case RUBY_PLATFORM
- when /linux/
+ when /darwin|linux/
force_tz_test = true
- when /darwin|freebsd|openbsd/
+ when /freebsd|openbsd/
has_lisbon_tz = false
force_tz_test = true
end
@@ -95,6 +95,9 @@ class TestTimeTZ < Test::Unit::TestCase
CORRECT_KIRITIMATI_SKIP_1994 = with_tz("Pacific/Kiritimati") {
Time.local(1994, 12, 31, 0, 0, 0).year == 1995
}
+ CORRECT_SINGAPORE_1982 = with_tz("Asia/Singapore") {
+ "2022g" if Time.local(1981, 12, 31, 23, 59, 59).utc_offset == 8*3600
+ }
def time_to_s(t)
t.to_s
@@ -140,9 +143,12 @@ class TestTimeTZ < Test::Unit::TestCase
def test_asia_singapore
with_tz(tz="Asia/Singapore") {
- assert_time_constructor(tz, "1981-12-31 23:59:59 +0730", :local, [1981,12,31,23,59,59])
- assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,0,0])
- assert_time_constructor(tz, "1982-01-01 00:59:59 +0800", :local, [1982,1,1,0,29,59])
+ assert_time_constructor(tz, "1981-12-31 23:29:59 +0730", :local, [1981,12,31,23,29,59])
+ if CORRECT_SINGAPORE_1982
+ assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1981,12,31,23,30,00])
+ assert_time_constructor(tz, "1982-01-01 00:00:00 +0800", :local, [1982,1,1,0,0,0])
+ assert_time_constructor(tz, "1982-01-01 00:29:59 +0800", :local, [1982,1,1,0,29,59])
+ end
assert_time_constructor(tz, "1982-01-01 00:30:00 +0800", :local, [1982,1,1,0,30,0])
}
end
@@ -196,7 +202,7 @@ class TestTimeTZ < Test::Unit::TestCase
def test_europe_lisbon
with_tz("Europe/Lisbon") {
- assert_equal("LMT", Time.new(-0x1_0000_0000_0000_0000).zone)
+ assert_include(%w"LMT CET", Time.new(-0x1_0000_0000_0000_0000).zone)
}
end if has_lisbon_tz
@@ -452,9 +458,12 @@ America/Managua Fri Jan 1 06:00:00 1993 UTC = Fri Jan 1 01:00:00 1993 EST isd
America/Managua Wed Jan 1 04:59:59 1997 UTC = Tue Dec 31 23:59:59 1996 EST isdst=0 gmtoff=-18000
America/Managua Wed Jan 1 05:00:00 1997 UTC = Tue Dec 31 23:00:00 1996 CST isdst=0 gmtoff=-21600
Asia/Singapore Sun Aug 8 16:30:00 1965 UTC = Mon Aug 9 00:00:00 1965 SGT isdst=0 gmtoff=27000
-Asia/Singapore Thu Dec 31 16:29:59 1981 UTC = Thu Dec 31 23:59:59 1981 SGT isdst=0 gmtoff=27000
+Asia/Singapore Thu Dec 31 15:59:59 1981 UTC = Thu Dec 31 23:29:59 1981 SGT isdst=0 gmtoff=27000
Asia/Singapore Thu Dec 31 16:30:00 1981 UTC = Fri Jan 1 00:30:00 1982 SGT isdst=0 gmtoff=28800
End
+ gen_zdump_test <<'End' if CORRECT_SINGAPORE_1982
+Asia/Singapore Thu Dec 31 16:00:00 1981 UTC = Fri Jan 1 00:00:00 1982 SGT isdst=0 gmtoff=28800
+End
gen_zdump_test CORRECT_TOKYO_DST_1951 ? <<'End' + (CORRECT_TOKYO_DST_1951 < "2018f" ? <<'2018e' : <<'2018f') : <<'End'
Asia/Tokyo Sat May 5 14:59:59 1951 UTC = Sat May 5 23:59:59 1951 JST isdst=0 gmtoff=32400
Asia/Tokyo Sat May 5 15:00:00 1951 UTC = Sun May 6 01:00:00 1951 JDT isdst=1 gmtoff=36000
@@ -749,6 +758,16 @@ class TestTimeTZ::DummyTZ < Test::Unit::TestCase
def self.make_timezone(tzname, abbr, utc_offset, abbr2 = nil, utc_offset2 = nil)
TestTimeTZ::TZ.new(tzname, abbr, utc_offset, abbr2, utc_offset2)
end
+
+ def test_fractional_second
+ x = Object.new
+ def x.local_to_utc(t); t + 8*3600; end
+ def x.utc_to_local(t); t - 8*3600; end
+
+ t1 = Time.new(2020,11,11,12,13,14.124r, '-08:00')
+ t2 = Time.new(2020,11,11,12,13,14.124r, x)
+ assert_equal(t1, t2)
+ end
end
begin
diff --git a/test/ruby/test_weakmap.rb b/test/ruby/test_weakmap.rb
index 3b9eef770a..46d8b50c03 100644
--- a/test/ruby/test_weakmap.rb
+++ b/test/ruby/test_weakmap.rb
@@ -73,6 +73,15 @@ class TestWeakMap < Test::Unit::TestCase
@wm.inspect)
end
+ def test_inspect_garbage
+ 1000.times do |i|
+ @wm[i] = Object.new
+ @wm.inspect
+ end
+ assert_match(/\A\#<#{@wm.class.name}:[^:]++:(?:\s\d+\s=>\s\#<(?:Object|collected):[^:<>]*+>(?:,|>\z))+/,
+ @wm.inspect)
+ end
+
def test_each
m = __callee__[/test_(.*)/, 1]
x1 = Object.new