Skip to content

Commit

Permalink
Showing 456 changed files with 12,965 additions and 3,574 deletions.
4 changes: 2 additions & 2 deletions test/mri/-ext-/bignum/test_big2str.rb
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@
class TestBignum < Test::Unit::TestCase
class TestBig2str < Test::Unit::TestCase

SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT
BITSPERDIG = Bignum::BITSPERDIG
SIZEOF_BDIGIT = Integer::SIZEOF_BDIGIT
BITSPERDIG = Integer::BITSPERDIG
BDIGMAX = (1 << BITSPERDIG) - 1

def test_big2str_generic
6 changes: 6 additions & 0 deletions test/mri/-ext-/bignum/test_bigzero.rb
Original file line number Diff line number Diff line change
@@ -10,5 +10,11 @@ def test_equal_0
assert_equal(0, Bug::Bignum.zero(i), "#{bug8204} Bignum.zero(#{i})")
end
end

def test_zero?
(0..10).each do |i|
assert_equal(true, Bug::Bignum.zero(i).zero?)
end
end
end
end
4 changes: 2 additions & 2 deletions test/mri/-ext-/bignum/test_div.rb
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@
class TestBignum < Test::Unit::TestCase
class TestDiv < Test::Unit::TestCase

SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT
BITSPERDIG = Bignum::BITSPERDIG
SIZEOF_BDIGIT = Integer::SIZEOF_BDIGIT
BITSPERDIG = Integer::BITSPERDIG
BDIGMAX = (1 << BITSPERDIG) - 1

def test_divrem_normal
12 changes: 6 additions & 6 deletions test/mri/-ext-/bignum/test_mul.rb
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@
class TestBignum < Test::Unit::TestCase
class TestMul < Test::Unit::TestCase

SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT
BITSPERDIG = Bignum::BITSPERDIG
SIZEOF_BDIGIT = Integer::SIZEOF_BDIGIT
BITSPERDIG = Integer::BITSPERDIG
BDIGMAX = (1 << BITSPERDIG) - 1

def test_mul_normal
@@ -61,14 +61,14 @@ def test_mul_balance
end

def test_mul_balance_2x16
x = (1 << Bignum::BITSPERDIG) | 1
y = (1 << Bignum::BITSPERDIG*16) | 1
x = (1 << Integer::BITSPERDIG) | 1
y = (1 << Integer::BITSPERDIG*16) | 1
assert_equal(x.big_mul_normal(y), x.big_mul_balance(y))
end

def test_mul_balance_2x17
x = (1 << Bignum::BITSPERDIG) | 1
y = (1 << Bignum::BITSPERDIG*17) | 1
x = (1 << Integer::BITSPERDIG) | 1
y = (1 << Integer::BITSPERDIG*17) | 1
assert_equal(x.big_mul_normal(y), x.big_mul_balance(y))
end

4 changes: 2 additions & 2 deletions test/mri/-ext-/bignum/test_str2big.rb
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@
class TestBignum < Test::Unit::TestCase
class TestStr2big < Test::Unit::TestCase

SIZEOF_BDIGIT = Bignum::SIZEOF_BDIGIT
BITSPERDIG = Bignum::BITSPERDIG
SIZEOF_BDIGIT = Integer::SIZEOF_BDIGIT
BITSPERDIG = Integer::BITSPERDIG
BDIGMAX = (1 << BITSPERDIG) - 1

def test_str2big_poweroftwo
2 changes: 1 addition & 1 deletion test/mri/-ext-/bug_reporter/test_bug_reporter.rb
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ def test_bug_reporter_add
]
tmpdir = Dir.mktmpdir

args = ["--disable-gems", "-r-test-/bug_reporter/bug_reporter",
args = ["--disable-gems", "-r-test-/bug_reporter",
"-C", tmpdir]
stdin = "register_sample_bug_reporter(12345); Process.kill :SEGV, $$"
assert_in_out_err(args, stdin, [], expected_stderr, encoding: "ASCII-8BIT")
2 changes: 1 addition & 1 deletion test/mri/-ext-/funcall/test_passing_block.rb
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ def self.target(*args, &block)
yield(*args) if block
end
end
require '-test-/funcall/funcall'
require '-test-/funcall'

def test_with_funcall2
ok = nil
15 changes: 15 additions & 0 deletions test/mri/-ext-/integer/test_integer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: false
require 'test/unit'
require '-test-/integer'

class TestInteger < Test::Unit::TestCase
FIXNUM_MIN = Integer::FIXNUM_MIN
FIXNUM_MAX = Integer::FIXNUM_MAX

def test_fixnum_range
assert_bignum(FIXNUM_MIN-1)
assert_fixnum(FIXNUM_MIN)
assert_fixnum(FIXNUM_MAX)
assert_bignum(FIXNUM_MAX+1)
end
end
48 changes: 48 additions & 0 deletions test/mri/-ext-/integer/test_my_integer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: false
require 'test/unit'
require "-test-/integer"

class TestIntegerExt < Test::Unit::TestCase
def test_my_integer_to_f
assert_raise(NotImplementedError) do
Bug::Integer::MyInteger.new.to_f
end

begin
Bug::Integer::MyInteger.class_eval do
def to_f
end
end

assert_nothing_raised do
Bug::Integer::MyInteger.new.to_f
end
ensure
Bug::Integer::MyInteger.class_eval do
remove_method :to_f
end
end
end

def test_my_integer_cmp
assert_raise(NotImplementedError) do
Bug::Integer::MyInteger.new <=> 0
end

begin
Bug::Integer::MyInteger.class_eval do
def <=>(other)
0
end
end

assert_nothing_raised do
Bug::Integer::MyInteger.new <=> 0
end
ensure
Bug::Integer::MyInteger.class_eval do
remove_method :<=>
end
end
end
end
2 changes: 1 addition & 1 deletion test/mri/-ext-/iseq_load/test_iseq_load.rb
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
require 'test/unit'

class TestIseqLoad < Test::Unit::TestCase
require '-test-/iseq_load/iseq_load'
require '-test-/iseq_load'
ISeq = RubyVM::InstructionSequence

def test_bug8543
2 changes: 1 addition & 1 deletion test/mri/-ext-/load/test_dot_dot.rb
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ class Test_DotDot < Test::Unit::TestCase
def test_load_dot_dot
feature = '[ruby-dev:41774]'
assert_nothing_raised(LoadError, feature) {
require '-test-/load/dot.dot/dot.dot'
require '-test-/load/dot.dot'
}
end
end
2 changes: 1 addition & 1 deletion test/mri/-ext-/method/test_arity.rb
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@ def foo2(a,b)
end
end

class B<A
class B < A
private :foo1, :foo2
end

7 changes: 4 additions & 3 deletions test/mri/-ext-/num2int/test_num2int.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: false
require 'test/unit'
require '-test-/num2int/num2int'
require '-test-/num2int'
require '-test-/integer'

class TestNum2int < Test::Unit::TestCase
SHRT_MIN = -32768
@@ -104,7 +105,7 @@ def assert_fix2i_success_internal(exp, func, arg)
end

def assert_fix2i_success(type, num, result=num)
return if !num.kind_of?(Fixnum)
return if !num.fixnum?
func = "FIX2#{type}".upcase
assert_fix2i_success_internal(result.to_s, func, num)
end
@@ -116,7 +117,7 @@ def assert_fix2i_error_internal(func, arg)
end

def assert_fix2i_error(type, num)
return if !num.kind_of?(Fixnum)
return if !num.fixnum?
func = "FIX2#{type}".upcase
assert_num2i_error_internal(func, num)
end
2 changes: 1 addition & 1 deletion test/mri/-ext-/path_to_class/test_path_to_class.rb
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
require 'test/unit'

class Test_PathToClass < Test::Unit::TestCase
require '-test-/path_to_class/path_to_class'
require '-test-/path_to_class'

def test_path_to_class
bug5691 = '[ruby-core:41410]'
32 changes: 32 additions & 0 deletions test/mri/-ext-/string/test_capacity.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# frozen_string_literal: true
require 'test/unit'
require '-test-/string'
require 'rbconfig/sizeof'

class Test_StringCapacity < Test::Unit::TestCase
def capa(str)
Bug::String.capacity(str)
end

def test_capacity_embeded
size = RbConfig::SIZEOF['void*'] * 3 - 1
assert_equal size, capa('foo')
end

def test_capacity_shared
assert_equal 0, capa(:abcdefghijklmnopqrstuvwxyz.to_s)
end

def test_capacity_normal
assert_equal 128, capa('1'*128)
end

def test_s_new_capacity
assert_equal("", String.new(capacity: 1000))
assert_equal(String, String.new(capacity: 1000).class)
assert_equal(10000, capa(String.new(capacity: 10000)))

assert_equal("", String.new(capacity: -1000))
assert_equal(capa(String.new(capacity: -10000)), capa(String.new(capacity: -1000)))
end
end
6 changes: 6 additions & 0 deletions test/mri/-ext-/string/test_cstr.rb
Original file line number Diff line number Diff line change
@@ -18,6 +18,12 @@ def test_long
assert_equal(0, s.cstr_term, Bug4319)
end

def test_shared
s = Bug::String.new("abcdef")*5
s = s.unterminated_substring(0, 29)
assert_equal(0, s.cstr_term, Bug4319)
end

def test_frozen
s0 = Bug::String.new("abcdefgh"*8)

9 changes: 9 additions & 0 deletions test/mri/-ext-/string/test_fstring.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# frozen_string_literal: false
require 'test/unit'
require '-test-/string'
require_relative '../symbol/noninterned_name'

class Test_String_Fstring < Test::Unit::TestCase
include Test_Symbol::NonInterned

def assert_fstring(str)
fstr = Bug::String.fstring(str)
yield str
@@ -54,6 +57,12 @@ def str.foo
assert_fstring(str) {|s| assert_send([s, :respond_to?, :foo])}
end

def test_singleton_class
str = noninterned_name.force_encoding("us-ascii")
fstr = Bug::String.fstring(str)
assert_raise(TypeError) {fstr.singleton_class}
end

class S < String
end

10 changes: 10 additions & 0 deletions test/mri/-ext-/string/test_modify_expand.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# frozen_string_literal: false
require 'test/unit'
require "-test-/string"
require "rbconfig/sizeof"

class Test_StringModifyExpand < Test::Unit::TestCase
def test_modify_expand_memory_leak
@@ -13,4 +14,13 @@ def test_modify_expand_memory_leak
s.replace("")
CMD
end

def test_integer_overflow
bug12390 = '[ruby-core:75592] [Bug #12390]'
s = Bug::String.new
long_max = (1 << (8 * RbConfig::SIZEOF['long'] - 1)) - 1
assert_raise(ArgumentError, bug12390) {
s.modify_expand!(long_max)
}
end
end
9 changes: 9 additions & 0 deletions test/mri/-ext-/string/test_set_len.rb
Original file line number Diff line number Diff line change
@@ -23,4 +23,13 @@ def test_shared
assert_equal("abc", @s1.set_len(3))
}
end

def test_capacity_equals_to_new_size
bug12757 = "[ruby-core:77257] [Bug #12757]"
# fill to ensure capacity does not decrease with force_encoding
str = Bug::String.new("\x00" * 128, capacity: 128)
str.force_encoding("UTF-32BE")
assert_equal 128, Bug::String.capacity(str)
assert_equal 127, str.set_len(127).bytesize, bug12757
end
end
4 changes: 1 addition & 3 deletions test/mri/-ext-/struct/test_member.rb
Original file line number Diff line number Diff line change
@@ -9,8 +9,6 @@ def test_member_get
s = S.new(1)
assert_equal(1, s.get(:a))
assert_raise_with_message(NameError, /is not a struct member/) {s.get(:b)}
EnvUtil.with_default_external(Encoding::UTF_8) do
assert_raise_with_message(NameError, /\u{3042}/) {s.get(:"\u{3042}")}
end
assert_raise_with_message(NameError, /\u{3042}/) {s.get(:"\u{3042}")}
end
end
15 changes: 15 additions & 0 deletions test/mri/-ext-/symbol/noninterned_name.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require "-test-/symbol"

module Test_Symbol
module NonInterned
module_function

def noninterned_name(prefix = "")
prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}"
begin
name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}"
end while Bug::Symbol.find(name)
name
end
end
end
23 changes: 6 additions & 17 deletions test/mri/-ext-/symbol/test_inadvertent_creation.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
# frozen_string_literal: false
require 'test/unit'
require "-test-/symbol"
require_relative 'noninterned_name'

module Test_Symbol
class TestInadvertent < Test::Unit::TestCase
def noninterned_name(prefix = "")
prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}"
begin
name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}"
end while Bug::Symbol.find(name)
name
end
include NonInterned

def setup
@obj = Object.new
@@ -362,22 +356,17 @@ def test_invalid_attr_accessor
end

def test_gc_attrset
assert_separately(['-r-test-/symbol', '-', '[ruby-core:62226] [Bug #9787]'], <<-'end;') # begin
bug = ARGV.shift
def noninterned_name(prefix = "")
prefix += "_#{Thread.current.object_id.to_s(36).tr('-', '_')}"
begin
name = "#{prefix}_#{rand(0x1000).to_s(16)}_#{Time.now.usec}"
end while Bug::Symbol.find(name) or Bug::Symbol.find(name + "=")
name
end
assert_separately(['-r-test-/symbol', '-r-ext-/symbol/noninterned_name', '-'], "#{<<-'begin;'}\n#{<<-"end;"}")
bug = '[ruby-core:62226] [Bug #9787]'
include Test_Symbol::NonInterned
names = Array.new(1000) {noninterned_name("gc")}
names.each {|n| n.to_sym}
GC.start(immediate_sweep: false)
names.each do |n|
eval(":#{n}=")
assert_nothing_raised(TypeError, bug) {eval("proc{self.#{n} = nil}")}
end
begin;
end;
end

