Skip to content

Instantly share code, notes, and snippets.

@zenspider
Created May 12, 2024 08:08
Show Gist options
  • Save zenspider/391536c12501eff15894ddd9de9c4198 to your computer and use it in GitHub Desktop.
Save zenspider/391536c12501eff15894ddd9de9c4198 to your computer and use it in GitHub Desktop.
+ Added -Werror to raise on any warning output. (byroot)
Also allows for -Wall or -W or -W<category>.
+ Added UnexpectedWarning as a failure summary type, added count to output if activated.
Fixed all tests to pass vanilla + -Werror.
Found (but not yet fixed) tests that currently fail vanilla if `$-w=nil`.
--- /dev/null 2024-05-12 01:05:47
+++ ./lib/minitest/error_on_warning.rb 2024-05-10 14:07:17
@@ -0,0 +1,11 @@
+module Minitest
+
+ module ErrorOnWarning
+ def warn(message, category: nil)
+ message = "[#{category}] #{message}" if category
+ raise UnexpectedWarning, message
+ end
+ end
+
+ ::Warning.singleton_class.prepend(ErrorOnWarning)
+end
diff -r old/Manifest.txt new/Manifest.txt
--- old/Manifest.txt
+++ new/Manifest.txt
@@ -10,6 +10,7 @@
lib/minitest/autorun.rb
lib/minitest/benchmark.rb
lib/minitest/compress.rb
+lib/minitest/error_on_warning.rb
lib/minitest/expectations.rb
lib/minitest/hell.rb
lib/minitest/manual_plugins.rb
diff -r old/lib/minitest.rb new/lib/minitest.rb
--- old/lib/minitest.rb
+++ new/lib/minitest.rb
@@ -253,6 +253,20 @@
options[:skip] = s.chars.to_a
end
+ ruby27plus = ::Warning.respond_to?(:[]=)
+
+ opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s|
+ options[:Werror] = true
+ case s
+ when "error", "all", nil then
+ require "minitest/error_on_warning"
+ $VERBOSE = true
+ ::Warning[:deprecated] = true if ruby27plus
+ else
+ ::Warning[s.to_sym] = true if ruby27plus # check validity of category
+ end
+ end
+
unless extensions.empty?
opts.separator ""
opts.separator "Known extensions: #{extensions.join(", ")}"
@@ -783,6 +797,11 @@
attr_accessor :errors
##
+ # Total number of tests that warned.
+
+ attr_accessor :warnings
+
+ ##
# Total number of tests that where skipped.
attr_accessor :skips
@@ -797,6 +816,7 @@
self.total_time = nil
self.failures = nil
self.errors = nil
+ self.warnings = nil
self.skips = nil
end
@@ -825,6 +845,7 @@
self.total_time = Minitest.clock_time - start_time
self.failures = aggregate[Assertion].size
self.errors = aggregate[UnexpectedError].size
+ self.warnings = aggregate[UnexpectedWarning].size
self.skips = aggregate[Skip].size
end
end
@@ -900,6 +921,8 @@
results.any?(&:skipped?) unless
options[:verbose] or options[:show_skips] or ENV["MT_NO_SKIP_MSG"]
+ extra.prepend ", %d warnings" % [warnings] if options[:Werror]
+
"%d runs, %d assertions, %d failures, %d errors, %d skips%s" %
[count, assertions, failures, errors, skips, extra]
end
@@ -1035,6 +1058,15 @@
end
##
+ # Assertion raised on warning when running in -Werror mode.
+
+ class UnexpectedWarning < Assertion
+ def result_label # :nodoc:
+ "Warning"
+ end
+ end
+
+ ##
# Provides a simple set of guards that you can use in your tests
# to skip execution if it is not applicable. These methods are
# mixed into Test as both instance and class methods so you
@@ -1107,7 +1139,7 @@
class BacktraceFilter
- MT_RE = %r%lib/minitest% #:nodoc:
+ MT_RE = %r%lib/minitest|internal:warning% #:nodoc:
attr_accessor :regexp
diff -r old/test/minitest/metametameta.rb new/test/minitest/metametameta.rb
--- old/test/minitest/metametameta.rb
+++ new/test/minitest/metametameta.rb
@@ -25,9 +25,20 @@
end
end
end
+
+ def error_on_warn?
+ defined?(Minitest::ErrorOnWarning)
+ end
+
+ def assert_deprecation re = /DEPRECATED/
+ assert_output "", re do
+ yield
+ end
+ rescue Minitest::UnexpectedWarning => e # raised if -Werror was used
+ assert_match re, e.message
+ end
end
-
class FakeNamedTest < Minitest::Test
@@count = 0
diff -r old/test/minitest/test_minitest_assertions.rb new/test/minitest/test_minitest_assertions.rb
--- old/test/minitest/test_minitest_assertions.rb
+++ new/test/minitest/test_minitest_assertions.rb
@@ -1,6 +1,7 @@
# encoding: UTF-8
require "minitest/autorun"
+require_relative "metametameta"
if defined? Encoding then
e = Encoding.default_external
@@ -33,7 +34,6 @@
class DummyTest
include Minitest::Assertions
- # include Minitest::Reportable # TODO: why do I really need this?
attr_accessor :assertions, :failure
@@ -58,15 +58,6 @@
"expected #{@assertion_count} assertions to be fired during the test, not #{@tc.assertions}")
end
- def assert_deprecated name
- dep = /DEPRECATED: #{name}. From #{__FILE__}:\d+(?::.*)?/
- dep = "" if $-w.nil?
-
- assert_output nil, dep do
- yield
- end
- end
-
def assert_triggered expected, klass = Minitest::Assertion
e = assert_raises klass do
yield
@@ -301,7 +292,7 @@
err_re = /Use assert_nil if expecting nil from .*test_minitest_\w+.rb/
err_re = "" if $-w.nil?
- assert_output "", err_re do
+ assert_deprecation err_re do
@tc.assert_equal nil, nil
end
end
@@ -975,15 +966,23 @@
end
def test_assert_send
- assert_deprecated :assert_send do
+ @assertion_count = 0 if error_on_warn?
+ assert_deprecation(/DEPRECATED: assert_send/) do
@tc.assert_send [1, :<, 2]
end
end
def test_assert_send_bad
- assert_deprecated :assert_send do
+ if error_on_warn? then
+ @assertion_count = 0
+ assert_deprecation(/DEPRECATED: assert_send/) do
+ @tc.assert_send [1, :>, 2]
+ end
+ else
assert_triggered "Expected 1.>(*[2]) to return true." do
- @tc.assert_send [1, :>, 2]
+ assert_deprecation(/DEPRECATED: assert_send/) do
+ @tc.assert_send [1, :>, 2]
+ end
end
end
end
@@ -1502,7 +1501,7 @@
d0 = Time.now
d1 = d0 + 86_400 # I am an idiot
- assert_output "", /Stale skip_until \"not yet\" at .*?:\d+$/ do
+ assert_deprecation(/Stale skip_until \"not yet\" at .*?:\d+$/) do
assert_skip_until d0, "not yet"
end
diff -r old/test/minitest/test_minitest_mock.rb new/test/minitest/test_minitest_mock.rb
--- old/test/minitest/test_minitest_mock.rb
+++ new/test/minitest/test_minitest_mock.rb
@@ -423,10 +423,12 @@
arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" }
mock = Minitest::Mock.new
- assert_output nil, /Using MT_KWARGS_HAC. yet passing kwargs/ do
+ assert_deprecation(/Using MT_KWARGS_HAC. yet passing kwargs/) do
mock.expect :foo, nil, [{}], k1: arg1, k2: arg2, k3: arg3
end
+ skip "-Werror" if error_on_warn? # mock above raised, so this is dead
+
mock.foo({}, k1: arg1, k2: arg2, k3: arg3)
assert_mock mock
diff -r old/test/minitest/test_minitest_spec.rb new/test/minitest/test_minitest_spec.rb
--- old/test/minitest/test_minitest_spec.rb
+++ new/test/minitest/test_minitest_spec.rb
@@ -284,18 +284,14 @@
end
it "needs to warn on equality with nil" do
- @assertion_count += 1 # extra test
+ @assertion_count = 3
+ @assertion_count += 2 unless error_on_warn? # 2 extra assertions
+
+ exp = /DEPRECATED: Use assert_nil if expecting nil from .* This will fail in Minitest 6./
- out, err = capture_io do
+ assert_deprecation exp do
assert_success _(nil).must_equal(nil)
end
-
- exp = "DEPRECATED: Use assert_nil if expecting nil from #{__FILE__}:#{__LINE__-3}. " \
- "This will fail in Minitest 6.\n"
- exp = "" if $-w.nil?
-
- assert_empty out
- assert_equal exp, err
end
it "needs to verify floats outside a delta" do
@@ -576,7 +572,8 @@
it "can NOT use must_equal in a thread. It must use expect in a thread" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
- assert_raises RuntimeError do
+
+ assert_raises RuntimeError, Minitest::UnexpectedWarning do
capture_io do
Thread.new { (1 + 1).must_equal 2 }.join
end
@@ -586,9 +583,9 @@
it "fails gracefully when expectation used outside of `it`" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
- @assertion_count += 1
+ @assertion_count += 2 # assert_match is compound
- e = assert_raises RuntimeError do
+ e = assert_raises RuntimeError, Minitest::UnexpectedWarning do
capture_io do
Thread.new { # forces ctx to be nil
describe("woot") do
@@ -598,17 +595,21 @@
end
end
- assert_equal "Calling #must_equal outside of test.", e.message
+ exp = "Calling #must_equal outside of test."
+ exp = "DEPRECATED: global use of must_equal from" if error_on_warn?
+
+ assert_match exp, e.message
end
it "deprecates expectation used without _" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
- @assertion_count += 3
+ @assertion_count += 1
+ @assertion_count += 2 unless error_on_warn?
exp = /DEPRECATED: global use of must_equal from/
- assert_output "", exp do
+ assert_deprecation exp do
(1 + 1).must_equal 2
end
end
@@ -618,12 +619,13 @@
it "deprecates expectation used without _ with empty backtrace_filter" do
skip "N/A" if ENV["MT_NO_EXPECTATIONS"]
- @assertion_count += 3
+ @assertion_count += 1
+ @assertion_count += 2 unless error_on_warn?
exp = /DEPRECATED: global use of must_equal from/
with_empty_backtrace_filter do
- assert_output "", exp do
+ assert_deprecation exp do
(1 + 1).must_equal 2
end
end
diff -r old/test/minitest/test_minitest_test.rb new/test/minitest/test_minitest_test.rb
--- old/test/minitest/test_minitest_test.rb
+++ new/test/minitest/test_minitest_test.rb
@@ -1126,19 +1126,19 @@
end
def test_rubinius_eh
- assert_output "", /DEPRECATED/ do
+ assert_deprecation do
assert self.class.rubinius? "rbx"
end
- assert_output "", /DEPRECATED/ do
+ assert_deprecation do
assert self.rubinius? "rbx"
end
end
def test_maglev_eh
- assert_output "", /DEPRECATED/ do
+ assert_deprecation do
assert self.class.maglev? "maglev"
end
- assert_output "", /DEPRECATED/ do
+ assert_deprecation do
assert self.maglev? "maglev"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment