Skip to content

Commit 364e25b

Browse files
committed
Make assert_separately tolerant to core method redefinitions
And split `TestRubyOptimization#test_objtostring` for each target class.
1 parent 3185786 commit 364e25b

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

test/ruby/test_optimization.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ def test_optimized_rescue
10801080
class Objtostring
10811081
end
10821082

1083-
def test_objtostring
1083+
def test_objtostring_immediate
10841084
assert_raise(NoMethodError){"#{BasicObject.new}"}
10851085
assert_redefine_method('Symbol', 'to_s', <<-'end')
10861086
assert_match %r{\A#<Symbol:0x[0-9a-f]+>\z}, "#{:foo}"
@@ -1094,11 +1094,17 @@ def test_objtostring
10941094
assert_redefine_method('FalseClass', 'to_s', <<-'end')
10951095
assert_match %r{\A#<FalseClass:0x[0-9a-f]+>\z}, "#{false}"
10961096
end
1097+
end
1098+
1099+
def test_objtostring_fixnum
10971100
assert_redefine_method('Integer', 'to_s', <<-'end')
10981101
(-1..10).each { |i|
10991102
assert_match %r{\A#<Integer:0x[0-9a-f]+>\z}, "#{i}"
11001103
}
11011104
end
1105+
end
1106+
1107+
def test_objtostring
11021108
assert_equal "TestRubyOptimization::Objtostring", "#{Objtostring}"
11031109
assert_match %r{\A#<Class:0x[0-9a-f]+>\z}, "#{Class.new}"
11041110
assert_match %r{\A#<Module:0x[0-9a-f]+>\z}, "#{Module.new}"

tool/lib/core_assertions.rb

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,35 @@ def assert_ruby_status(args, test_stdin="", message=nil, **opt)
303303

304304
def separated_runner(token, out = nil)
305305
include(*Test::Unit::TestCase.ancestors.select {|c| !c.is_a?(Class) })
306+
306307
out = out ? IO.new(out, 'w') : STDOUT
308+
309+
# avoid method redefinitions
310+
out_write = out.method(:write)
311+
integer_to_s = Integer.instance_method(:to_s)
312+
array_pack = Array.instance_method(:pack)
313+
marshal_dump = Marshal.method(:dump)
314+
assertions_ivar_set = Test::Unit::Assertions.method(:instance_variable_set)
315+
assertions_ivar_get = Test::Unit::Assertions.method(:instance_variable_get)
316+
Test::Unit::Assertions.module_eval do
317+
@_assertions = 0
318+
319+
undef _assertions=
320+
define_method(:_assertions=, ->(n) {assertions_ivar_set.call(:@_assertions, n)})
321+
322+
undef _assertions
323+
define_method(:_assertions, -> {assertions_ivar_get.call(:@_assertions)})
324+
end
325+
# assume Method#call and UnboundMethod#bind_call need to work as the original
326+
307327
at_exit {
308-
out.puts "#{token}<error>", [Marshal.dump($!)].pack('m'), "#{token}</error>", "#{token}assertions=#{self._assertions}"
328+
assertions = assertions_ivar_get.call(:@_assertions)
329+
out_write.call <<~OUT
330+
#{token}<error>
331+
#{array_pack.bind_call([marshal_dump.call($!)], 'm')}
332+
#{token}</error>
333+
#{token}assertions=#{integer_to_s.bind_call(assertions)}
334+
OUT
309335
}
310336
if defined?(Test::Unit::Runner)
311337
Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true)
@@ -360,7 +386,9 @@ def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **o
360386
raise if $!
361387
abort = status.coredump? || (status.signaled? && ABORT_SIGNALS.include?(status.termsig))
362388
assert(!abort, FailDesc[status, nil, stderr])
363-
self._assertions += res[/^#{token_re}assertions=(\d+)/, 1].to_i
389+
if (assertions = res[/^#{token_re}assertions=(\d+)/, 1].to_i) > 0
390+
self._assertions += assertions
391+
end
364392
begin
365393
res = Marshal.load(res[/^#{token_re}<error>\n\K.*\n(?=#{token_re}<\/error>$)/m].unpack1("m"))
366394
rescue => marshal_error

0 commit comments

Comments
 (0)