20 changes: 8 additions & 12 deletions test/mri/-ext-/symbol/test_type.rb
Original file line number Diff line number Diff line change
@@ -123,21 +123,17 @@ def test_attrset
end

def test_check_id_invalid_type
EnvUtil.with_default_external(Encoding::UTF_8) do
cx = EnvUtil.labeled_class("X\u{1f431}")
assert_raise_with_message(TypeError, /X\u{1F431}/) {
Bug::Symbol.pinneddown?(cx)
}
end
cx = EnvUtil.labeled_class("X\u{1f431}")
assert_raise_with_message(TypeError, /X\u{1F431}/) {
Bug::Symbol.pinneddown?(cx)
}
end

def test_check_symbol_invalid_type
EnvUtil.with_default_external(Encoding::UTF_8) do
cx = EnvUtil.labeled_class("X\u{1f431}")
assert_raise_with_message(TypeError, /X\u{1F431}/) {
Bug::Symbol.find(cx)
}
end
cx = EnvUtil.labeled_class("X\u{1f431}")
assert_raise_with_message(TypeError, /X\u{1F431}/) {
Bug::Symbol.find(cx)
}
end
end
end
2 changes: 1 addition & 1 deletion test/mri/-ext-/test_bug-3571.rb
Original file line number Diff line number Diff line change
@@ -16,6 +16,6 @@ def test_block_call_id
"-:2:in `start'",
"-:2:in `<main>'",
]
assert_in_out_err(%w"-r-test-/bug-3571/bug", src, [], out, bug3571)
assert_in_out_err(%w"-r-test-/bug_3571", src, [], out, bug3571)
end
end
2 changes: 1 addition & 1 deletion test/mri/-ext-/test_bug-5832.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: false
require '-test-/bug-5832/bug'
require '-test-/bug_5832'

class Test_BUG_5832 < Test::Unit::TestCase
def test_block_passing
4 changes: 2 additions & 2 deletions test/mri/-ext-/typeddata/test_typeddata.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: false
require 'test/unit'
require "-test-/typeddata/typeddata"
require "-test-/typeddata"

class Test_TypedData < Test::Unit::TestCase
def test_wrong_argtype
@@ -10,7 +10,7 @@ def test_wrong_argtype

assert_raise_with_message(TypeError, "wrong argument type Symbol (expected typed_data)") {Bug::TypedData.check(:e)}

assert_raise_with_message(TypeError, "wrong argument type Fixnum (expected typed_data)") {Bug::TypedData.check(0)}
assert_raise_with_message(TypeError, "wrong argument type Integer (expected typed_data)") {Bug::TypedData.check(0)}

assert_raise_with_message(TypeError, "wrong argument type String (expected typed_data)") {Bug::TypedData.check("a")}

Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
require 'test/unit'

class TestWaitForSingleFD < Test::Unit::TestCase
require '-test-/wait_for_single_fd/wait_for_single_fd'
require '-test-/wait_for_single_fd'

def with_pipe
r, w = IO.pipe
14 changes: 9 additions & 5 deletions test/mri/-ext-/win32/test_dln.rb
Original file line number Diff line number Diff line change
@@ -8,15 +8,19 @@ module Win32
class TestDln < Test::Unit::TestCase
def test_check_imported
bug = '[Bug #6303]'
assert_in_out_err(['-r-test-/win32/dln', '-eexit'], '', [], [], bug, timeout: 10)
so = ::File.expand_path("../ext/-test-/win32/dln/dlntest.dll", ::EnvUtil.rubybin)
assert_send([::File, :file?, so])
path = ::ENV['PATH']
path = ::File.dirname(so) + ::RbConfig::CONFIG["PATH_SEPARATOR"] + path
assert_in_out_err([{'PATH'=>path}, '-r-test-/win32/dln', '-eexit'], '', [], [], bug, timeout: 10)
end

def test_nonascii_load
bug9699 = '[ruby-core:61845] [Bug #9699]'
so = "-test-/dln/empty." + RbConfig::CONFIG["DLEXT"]
so = "-test-/dln/empty." + ::RbConfig::CONFIG["DLEXT"]
so = $:.find {|d| d = ::File.join(d, so); break d if ::File.exist?(d)}
assert_not_nil(so)
Dir.mkdir(dir = ::File.join(testdir = Dir.mktmpdir("test"), "\u{30c6 30b9 30c8}"))
::Dir.mkdir(dir = ::File.join(testdir = ::Dir.mktmpdir("test"), "\u{30c6 30b9 30c8}"))
::File.copy_stream(so, ::File.join(dir, ::File.basename(so)))
assert_separately(['-', bug9699, testdir, ::File.basename(so)], <<-'end;')
bug, dir, so = *ARGV
@@ -26,8 +30,8 @@ def test_nonascii_load
end;
ensure
::File.unlink(::File.join(dir, ::File.basename(so))) rescue nil
Dir.rmdir(dir) rescue nil
Dir.rmdir(testdir) rescue nil
::Dir.rmdir(dir) rescue nil
::Dir.rmdir(testdir) rescue nil
end

end
18 changes: 18 additions & 0 deletions test/mri/bigdecimal/test_bigdecimal.rb
Original file line number Diff line number Diff line change
@@ -459,6 +459,18 @@ def test_cmp_nan
assert_equal(false, BigDecimal.new("NaN") > n1)
end

def test_cmp_float_nan
assert_equal(nil, BigDecimal.new("1") <=> Float::NAN)
end

def test_cmp_float_pos_inf
assert_equal(-1, BigDecimal.new("1") <=> Float::INFINITY)
end

def test_cmp_float_neg_inf
assert_equal(+1, BigDecimal.new("1") <=> -Float::INFINITY)
end

def test_cmp_failing_coercion
n1 = BigDecimal.new("1")
assert_equal(nil, n1 <=> nil)
@@ -795,6 +807,12 @@ def test_div_bigdecimal
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
assert_equal(0, BigDecimal("0").div(BigDecimal("Infinity")))
end

x = BigDecimal.new("1")
y = BigDecimal.new("0.22")
(2..20).each do |i|
assert_equal ("0."+"45"*(i/2)+"5"*(i%2)+"E1"), x.div(y, i).to_s, "#{i}"
end
end

def test_abs_bigdecimal
7 changes: 5 additions & 2 deletions test/mri/cgi/test_cgi_cookie.rb
Original file line number Diff line number Diff line change
@@ -88,9 +88,12 @@ def test_cgi_cookie_parse
assert_equal(name, cookie.name)
assert_equal(value, cookie.value)
end
## ',' separator
cookie_str = 'name1=val1&val2, name2=val2&%26%3C%3E%22&%E3%82%86%E3%82%93%E3%82%86%E3%82%93,_session_id=12345'
## don't allow ',' separator
cookie_str = 'name1=val1&val2, name2=val2'
cookies = CGI::Cookie.parse(cookie_str)
list = [
['name1', ['val1', 'val2, name2=val2']],
]
list.each do |name, value|
cookie = cookies[name]
assert_equal(name, cookie.name)
2 changes: 1 addition & 1 deletion test/mri/cgi/test_cgi_header.rb
Original file line number Diff line number Diff line change
@@ -147,7 +147,7 @@ def test_cgi_http_header_nph
date = /^Date: ([A-Z][a-z]{2}, \d{2} [A-Z][a-z]{2} \d{4} \d\d:\d\d:\d\d GMT)\r\n/
[actual1, actual2, actual3].each do |actual|
assert_match(date, actual)
assert_includes(time_start..time_end, date =~ actual && Time.parse($1).to_i)
assert_include(time_start..time_end, date =~ actual && Time.parse($1).to_i)
actual.sub!(date, "Date: DATE_IS_REMOVED\r\n")
end
## assertion
37 changes: 37 additions & 0 deletions test/mri/cgi/test_cgi_util.rb
Original file line number Diff line number Diff line change
@@ -98,6 +98,43 @@ def test_cgi_unescapeHTML
assert_equal("'&\"><", CGI::unescapeHTML("&#39;&amp;&quot;&gt;&lt;"))
end

def test_cgi_unescapeHTML_invalid
assert_equal('&<&amp>&quot&abcdefghijklmn', CGI::unescapeHTML('&&lt;&amp&gt;&quot&abcdefghijklmn'))
end

Encoding.list.each do |enc|
begin
escaped = "&#39;&amp;&quot;&gt;&lt;".encode(enc)
unescaped = "'&\"><".encode(enc)
rescue Encoding::ConverterNotFoundError
next
else
define_method("test_cgi_escapeHTML:#{enc.name}") do
assert_equal(escaped, CGI::escapeHTML(unescaped))
end
define_method("test_cgi_unescapeHTML:#{enc.name}") do
assert_equal(unescaped, CGI::unescapeHTML(escaped))
end
end
end

Encoding.list.each do |enc|
next unless enc.ascii_compatible?
begin
escaped = "%25+%2B"
unescaped = "% +".encode(enc)
rescue Encoding::ConverterNotFoundError
next
else
define_method("test_cgi_escape:#{enc.name}") do
assert_equal(escaped, CGI::escape(unescaped))
end
define_method("test_cgi_unescape:#{enc.name}") do
assert_equal(unescaped, CGI::unescape(escaped, enc))
end
end
end

def test_cgi_unescapeHTML_uppercasecharacter
assert_equal("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86", CGI::unescapeHTML("&#x3042;&#x3044;&#X3046;"))
end
32 changes: 20 additions & 12 deletions test/mri/coverage/test_coverage.rb
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@ def test_coverage_snapshot
Dir.chdir(tmp) {
File.open("test.rb", "w") do |f|
f.puts <<-EOS
def coverage_test_method
def TestCoverage.coverage_test_snapshot
:ok
end
EOS
@@ -38,7 +38,7 @@ def coverage_test_method
Coverage.start
require tmp + '/test.rb'
cov = Coverage.peek_result[tmp + '/test.rb']
coverage_test_method
TestCoverage.coverage_test_snapshot
cov2 = Coverage.peek_result[tmp + '/test.rb']
assert_equal cov[1] + 1, cov2[1]
assert_equal cov2, Coverage.result[tmp + '/test.rb']
@@ -55,36 +55,35 @@ def test_restarting_coverage
Dir.chdir(tmp) {
File.open("test.rb", "w") do |f|
f.puts <<-EOS
def coverage_test_method
def TestCoverage.coverage_test_restarting
:ok
end
EOS
end

File.open("test2.rb", "w") do |f|
f.puts <<-EOS
def coverage_test_method2
:ok
:ok
end
itself
EOS
end

Coverage.start
require tmp + '/test.rb'
assert_equal 3, Coverage.result[tmp + '/test.rb'].size
cov = { "#{tmp}/test.rb" => [1, 0, nil] }
assert_equal cov, Coverage.result

# Restart coverage but '/test.rb' is required before restart,
# so coverage is not recorded.
Coverage.start
coverage_test_method
assert_equal 0, Coverage.result[tmp + '/test.rb'].size
TestCoverage.coverage_test_restarting
assert_equal({}, Coverage.result)

# Restart coverage and '/test2.rb' is required after restart,
# so coverage is recorded.
Coverage.start
require tmp + '/test2.rb'
assert_equal 4, Coverage.result[tmp + '/test2.rb'].size
cov = { "#{tmp}/test2.rb" => [1] }
assert_equal cov, Coverage.result
}
}
ensure
@@ -111,4 +110,13 @@ def test_big_code
ensure
$".replace loaded_features
end
end

def test_nonpositive_linenumber
bug12517 = '[ruby-core:76141] [Bug #12517]'
Coverage.start
assert_nothing_raised(ArgumentError, bug12517) do
RubyVM::InstructionSequence.compile(":ok", nil, "<compiled>", 0)
end
assert_include Coverage.result, "<compiled>"
end
end unless ENV['COVERAGE']
6 changes: 3 additions & 3 deletions test/mri/csv/test_data_converters.rb
Original file line number Diff line number Diff line change
@@ -105,7 +105,7 @@ def test_convert_order_integer_float
end

# gives us proper number conversion
assert_equal( [String, String, Fixnum, String, Float],
assert_equal( [String, String, Integer, String, Float],
@parser.shift.map { |field| field.class } )
end

@@ -114,7 +114,7 @@ def test_builtin_numeric_combo_converter
assert_nothing_raised(Exception) { @parser.convert(:numeric) }

# and use
assert_equal( [String, String, Fixnum, String, Float],
assert_equal( [String, String, Integer, String, Float],
@parser.shift.map { |field| field.class } )
end

@@ -125,7 +125,7 @@ def test_builtin_all_nested_combo_converter
assert_nothing_raised(Exception) { @parser.convert(:all) }

# and use
assert_equal( [String, String, Fixnum, String, Float, DateTime],
assert_equal( [String, String, Integer, String, Float, DateTime],
@parser.shift.map { |field| field.class } )
end

23 changes: 23 additions & 0 deletions test/mri/csv/test_features.rb
Original file line number Diff line number Diff line change
@@ -142,6 +142,29 @@ def test_skip_blanks
assert_equal(3, count)
end

def test_liberal_parsing
input = '"Johnson, Dwayne",Dwayne "The Rock" Johnson'
assert_raise(CSV::MalformedCSVError) do
CSV.parse_line(input)
end
assert_equal(["Johnson, Dwayne", 'Dwayne "The Rock" Johnson'],
CSV.parse_line(input, liberal_parsing: true))

input = '"quoted" field'
assert_raise(CSV::MalformedCSVError) do
CSV.parse_line(input)
end
assert_equal(['"quoted" field'],
CSV.parse_line(input, liberal_parsing: true))

assert_raise(CSV::MalformedCSVError) do
CSV.parse_line('is,this "three," or four,fields', liberal_parsing: true)
end

assert_equal(["is", 'this "three', ' or four"', "fields"],
CSV.parse_line('is,this "three, or four",fields', liberal_parsing: true))
end

def test_csv_behavior_readers
%w[ unconverted_fields return_headers write_headers
skip_blanks force_quotes ].each do |behavior|
25 changes: 23 additions & 2 deletions test/mri/csv/test_row.rb
Original file line number Diff line number Diff line change
@@ -209,9 +209,20 @@ def test_delete
# by header
assert_equal(["C", 3], @row.delete("C"))

# using a block
end

def test_delete_if
assert_equal(@row, @row.delete_if { |h, f| h == "A" and not f.nil? })
assert_equal([["A", nil]], @row.to_a)
assert_equal([["B", 2], ["C", 3], ["A", nil]], @row.to_a)
end

def test_delete_if_without_block
enum = @row.delete_if
assert_instance_of(Enumerator, enum)
assert_equal(@row.size, enum.size)

assert_equal(@row, enum.each { |h, f| h == "A" and not f.nil? })
assert_equal([["B", 2], ["C", 3], ["A", nil]], @row.to_a)
end

def test_fields
@@ -281,6 +292,16 @@ def test_each

# verify that we can chain the call
assert_equal(@row, @row.each { })

# without block
ary = @row.to_a
enum = @row.each
assert_instance_of(Enumerator, enum)
assert_equal(@row.size, enum.size)
enum.each do |pair|
assert_equal(ary.first.first, pair.first)
assert_equal(ary.shift.last, pair.last)
end
end

def test_enumerable
59 changes: 59 additions & 0 deletions test/mri/csv/test_table.rb
Original file line number Diff line number Diff line change
@@ -220,6 +220,17 @@ def test_each
# verify that we can chain the call
assert_equal(@table, @table.each { })

# without block
enum = @table.each
assert_instance_of(Enumerator, enum)
assert_equal(@table.size, enum.size)

i = 0
enum.each do |row|
assert_equal(@rows[i], row)
i += 1
end

###################
### Column Mode ###
###################
@@ -231,6 +242,17 @@ def test_each
assert_equal(@table[header], column)
end

# without block
enum = @table.each
assert_instance_of(Enumerator, enum)
assert_equal(@table.headers.size, enum.size)

headers = @table.headers
enum.each do |header, column|
assert_equal(headers.shift, header)
assert_equal(@table[header], column)
end

############################
### One Shot Mode Change ###
############################
@@ -363,6 +385,24 @@ def test_delete_if_row
END_RESULT
end

def test_delete_if_row_without_block
######################
### Mixed/Row Mode ###
######################
enum = @table.delete_if
assert_instance_of(Enumerator, enum)
assert_equal(@table.size, enum.size)

# verify that we can chain the call
assert_equal(@table, enum.each { |row| (row["B"] % 2).zero? })

# verify resulting table
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
A,B,C
4,5,6
END_RESULT
end

def test_delete_if_column
###################
### Column Mode ###
@@ -378,6 +418,25 @@ def test_delete_if_column
END_RESULT
end

def test_delete_if_column_without_block
###################
### Column Mode ###
###################
@table.by_col!

enum = @table.delete_if
assert_instance_of(Enumerator, enum)
assert_equal(@table.headers.size, enum.size)

assert_equal(@table, enum.each { |h, v| h > "A" })
assert_equal(<<-END_RESULT.gsub(/^\s+/, ""), @table.to_csv)
A
1
4
7
END_RESULT
end

def test_values_at
##################
### Mixed Mode ###
2 changes: 1 addition & 1 deletion test/mri/date/test_date.rb
Original file line number Diff line number Diff line change
@@ -135,7 +135,7 @@ def test_freeze
d = Date.new
d.freeze
assert_equal(true, d.frozen?)
assert_instance_of(Fixnum, d.yday)
assert_instance_of(Integer, d.yday)
assert_instance_of(String, d.to_s)
end

25 changes: 20 additions & 5 deletions test/mri/date/test_date_conv.rb
Original file line number Diff line number Diff line change
@@ -3,6 +3,15 @@
require 'date'

class TestDateConv < Test::Unit::TestCase
def with_tz(tz)
old = ENV["TZ"]
begin
ENV["TZ"] = tz
yield
ensure
ENV["TZ"] = old
end
end

def test_to_class
[Time.now, Date.today, DateTime.now].each do |o|
@@ -22,6 +31,14 @@ def test_to_time__from_time
t2 = t.to_time.utc
assert_equal([2004, 9, 19, 1, 2, 3, 456789],
[t2.year, t2.mon, t2.mday, t2.hour, t2.min, t2.sec, t2.usec])

t = Time.new(2004, 9, 19, 1, 2, 3, '+03:00')
with_tz('Asia/Tokyo') do
t2 = t.to_time
assert_equal([2004, 9, 19, 1, 2, 3],
[t2.year, t2.mon, t2.mday, t2.hour, t2.min, t2.sec])
assert_equal(3 * 60 * 60, t2.gmt_offset)
end
end

def test_to_time__from_date
@@ -32,12 +49,10 @@ def test_to_time__from_date
end

def test_to_time__from_datetime
d = DateTime.new(2004, 9, 19, 1, 2, 3, 9.to_r/24) + 456789.to_r/86400000000
d = DateTime.new(2004, 9, 19, 1, 2, 3, 8.to_r/24) + 456789.to_r/86400000000
t = d.to_time
if t.utc_offset == 9*60*60
assert_equal([2004, 9, 19, 1, 2, 3, 456789],
[t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec])
end
assert_equal([2004, 9, 19, 1, 2, 3, 456789, 8*60*60],
[t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec, t.utc_offset])

d = DateTime.new(2004, 9, 19, 1, 2, 3, 0) + 456789.to_r/86400000000
t = d.to_time.utc
8 changes: 8 additions & 0 deletions test/mri/date/test_date_strftime.rb
Original file line number Diff line number Diff line change
@@ -420,4 +420,12 @@ def test__different_format

end

def test_overflow
assert_raise(ArgumentError, Errno::ERANGE) {
Date.new(2000,1,1).strftime("%2147483647c")
}
assert_raise(ArgumentError, Errno::ERANGE) {
DateTime.new(2000,1,1).strftime("%2147483647c")
}
end
end
2 changes: 1 addition & 1 deletion test/mri/dbm/test_dbm.rb
Original file line number Diff line number Diff line change
@@ -219,7 +219,7 @@ def test_aset
num += 1 if i == 0
assert_equal(num, @dbm.size)

# Fixnum
# Integer
assert_equal('200', @dbm['100'] = '200')
assert_equal('200', @dbm['100'])

16 changes: 11 additions & 5 deletions test/mri/digest/test_digest.rb
Original file line number Diff line number Diff line change
@@ -154,17 +154,21 @@ class TestSHA384 < Test::Unit::TestCase
include TestDigest
ALGO = Digest::SHA384
DATA = {
Data1 => "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7",
Data2 => "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b",
Data1 => "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"\
"8086072ba1e7cc2358baeca134c825a7",
Data2 => "3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6"\
"b0455a8520bc4e6f5fe95b1fe3c8452b",
}
end if defined?(Digest::SHA384)

class TestSHA512 < Test::Unit::TestCase
include TestDigest
ALGO = Digest::SHA512
DATA = {
Data1 => "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
Data2 => "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445",
Data1 => "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"\
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f",
Data2 => "204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c335"\
"96fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445",
}
end if defined?(Digest::SHA512)

@@ -176,7 +180,9 @@ def test_s_file
tmpfile.print str
tmpfile.close

assert_equal "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", Digest::SHA2.file(tmpfile.path, 384).hexdigest
assert_equal "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed"\
"8086072ba1e7cc2358baeca134c825a7",
Digest::SHA2.file(tmpfile.path, 384).hexdigest
}
end

7 changes: 3 additions & 4 deletions test/mri/drb/drbtest.rb
Original file line number Diff line number Diff line change
@@ -3,17 +3,16 @@
require 'drb/drb'
require 'drb/extservm'
require 'timeout'
require 'shellwords'

module DRbTests

class DRbService
@@manager = DRb::ExtServManager.new
@@ruby = Shellwords.escape(EnvUtil.rubybin)
@@ruby += " -d" if $DEBUG
@@ruby = [EnvUtil.rubybin]
@@ruby << "-d" if $DEBUG
def self.add_service_command(nm)
dir = File.dirname(File.expand_path(__FILE__))
DRb::ExtServManager.command[nm] = [@@ruby, "#{dir}/#{nm}"]
DRb::ExtServManager.command[nm] = @@ruby + ["#{dir}/#{nm}"]
end

%w(ut_drb.rb ut_array.rb ut_port.rb ut_large.rb ut_safe1.rb ut_eval.rb ut_eq.rb).each do |nm|
42 changes: 42 additions & 0 deletions test/mri/drb/test_drb.rb
Original file line number Diff line number Diff line change
@@ -306,11 +306,18 @@ def test_01_large_ary
ary = [2] * 10240
assert_equal(10240, @there.size(ary))
assert_equal(20480, @there.sum(ary))
assert_equal(2 ** 10240, @there.multiply(ary))
assert_equal(2, @there.avg(ary))
assert_equal(2, @there.median(ary))
end

def test_02_large_ary
ary = ["Hello, World"] * 10240
assert_equal(10240, @there.size(ary))
assert_equal(ary[0..ary.length].inject(:+), @there.sum(ary))
assert_raise (TypeError) {@there.multiply(ary)}
assert_raise (TypeError) {@there.avg(ary)}
assert_raise (TypeError) {@there.median(ary)}
end

def test_03_large_ary
@@ -334,6 +341,41 @@ def test_05_too_large_ary
end
assert_kind_of(StandardError, exception)
end

def test_06_array_operations
ary = [1,50,3,844,7,45,23]
assert_equal(7, @there.size(ary))
assert_equal(973, @there.sum(ary))
assert_equal(917217000, @there.multiply(ary))
assert_equal(139.0, @there.avg(ary))
assert_equal(23.0, @there.median(ary))

ary2 = [1,2,3,4]
assert_equal(4, @there.size(ary2))
assert_equal(10, @there.sum(ary2))
assert_equal(24, @there.multiply(ary2))
assert_equal(2.5, @there.avg(ary2))
assert_equal(2.5, @there.median(ary2))

end

def test_07_one_element_array
ary = [50]
assert_equal(1, @there.size(ary))
assert_equal(50, @there.sum(ary))
assert_equal(50, @there.multiply(ary))
assert_equal(50.0, @there.avg(ary))
assert_equal(50.0, @there.median(ary))
end

def test_08_empty_array
ary = []
assert_equal(0, @there.size(ary))
assert_equal(nil, @there.sum(ary))
assert_equal(nil, @there.multiply(ary))
assert_equal(nil, @there.avg(ary))
assert_equal(nil, @there.median(ary))
end
end

class TestBug4409 < Test::Unit::TestCase
2 changes: 0 additions & 2 deletions test/mri/drb/ut_array_drbssl.rb
Original file line number Diff line number Diff line change
@@ -20,8 +20,6 @@ module DRbTests
-----END DH PARAMETERS-----
_end_of_pem_

TEST_KEY_DH1024.priv_key = OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16)

end

config = Hash.new
2 changes: 0 additions & 2 deletions test/mri/drb/ut_drb_drbssl.rb
Original file line number Diff line number Diff line change
@@ -19,8 +19,6 @@ module DRbTests
-----END DH PARAMETERS-----
_end_of_pem_

TEST_KEY_DH1024.priv_key = OpenSSL::BN.new("48561834C67E65FFD2A9B47F41E5E78FDC95C387428FDB1E4B0188B64D1643C3A8D3455B945B7E8C4D166010C7C2CE23BFB9BEF43D0348FE7FA5284B0225E7FE1537546D114E3D8A4411B9B9351AB451E1A358F50ED61B1F00DA29336EEBBD649980AC86D76AF8BBB065298C2052672EEF3EF13AB47A15275FC2836F3AC74CEA", 16)

end

config = Hash.new
26 changes: 22 additions & 4 deletions test/mri/drb/ut_large.rb
Original file line number Diff line number Diff line change
@@ -13,11 +13,29 @@ def size(ary)
end

def sum(ary)
sum = 0
ary.each do |e|
sum += e.to_i
ary.inject(:+)
end

def multiply(ary)
ary.inject(:*)
end

def avg(ary)
return if ary.empty?
if ary.any? {|n| n.is_a? String}
raise TypeError
else
sum(ary).to_f / ary.count
end
end

def median(ary)
return if ary.empty?
if ary.any? {|n| n.is_a? String}
raise TypeError
else
avg ary.sort[((ary.length - 1) / 2)..(ary.length / 2)]
end
sum
end

def arg_test(*arg)
102 changes: 61 additions & 41 deletions test/mri/drb/ut_timerholder.rb
Original file line number Diff line number Diff line change
@@ -1,54 +1,74 @@
# frozen_string_literal: false
require 'runit/testcase'
require 'runit/cui/testrunner'
require 'timerholder'
require 'test/unit'
require 'drb/timeridconv'

module DRbTests

class TimerHolderTest < RUNIT::TestCase
def do_test(timeout, keeper_sleep = nil)
holder = TimerHolder.new(timeout)
holder.keeper_sleep = keeper_sleep if keeper_sleep
key = holder.add(self)
sleep(timeout * 0.5)
assert_equal(holder.peek(key), self)
holder.delete(key)
assert(!holder.include?(key))
key = holder.add(self)
sleep(timeout+0.5)
assert_equal(holder.fetch(key), nil)
key = holder.add(self)
assert_equal(holder.fetch(key), self)
holder.store(key, true)
assert_equal(holder.fetch(key), true)
assert_equal(holder.include?(key), true)
sleep(timeout+0.5)
assert_exception(TimerHolder::InvalidIndexError) do
holder.store(key, 1)
class TimerIdConvTest < Test::Unit::TestCase
def test_usecase_01
keeping = 0.1
idconv = DRb::TimerIdConv.new(keeping)

key = idconv.to_id(self)
assert_equal(key, self.__id__)
sleep(keeping)
assert_equal(idconv.to_id(false), false.__id__)
assert_equal(idconv.to_obj(key), self)
sleep(keeping)

assert_equal(idconv.to_obj(key), self)
sleep(keeping)

assert_equal(idconv.to_id(true), true.__id__)
sleep(keeping)

assert_raise do
assert_equal(idconv.to_obj(key), self)
end

assert_raise do
assert_equal(idconv.to_obj(false.__id__), false)
end
assert_equal(holder.include?(key), false)
key = holder.add(self)
sleep(timeout * 0.5)
assert(holder.include?(key))
holder.extend(key, timeout)
sleep(timeout * 0.5)
assert(holder.include?(key))
sleep(timeout * 0.6)
assert(!holder.include?(key))
holder.delete(key)
end

def test_00
do_test(0.5)
key = idconv.to_id(self)
assert_equal(key, self.__id__)
assert_equal(idconv.to_id(true), true.__id__)
sleep(keeping)
GC.start
sleep(keeping)
GC.start
assert_raise do
assert_equal(idconv.to_obj(key), self)
end
end

def test_01
do_test(1, 0.5)
def test_usecase_02
keeping = 0.1
idconv = DRb::TimerIdConv.new(keeping)

key = idconv.to_id(self)
assert_equal(key, self.__id__)
sleep(keeping)
GC.start
sleep(keeping)
GC.start
assert_raise do
assert_equal(idconv.to_obj(key), self)
end
GC.start

key = idconv.to_id(self)
assert_equal(key, self.__id__)
sleep(keeping)
GC.start
sleep(keeping)
GC.start
assert_raise do
assert_equal(idconv.to_obj(key), self)
end
end
end

end

if __FILE__ == $0
RUNIT::CUI::TestRunner.run(DRbTests::TimerHolderTest.suite)
end

48 changes: 36 additions & 12 deletions test/mri/dtrace/helper.rb
Original file line number Diff line number Diff line change
@@ -10,11 +10,45 @@
else
ok = false
end
if ok
case RUBY_PLATFORM
when /darwin/i
begin
require 'pty'
rescue LoadError
ok = false
end
end
end
ok &= (`dtrace -V` rescue false)
module DTrace
class TestCase < Test::Unit::TestCase
INCLUDE = File.expand_path('..', File.dirname(__FILE__))

case RUBY_PLATFORM
when /solaris/i
# increase bufsize to 8m (default 4m on Solaris)
DTRACE_CMD = %w[dtrace -b 8m]
when /darwin/i
READ_PROBES = proc do |cmd|
lines = nil
PTY.spawn(*cmd) do |io, _, pid|
lines = io.readlines.each {|line| line.sub!(/\r$/, "")}
Process.wait(pid)
end
lines
end
end

DTRACE_CMD ||= %w[dtrace]

READ_PROBES ||= proc do |cmd|
IO.popen(cmd, err: [:child, :out], &:readlines)
end

exeext = Regexp.quote(RbConfig::CONFIG["EXEEXT"])
RUBYBIN = EnvUtil.rubybin.sub(/\/ruby-runner(?=#{exeext}\z)/, '/miniruby')

def trap_probe d_program, ruby_program
d = Tempfile.new(%w'probe .d')
d.write d_program
@@ -27,15 +61,7 @@ def trap_probe d_program, ruby_program
d_path = d.path
rb_path = rb.path

case RUBY_PLATFORM
when /solaris/i
# increase bufsize to 8m (default 4m on Solaris)
cmd = [ "dtrace", "-b", "8m" ]
else
cmd = [ "dtrace" ]
end

cmd.concat [ "-q", "-s", d_path, "-c", "#{EnvUtil.rubybin} -I#{INCLUDE} #{rb_path}"]
cmd = [*DTRACE_CMD, "-q", "-s", d_path, "-c", "#{RUBYBIN} -I#{INCLUDE} #{rb_path}"]
if sudo = @@sudo
[RbConfig::CONFIG["LIBPATHENV"], "RUBY", "RUBYOPT"].each do |name|
if name and val = ENV[name]
@@ -44,9 +70,7 @@ def trap_probe d_program, ruby_program
end
cmd.unshift(sudo)
end
probes = IO.popen(cmd, err: [:child, :out]) do |io|
io.readlines
end
probes = READ_PROBES.(cmd)
d.close(true)
rb.close(true)
yield(d_path, rb_path, probes)
6 changes: 3 additions & 3 deletions test/mri/dtrace/test_method_cache.rb
Original file line number Diff line number Diff line change
@@ -9,9 +9,9 @@ class String; end
class String; def abc() end end
class Object; def abc() end end
code
assert_not_includes lines, "String #{rbfile} 1\n"
assert_includes lines, "String #{rbfile} 2\n"
assert_includes lines, "global #{rbfile} 3\n"
assert_not_include lines, "String #{rbfile} 1\n"
assert_include lines, "String #{rbfile} 2\n"
assert_include lines, "global #{rbfile} 3\n"
end
end

131 changes: 93 additions & 38 deletions test/mri/erb/test_erb.rb
Original file line number Diff line number Diff line change
@@ -203,13 +203,13 @@ def test_def_class
erb = @erb.new('hello')
cls = erb.def_class
assert_equal(Object, cls.superclass)
assert(cls.new.respond_to?('result'))
assert_respond_to(cls.new, 'result')
cls = erb.def_class(Foo)
assert_equal(Foo, cls.superclass)
assert(cls.new.respond_to?('result'))
assert_respond_to(cls.new, 'result')
cls = erb.def_class(Object, 'erb')
assert_equal(Object, cls.superclass)
assert(cls.new.respond_to?('erb'))
assert_respond_to(cls.new, 'erb')
end

def test_percent
@@ -262,21 +262,21 @@ def test_def_erb_method
fname = File.join(File.dirname(File.expand_path(__FILE__)), 'hello.erb')
def_erb_method('hello', fname)
end
assert(klass.new.respond_to?('hello'))
assert_respond_to(klass.new, 'hello')

assert(! klass.new.respond_to?('hello_world'))
assert_not_respond_to(klass.new, 'hello_world')
erb = @erb.new('hello, world')
klass.module_eval do
def_erb_method('hello_world', erb)
end
assert(klass.new.respond_to?('hello_world'))
assert_respond_to(klass.new, 'hello_world')
end

def test_def_method_without_filename
klass = Class.new
erb = ERB.new("<% raise ::TestERB::MyError %>")
erb.filename = "test filename"
assert(! klass.new.respond_to?('my_error'))
assert_not_respond_to(klass.new, 'my_error')
erb.def_method(klass, 'my_error')
e = assert_raise(::TestERB::MyError) {
klass.new.my_error
@@ -288,7 +288,7 @@ def test_def_method_with_fname
klass = Class.new
erb = ERB.new("<% raise ::TestERB::MyError %>")
erb.filename = "test filename"
assert(! klass.new.respond_to?('my_error'))
assert_not_respond_to(klass.new, 'my_error')
erb.def_method(klass, 'my_error', 'test fname')
e = assert_raise(::TestERB::MyError) {
klass.new.my_error
@@ -342,12 +342,10 @@ def test_keep_lineno
EOS

erb = ERB.new(src, nil, '%')
begin
e = assert_raise(RuntimeError) {
erb.result
assert(false)
rescue
assert_match(/\A\(erb\):4\b/, $@[0].to_s)
end
}
assert_match(/\A\(erb\):4\b/, e.backtrace[0].to_s)

src = <<EOS
%>
@@ -389,28 +387,22 @@ def test_keep_lineno
EOS

erb = ERB.new(src)
begin
e = assert_raise(RuntimeError) {
erb.result
assert(false)
rescue
assert_match(/\A\(erb\):5\b/, $@[0].to_s)
end
}
assert_match(/\A\(erb\):5\b/, e.backtrace[0].to_s)

erb = ERB.new(src, nil, '>')
begin
e = assert_raise(RuntimeError) {
erb.result
assert(false)
rescue
assert_match(/\A\(erb\):5\b/, $@[0].to_s)
end
}
assert_match(/\A\(erb\):5\b/, e.backtrace[0].to_s)

erb = ERB.new(src, nil, '<>')
begin
e = assert_raise(RuntimeError) {
erb.result
assert(false)
rescue
assert_match(/\A\(erb\):5\b/, $@[0].to_s)
end
}
assert_match(/\A\(erb\):5\b/, e.backtrace[0].to_s)

src = <<EOS
% y = 'Hello'
@@ -421,20 +413,16 @@ def test_keep_lineno
EOS

erb = ERB.new(src, nil, '-')
begin
e = assert_raise(RuntimeError) {
erb.result
assert(false)
rescue
assert_match(/\A\(erb\):5\b/, $@[0].to_s)
end
}
assert_match(/\A\(erb\):5\b/, e.backtrace[0].to_s)

erb = ERB.new(src, nil, '%-')
begin
e = assert_raise(RuntimeError) {
erb.result
assert(false)
rescue
assert_match(/\A\(erb\):5\b/, $@[0].to_s)
end
}
assert_match(/\A\(erb\):5\b/, e.backtrace[0].to_s)
end

def test_explicit
@@ -481,6 +469,73 @@ def test_url_encode
def test_percent_after_etag
assert_equal("1%", @erb.new("<%= 1 %>%", nil, "%").result)
end

def test_token_extension
extended_erb = Class.new(ERB)
extended_erb.module_eval do
def make_compiler(trim_mode)
compiler = Class.new(ERB::Compiler)
compiler.module_eval do
def compile_stag(stag, out, scanner)
case stag
when '<%=='
scanner.stag = stag
add_put_cmd(out, content) if content.size > 0
self.content = ''
else
super
end
end

def compile_content(stag, out)
case stag
when '<%=='
out.push("#{@insert_cmd}(::ERB::Util.html_escape(#{content}))")
else
super
end
end

def make_scanner(src)
scanner = Class.new(ERB::Compiler::SimpleScanner)
scanner.module_eval do
def stags
['<%=='] + super
end
end
scanner.new(src, @trim_mode, @percent)
end
end
compiler.new(trim_mode)
end
end

src = <<~EOS
<% tag = '<>' \%>
<\%= tag \%>
<\%== tag \%>
EOS
ans = <<~EOS
<>
&lt;&gt;
EOS
assert_equal(ans, extended_erb.new(src).result)
end

def test_frozen_string_literal
bug12031 = '[ruby-core:73561] [Bug #12031]'
e = @erb.new("<%#encoding: us-ascii%>a")
e.src.sub!(/\A#(?:-\*-)?(.*)(?:-\*-)?/) {
'# -*- \1; frozen-string-literal: true -*-'
}
assert_equal("a", e.result, bug12031)

%w(false true).each do |flag|
erb = @erb.new("<%#frozen-string-literal: #{flag}%><%=''.frozen?%>")
assert_equal(flag, erb.result)
end
end
end

class TestERBCoreWOStrScan < TestERBCore
8 changes: 8 additions & 0 deletions test/mri/fiddle/test_handle.rb
Original file line number Diff line number Diff line change
@@ -182,5 +182,13 @@ def test_dlerror
def test_no_memory_leak
assert_no_memory_leak(%w[-W0 -rfiddle.so], '', '100_000.times {Fiddle::Handle.allocate}; GC.start', rss: true)
end

if /cygwin|mingw|mswin/ =~ RUBY_PLATFORM
def test_fallback_to_ansi
k = Fiddle::Handle.new("kernel32.dll")
ansi = k["GetFileAttributesA"]
assert_equal(ansi, k["GetFileAttributes"], "should fallback to ANSI version")
end
end
end
end if defined?(Fiddle)
6 changes: 3 additions & 3 deletions test/mri/fiddle/test_pointer.rb
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ def test_malloc_free_func
end

def test_to_str
str = "hello world"
str = Marshal.load(Marshal.dump("hello world"))
ptr = Pointer[str]

assert_equal 3, ptr.to_str(3).length
@@ -46,7 +46,7 @@ def test_to_str
end

def test_to_s
str = "hello world"
str = Marshal.load(Marshal.dump("hello world"))
ptr = Pointer[str]

assert_equal 3, ptr.to_s(3).length
@@ -202,7 +202,7 @@ def test_aref_aset
assert_equal(str[0].ord, ptr[0])
assert_equal(str[1].ord, ptr[1])
}
str = 'abc'
str = Marshal.load(Marshal.dump('abc'))
ptr = Pointer[str]
check.call(str, ptr)

30 changes: 24 additions & 6 deletions test/mri/fileutils/test_fileutils.rb
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
require 'test/unit'

class TestFileUtils < Test::Unit::TestCase
TMPROOT = "#{Dir.tmpdir}/fileutils.rb.#{$$}"
include Test::Unit::FileAssertions

def assert_output_lines(expected, fu = self, message=nil)
@@ -96,8 +95,7 @@ def distinct_uids(n = 2)
end

begin
tmproot = TMPROOT
Dir.mkdir tmproot unless File.directory?(tmproot)
tmproot = Dir.mktmpdir "fileutils"
Dir.chdir tmproot do
Dir.mkdir("\n")
Dir.rmdir("\n")
@@ -145,8 +143,7 @@ def mymkdir(path)
def setup
@prevdir = Dir.pwd
@groups = Process.groups if have_file_perm?
tmproot = TMPROOT
mymkdir tmproot unless File.directory?(tmproot)
tmproot = @tmproot = Dir.mktmpdir "fileutils"
Dir.chdir tmproot
my_rm_rf 'data'; mymkdir 'data'
my_rm_rf 'tmp'; mymkdir 'tmp'
@@ -155,7 +152,7 @@ def setup

def teardown
Dir.chdir @prevdir
my_rm_rf TMPROOT
my_rm_rf @tmproot
end


@@ -364,6 +361,11 @@ def test_cp_r
assert_raise(ArgumentError, bug3588) do
cp_r 'tmp2', 'tmp2/new_tmp2'
end

bug12892 = '[ruby-core:77885] [Bug #12892]'
assert_raise(Errno::ENOENT, bug12892) do
cp_r 'non/existent', 'tmp'
end
end

def test_cp_r_symlink
@@ -968,6 +970,22 @@ def test_install_pathname
}
end

def test_install_owner_option
File.open('tmp/aaa', 'w') {|f| f.puts 'aaa' }
File.open('tmp/bbb', 'w') {|f| f.puts 'bbb' }
assert_nothing_raised {
install 'tmp/aaa', 'tmp/bbb', :owner => "nobody", :noop => true
}
end

def test_install_group_option
File.open('tmp/aaa', 'w') {|f| f.puts 'aaa' }
File.open('tmp/bbb', 'w') {|f| f.puts 'bbb' }
assert_nothing_raised {
install 'tmp/aaa', 'tmp/bbb', :group => "nobody", :noop => true
}
end

def test_chmod
check_singleton :chmod

2 changes: 1 addition & 1 deletion test/mri/gdbm/test_gdbm.rb
Original file line number Diff line number Diff line change
@@ -273,7 +273,7 @@ def test_aset
num += 1 if i == 0
assert_equal(num, @gdbm.size)

# Fixnum
# Integer
assert_equal('200', @gdbm['100'] = '200')
assert_equal('200', @gdbm['100'])

26 changes: 22 additions & 4 deletions test/mri/io/console/test_io_console.rb
Original file line number Diff line number Diff line change
@@ -7,6 +7,9 @@
end

class TestIO_Console < Test::Unit::TestCase
end

defined?(PTY) and defined?(IO.console) and TestIO_Console.class_eval do
Bug6116 = '[ruby-dev:45309]'

def test_raw
@@ -294,9 +297,9 @@ def run_pty(src, n = 1)
w.close if w
Process.wait(pid) if pid
end
end if defined?(PTY) and defined?(IO::console)
end

class TestIO_Console < Test::Unit::TestCase
defined?(IO.console) and TestIO_Console.class_eval do
case
when Process.respond_to?(:daemon)
noctty = [EnvUtil.rubybin, "-e", "Process.daemon(true)"]
@@ -335,9 +338,24 @@ def test_noctty
t2.close!
end
end
end if defined?(IO.console)
end

class TestIO_Console < Test::Unit::TestCase
defined?(IO.console) and IO.console and IO.console.respond_to?(:pressed?) and
TestIO_Console.class_eval do
def test_pressed_valid
assert_include([true, false], IO.console.pressed?("HOME"))
assert_include([true, false], IO.console.pressed?(:"HOME"))
end

def test_pressed_invalid
e = assert_raise(ArgumentError) do
IO.console.pressed?("HOME\0")
end
assert_match(/unknown virtual key code/, e.message)
end
end

TestIO_Console.class_eval do
def test_stringio_getch
assert_separately %w"--disable=gems -rstringio -rio/console", %q{
assert_operator(StringIO, :method_defined?, :getch)
56 changes: 53 additions & 3 deletions test/mri/io/wait/test_io_wait.rb
Original file line number Diff line number Diff line change
@@ -37,16 +37,16 @@ def test_nread_buffered
end

def test_ready?
refute @r.ready?, "shouldn't ready, but ready"
assert_not_predicate @r, :ready?, "shouldn't ready, but ready"
@w.syswrite "."
sleep 0.1
assert @r.ready?, "should ready, but not"
assert_predicate @r, :ready?, "should ready, but not"
end

def test_buffered_ready?
@w.syswrite ".\n!"
assert_equal ".\n", @r.gets
assert @r.ready?
assert_predicate @r, :ready?
end

def test_wait
@@ -80,6 +80,37 @@ def test_wait_eof
th.join
end

def test_wait_readable
assert_nil @r.wait_readable(0)
@w.syswrite "."
sleep 0.1
assert_equal @r, @r.wait_readable(0)
end

def test_wait_readable_buffered
@w.syswrite ".\n!"
assert_equal ".\n", @r.gets
assert_equal true, @r.wait_readable(0)
end

def test_wait_readable_forever
th = Thread.new { sleep 0.01; @w.syswrite "." }
assert_equal @r, @r.wait_readable
ensure
th.join
end

def test_wait_readable_eof
th = Thread.new { sleep 0.01; @w.close }
ret = nil
assert_nothing_raised(Timeout::Error) do
Timeout.timeout(0.1) { ret = @r.wait_readable }
end
assert_equal @r, ret
ensure
th.join
end

def test_wait_writable
assert_equal @w, @w.wait_writable
end
@@ -103,6 +134,25 @@ def test_wait_writable_closed
assert_raise(IOError) { @w.wait_writable }
end

def test_wait_readwrite
assert_equal @r.wait(0, :write), @r.wait(0, :read_write)
end

def test_wait_readwrite_timeout
assert_equal @w, @w.wait(0.01, :read_write)
written = fill_pipe
if /aix/ =~ RUBY_PLATFORM
# IO#wait internally uses select(2) on AIX.
# AIX's select(2) returns "readable" for the write-side fd
# of a pipe, so @w.wait(0.01, :read_write) does not return nil.
assert_equal @w, @w.wait(0.01, :read_write)
else
assert_nil @w.wait(0.01, :read_write)
end
@r.read(written)
assert_equal @w, @w.wait(0.01, :read_write)
end

private

def fill_pipe
1 change: 1 addition & 0 deletions test/mri/json/fixtures/obsolete_fail1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"A JSON payload should be an object or array, not a string."
193 changes: 193 additions & 0 deletions test/mri/json/json_addition_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#frozen_string_literal: false
require 'test_helper'
require 'json/add/core'
require 'json/add/complex'
require 'json/add/rational'
require 'json/add/bigdecimal'
require 'json/add/ostruct'
require 'date'

class JSONAdditionTest < Test::Unit::TestCase
include JSON

class A
def initialize(a)
@a = a
end

attr_reader :a

def ==(other)
a == other.a
end

def self.json_create(object)
new(*object['args'])
end

def to_json(*args)
{
'json_class' => self.class.name,
'args' => [ @a ],
}.to_json(*args)
end
end

class A2 < A
def to_json(*args)
{
'json_class' => self.class.name,
'args' => [ @a ],
}.to_json(*args)
end
end

class B
def self.json_creatable?
false
end

def to_json(*args)
{
'json_class' => self.class.name,
}.to_json(*args)
end
end

class C
def self.json_creatable?
false
end

def to_json(*args)
{
'json_class' => 'JSONAdditionTest::Nix',
}.to_json(*args)
end
end

def test_extended_json
a = A.new(666)
assert A.json_creatable?
json = generate(a)
a_again = parse(json, :create_additions => true)
assert_kind_of a.class, a_again
assert_equal a, a_again
end

def test_extended_json_default
a = A.new(666)
assert A.json_creatable?
json = generate(a)
a_hash = parse(json)
assert_kind_of Hash, a_hash
end

def test_extended_json_disabled
a = A.new(666)
assert A.json_creatable?
json = generate(a)
a_again = parse(json, :create_additions => true)
assert_kind_of a.class, a_again
assert_equal a, a_again
a_hash = parse(json, :create_additions => false)
assert_kind_of Hash, a_hash
assert_equal(
{"args"=>[666], "json_class"=>"JSONAdditionTest::A"}.sort_by { |k,| k },
a_hash.sort_by { |k,| k }
)
end

def test_extended_json_fail1
b = B.new
assert !B.json_creatable?
json = generate(b)
assert_equal({ "json_class"=>"JSONAdditionTest::B" }, parse(json))
end

def test_extended_json_fail2
c = C.new
assert !C.json_creatable?
json = generate(c)
assert_raise(ArgumentError, NameError) { parse(json, :create_additions => true) }
end

def test_raw_strings
raw = ''
raw.respond_to?(:encode!) and raw.encode!(Encoding::ASCII_8BIT)
raw_array = []
for i in 0..255
raw << i
raw_array << i
end
json = raw.to_json_raw
json_raw_object = raw.to_json_raw_object
hash = { 'json_class' => 'String', 'raw'=> raw_array }
assert_equal hash, json_raw_object
assert_match(/\A\{.*\}\z/, json)
assert_match(/"json_class":"String"/, json)
assert_match(/"raw":\[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255\]/, json)
raw_again = parse(json, :create_additions => true)
assert_equal raw, raw_again
end

MyJsonStruct = Struct.new 'MyJsonStruct', :foo, :bar

def test_core
t = Time.now
assert_equal t, JSON(JSON(t), :create_additions => true)
d = Date.today
assert_equal d, JSON(JSON(d), :create_additions => true)
d = DateTime.civil(2007, 6, 14, 14, 57, 10, Rational(1, 12), 2299161)
assert_equal d, JSON(JSON(d), :create_additions => true)
assert_equal 1..10, JSON(JSON(1..10), :create_additions => true)
assert_equal 1...10, JSON(JSON(1...10), :create_additions => true)
assert_equal "a".."c", JSON(JSON("a".."c"), :create_additions => true)
assert_equal "a"..."c", JSON(JSON("a"..."c"), :create_additions => true)
s = MyJsonStruct.new 4711, 'foot'
assert_equal s, JSON(JSON(s), :create_additions => true)
struct = Struct.new :foo, :bar
s = struct.new 4711, 'foot'
assert_raise(JSONError) { JSON(s) }
begin
raise TypeError, "test me"
rescue TypeError => e
e_json = JSON.generate e
e_again = JSON e_json, :create_additions => true
assert_kind_of TypeError, e_again
assert_equal e.message, e_again.message
assert_equal e.backtrace, e_again.backtrace
end
assert_equal(/foo/, JSON(JSON(/foo/), :create_additions => true))
assert_equal(/foo/i, JSON(JSON(/foo/i), :create_additions => true))
end

def test_utc_datetime
now = Time.now
d = DateTime.parse(now.to_s, :create_additions => true) # usual case
assert_equal d, parse(d.to_json, :create_additions => true)
d = DateTime.parse(now.utc.to_s) # of = 0
assert_equal d, parse(d.to_json, :create_additions => true)
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(1,24))
assert_equal d, parse(d.to_json, :create_additions => true)
d = DateTime.civil(2008, 6, 17, 11, 48, 32, Rational(12,24))
assert_equal d, parse(d.to_json, :create_additions => true)
end

def test_rational_complex
assert_equal Rational(2, 9), parse(JSON(Rational(2, 9)), :create_additions => true)
assert_equal Complex(2, 9), parse(JSON(Complex(2, 9)), :create_additions => true)
end

def test_bigdecimal
assert_equal BigDecimal('3.141', 23), JSON(JSON(BigDecimal('3.141', 23)), :create_additions => true)
assert_equal BigDecimal('3.141', 666), JSON(JSON(BigDecimal('3.141', 666)), :create_additions => true)
end

def test_ostruct
o = OpenStruct.new
# XXX this won't work; o.foo = { :bar => true }
o.foo = { 'bar' => true }
assert_equal o, parse(JSON(o), :create_additions => true)
end
end
126 changes: 126 additions & 0 deletions test/mri/json/json_common_interface_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#frozen_string_literal: false
require 'test_helper'
require 'stringio'
require 'tempfile'

class JSONCommonInterfaceTest < Test::Unit::TestCase
include JSON

def setup
@hash = {
'a' => 2,
'b' => 3.141,
'c' => 'c',
'd' => [ 1, "b", 3.14 ],
'e' => { 'foo' => 'bar' },
'g' => "\"\0\037",
'h' => 1000.0,
'i' => 0.001
}
@json = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},'\
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
end

def test_index
assert_equal @json, JSON[@hash]
assert_equal @hash, JSON[@json]
end

def test_parser
assert_match /::Parser\z/, JSON.parser.name
end

def test_generator
assert_match /::Generator\z/, JSON.generator.name
end

def test_state
assert_match /::Generator::State\z/, JSON.state.name
end

def test_create_id
assert_equal 'json_class', JSON.create_id
JSON.create_id = 'foo_bar'
assert_equal 'foo_bar', JSON.create_id
ensure
JSON.create_id = 'json_class'
end

def test_deep_const_get
assert_raise(ArgumentError) { JSON.deep_const_get('Nix::Da') }
assert_equal File::SEPARATOR, JSON.deep_const_get('File::SEPARATOR')
end

def test_parse
assert_equal [ 1, 2, 3, ], JSON.parse('[ 1, 2, 3 ]')
end

def test_parse_bang
assert_equal [ 1, NaN, 3, ], JSON.parse!('[ 1, NaN, 3 ]')
end

def test_generate
assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ])
end

