1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2022-03-03 14:43:11 +01:00
parent c1790f8c11
commit 1dc6bed0ca
8 changed files with 49 additions and 15 deletions

View file

@ -4,4 +4,4 @@ $:.unshift File.expand_path('../../lib', __FILE__)
require 'mspec/commands/mspec'
MSpecMain.main
MSpecMain.main(false)

View file

@ -25,6 +25,7 @@ class MSpecMain < MSpecScript
config[:command] = argv.shift if ["ci", "run", "tag"].include?(argv[0])
options = MSpecOptions.new "mspec [COMMAND] [options] (FILE|DIRECTORY|GLOB)+", 30, config
@options = options
options.doc " The mspec command sets up and invokes the sub-commands"
options.doc " (see below) to enable, for instance, running the specs"
@ -110,8 +111,9 @@ class MSpecMain < MSpecScript
if config[:multi]
exit multi_exec(argv)
else
$stderr.puts "$ #{argv.join(' ')}"
$stderr.flush
log = config[:options].include?('--error-output') ? $stdout : $stderr
log.puts "$ #{argv.join(' ')}"
log.flush
exec(*argv, close_others: false)
end
end

View file

@ -1,4 +1,6 @@
class RaiseErrorMatcher
FAILURE_MESSAGE_FOR_EXCEPTION = {}.compare_by_identity
attr_writer :block
def initialize(exception, message, &block)
@ -15,7 +17,7 @@ class RaiseErrorMatcher
def matches?(proc)
@result = proc.call
return false
rescue Exception => actual
rescue Object => actual
@actual = actual
if matching_exception?(actual)
@ -23,7 +25,7 @@ class RaiseErrorMatcher
@block[actual] if @block
return true
else
actual.instance_variable_set(:@mspec_raise_error_message, failure_message)
FAILURE_MESSAGE_FOR_EXCEPTION[actual] = failure_message
raise actual
end
end

View file

@ -29,7 +29,7 @@ class ExceptionState
if @failure
message
elsif raise_error_message = @exception.instance_variable_get(:@mspec_raise_error_message)
elsif raise_error_message = RaiseErrorMatcher::FAILURE_MESSAGE_FOR_EXCEPTION[@exception]
raise_error_message.join("\n")
else
"#{@exception.class}: #{message}"

View file

@ -1,6 +1,7 @@
require 'mspec/expectations/expectations'
require 'mspec/runner/actions/timer'
require 'mspec/runner/actions/tally'
require 'mspec/utils/options'
if ENV['CHECK_LEAKS']
require 'mspec/runner/actions/leakchecker'
@ -18,10 +19,17 @@ class BaseFormatter
@count = 0 # For subclasses
if out.nil?
@out = $stdout
else
if out
@out = File.open out, "w"
else
@out = $stdout
end
err = MSpecOptions.latest && MSpecOptions.latest.config[:error_output]
if err
@err = (err == 'stderr') ? $stderr : File.open(err, "w")
else
@err = @out
end
end
@ -115,9 +123,9 @@ class BaseFormatter
def print_exception(exc, count)
outcome = exc.failure? ? "FAILED" : "ERROR"
print "\n#{count})\n#{exc.description} #{outcome}\n"
print exc.message, "\n"
print exc.backtrace, "\n"
@err.print "\n#{count})\n#{exc.description} #{outcome}\n"
@err.print exc.message, "\n"
@err.print exc.backtrace, "\n"
end
# A convenience method to allow printing to different outputs.

View file

@ -117,7 +117,7 @@ module MSpec
raise e
rescue SkippedSpecError => e
return false
rescue Exception => exc
rescue Object => exc
register_exit 1
actions :exception, ExceptionState.new(current && current.state, location, exc)
return false

View file

@ -32,6 +32,10 @@ class MSpecOptions
# Raised if an unrecognized option is encountered.
class ParseError < Exception; end
class << self
attr_accessor :latest
end
attr_accessor :config, :banner, :width, :options
def initialize(banner = "", width = 30, config = nil)
@ -46,7 +50,7 @@ class MSpecOptions
@extra << x
}
yield self if block_given?
MSpecOptions.latest = self
end
# Registers an option. Acceptable formats for arguments are:
@ -311,6 +315,11 @@ class MSpecOptions
"Write formatter output to FILE") do |f|
config[:output] = f
end
on("--error-output", "FILE",
"Write error output of failing specs to FILE, or $stderr if value is 'stderr'.") do |f|
config[:error_output] = f
end
end
def filters

View file

@ -37,6 +37,17 @@ class MSpecScript
config[key]
end
class << self
attr_accessor :child_process
end
# True if the current process is the one going to run the specs with `MSpec.process`.
# False for e.g. `mspec` which exec's to `mspec-run`.
# This is useful in .mspec config files.
def self.child_process?
MSpecScript.child_process
end
def initialize
check_version!
@ -267,7 +278,9 @@ class MSpecScript
# Instantiates an instance and calls the series of methods to
# invoke the script.
def self.main
def self.main(child_process = true)
MSpecScript.child_process = child_process
script = new
script.load_default
script.try_load '~/.mspecrc'