From 1dc6bed0ca6ca379f1c4b2e9fc0dee72dbf1e205 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 3 Mar 2022 14:43:11 +0100 Subject: Update to ruby/mspec@bd47c2a --- spec/mspec/bin/mspec | 2 +- spec/mspec/lib/mspec/commands/mspec.rb | 6 ++++-- spec/mspec/lib/mspec/matchers/raise_error.rb | 6 ++++-- spec/mspec/lib/mspec/runner/exception.rb | 2 +- spec/mspec/lib/mspec/runner/formatters/base.rb | 18 +++++++++++++----- spec/mspec/lib/mspec/runner/mspec.rb | 2 +- spec/mspec/lib/mspec/utils/options.rb | 11 ++++++++++- spec/mspec/lib/mspec/utils/script.rb | 15 ++++++++++++++- 8 files changed, 48 insertions(+), 14 deletions(-) diff --git a/spec/mspec/bin/mspec b/spec/mspec/bin/mspec index f833257bb0..5bd753c06d 100755 --- a/spec/mspec/bin/mspec +++ b/spec/mspec/bin/mspec @@ -4,4 +4,4 @@ $:.unshift File.expand_path('../../lib', __FILE__) require 'mspec/commands/mspec' -MSpecMain.main +MSpecMain.main(false) diff --git a/spec/mspec/lib/mspec/commands/mspec.rb b/spec/mspec/lib/mspec/commands/mspec.rb index 9d82949ff1..9c38cebcda 100755 --- a/spec/mspec/lib/mspec/commands/mspec.rb +++ b/spec/mspec/lib/mspec/commands/mspec.rb @@ -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 diff --git a/spec/mspec/lib/mspec/matchers/raise_error.rb b/spec/mspec/lib/mspec/matchers/raise_error.rb index 0ee8953519..54378bb34c 100644 --- a/spec/mspec/lib/mspec/matchers/raise_error.rb +++ b/spec/mspec/lib/mspec/matchers/raise_error.rb @@ -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 diff --git a/spec/mspec/lib/mspec/runner/exception.rb b/spec/mspec/lib/mspec/runner/exception.rb index e07f02f684..23375733e6 100644 --- a/spec/mspec/lib/mspec/runner/exception.rb +++ b/spec/mspec/lib/mspec/runner/exception.rb @@ -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}" diff --git a/spec/mspec/lib/mspec/runner/formatters/base.rb b/spec/mspec/lib/mspec/runner/formatters/base.rb index 6c075c4d0a..c7c50c40d8 100644 --- a/spec/mspec/lib/mspec/runner/formatters/base.rb +++ b/spec/mspec/lib/mspec/runner/formatters/base.rb @@ -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? + 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 - @out = File.open out, "w" + @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. diff --git a/spec/mspec/lib/mspec/runner/mspec.rb b/spec/mspec/lib/mspec/runner/mspec.rb index 8331086196..19cf59b7d2 100644 --- a/spec/mspec/lib/mspec/runner/mspec.rb +++ b/spec/mspec/lib/mspec/runner/mspec.rb @@ -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 diff --git a/spec/mspec/lib/mspec/utils/options.rb b/spec/mspec/lib/mspec/utils/options.rb index bef1dbdd2e..23a4c9a2a0 100644 --- a/spec/mspec/lib/mspec/utils/options.rb +++ b/spec/mspec/lib/mspec/utils/options.rb @@ -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 diff --git a/spec/mspec/lib/mspec/utils/script.rb b/spec/mspec/lib/mspec/utils/script.rb index a77476ee2e..b9f8b17fdc 100644 --- a/spec/mspec/lib/mspec/utils/script.rb +++ b/spec/mspec/lib/mspec/utils/script.rb @@ -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' -- cgit v1.2.1