def test_fast_generate
assert_equal '[1,2,3]', JSON.generate([ 1, 2, 3 ])
end

def test_pretty_generate
assert_equal "[\n 1,\n 2,\n 3\n]", JSON.pretty_generate([ 1, 2, 3 ])
end

def test_load
assert_equal @hash, JSON.load(@json)
tempfile = Tempfile.open('@json')
tempfile.write @json
tempfile.rewind
assert_equal @hash, JSON.load(tempfile)
stringio = StringIO.new(@json)
stringio.rewind
assert_equal @hash, JSON.load(stringio)
assert_equal nil, JSON.load(nil)
assert_equal nil, JSON.load('')
ensure
tempfile.close!
end

def test_load_with_options
json = '{ "foo": NaN }'
assert JSON.load(json, nil, :allow_nan => true)['foo'].nan?
end

def test_load_null
assert_equal nil, JSON.load(nil, nil, :allow_blank => true)
assert_raise(TypeError) { JSON.load(nil, nil, :allow_blank => false) }
assert_raise(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) }
end

def test_dump
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
assert_equal too_deep, dump(eval(too_deep))
assert_kind_of String, Marshal.dump(eval(too_deep))
assert_raise(ArgumentError) { dump(eval(too_deep), 100) }
assert_raise(ArgumentError) { Marshal.dump(eval(too_deep), 100) }
assert_equal too_deep, dump(eval(too_deep), 101)
assert_kind_of String, Marshal.dump(eval(too_deep), 101)
output = StringIO.new
dump(eval(too_deep), output)
assert_equal too_deep, output.string
output = StringIO.new
dump(eval(too_deep), output, 101)
assert_equal too_deep, output.string
end

