summaryrefslogtreecommitdiff
path: root/tool
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2019-07-15 09:39:22 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2019-07-15 09:40:22 +0900
commit08b340d2f68daf6bbaba9be77ee7c17150bd7adb (patch)
tree5a08cc188ba1cd727064f28d6a99628ef2b168ba /tool
parente8ddbc0239b9dfa32787e93c6942f085e5c42b49 (diff)
Separate the assertions of ruby core tests from test/unit/assertions.
Diffstat (limited to 'tool')
-rw-r--r--tool/lib/test/unit/assertions.rb207
-rw-r--r--tool/lib/test/unit/core_assertions.rb216
2 files changed, 218 insertions, 205 deletions
diff --git a/tool/lib/test/unit/assertions.rb b/tool/lib/test/unit/assertions.rb
index 169a3dcc7e..0c68a93b02 100644
--- a/tool/lib/test/unit/assertions.rb
+++ b/tool/lib/test/unit/assertions.rb
@@ -1,15 +1,12 @@
# frozen_string_literal: true
require 'minitest/unit'
+require 'test/unit/core_assertions'
require 'pp'
module Test
module Unit
module Assertions
- include MiniTest::Assertions
-
- def mu_pp(obj) #:nodoc:
- obj.pretty_inspect.chomp
- end
+ include Test::Unit::CoreAssertions
MINI_DIR = File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), "minitest") #:nodoc:
@@ -554,80 +551,6 @@ EOT
assert !status.signaled?, FailDesc[status, message, out]
end
- FailDesc = proc do |status, message = "", out = ""|
- pid = status.pid
- now = Time.now
- faildesc = proc do
- if signo = status.termsig
- signame = Signal.signame(signo)
- sigdesc = "signal #{signo}"
- end
- log = EnvUtil.diagnostic_reports(signame, pid, now)
- if signame
- sigdesc = "SIG#{signame} (#{sigdesc})"
- end
- if status.coredump?
- sigdesc = "#{sigdesc} (core dumped)"
- end
- full_message = ''.dup
- message = message.call if Proc === message
- if message and !message.empty?
- full_message << message << "\n"
- end
- full_message << "pid #{pid}"
- full_message << " exit #{status.exitstatus}" if status.exited?
- full_message << " killed by #{sigdesc}" if sigdesc
- if out and !out.empty?
- full_message << "\n" << out.b.gsub(/^/, '| ')
- full_message.sub!(/(?<!\n)\z/, "\n")
- end
- if log
- full_message << "Diagnostic reports:\n" << log.b.gsub(/^/, '| ')
- end
- full_message
- end
- faildesc
- end
-
- def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil,
- success: nil, **opt)
- args = Array(args).dup
- args.insert((Hash === args[0] ? 1 : 0), '--disable=gems')
- stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, true, true, **opt)
- if signo = status.termsig
- EnvUtil.diagnostic_reports(Signal.signame(signo), status.pid, Time.now)
- end
- if block_given?
- raise "test_stdout ignored, use block only or without block" if test_stdout != []
- raise "test_stderr ignored, use block only or without block" if test_stderr != []
- yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp }, status)
- else
- all_assertions(message) do |a|
- [["stdout", test_stdout, stdout], ["stderr", test_stderr, stderr]].each do |key, exp, act|
- a.for(key) do
- if exp.is_a?(Regexp)
- assert_match(exp, act)
- elsif exp.all? {|e| String === e}
- assert_equal(exp, act.lines.map {|l| l.chomp })
- else
- assert_pattern_list(exp, act)
- 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
- end
-
def assert_ruby_status(args, test_stdin="", message=nil, **opt)
out, _, status = EnvUtil.invoke_ruby(args, test_stdin, true, :merge_to_stdout, **opt)
desc = FailDesc[status, message, out]
@@ -636,57 +559,6 @@ EOT
assert(status.success?, desc)
end
- ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV TERM")
-
- def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **opt)
- unless file and line
- loc, = caller_locations(1,1)
- file ||= loc.path
- line ||= loc.lineno
- end
- src = <<eom
-# -*- coding: #{line += __LINE__; src.encoding}; -*-
- require #{__dir__.dump};include Test::Unit::Assertions
- END {
- puts [Marshal.dump($!)].pack('m'), "assertions=\#{self._assertions}"
- }
-#{line -= __LINE__; src}
- class Test::Unit::Runner
- @@stop_auto_run = true
- end
-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, **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
- begin
- res = Marshal.load(stdout.unpack("m")[0])
- rescue => marshal_error
- ignore_stderr = nil
- end
- if res
- if bt = res.backtrace
- bt.each do |l|
- l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"}
- end
- bt.concat(caller)
- else
- res.set_backtrace(caller)
- end
- raise res unless SystemExit === res
- end
-
- # really is it succeed?
- unless ignore_stderr
- # the body of assert_separately must not output anything to detect error
- assert(stderr.empty?, FailDesc[status, "assert_separately failed with error message", stderr])
- end
- assert(status.success?, FailDesc[status, "assert_separately failed", stderr])
- raise marshal_error if marshal_error
- end
-
def assert_warning(pat, msg = nil)
result = nil
stderr = EnvUtil.with_default_internal(pat.encoding) {
@@ -799,10 +671,6 @@ eom
assert(1.0/f == -Float::INFINITY, "#{f} is not -0.0")
end
- def assert_file
- AssertFile
- end
-
# pattern_list is an array which contains regexp and :*.
# :* means any sequence.
#
@@ -878,77 +746,6 @@ eom
end
end
- class << (AssertFile = Struct.new(:failure_message).new)
- include Assertions
- def assert_file_predicate(predicate, *args)
- if /\Anot_/ =~ predicate
- predicate = $'
- neg = " not"
- end
- result = File.__send__(predicate, *args)
- result = !result if neg
- mesg = "Expected file ".dup << args.shift.inspect
- mesg << "#{neg} to be #{predicate}"
- mesg << mu_pp(args).sub(/\A\[(.*)\]\z/m, '(\1)') unless args.empty?
- mesg << " #{failure_message}" if failure_message
- assert(result, mesg)
- end
- alias method_missing assert_file_predicate
-
- def for(message)
- clone.tap {|a| a.failure_message = message}
- end
- end
-
- class AllFailures
- attr_reader :failures
-
- def initialize
- @count = 0
- @failures = {}
- end
-
- def for(key)
- @count += 1
- yield
- rescue Exception => e
- @failures[key] = [@count, e]
- end
-
- def foreach(*keys)
- keys.each do |key|
- @count += 1
- begin
- yield key
- rescue Exception => e
- @failures[key] = [@count, e]
- end
- end
- end
-
- def message
- i = 0
- total = @count.to_s
- fmt = "%#{total.size}d"
- @failures.map {|k, (n, v)|
- v = v.message
- "\n#{i+=1}. [#{fmt%n}/#{total}] Assertion for #{k.inspect}\n#{v.b.gsub(/^/, ' | ').force_encoding(v.encoding)}"
- }.join("\n")
- end
-
- def pass?
- @failures.empty?
- end
- end
-
- def assert_all_assertions(msg = nil)
- all = AllFailures.new
- yield all
- ensure
- assert(all.pass?, message(msg) {all.message.chomp(".")})
- end
- alias all_assertions assert_all_assertions
-
def assert_all_assertions_foreach(msg = nil, *keys, &block)
all = AllFailures.new
all.foreach(*keys, &block)
diff --git a/tool/lib/test/unit/core_assertions.rb b/tool/lib/test/unit/core_assertions.rb
new file mode 100644
index 0000000000..21be860176
--- /dev/null
+++ b/tool/lib/test/unit/core_assertions.rb
@@ -0,0 +1,216 @@
+# frozen_string_literal: true
+
+require_relative '../../envutil'
+
+module Test
+ module Unit
+ module CoreAssertions
+ include MiniTest::Assertions
+
+ def mu_pp(obj) #:nodoc:
+ obj.pretty_inspect.chomp
+ end
+
+ def assert_file
+ AssertFile
+ end
+
+ FailDesc = proc do |status, message = "", out = ""|
+ pid = status.pid
+ now = Time.now
+ faildesc = proc do
+ if signo = status.termsig
+ signame = Signal.signame(signo)
+ sigdesc = "signal #{signo}"
+ end
+ log = EnvUtil.diagnostic_reports(signame, pid, now)
+ if signame
+ sigdesc = "SIG#{signame} (#{sigdesc})"
+ end
+ if status.coredump?
+ sigdesc = "#{sigdesc} (core dumped)"
+ end
+ full_message = ''.dup
+ message = message.call if Proc === message
+ if message and !message.empty?
+ full_message << message << "\n"
+ end
+ full_message << "pid #{pid}"
+ full_message << " exit #{status.exitstatus}" if status.exited?
+ full_message << " killed by #{sigdesc}" if sigdesc
+ if out and !out.empty?
+ full_message << "\n" << out.b.gsub(/^/, '| ')
+ full_message.sub!(/(?<!\n)\z/, "\n")
+ end
+ if log
+ full_message << "Diagnostic reports:\n" << log.b.gsub(/^/, '| ')
+ end
+ full_message
+ end
+ faildesc
+ end
+
+ def assert_in_out_err(args, test_stdin = "", test_stdout = [], test_stderr = [], message = nil,
+ success: nil, **opt)
+ args = Array(args).dup
+ args.insert((Hash === args[0] ? 1 : 0), '--disable=gems')
+ stdout, stderr, status = EnvUtil.invoke_ruby(args, test_stdin, true, true, **opt)
+ if signo = status.termsig
+ EnvUtil.diagnostic_reports(Signal.signame(signo), status.pid, Time.now)
+ end
+ if block_given?
+ raise "test_stdout ignored, use block only or without block" if test_stdout != []
+ raise "test_stderr ignored, use block only or without block" if test_stderr != []
+ yield(stdout.lines.map {|l| l.chomp }, stderr.lines.map {|l| l.chomp }, status)
+ else
+ all_assertions(message) do |a|
+ [["stdout", test_stdout, stdout], ["stderr", test_stderr, stderr]].each do |key, exp, act|
+ a.for(key) do
+ if exp.is_a?(Regexp)
+ assert_match(exp, act)
+ elsif exp.all? {|e| String === e}
+ assert_equal(exp, act.lines.map {|l| l.chomp })
+ else
+ assert_pattern_list(exp, act)
+ 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
+ end
+
+ ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV TERM")
+
+ def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **opt)
+ unless file and line
+ loc, = caller_locations(1,1)
+ file ||= loc.path
+ line ||= loc.lineno
+ end
+ src = <<eom
+# -*- coding: #{line += __LINE__; src.encoding}; -*-
+ require #{__dir__.dump};include Test::Unit::Assertions
+ END {
+ puts [Marshal.dump($!)].pack('m'), "assertions=\#{self._assertions}"
+ }
+#{line -= __LINE__; src}
+ class Test::Unit::Runner
+ @@stop_auto_run = true
+ end
+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, **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
+ begin
+ res = Marshal.load(stdout.unpack("m")[0])
+ rescue => marshal_error
+ ignore_stderr = nil
+ end
+ if res
+ if bt = res.backtrace
+ bt.each do |l|
+ l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"}
+ end
+ bt.concat(caller)
+ else
+ res.set_backtrace(caller)
+ end
+ raise res unless SystemExit === res
+ end
+
+ # really is it succeed?
+ unless ignore_stderr
+ # the body of assert_separately must not output anything to detect error
+ assert(stderr.empty?, FailDesc[status, "assert_separately failed with error message", stderr])
+ end
+ assert(status.success?, FailDesc[status, "assert_separately failed", stderr])
+ raise marshal_error if marshal_error
+ end
+
+ class << (AssertFile = Struct.new(:failure_message).new)
+ include CoreAssertions
+ def assert_file_predicate(predicate, *args)
+ if /\Anot_/ =~ predicate
+ predicate = $'
+ neg = " not"
+ end
+ result = File.__send__(predicate, *args)
+ result = !result if neg
+ mesg = "Expected file ".dup << args.shift.inspect
+ mesg << "#{neg} to be #{predicate}"
+ mesg << mu_pp(args).sub(/\A\[(.*)\]\z/m, '(\1)') unless args.empty?
+ mesg << " #{failure_message}" if failure_message
+ assert(result, mesg)
+ end
+ alias method_missing assert_file_predicate
+
+ def for(message)
+ clone.tap {|a| a.failure_message = message}
+ end
+ end
+
+ class AllFailures
+ attr_reader :failures
+
+ def initialize
+ @count = 0
+ @failures = {}
+ end
+
+ def for(key)
+ @count += 1
+ yield
+ rescue Exception => e
+ @failures[key] = [@count, e]
+ end
+
+ def foreach(*keys)
+ keys.each do |key|
+ @count += 1
+ begin
+ yield key
+ rescue Exception => e
+ @failures[key] = [@count, e]
+ end
+ end
+ end
+
+ def message
+ i = 0
+ total = @count.to_s
+ fmt = "%#{total.size}d"
+ @failures.map {|k, (n, v)|
+ v = v.message
+ "\n#{i+=1}. [#{fmt%n}/#{total}] Assertion for #{k.inspect}\n#{v.b.gsub(/^/, ' | ').force_encoding(v.encoding)}"
+ }.join("\n")
+ end
+
+ def pass?
+ @failures.empty?
+ end
+ end
+
+ def assert_all_assertions(msg = nil)
+ all = AllFailures.new
+ yield all
+ ensure
+ assert(all.pass?, message(msg) {all.message.chomp(".")})
+ end
+ alias all_assertions assert_all_assertions
+
+ end
+ end
+end