From 2a171da6b9339d7bd3855609917c1c50981f4c26 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Sun, 20 Dec 2015 22:11:19 -0600 Subject: [PATCH] Hack Minitest to make it less dependent on at_exit --- .rubocop.yml | 26 ++++++++++++++ .rubocop_todo.yml | 7 ---- test/capture_warnings.rb | 8 +++-- test/test_helper.rb | 77 ++++++++++++++++++++++++++++++++-------- 4 files changed, 93 insertions(+), 25 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index db25cbf5..f31d8344 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -58,3 +58,29 @@ Style/MultilineOperationIndentation: Style/BlockDelimiters: Enabled: true EnforcedStyle: line_count_based + +########## test_helper.rb sanity +Style/EndBlock: + Exclude: + - test/test_helper.rb + +Style/SpecialGlobalVars: + Exclude: + - test/test_helper.rb + +Style/GlobalVars: + Exclude: + - test/test_helper.rb + +Style/AndOr: + Exclude: + - test/test_helper.rb + - 'lib/active_model/serializer/lint.rb' + +Style/Not: + Exclude: + - test/test_helper.rb + +Style/ClassCheck: + Exclude: + - test/test_helper.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c9a58846..865022c3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -53,13 +53,6 @@ Style/AlignHash: Exclude: - 'test/action_controller/json_api/pagination_test.rb' -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/AndOr: - Exclude: - - 'lib/active_model/serializer/lint.rb' - # Offense count: 25 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/test/capture_warnings.rb b/test/capture_warnings.rb index d3674cab..2c4d7b64 100644 --- a/test/capture_warnings.rb +++ b/test/capture_warnings.rb @@ -17,17 +17,19 @@ class CaptureWarnings @output = STDOUT end - def execute! + def execute!(minitest_run) $VERBOSE = true $stderr.reopen(stderr_file.path) - - Minitest.after_run do + at_exit do stderr_file.rewind lines = stderr_file.read.split("\n") stderr_file.close! $stderr.reopen(STDERR) after_tests(lines) end + proc do |argv| + minitest_run.call(argv) + end end def after_tests(lines) diff --git a/test/test_helper.rb b/test/test_helper.rb index 9d069820..b87a78f8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -20,27 +20,35 @@ require 'active_support/json' require 'fileutils' FileUtils.mkdir_p(File.expand_path('../../tmp/cache', __FILE__)) +# https://github.com/seattlerb/minitest/blob/master/lib/minitest/autorun.rb gem 'minitest' -require 'minitest/autorun' -require 'minitest/reporters' -Minitest::Reporters.use! -if defined?(Minitest::Test) - $minitest_version = 5 # rubocop:disable Style/GlobalVars - # Minitest 5 - # https://github.com/seattlerb/minitest/blob/e21fdda9d/lib/minitest/autorun.rb - # https://github.com/seattlerb/minitest/blob/e21fdda9d/lib/minitest.rb#L45-L59 -else - $minitest_version = 4 # rubocop:disable Style/GlobalVars +begin + require 'minitest' +rescue LoadError + # Minitest 4 + require 'minitest/unit' + require 'minitest/spec' + require 'minitest/mock' + $minitest_version = 4 # Minitest 4 # https://github.com/seattlerb/minitest/blob/644a52fd0/lib/minitest/autorun.rb # https://github.com/seattlerb/minitest/blob/644a52fd0/lib/minitest/unit.rb#L768-L787 # Ensure backward compatibility with Minitest 4 Minitest = MiniTest unless defined?(Minitest) Minitest::Test = MiniTest::Unit::TestCase - def Minitest.after_run(&block) - MiniTest::Unit.after_tests(&block) - end + minitest_run = ->(argv) { MiniTest::Unit.new.run(argv) } +else + # Minitest 5 + $minitest_version = 5 + # Minitest 5 + # https://github.com/seattlerb/minitest/blob/e21fdda9d/lib/minitest/autorun.rb + # https://github.com/seattlerb/minitest/blob/e21fdda9d/lib/minitest.rb#L45-L59 + require 'minitest/spec' + require 'minitest/mock' + minitest_run = ->(argv) { Minitest.run(argv) } end +require 'minitest/reporters' +Minitest::Reporters.use! # If there's no failure info, try disabling capturing stderr: # `env CAPTURE_STDERR=false rake` @@ -48,7 +56,7 @@ end # for 4.x and 5.x. if ENV['CAPTURE_STDERR'] !~ /false|1/i require 'capture_warnings' - CaptureWarnings.new(_fail_build = true).execute! + minitest_run = CaptureWarnings.new(_fail_build = true).execute!(minitest_run) else $VERBOSE = true end @@ -71,6 +79,45 @@ require 'fixtures/active_record' require 'fixtures/poro' ActiveSupport.on_load(:active_model_serializers) do - $action_controller_logger = ActiveModelSerializers.logger # rubocop:disable Style/GlobalVars + $action_controller_logger = ActiveModelSerializers.logger ActiveModelSerializers.logger = Logger.new(IO::NULL) end + +# From: +# https://github.com/seattlerb/minitest/blob/644a52fd0/lib/minitest/unit.rb#L768-L787 +# https://github.com/seattlerb/minitest/blob/e21fdda9d/lib/minitest.rb#L45-L59 +# But we've replaced `at_exit` with `END` called before the 'at_exit' hook. +class MiniTestHack + def self.autorun(minitest_run) + # don't run if there was a non-exit exception + return if $! and not ($!.kind_of? SystemExit and $!.success?) + + # Original Comment: + # the order here is important. The at_exit handler must be + # installed before anyone else gets a chance to install their + # own, that way we can be assured that our exit will be last + # to run (at_exit stacks). + # + # Now: + # The after_run blocks now only run on SigEXIT, which is fine. + exit_code = nil + + trap('EXIT') do + if $minitest_version == 5 + @@after_run.reverse_each(&:call) + else + @@after_tests.reverse_each(&:call) + end + + exit exit_code || false + end + + exit_code = minitest_run.call(ARGV) + end +end +# Run MiniTest in `END`, so that it finishes before `at_exit` fires, +# which guarantees we can run code after MiniTest finishes +# via an `at_exit` block. +# This is in service of silencing non-app warnings during test run, +# and leaves us with the warnings in our app. +END { MiniTestHack.autorun(minitest_run) }