def test_dump_should_modify_defaults
max_nesting = JSON.dump_default_options[:max_nesting]
dump([], StringIO.new, 10)
assert_equal max_nesting, JSON.dump_default_options[:max_nesting]
end

def test_JSON
assert_equal @json, JSON(@hash)
assert_equal @hash, JSON(@json)
end
end
105 changes: 105 additions & 0 deletions test/mri/json/json_encoding_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# encoding: utf-8
#frozen_string_literal: false
require 'test_helper'

class JSONEncodingTest < Test::Unit::TestCase
include JSON

def setup
@utf_8 = '"© ≠ €!"'
@ascii_8bit = @utf_8.dup.force_encoding('ascii-8bit')
@parsed = "© ≠ €!"
@generated = '"\u00a9 \u2260 \u20ac!"'
if String.method_defined?(:encode)
@utf_16_data = @parsed.encode('utf-16be', 'utf-8')
@utf_16be = @utf_8.encode('utf-16be', 'utf-8')
@utf_16le = @utf_8.encode('utf-16le', 'utf-8')
@utf_32be = @utf_8.encode('utf-32be', 'utf-8')
@utf_32le = @utf_8.encode('utf-32le', 'utf-8')
else
require 'iconv'
@utf_16_data, = Iconv.iconv('utf-16be', 'utf-8', @parsed)
@utf_16be, = Iconv.iconv('utf-16be', 'utf-8', @utf_8)
@utf_16le, = Iconv.iconv('utf-16le', 'utf-8', @utf_8)
@utf_32be, = Iconv.iconv('utf-32be', 'utf-8', @utf_8)
@utf_32le, = Iconv.iconv('utf-32le', 'utf-8', @utf_8)
end
end

def test_parse
assert_equal @parsed, JSON.parse(@ascii_8bit)
assert_equal @parsed, JSON.parse(@utf_8)
assert_equal @parsed, JSON.parse(@utf_16be)
assert_equal @parsed, JSON.parse(@utf_16le)
assert_equal @parsed, JSON.parse(@utf_32be)
assert_equal @parsed, JSON.parse(@utf_32le)
end

def test_generate
assert_equal @generated, JSON.generate(@parsed, :ascii_only => true)
assert_equal @generated, JSON.generate(@utf_16_data, :ascii_only => true)
end

def test_unicode
assert_equal '""', ''.to_json
assert_equal '"\\b"', "\b".to_json
assert_equal '"\u0001"', 0x1.chr.to_json
assert_equal '"\u001f"', 0x1f.chr.to_json
assert_equal '" "', ' '.to_json
assert_equal "\"#{0x7f.chr}\"", 0x7f.chr.to_json
utf8 = [ "© ≠ €! \01" ]
json = '["© ≠ €! \u0001"]'
assert_equal json, utf8.to_json(:ascii_only => false)
assert_equal utf8, parse(json)
json = '["\u00a9 \u2260 \u20ac! \u0001"]'
assert_equal json, utf8.to_json(:ascii_only => true)
assert_equal utf8, parse(json)
utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
json = "[\"\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212\"]"
assert_equal utf8, parse(json)
assert_equal json, utf8.to_json(:ascii_only => false)
utf8 = ["\343\201\202\343\201\204\343\201\206\343\201\210\343\201\212"]
assert_equal utf8, parse(json)
json = "[\"\\u3042\\u3044\\u3046\\u3048\\u304a\"]"
assert_equal json, utf8.to_json(:ascii_only => true)
assert_equal utf8, parse(json)
utf8 = ['საქართველო']
json = '["საქართველო"]'
assert_equal json, utf8.to_json(:ascii_only => false)
json = "[\"\\u10e1\\u10d0\\u10e5\\u10d0\\u10e0\\u10d7\\u10d5\\u10d4\\u10da\\u10dd\"]"
assert_equal json, utf8.to_json(:ascii_only => true)
assert_equal utf8, parse(json)
assert_equal '["Ã"]', generate(["Ã"], :ascii_only => false)
assert_equal '["\\u00c3"]', generate(["Ã"], :ascii_only => true)
assert_equal ["€"], parse('["\u20ac"]')
utf8 = ["\xf0\xa0\x80\x81"]
json = "[\"\xf0\xa0\x80\x81\"]"
assert_equal json, generate(utf8, :ascii_only => false)
assert_equal utf8, parse(json)
json = '["\ud840\udc01"]'
assert_equal json, generate(utf8, :ascii_only => true)
assert_equal utf8, parse(json)
end

def test_chars
(0..0x7f).each do |i|
json = '["\u%04x"]' % i
if RUBY_VERSION >= "1.9."
i = i.chr
end
assert_equal i, parse(json).first[0]
if i == ?\b
generated = generate(["" << i])
assert '["\b"]' == generated || '["\10"]' == generated
elsif [?\n, ?\r, ?\t, ?\f].include?(i)
assert_equal '[' << ('' << i).dump << ']', generate(["" << i])
elsif i.chr < 0x20.chr
assert_equal json, generate(["" << i])
end
end
assert_raise(JSON::GeneratorError) do
generate(["\x80"], :ascii_only => true)
end
assert_equal "\302\200", parse('["\u0080"]').first
end
end
15 changes: 15 additions & 0 deletions test/mri/json/json_ext_parser_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#frozen_string_literal: false
require 'test_helper'

class JSONExtParserTest < Test::Unit::TestCase
if defined?(JSON::Ext::Parser)
def test_allocate
parser = JSON::Ext::Parser.new("{}")
assert_raise(TypeError, '[ruby-core:35079]') do
parser.__send__(:initialize, "{}")
end
parser = JSON::Ext::Parser.allocate
assert_raise(TypeError, '[ruby-core:35079]') { parser.source }
end
end
end
32 changes: 32 additions & 0 deletions test/mri/json/json_fixtures_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#frozen_string_literal: false
require 'test_helper'

class JSONFixturesTest < Test::Unit::TestCase
def setup
fixtures = File.join(File.dirname(__FILE__), 'fixtures/{fail,pass}.json')
passed, failed = Dir[fixtures].partition { |f| f['pass'] }
@passed = passed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
@failed = failed.inject([]) { |a, f| a << [ f, File.read(f) ] }.sort
end

def test_passing
for name, source in @passed
begin
assert JSON.parse(source),
"Did not pass for fixture '#{name}': #{source.inspect}"
rescue => e
warn "\nCaught #{e.class}(#{e}) for fixture '#{name}': #{source.inspect}\n#{e.backtrace * "\n"}"
raise e
end
end
end

def test_failing
for name, source in @failed
assert_raise(JSON::ParserError, JSON::NestingError,
"Did not fail for fixture '#{name}': #{source.inspect}") do
JSON.parse(source)
end
end
end
end
377 changes: 377 additions & 0 deletions test/mri/json/json_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,377 @@
#!/usr/bin/env ruby
# encoding: utf-8
# frozen_string_literal: false

require 'test_helper'

class JSONGeneratorTest < Test::Unit::TestCase
include JSON

def setup
@hash = {
'a' => 2,
'b' => 3.141,
'c' => 'c',
'd' => [ 1, "b", 3.14 ],
'e' => { 'foo' => 'bar' },
'g' => "\"\0\037",
'h' => 1000.0,
'i' => 0.001
}
@json2 = '{"a":2,"b":3.141,"c":"c","d":[1,"b",3.14],"e":{"foo":"bar"},' +
'"g":"\\"\\u0000\\u001f","h":1000.0,"i":0.001}'
@json3 = <<'EOT'.chomp
{
"a": 2,
"b": 3.141,
"c": "c",
"d": [
1,
"b",
3.14
],
"e": {
"foo": "bar"
},
"g": "\"\u0000\u001f",
"h": 1000.0,
"i": 0.001
}
EOT
end

def test_generate
json = generate(@hash)
assert_equal(parse(@json2), parse(json))
json = JSON[@hash]
assert_equal(parse(@json2), parse(json))
parsed_json = parse(json)
assert_equal(@hash, parsed_json)
json = generate({1=>2})
assert_equal('{"1":2}', json)
parsed_json = parse(json)
assert_equal({"1"=>2}, parsed_json)
assert_equal '666', generate(666)
end

def test_generate_pretty
json = pretty_generate(@hash)
# hashes aren't (insertion) ordered on every ruby implementation
# assert_equal(@json3, json)
assert_equal(parse(@json3), parse(json))
parsed_json = parse(json)
assert_equal(@hash, parsed_json)
json = pretty_generate({1=>2})
assert_equal(<<'EOT'.chomp, json)
{
"1": 2
}
EOT
parsed_json = parse(json)
assert_equal({"1"=>2}, parsed_json)
assert_equal '666', pretty_generate(666)
end

def test_generate_custom
state = State.new(:space_before => " ", :space => " ", :indent => "<i>", :object_nl => "\n", :array_nl => "<a_nl>")
json = generate({1=>{2=>3,4=>[5,6]}}, state)
assert_equal(<<'EOT'.chomp, json)
{
<i>"1" : {
<i><i>"2" : 3,
<i><i>"4" : [<a_nl><i><i><i>5,<a_nl><i><i><i>6<a_nl><i><i>]
<i>}
}
EOT
end

def test_fast_generate
json = fast_generate(@hash)
assert_equal(parse(@json2), parse(json))
parsed_json = parse(json)
assert_equal(@hash, parsed_json)
json = fast_generate({1=>2})
assert_equal('{"1":2}', json)
parsed_json = parse(json)
assert_equal({"1"=>2}, parsed_json)
assert_equal '666', fast_generate(666)
end

def test_own_state
state = State.new
json = generate(@hash, state)
assert_equal(parse(@json2), parse(json))
parsed_json = parse(json)
assert_equal(@hash, parsed_json)
json = generate({1=>2}, state)
assert_equal('{"1":2}', json)
parsed_json = parse(json)
assert_equal({"1"=>2}, parsed_json)
assert_equal '666', generate(666, state)
end

def test_states
json = generate({1=>2}, nil)
assert_equal('{"1":2}', json)
s = JSON.state.new
assert s.check_circular?
assert s[:check_circular?]
h = { 1=>2 }
h[3] = h
assert_raise(JSON::NestingError) { generate(h) }
assert_raise(JSON::NestingError) { generate(h, s) }
s = JSON.state.new
a = [ 1, 2 ]
a << a
assert_raise(JSON::NestingError) { generate(a, s) }
assert s.check_circular?
assert s[:check_circular?]
end

def test_pretty_state
state = PRETTY_STATE_PROTOTYPE.dup
assert_equal({
:allow_nan => false,
:array_nl => "\n",
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
:indent => " ",
:max_nesting => 100,
:object_nl => "\n",
:space => " ",
:space_before => "",
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

def test_safe_state
state = SAFE_STATE_PROTOTYPE.dup
assert_equal({
:allow_nan => false,
:array_nl => "",
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
:indent => "",
:max_nesting => 100,
:object_nl => "",
:space => "",
:space_before => "",
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

def test_fast_state
state = FAST_STATE_PROTOTYPE.dup
assert_equal({
:allow_nan => false,
:array_nl => "",
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
:indent => "",
:max_nesting => 0,
:object_nl => "",
:space => "",
:space_before => "",
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

def test_allow_nan
assert_raise(GeneratorError) { generate([JSON::NaN]) }
assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
assert_raise(GeneratorError) { fast_generate([JSON::NaN]) }
assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
assert_raise(GeneratorError) { generate([JSON::Infinity]) }
assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
assert_raise(GeneratorError) { fast_generate([JSON::Infinity]) }
assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
assert_raise(GeneratorError) { fast_generate([JSON::MinusInfinity]) }
assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
end

def test_depth
ary = []; ary << ary
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
assert_raise(JSON::NestingError) { generate(ary) }
assert_equal 0, JSON::SAFE_STATE_PROTOTYPE.depth
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
assert_raise(JSON::NestingError) { JSON.pretty_generate(ary) }
assert_equal 0, JSON::PRETTY_STATE_PROTOTYPE.depth
s = JSON.state.new
assert_equal 0, s.depth
assert_raise(JSON::NestingError) { ary.to_json(s) }
assert_equal 100, s.depth
end

def test_buffer_initial_length
s = JSON.state.new
assert_equal 1024, s.buffer_initial_length
s.buffer_initial_length = 0
assert_equal 1024, s.buffer_initial_length
s.buffer_initial_length = -1
assert_equal 1024, s.buffer_initial_length
s.buffer_initial_length = 128
assert_equal 128, s.buffer_initial_length
end

def test_gc
if respond_to?(:assert_in_out_err)
assert_in_out_err(%w[-rjson --disable-gems], <<-EOS, [], [])
bignum_too_long_to_embed_as_string = 1234567890123456789012345
expect = bignum_too_long_to_embed_as_string.to_s
GC.stress = true
10.times do |i|
tmp = bignum_too_long_to_embed_as_string.to_json
raise "'\#{expect}' is expected, but '\#{tmp}'" unless tmp == expect
end
EOS
end
end if GC.respond_to?(:stress=)

def test_configure_using_configure_and_merge
numbered_state = {
:indent => "1",
:space => '2',
:space_before => '3',
:object_nl => '4',
:array_nl => '5'
}
state1 = JSON.state.new
state1.merge(numbered_state)
assert_equal '1', state1.indent
assert_equal '2', state1.space
assert_equal '3', state1.space_before
assert_equal '4', state1.object_nl
assert_equal '5', state1.array_nl
state2 = JSON.state.new
state2.configure(numbered_state)
assert_equal '1', state2.indent
assert_equal '2', state2.space
assert_equal '3', state2.space_before
assert_equal '4', state2.object_nl
assert_equal '5', state2.array_nl
end

def test_configure_hash_conversion
state = JSON.state.new
state.configure(:indent => '1')
assert_equal '1', state.indent
state = JSON.state.new
foo = 'foo'
assert_raise(TypeError) do
state.configure(foo)
end
def foo.to_h
{ :indent => '2' }
end
state.configure(foo)
assert_equal '2', state.indent
end

if defined?(JSON::Ext::Generator)
def test_broken_bignum # [ruby-core:38867]
pid = fork do
x = 1 << 64
x.class.class_eval do
def to_s
end
end
begin
JSON::Ext::Generator::State.new.generate(x)
exit 1
rescue TypeError
exit 0
end
end
_, status = Process.waitpid2(pid)
assert status.success?
rescue NotImplementedError
# forking to avoid modifying core class of a parent process and
# introducing race conditions of tests are run in parallel
end
end

def test_hash_likeness_set_symbol
state = JSON.state.new
assert_equal nil, state[:foo]
assert_equal nil.class, state[:foo].class
assert_equal nil, state['foo']
state[:foo] = :bar
assert_equal :bar, state[:foo]
assert_equal :bar, state['foo']
state_hash = state.to_hash
assert_kind_of Hash, state_hash
assert_equal :bar, state_hash[:foo]
end

def test_hash_likeness_set_string
state = JSON.state.new
assert_equal nil, state[:foo]
assert_equal nil, state['foo']
state['foo'] = :bar
assert_equal :bar, state[:foo]
assert_equal :bar, state['foo']
state_hash = state.to_hash
assert_kind_of Hash, state_hash
assert_equal :bar, state_hash[:foo]
end

def test_json_generate
assert_raise JSON::GeneratorError do
assert_equal true, generate(["\xea"])
end
end

def test_nesting
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
too_deep_ary = eval too_deep
assert_raise(JSON::NestingError) { generate too_deep_ary }
assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
ok = generate too_deep_ary, :max_nesting => 101
assert_equal too_deep, ok
ok = generate too_deep_ary, :max_nesting => nil
assert_equal too_deep, ok
ok = generate too_deep_ary, :max_nesting => false
assert_equal too_deep, ok
ok = generate too_deep_ary, :max_nesting => 0
assert_equal too_deep, ok
end

def test_backslash
data = [ '\\.(?i:gif|jpe?g|png)$' ]
json = '["\\\\.(?i:gif|jpe?g|png)$"]'
assert_equal json, generate(data)
#
data = [ '\\"' ]
json = '["\\\\\""]'
assert_equal json, generate(data)
#
data = [ '/' ]
json = '["/"]'
assert_equal json, generate(data)
#
data = ['"']
json = '["\""]'
assert_equal json, generate(data)
#
data = ["'"]
json = '["\\\'"]'
assert_equal '["\'"]', generate(data)
end

def test_string_subclass
s = Class.new(String) do
def to_s; self; end
undef to_json
end
assert_nothing_raised(SystemStackError) do
assert_equal '["foo"]', JSON.generate([s.new('foo')])
end
end
end
82 changes: 82 additions & 0 deletions test/mri/json/json_generic_object_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#frozen_string_literal: false
require 'test_helper'

class JSONGenericObjectTest < Test::Unit::TestCase
include JSON

def setup
@go = GenericObject[ :a => 1, :b => 2 ]
end

def test_attributes
assert_equal 1, @go.a
assert_equal 1, @go[:a]
assert_equal 2, @go.b
assert_equal 2, @go[:b]
assert_nil @go.c
assert_nil @go[:c]
end

def test_generate_json
switch_json_creatable do
assert_equal @go, JSON(JSON(@go), :create_additions => true)
end
end

def test_parse_json
assert_kind_of Hash,
JSON(
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
:create_additions => true
)
switch_json_creatable do
assert_equal @go, l =
JSON(
'{ "json_class": "JSON::GenericObject", "a": 1, "b": 2 }',
:create_additions => true
)
assert_equal 1, l.a
assert_equal @go,
l = JSON('{ "a": 1, "b": 2 }', :object_class => GenericObject)
assert_equal 1, l.a
assert_equal GenericObject[:a => GenericObject[:b => 2]],
l = JSON('{ "a": { "b": 2 } }', :object_class => GenericObject)
assert_equal 2, l.a.b
end
end

def test_from_hash
result = GenericObject.from_hash(
:foo => { :bar => { :baz => true }, :quux => [ { :foobar => true } ] })
assert_kind_of GenericObject, result.foo
assert_kind_of GenericObject, result.foo.bar
assert_equal true, result.foo.bar.baz
assert_kind_of GenericObject, result.foo.quux.first
assert_equal true, result.foo.quux.first.foobar
assert_equal true, GenericObject.from_hash(true)
end

def test_json_generic_object_load
empty = JSON::GenericObject.load(nil)
assert_kind_of JSON::GenericObject, empty
simple_json = '{"json_class":"JSON::GenericObject","hello":"world"}'
simple = JSON::GenericObject.load(simple_json)
assert_kind_of JSON::GenericObject, simple
assert_equal "world", simple.hello
converting = JSON::GenericObject.load('{ "hello": "world" }')
assert_kind_of JSON::GenericObject, converting
assert_equal "world", converting.hello

json = JSON::GenericObject.dump(JSON::GenericObject[:hello => 'world'])
assert_equal JSON(json), JSON('{"json_class":"JSON::GenericObject","hello":"world"}')
end

private

def switch_json_creatable
JSON::GenericObject.json_creatable = true
yield
ensure
JSON::GenericObject.json_creatable = false
end
end
466 changes: 466 additions & 0 deletions test/mri/json/json_parser_test.rb

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions test/mri/json/json_string_matching_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#frozen_string_literal: false
require 'test_helper'
require 'time'

class JSONStringMatchingTest < Test::Unit::TestCase
include JSON

class TestTime < ::Time
def self.json_create(string)
Time.parse(string)
end

def to_json(*)
%{"#{strftime('%FT%T%z')}"}
end

def ==(other)
to_i == other.to_i
end
end

def test_match_date
t = TestTime.new
t_json = [ t ].to_json
time_regexp = /\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}\z/
assert_equal [ t ],
parse(
t_json,
:create_additions => true,
:match_string => { time_regexp => TestTime }
)
assert_equal [ t.strftime('%FT%T%z') ],
parse(
t_json,
:match_string => { time_regexp => TestTime }
)
end
end
21 changes: 21 additions & 0 deletions test/mri/json/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
case ENV['JSON']
when 'pure'
$:.unshift 'lib'
require 'json/pure'
when 'ext'
$:.unshift 'ext', 'lib'
require 'json/ext'
else
$:.unshift 'ext', 'lib'
require 'json'
end

require 'test/unit'
begin
require 'byebug'
rescue LoadError
end
if ENV['START_SIMPLECOV'].to_i == 1
require 'simplecov'
SimpleCov.start
end
14 changes: 14 additions & 0 deletions test/mri/lib/-test-/integer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'test/unit'
require '-test-/integer.so'

module Test::Unit::Assertions
def assert_fixnum(v, msg=nil)
assert_instance_of(Integer, v, msg)
assert_predicate(v, :fixnum?, msg)
end

def assert_bignum(v, msg=nil)
assert_instance_of(Integer, v, msg)
assert_predicate(v, :bignum?, msg)
end
end
6 changes: 6 additions & 0 deletions test/mri/lib/envutil.rb
Original file line number Diff line number Diff line change
@@ -3,6 +3,12 @@
require "open3"
require "timeout"
require_relative "find_executable"
require "rbconfig/sizeof"

class Integer
FIXNUM_MIN = -(1 << (8 * RbConfig::SIZEOF['long'] - 2))
FIXNUM_MAX = (1 << (8 * RbConfig::SIZEOF['long'] - 2)) - 1
end

module EnvUtil
def rubybin
6 changes: 3 additions & 3 deletions test/mri/lib/iseq_loader_checker.rb
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ def self.compare_dump_and_load i1, dumper, loader

def self.translate i1
# check to_a/load_iseq
i2_ary = compare_dump_and_load(i1,
compare_dump_and_load(i1,
proc{|iseq|
ary = iseq.to_a
ary[9] == :top ? ary : nil
@@ -57,8 +57,8 @@ def self.translate i1
proc{|iseq|
begin
iseq.to_binary
rescue RuntimeError => e # not a toplevel
# STDERR.puts [:failed, e, iseq].inspect
rescue RuntimeError # not a toplevel
# STDERR.puts [:failed, $!, iseq].inspect
nil
end
},
2 changes: 1 addition & 1 deletion test/mri/lib/leakchecker.rb
Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ def check_tempfile_leak(test_name)

def find_threads
Thread.list.find_all {|t|
t != Thread.current && /\AWEBrick::/ !~ t.class.name && t.alive?
t != Thread.current && t.alive?
}
end

41 changes: 25 additions & 16 deletions test/mri/lib/memory_status.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# frozen_string_literal: false
begin
require '-test-/memory_status.so'
rescue LoadError
end

module Memory
keys = []
vals = []

case
when File.exist?(procfile = "/proc/self/status") && (pat = /^Vm(\w+):\s+(\d+)/) =~ File.binread(procfile)
when File.exist?(procfile = "/proc/self/status") && (pat = /^Vm(\w+):\s+(\d+)/) =~ (data = File.binread(procfile))
PROC_FILE = procfile
VM_PAT = pat
def self.read_status
@@ -13,7 +17,7 @@ def self.read_status
end
end

read_status {|k, v| keys << k; vals << v}
data.scan(pat) {|k, v| keys << k.downcase.intern}

when /mswin|mingw/ =~ RUBY_PLATFORM
require 'fiddle/import'
@@ -59,13 +63,12 @@ def self.read_status
yield :size, info.PagefileUsage
end
end
else
PAT = /^\s*(\d+)\s+(\d+)$/
require_relative 'find_executable'
if PSCMD = EnvUtil.find_executable("ps", "-ovsz=", "-orss=", "-p", $$.to_s) {|out| PAT =~ out}
PSCMD.pop
end
raise MiniTest::Skip, "ps command not found" unless PSCMD
when (require_relative 'find_executable'
pat = /^\s*(\d+)\s+(\d+)$/
pscmd = EnvUtil.find_executable("ps", "-ovsz=", "-orss=", "-p", $$.to_s) {|out| pat =~ out})
pscmd.pop
PAT = pat
PSCMD = pscmd

keys << :size << :rss
def self.read_status
@@ -74,19 +77,25 @@ def self.read_status
yield :rss, $2.to_i*1024
end
end
else
def self.read_status
raise NotImplementedError, "unsupported platform"
end
end

Status = Struct.new(*keys)
if !keys.empty?
Status = Struct.new(*keys)
end
end unless defined?(Memory::Status)

class Status
if defined?(Memory::Status)
class Memory::Status
def _update
Memory.read_status do |key, val|
self[key] = val
end
end
end
end unless method_defined?(:_update)

class Status
Header = members.map {|k| k.to_s.upcase.rjust(6)}.join('')
Format = "%6d"

@@ -132,7 +141,7 @@ def self.parse(str)
]
_, err, status = EnvUtil.invoke_ruby(args, "exit(0)", true, true)
if status.exitstatus == 0 && err.to_s.empty? then
NO_MEMORY_LEAK_ENVS = envs
Memory::NO_MEMORY_LEAK_ENVS = envs
end
end
end #case RUBY_PLATFORM
4 changes: 2 additions & 2 deletions test/mri/lib/minitest/unit.rb
Original file line number Diff line number Diff line change
@@ -998,7 +998,7 @@ def puke klass, meth, e
else
@errors += 1
bt = MiniTest::filter_backtrace(e.backtrace).join "\n "
"Error:\n#{klass}##{meth}:\n#{e.class}: #{e.message}\n #{bt}\n"
"Error:\n#{klass}##{meth}:\n#{e.class}: #{e.message.b}\n #{bt}\n"
end
@report << e
e[0, 1]
@@ -1008,7 +1008,7 @@ def initialize # :nodoc:
@report = []
@errors = @failures = @skips = 0
@verbose = false
@mutex = defined?(Mutex) ? Mutex.new : nil
@mutex = Thread::Mutex.new
@info_signal = Signal.list['INFO']
end

73 changes: 42 additions & 31 deletions test/mri/lib/test/unit.rb
Original file line number Diff line number Diff line change
@@ -86,7 +86,7 @@ def setup_options(opts, options)
self.verbose = options[:verbose]
end

opts.on '-n', '--name PATTERN', "Filter test method names on pattern: /REGEXP/ or STRING" do |a|
opts.on '-n', '--name PATTERN', "Filter test method names on pattern: /REGEXP/, !/REGEXP/ or STRING" do |a|
(options[:filter] ||= []) << a
end

@@ -110,7 +110,7 @@ def non_options(files, options)
end
unless negative.empty?
negative = Regexp.union(*negative.map! {|s| s[neg_pat, 1]})
filter = /\A(?!.*#{negative})#{filter}/
filter = /\A(?=.*#{filter})(?!.*#{negative})/
end
if Regexp === filter
# bypass conversion in minitest
@@ -177,7 +177,7 @@ def setup_options(opts, options)

class Worker
def self.launch(ruby,args=[])
io = IO.popen([*ruby,
io = IO.popen([*ruby, "-W1",
"#{File.dirname(__FILE__)}/unit/parallel.rb",
*args], "rb+")
new(io, io.pid, :waiting)
@@ -257,7 +257,7 @@ def died(*additional)
end

def to_s
if @file
if @file and @status != :ready
"#{@pid}=#{@file}"
else
"#{@pid}:#{@status.to_s.ljust(7)}"
@@ -281,6 +281,7 @@ def after_worker_down(worker, e=nil, c=false)
return unless @options[:parallel]
return if @interrupt
warn e if e
real_file = worker.real_file and warn "running file: #{real_file}"
@need_quit = true
warn ""
warn "Some worker was crashed. It seems ruby interpreter's bug"
@@ -356,7 +357,6 @@ def deal(io, type, result, rep, shutting_down = false)
# just only dots, ignore
when /^okay$/
worker.status = :running
jobs_status
when /^ready(!)?$/
bang = $1
worker.status = :ready
@@ -369,7 +369,7 @@ def deal(io, type, result, rep, shutting_down = false)
worker.run(task, type)
@test_count += 1

jobs_status
jobs_status(worker)
when /^done (.+?)$/
begin
r = Marshal.load($1.unpack("m")[0])
@@ -380,11 +380,12 @@ def deal(io, type, result, rep, shutting_down = false)
result << r[0..1] unless r[0..1] == [nil,nil]
rep << {file: worker.real_file, report: r[2], result: r[3], testcase: r[5]}
$:.push(*r[4]).uniq!
jobs_status(worker) if @options[:job_status] == :replace
return true
when /^p (.+?)$/
del_jobs_status
print $1.unpack("m")[0]
jobs_status if @options[:job_status] == :replace
jobs_status(worker) if @options[:job_status] == :replace
when /^after (.+?)$/
@warnings << Marshal.load($1.unpack("m")[0])
when /^bye (.+?)$/
@@ -450,7 +451,7 @@ def _run_parallel suites, type, result
suites.map! {|r| eval("::"+r[:testcase])}
del_status_line or puts
unless suites.empty?
puts "Retrying..."
puts "\n""Retrying..."
_run_suites(suites, type)
end
end
@@ -497,11 +498,16 @@ def _run_suites suites, type
end
}
end
del_status_line
result
end
end

module Skipping # :nodoc: all
def failed(s)
super if !s or @options[:hide_skip]
end

private
def setup_options(opts, options)
super
@@ -525,6 +531,7 @@ def _run_suites(suites, type)
report.reject!{|r| r.start_with? "Skipped:" } if @options[:hide_skip]
report.sort_by!{|r| r.start_with?("Skipped:") ? 0 : \
(r.start_with?("Failure:") ? 1 : 2) }
failed(nil)
result
end
end
@@ -546,31 +553,31 @@ def terminal_width

def del_status_line(flush = true)
@status_line_size ||= 0
unless @options[:job_status] == :replace
$stdout.puts
return
if @options[:job_status] == :replace
$stdout.print "\r"+" "*@status_line_size+"\r"
else
$stdout.puts if @status_line_size > 0
end
print "\r"+" "*@status_line_size+"\r"
$stdout.flush if flush
@status_line_size = 0
end

def add_status(line, flush: true)
unless @options[:job_status] == :replace
print(line)
return
end
def add_status(line)
@status_line_size ||= 0
line = line[0...(terminal_width-@status_line_size)]
if @options[:job_status] == :replace
line = line[0...(terminal_width-@status_line_size)]
end
print line
$stdout.flush if flush
@status_line_size += line.size
end

def jobs_status
return unless @options[:job_status]
puts "" unless @options[:verbose] or @options[:job_status] == :replace
status_line = @workers.map(&:to_s).join(" ")
def jobs_status(worker)
return if !@options[:job_status] or @options[:verbose]
if @options[:job_status] == :replace
status_line = @workers.map(&:to_s).join(" ")
else
status_line = worker.to_s
end
update_status(status_line) or (puts; nil)
end

@@ -611,8 +618,8 @@ def _prepare_run(suites, type)
end
if color or @options[:job_status] == :replace
@verbose = !options[:parallel]
@output = Output.new(self)
end
@output = Output.new(self) unless @options[:testing]
filter = options[:filter]
type = "#{type}_methods"
total = if filter
@@ -631,17 +638,20 @@ def new_test(s)

def update_status(s)
count = @test_count.to_s(10).rjust(@total_tests.size)
del_status_line(false) if @options[:job_status] == :replace
del_status_line(false)
print(@passed_color)
add_status("[#{count}/#{@total_tests}]", flush: false)
add_status("[#{count}/#{@total_tests}]")
print(@reset_color)
add_status(" #{s}")
$stdout.print "\r" if @options[:job_status] == :replace and !@verbose
$stdout.flush
end

def _print(s); $stdout.print(s); end
def succeed; del_status_line; end

def failed(s)
return if s and @options[:job_status] != :replace
sep = "\n"
@report_count ||= 0
report.each do |msg|
@@ -682,9 +692,9 @@ def setup_options(opts, options)

options[:job_status] = nil

opts.on '--jobs-status [TYPE]', [:normal, :replace],
opts.on '--jobs-status [TYPE]', [:normal, :replace, :none],
"Show status of jobs every file; Disabled when --jobs isn't specified." do |type|
options[:job_status] = type || :normal
options[:job_status] = (type || :normal if type != :none)
end

opts.on '--color[=WHEN]',
@@ -710,7 +720,7 @@ def print(s)
when /\A(.*\#.*) = \z/
runner.new_test($1)
when /\A(.* s) = \z/
runner.add_status(" = "+$1.chomp)
runner.add_status(" = #$1")
when /\A\.+\z/
runner.succeed
when /\A[EFS]\z/
@@ -747,6 +757,7 @@ def setup_options(parser, options)

module GlobOption # :nodoc: all
@@testfile_prefix = "test"
@@testfile_suffix = "test"

def setup_options(parser, options)
super
@@ -773,7 +784,7 @@ def non_options(files, options)
next if f.empty?
path = f
end
if !(match = Dir["#{path}/**/#{@@testfile_prefix}_*.rb"]).empty?
if !(match = (Dir["#{path}/**/#{@@testfile_prefix}_*.rb"] + Dir["#{path}/**/*_#{@@testfile_suffix}.rb"]).uniq).empty?
if reject
match.reject! {|n|
n[(prefix.length+1)..-1] if prefix
@@ -878,7 +889,7 @@ def self.load(dirs, name)
nil
else
instance ||= new({})
instance.instance_eval(src)
instance.instance_eval(src, path)
end
end
instance
51 changes: 38 additions & 13 deletions test/mri/lib/test/unit/assertions.rb
Original file line number Diff line number Diff line change
@@ -131,14 +131,20 @@ def assert_raise_with_message(exception, expected, msg = nil, &block)
raise TypeError, "Expected #{expected.inspect} to be a kind of String or Regexp, not #{expected.class}"
end

ex = assert_raise(exception, msg || proc {"Exception(#{exception}) with message matches to #{expected.inspect}"}) {yield}
ex = m = nil
EnvUtil.with_default_internal(expected.encoding) do
ex = assert_raise(exception, msg || proc {"Exception(#{exception}) with message matches to #{expected.inspect}"}) do
yield
end
m = ex.message
end
msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"}

if assert == :assert_equal
assert_equal(expected, ex.message, msg)
assert_equal(expected, m, msg)
else
msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp ex.message}" }
assert expected =~ ex.message, msg
msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp m}" }
assert expected =~ m, msg
block.binding.eval("proc{|_|$~=_}").call($~)
end
ex
@@ -186,7 +192,6 @@ def assert_nothing_raised(*args)
raise
end
end
nil
end

# :call-seq:
@@ -447,6 +452,9 @@ def assert_not_all?(obj, m = nil, &blk)
assert(failed.empty?, message(m) {failed.pretty_inspect})
end

# compatiblity with test-unit
alias pend skip

def assert_valid_syntax(code, fname = caller_locations(1, 1)[0], mesg = fname.to_s, verbose: nil)
code = code.b
code.sub!(/\A(?:\xef\xbb\xbf)?(\s*\#.*$)*(\n)?/n) {
@@ -540,7 +548,8 @@ def assert_normal_exit(testsrc, message = '', child_env: nil, **opt)
faildesc
end

def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil, **opt)
def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil,
success: nil, **opt)
stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, true, true, **opt)
if signo = status.termsig
EnvUtil.diagnostic_reports(Signal.signame(signo), EnvUtil.rubybin, status.pid, Time.now)
@@ -562,6 +571,15 @@ def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [],
end
end
end
unless success.nil?
a.for("success?") do
if success
assert_predicate(status, :success?)
else
assert_not_predicate(status, :success?)
end
end
end
end
status
end
@@ -597,7 +615,7 @@ class Test::Unit::Runner
eom
args = args.dup
args.insert((Hash === args.first ? 1 : 0), "-w", "--disable=gems", *$:.map {|l| "-I#{l}"})
stdout, stderr, status = EnvUtil.invoke_ruby(args, src, true, true, timeout_error: nil, **opt)
stdout, stderr, status = EnvUtil.invoke_ruby(args, src, true, true, **opt)
abort = status.coredump? || (status.signaled? && ABORT_SIGNALS.include?(status.termsig))
assert(!abort, FailDesc[status, nil, stderr])
self._assertions += stdout[/^assertions=(\d+)/, 1].to_i
@@ -628,7 +646,11 @@ class Test::Unit::Runner
end

def assert_warning(pat, msg = nil)
stderr = EnvUtil.verbose_warning { yield }
stderr = EnvUtil.verbose_warning {
EnvUtil.with_default_internal(pat.encoding) {
yield
}
}
msg = message(msg) {diff pat, stderr}
assert(pat === stderr, msg)
end
@@ -638,14 +660,16 @@ def assert_warn(*args)
end

def assert_no_memory_leak(args, prepare, code, message=nil, limit: 2.0, rss: false, **opt)
require_relative 'memory_status'
require_relative '../../memory_status'
raise MiniTest::Skip, "unsupported platform" unless defined?(Memory::Status)

token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m"
token_dump = token.dump
token_re = Regexp.quote(token)
envs = args.shift if Array === args and Hash === args.first
args = [
"--disable=gems",
"-r", File.expand_path("../memory_status", __FILE__),
"-r", File.expand_path("../../../memory_status", __FILE__),
*args,
"-v", "-",
]
@@ -802,7 +826,7 @@ def message
total = @count.to_s
fmt = "%#{total.size}d"
@failures.map {|k, (n, v)|
"\n#{i+=1}. [#{fmt%n}/#{total}] Assertion for #{k.inspect}\n#{v.message.gsub(/^/, ' | ')}"
"\n#{i+=1}. [#{fmt%n}/#{total}] Assertion for #{k.inspect}\n#{v.message.b.gsub(/^/, ' | ')}"
}.join("\n")
end

@@ -811,12 +835,13 @@ def pass?
end
end

def all_assertions(msg = nil)
def assert_all_assertions(msg = nil)
all = AllFailures.new
yield all
ensure
assert(all.pass?, message(msg) {all.message})
assert(all.pass?, message(msg) {all.message.chomp(".")})
end
alias all_assertions assert_all_assertions

def build_message(head, template=nil, *arguments) #:nodoc:
template &&= template.chomp
Loading

0 comments on commit c752675

Please sign in to comment.