pax_global_header 0000666 0000000 0000000 00000000064 14730577022 0014521 g ustar 00root root 0000000 0000000 52 comment=180123020ea837bbfce5387fafaf01a0c4364578
ruby-warning-1.5.0/ 0000775 0000000 0000000 00000000000 14730577022 0014150 5 ustar 00root root 0000000 0000000 ruby-warning-1.5.0/.ci.gemfile 0000664 0000000 0000000 00000000114 14730577022 0016147 0 ustar 00root root 0000000 0000000 source 'https://rubygems.org'
gem 'rake'
gem 'minitest-global_expectations'
ruby-warning-1.5.0/.github/ 0000775 0000000 0000000 00000000000 14730577022 0015510 5 ustar 00root root 0000000 0000000 ruby-warning-1.5.0/.github/workflows/ 0000775 0000000 0000000 00000000000 14730577022 0017545 5 ustar 00root root 0000000 0000000 ruby-warning-1.5.0/.github/workflows/ci.yml 0000664 0000000 0000000 00000001016 14730577022 0020661 0 ustar 00root root 0000000 0000000 name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
permissions:
contents: read
jobs:
tests:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: [ 2.4, 2.5, 2.6, 2.7, "3.0", 3.1, 3.2, 3.3]
name: ${{ matrix.ruby }}
env:
BUNDLE_GEMFILE: .ci.gemfile
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- run: bundle exec rake
ruby-warning-1.5.0/.gitignore 0000664 0000000 0000000 00000000037 14730577022 0016140 0 ustar 00root root 0000000 0000000 /warning-*.gem
/rdoc
/coverage
ruby-warning-1.5.0/CHANGELOG 0000664 0000000 0000000 00000004722 14730577022 0015367 0 ustar 00root root 0000000 0000000 === 1.5.0 (2024-12-18)
* Handle warning formats produced by prism compiler (jeremyevans)
* Add support for :default_gem_removal as regexp argument to Warning.ignore (jamiemccarthy, jeremyevans) (#24)
=== 1.4.0 (2024-05-24)
* Add support for :ignored_block as regexp argument to Warning.ignore (jeremyevans)
* Support new warning format in Ruby 3.4 (jeremyevans)
=== 1.3.0 (2022-07-14)
* Allow Warning.clear to take a block, and restore current state after block (splattael) (#18, #20)
* Raise ArgumentError if Warning.process is passed non-String as first argument (splattael) (#17, #19)
=== 1.2.1 (2021-10-04)
* Recognize additional void context warnings (kachick) (#13)
=== 1.2.0 (2021-02-16)
* Add support for :void_context as regexp argument to Warning.ignore (jeremyevans)
* Support :category keyword to Warning.warn on Ruby 3.0 (jeremyevans)
* Fix :taint warning handling on Ruby 3.0 (jeremyevans)
* Fix :ambiguous_slash warning handling on Ruby 3.0 (jeremyevans)
=== 1.1.0 (2020-06-12)
* Allow Warning.process to be called with a hash of actions instead of a block (jeremyevans)
* Handle Warning.process blocks that return :default, :backtrace, or :raise specially (jeremyevans)
* Add support for :mismatched_indentations as regexp argument to Warning.ignore (qortex) (#7)
=== 1.0.0 (2020-01-21)
* Add support for :taint as regexp argument to Warning.ignore (jeremyevans)
* Add support for :safe as regexp argument to Warning.ignore (jeremyevans)
* Add Warning.dedup for deduplicating warnings (jeremyevans)
* Add support for :keyword_separation as regexp argument to Warning.ignore (jeremyevans)
=== 0.10.1 (2017-11-16)
* Correctly handle Warning.freeze (jeremyevans)
=== 0.10.0 (2016-11-16)
* Add support for :arg_prefix and :shadow as regexp argument to Warning.ignore (jeremyevans)
* Add support for :useless_operator as regexp argument to Warning.ignore (jeremyevans)
* Add support for :missing_gvar as regexp argument to Warning.ignore (jeremyevans)
* Add support for :ambiguous_slash and :unused_var as regexp arguments to Warning.ignore (jeremyevans)
* Add support for :fixnum and :bignum as regexp arguments to Warning.ignore (jeremyevans)
* Add support for array of symbols as regexp argument to Warning.ignore (jeremyevans)
* Add support for :not_reached as regexp argument to Warning.ignore (jeremyevans)
* Add support for :missing_ivar and :method_redefined as regexp argument to Warning.ignore (jeremyevans)
=== 0.9.0 (2016-08-09)
* Initial Public Release
ruby-warning-1.5.0/MIT-LICENSE 0000664 0000000 0000000 00000002026 14730577022 0015604 0 ustar 00root root 0000000 0000000 Copyright (c) 2016-2022 Jeremy Evans
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
ruby-warning-1.5.0/README.rdoc 0000664 0000000 0000000 00000011305 14730577022 0015756 0 ustar 00root root 0000000 0000000 = ruby-warning
ruby-warning adds custom processing for warnings, including the
ability to ignore specific warning messages, ignore warnings
in specific files/directories, include backtraces with warnings,
treat warnings as errors, deduplicate warnings, and add
custom handling for all warnings in specific files/directories.
ruby-warning requires ruby 2.4+, as previous versions of ruby do
not support custom processing of warnings.
= Installation
gem install warning
= Source Code
Source code is available on GitHub at https://github.com/jeremyevans/ruby-warning
= Usage
By default, requiring the library does not make changes to how ruby processes
warnings, it just adds methods that allow you to customize the processing.
Warning.ignore takes a regexp and optionally a path prefix, and ignores
any warning that matches the regular expression if it starts with the path
prefix. It can also take a symbol or an array of symbols, and will use an
appropriate regexp. The supported symbols are:
* :arg_prefix
* :ambiguous_slash
* :bignum
* :default_gem_removal
* :fixnum
* :ignored_block
* :keyword_separation
* :method_redefined
* :mismatched_indentations
* :missing_gvar
* :missing_ivar
* :not_reached
* :safe
* :shadow
* :taint
* :unused_var
* :useless_operator
* :void_context
Warning.process takes an optional path prefix and a block, and if the
warning string starts with the path prefix, it calls the block with the warning
string instead of performing the default behavior. You can call
Warning.process multiple times and it will operate intelligently,
choosing the longest path prefix that the string starts with.
Warning.process blocks can return +:default+ to use the default
behavior, +:backtrace+ to use the default behavior and also print the backtrace
or +:raise+ to raise the warning string as a RuntimeError.
Warning.process can also accept a hash of actions instead of a block,
with keys being regexps (or symbols supported by Warning.ignore) and
values being callable objects (or +:default+, +:backtrace+, or +:raise+).
Warning.dedup deduplicates warnings, so that if a warning is received
that is the same as a warning that has already been processed, the warning is
ignored. Note that this should be used with care, since if the application
generates an arbitrary number of unique warnings, that can lead to unbounded
memory growth.
Warning.clear resets the library to its initial state, clearing the
current ignored warnings and warning processors, and turning off deduplication.
By using path prefixes, it's fairly easy for a gem to set that specific warnings
should be ignored inside the gem's directory.
Note that path prefixes will not correctly handle warnings raised by
Kernel#warn, unless the warning message given to Kernel#warn
starts with the filename where the warning is used. The Kernel#warn
+:uplevel+ option will make sure the warning starts with the filename.
Note that many of the warnings this library can ignore are warnings caused
during compilation (i.e. when files are loaded via require). You should
require this library and setup the appropriate warning handling before
loading any code that could cause warnings.
= Examples
# Ignore all uninitialized instance variable warnings
Warning.ignore(/instance variable @\w+ not initialized/)
# Ignore all uninitialized instance variable warnings in current file
Warning.ignore(/instance variable @\w+ not initialized/, __FILE__)
# Ignore all uninitialized instance variable warnings in current file
Warning.ignore(:missing_ivar, __FILE__)
# Ignore all Fixnum and Bignum warnings in current file
Warning.ignore([:fixnum, :bignum], __FILE__)
# Write warning to LOGGER at level warning
Warning.process do |warning|
LOGGER.warning(warning)
end
# Write warnings in the current file to LOGGER at level error
Warning.process(__FILE__) do |warning|
LOGGER.error(warning)
end
# Write warnings in the current file to $stderr, but include backtrace
Warning.process(__FILE__) do |warning|
:backtrace
end
# Raise warnings in the current file as RuntimeErrors, with the warning
# string as the exception message
Warning.process(__FILE__) do |warning|
:raise
end
# Raise keyword argument separation warnings in the current file as
# RuntimeErrors, and write ambiguous slash warnings to $stderr, including
# the backtrace
Warning.process(__FILE__, keyword_separation: :raise,
ambiguous_slash: :backtrace)
# Deduplicate warnings
Warning.dedup
# Ignore all warnings in Gem dependencies
Gem.path.each do |path|
Warning.ignore(//, path)
end
= License
MIT
= Author
Jeremy Evans
ruby-warning-1.5.0/Rakefile 0000664 0000000 0000000 00000002277 14730577022 0015625 0 ustar 00root root 0000000 0000000 require "rake"
require "rake/clean"
require "rdoc/task"
CLEAN.include ["warning-*.gem", "rdoc"]
desc "Build warning gem"
task :package=>[:clean] do |p|
sh %{#{FileUtils::RUBY} -S gem build warning.gemspec}
end
### Specs
desc "Run tests"
task :test do
sh "#{FileUtils::RUBY} -w #{'-W:strict_unused_block' if RUBY_VERSION >= '3.4'} test/test_warning.rb"
end
desc "Run tests with frozen Warning"
task :test_freeze do
sh "#{FileUtils::RUBY} -w #{'-W:strict_unused_block' if RUBY_VERSION >= '3.4'} test/test_freeze_warning.rb"
end
desc "Run tests with coverage"
task :test_cov do
ENV['COVERAGE'] = 'regular'
sh "#{FileUtils::RUBY} -w test/test_warning.rb"
ENV['COVERAGE'] = 'frozen'
sh "#{FileUtils::RUBY} -w test/test_freeze_warning.rb"
end
desc "Run all tests"
task :default=>[:test, :test_freeze]
### RDoc
RDOC_OPTS = ['--main', 'README.rdoc', "--quiet", "--line-numbers", "--inline-source", '--title', 'ruby-warning: Add custom processing for warnings']
begin
gem 'hanna'
RDOC_OPTS.concat(['-f', 'hanna'])
rescue Gem::LoadError
end
RDoc::Task.new do |rdoc|
rdoc.rdoc_dir = "rdoc"
rdoc.options += RDOC_OPTS
rdoc.rdoc_files.add %w"README.rdoc CHANGELOG MIT-LICENSE lib/**/*.rb"
end
ruby-warning-1.5.0/lib/ 0000775 0000000 0000000 00000000000 14730577022 0014716 5 ustar 00root root 0000000 0000000 ruby-warning-1.5.0/lib/warning.rb 0000664 0000000 0000000 00000026474 14730577022 0016725 0 ustar 00root root 0000000 0000000 require 'monitor'
module Warning
module Processor
# Map of symbols to regexps for warning messages to ignore.
IGNORE_MAP = {
ambiguous_slash: /: warning: ambiguous first argument; put parentheses or a space even after [`']\/' operator\n\z|: warning: ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after [`']\/' operator\n\z|ambiguous `\/`; wrap regexp in parentheses or add a space after `\/` operator\n\z/,
arg_prefix: /: warning: ([`'][&\*]'||ambiguous `[\*&]` has been) interpreted as( an)? argument prefix\n\z/,
bignum: /: warning: constant ::Bignum is deprecated\n\z/,
default_gem_removal: /: warning: .+? was loaded from the standard library, but will no longer be part of the default gems starting from Ruby [\d.]+\./,
fixnum: /: warning: constant ::Fixnum is deprecated\n\z/,
ignored_block: /: warning: the block passed to '.+' defined at .+:\d+ may be ignored\n\z/,
method_redefined: /: warning: method redefined; discarding old .+\n\z|: warning: previous definition of .+ was here\n\z/,
missing_gvar: /: warning: global variable [`']\$.+' not initialized\n\z/,
missing_ivar: /: warning: instance variable @.+ not initialized\n\z/,
not_reached: /: warning: statement not reached\n\z/,
shadow: /: warning: shadowing outer local variable - \w+\n\z/,
unused_var: /: warning: assigned but unused variable - \w+\n\z/,
useless_operator: /: warning: possibly useless use of [>method /regexp/
# :bignum :: Ignore warnings when referencing the ::Bignum constant.
# :default_gem_removal :: Ignore warnings that a gem will be removed from the default gems
# in a future Ruby version.
# :fixnum :: Ignore warnings when referencing the ::Fixnum constant.
# :keyword_separation :: Ignore warnings related to keyword argument separation.
# :method_redefined :: Ignore warnings when defining a method in a class/module where a
# method of the same name was already defined in that class/module.
# :missing_gvar :: Ignore warnings for accesses to global variables
# that have not yet been initialized
# :missing_ivar :: Ignore warnings for accesses to instance variables
# that have not yet been initialized
# :not_reached :: Ignore statement not reached warnings.
# :safe :: Ignore warnings related to $SAFE and related C-API functions.
# :shadow :: Ignore warnings related to shadowing outer local variables.
# :taint :: Ignore warnings related to taint and related methods and C-API functions.
# :unused_var :: Ignore warnings for unused variables.
# :useless_operator :: Ignore warnings when using operators such as == and > when the
# result is not used.
# :void_context :: Ignore warnings for :: to reference constants when the result is not
# used (often used to trigger autoload).
#
# Examples:
#
# # Ignore all uninitialized instance variable warnings
# Warning.ignore(/instance variable @\w+ not initialized/)
#
# # Ignore all uninitialized instance variable warnings in current file
# Warning.ignore(/instance variable @\w+ not initialized/, __FILE__)
#
# # Ignore all uninitialized instance variable warnings in current file
# Warning.ignore(:missing_ivar, __FILE__)
#
# # Ignore all uninitialized instance variable and method redefined warnings in current file
# Warning.ignore([:missing_ivar, :method_redefined], __FILE__)
def ignore(regexp, path='')
unless regexp = convert_regexp(regexp)
raise TypeError, "first argument to Warning.ignore should be Regexp, Symbol, or Array of Symbols, got #{regexp.inspect}"
end
synchronize do
@ignore << [path, regexp]
end
nil
end
# Handle all warnings starting with the given path, instead of
# the default behavior of printing them to $stderr. Examples:
#
# # Write warning to LOGGER at level warning
# Warning.process do |warning|
# LOGGER.warning(warning)
# end
#
# # Write warnings in the current file to LOGGER at level error level
# Warning.process(__FILE__) do |warning|
# LOGGER.error(warning)
# end
#
# The block can return one of the following symbols:
#
# :default :: Take the default action (call super, printing to $stderr).
# :backtrace :: Take the default action (call super, printing to $stderr),
# and also print the backtrace.
# :raise :: Raise a RuntimeError with the warning as the message.
#
# If the block returns anything else, it is assumed the block completely handled
# the warning and takes no other action.
#
# Instead of passing a block, you can pass a hash of actions to take for specific
# warnings, using regexp as keys and a callable objects as values:
#
# Warning.process(__FILE__,
# /instance variable @\w+ not initialized/ => proc do |warning|
# LOGGER.warning(warning)
# end,
# /global variable [`']\$\w+' not initialized/ => proc do |warning|
# LOGGER.error(warning)
# end
# )
#
# Instead of passing a regexp as a key, you can pass a symbol that is recognized
# by Warning.ignore. Instead of passing a callable object as a value, you can
# pass a symbol, which will be treated as a callable object that returns that symbol:
#
# Warning.process(__FILE__, :missing_ivar=>:backtrace, :keyword_separation=>:raise)
def process(path='', actions=nil, &block)
unless path.is_a?(String)
raise ArgumentError, "path must be a String (given an instance of #{path.class})"
end
if block
if actions
raise ArgumentError, "cannot pass both actions and block to Warning.process"
end
elsif actions
block = {}
actions.each do |regexp, value|
unless regexp = convert_regexp(regexp)
raise TypeError, "action provided to Warning.process should be Regexp, Symbol, or Array of Symbols, got #{regexp.inspect}"
end
block[regexp] = ACTION_PROC_MAP[value] || value
end
else
raise ArgumentError, "must pass either actions or block to Warning.process"
end
synchronize do
@process << [path, block]
@process.sort_by!(&:first)
@process.reverse!
end
nil
end
if RUBY_VERSION >= '3.0'
method_args = ', category: nil'
super_ = "category ? super : super(str)"
# :nocov:
else
super_ = "super"
# :nocov:
end
class_eval(<<-END, __FILE__, __LINE__+1)
def warn(str#{method_args})
synchronize{@ignore.dup}.each do |path, regexp|
if str.start_with?(path) && regexp.match?(str)
return
end
end
if @dedup
if synchronize{@dedup[str]}
return
end
synchronize{@dedup[str] = true}
end
action = catch(:action) do
synchronize{@process.dup}.each do |path, block|
if str.start_with?(path)
if block.is_a?(Hash)
block.each do |regexp, blk|
if regexp.match?(str)
throw :action, blk.call(str)
end
end
else
throw :action, block.call(str)
end
end
end
:default
end
case action
when :default
#{super_}
when :backtrace
#{super_}
$stderr.puts caller
when :raise
raise str
else
# nothing
end
nil
end
END
private
# Convert the given Regexp, Symbol, or Array of Symbols into a Regexp.
def convert_regexp(regexp)
case regexp
when Regexp
regexp
when Symbol
IGNORE_MAP.fetch(regexp)
when Array
Regexp.union(regexp.map{|re| IGNORE_MAP.fetch(re)})
else
# nothing
end
end
def synchronize(&block)
@monitor.synchronize(&block)
end
end
@ignore = []
@process = []
@dedup = false
@monitor = Monitor.new
extend Processor
end
ruby-warning-1.5.0/test/ 0000775 0000000 0000000 00000000000 14730577022 0015127 5 ustar 00root root 0000000 0000000 ruby-warning-1.5.0/test/default_gem_usage.rb 0000664 0000000 0000000 00000000160 14730577022 0021111 0 ustar 00root root 0000000 0000000 require_relative '../lib/warning'
require 'bundler/inline'
Warning.ignore :default_gem_removal
gemfile do
end
ruby-warning-1.5.0/test/default_gem_usage_32.rb 0000664 0000000 0000000 00000000064 14730577022 0021420 0 ustar 00root root 0000000 0000000 require_relative 'default_gem_usage'
require 'racc'
ruby-warning-1.5.0/test/default_gem_usage_33.rb 0000664 0000000 0000000 00000000063 14730577022 0021420 0 ustar 00root root 0000000 0000000 require_relative 'default_gem_usage'
require 'csv'
ruby-warning-1.5.0/test/default_gem_usage_34.rb 0000664 0000000 0000000 00000000066 14730577022 0021424 0 ustar 00root root 0000000 0000000 require_relative 'default_gem_usage'
require 'fiddle'
ruby-warning-1.5.0/test/fixtures/ 0000775 0000000 0000000 00000000000 14730577022 0017000 5 ustar 00root root 0000000 0000000 ruby-warning-1.5.0/test/fixtures/mismatched_indentations.rb 0000664 0000000 0000000 00000000144 14730577022 0024221 0 ustar 00root root 0000000 0000000 # Example that will trigger the "mismatched indentations" warning from Ruby
if 2 > 1
true
end
ruby-warning-1.5.0/test/test_freeze_warning.rb 0000664 0000000 0000000 00000003261 14730577022 0021522 0 ustar 00root root 0000000 0000000 require_relative 'test_helper'
class WarningFreezeTest < Minitest::Test
module EnvUtil
def verbose_warning
stderr = String.new
class << stderr
alias write <<
end
stderr, $stderr, verbose, $VERBOSE = $stderr, stderr, $VERBOSE, true
yield stderr
return $stderr
ensure
stderr, $stderr, $VERBOSE = $stderr, stderr, verbose
end
module_function :verbose_warning
def with_default_internal(enc)
verbose, $VERBOSE = $VERBOSE, nil
origenc, Encoding.default_internal = Encoding.default_internal, enc
$VERBOSE = verbose
yield
ensure
verbose, $VERBOSE = $VERBOSE, nil
Encoding.default_internal = origenc
$VERBOSE = verbose
end
module_function :with_default_internal
end
def assert_warning(pat, msg = nil)
stderr = EnvUtil.verbose_warning {
EnvUtil.with_default_internal(pat.encoding) {
yield
}
}
msg = message(msg) {diff pat, stderr}
assert(pat === stderr, msg)
end
def test_warning_ignore
w = nil
Warning.ignore(/global variable [`']\$test_warning_ignore' not initialized/)
Warning.process do |warning|
w = [4, warning]
end
Warning.freeze
assert_raises RuntimeError do
Warning.ignore(/global variable [`']\$test_warning_ignore' not initialized/)
end
assert_raises RuntimeError do
Warning.process{|warning| w = [4, warning]}
end
assert_warning '' do
$test_warning_ignore
end
assert_nil w
assert_warning '' do
$test_warning_ignore2
end
assert_equal(4, w.first)
assert_match(/global variable [`']\$test_warning_ignore2' not initialized/, w.last)
end
end
ruby-warning-1.5.0/test/test_helper.rb 0000664 0000000 0000000 00000000701 14730577022 0017770 0 ustar 00root root 0000000 0000000 if coverage_type = ENV.delete('COVERAGE')
require 'simplecov'
SimpleCov.start do
enable_coverage :branch
command_name coverage_type
add_filter "/spec/"
add_group('Missing'){|src| src.covered_percent < 100}
add_group('Covered'){|src| src.covered_percent == 100}
end
end
ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
require 'minitest/global_expectations/autorun'
require_relative '../lib/warning'
ruby-warning-1.5.0/test/test_warning.rb 0000664 0000000 0000000 00000041246 14730577022 0020167 0 ustar 00root root 0000000 0000000 require_relative 'test_helper'
require 'pathname'
require 'open3'
require 'rbconfig'
class WarningTest < Minitest::Test
module EnvUtil
def verbose_warning
stderr = String.new
class << stderr
alias write <<
def puts(*a)
self << a.join("\n")
end
end
stderr, $stderr, verbose, $VERBOSE = $stderr, stderr, $VERBOSE, true
yield stderr
return $stderr
ensure
stderr, $stderr, $VERBOSE = $stderr, stderr, verbose
end
module_function :verbose_warning
def with_default_internal(enc)
verbose, $VERBOSE = $VERBOSE, nil
origenc, Encoding.default_internal = Encoding.default_internal, enc
$VERBOSE = verbose
yield
ensure
verbose, $VERBOSE = $VERBOSE, nil
Encoding.default_internal = origenc
$VERBOSE = verbose
end
module_function :with_default_internal
end
def assert_warning(pat, msg = nil)
stderr = EnvUtil.verbose_warning {
EnvUtil.with_default_internal(pat.encoding) {
yield
}
}
msg = message(msg) {diff pat, stderr}
assert(pat === stderr, msg)
end
def teardown
Warning.clear
end
def test_warning_clear_ignore
Warning.ignore(/.*/)
assert_warning '' do
Warning.warn 'foo'
end
Warning.clear do
assert_warning 'foo' do
Warning.warn 'foo'
end
end
assert_warning '' do
Warning.warn 'foo'
end
Warning.clear
assert_warning 'foo' do
Warning.warn 'foo'
end
end
def test_warning_clear_process
Warning.process('', /foo/ => :raise)
e = assert_raises(RuntimeError) do
Warning.warn 'foo'
end
assert_equal('foo', e.message)
Warning.clear do
assert_warning 'foo' do
Warning.warn 'foo'
end
end
e = assert_raises(RuntimeError) do
Warning.warn 'foo'
end
assert_equal('foo', e.message)
Warning.clear
assert_warning 'foo' do
Warning.warn 'foo'
end
end
def test_warning_clear_dedup
Warning.dedup
assert_warning 'foo' do
Warning.warn 'foo'
end
assert_warning '' do
Warning.warn 'foo'
end
Warning.clear do
assert_warning 'foo' do
Warning.warn 'foo'
end
assert_warning 'foo' do
Warning.warn 'foo'
end
end
assert_warning '' do
Warning.warn 'foo'
end
Warning.clear
assert_warning 'foo' do
Warning.warn 'foo'
end
assert_warning 'foo' do
Warning.warn 'foo'
end
end
def test_warning_dedup
gvar = ->{$test_warning_dedup}
assert_warning(/global variable [`']\$test_warning_dedup' not initialized/) do
gvar.call
end
assert_warning(/global variable [`']\$test_warning_dedup' not initialized/) do
gvar.call
end
Warning.dedup
assert_warning(/global variable [`']\$test_warning_dedup' not initialized/) do
gvar.call
end
assert_warning('') do
gvar.call
end
end
def test_warning_ignore
assert_warning(/global variable [`']\$test_warning_ignore' not initialized/) do
assert_nil($test_warning_ignore)
end
Warning.ignore(/global variable [`']\$test_warning_ignore' not initialized/)
assert_warning '' do
assert_nil($test_warning_ignore)
end
assert_warning(/global variable [`']\$test_warning_ignore2' not initialized/) do
assert_nil($test_warning_ignore2)
end
Warning.ignore(/global variable [`']\$test_warning_ignore2' not initialized/, __FILE__)
assert_warning '' do
assert_nil($test_warning_ignore2)
end
assert_warning(/global variable [`']\$test_warning_ignore3' not initialized/) do
assert_nil($test_warning_ignore3)
end
Warning.ignore(/global variable [`']\$test_warning_ignore3' not initialized/, __FILE__ + 'a')
assert_warning(/global variable [`']\$test_warning_ignore3' not initialized/) do
assert_nil($test_warning_ignore3)
end
assert_raises(TypeError) do
Warning.ignore(Object.new)
end
end
def test_warning_ignore_missing_ivar
Warning.clear
unless RUBY_VERSION >= '3.0'
assert_warning(/instance variable @ivar not initialized/) do
assert_nil(instance_variable_get(:@ivar))
end
end
Warning.ignore(:missing_ivar, __FILE__)
assert_warning '' do
assert_nil(instance_variable_get(:@ivar))
end
end
def test_warning_ignore_missing_gvar
assert_warning(/global variable [`']\$gvar' not initialized/) do
$gvar
end
Warning.ignore(:missing_gvar, __FILE__)
assert_warning '' do
$gvar
end
end
def test_warning_ignore_method_redefined
def self.a; end
assert_warning(/method redefined; discarding old a.+previous definition of a was here/m) do
def self.a; end
end
Warning.ignore(:method_redefined, __FILE__)
assert_warning '' do
def self.a; end
end
end
def test_warning_ignore_not_reached
assert_warning(/: warning: statement not reached/) do
instance_eval('def self.b; return; 1 end', __FILE__)
end
Warning.ignore(:not_reached, __FILE__)
assert_warning '' do
instance_eval('def self.c; return; 1 end', __FILE__)
end
end
def test_warning_ignore_fixnum
assert_warning(/warning: constant ::Fixnum is deprecated/) do
::Fixnum
end
Warning.ignore(:fixnum, __FILE__)
assert_warning '' do
::Fixnum
end
end if RUBY_VERSION < '3.2'
def test_warning_ignore_bignum
assert_warning(/warning: constant ::Bignum is deprecated/) do
::Bignum
end
Warning.ignore(:bignum, __FILE__)
assert_warning '' do
::Bignum
end
end if RUBY_VERSION < '3.2'
def test_warning_ignore_void_context
assert_warning(/warning: possibly useless use of :: in void context/) do
instance_eval('::Object; nil', __FILE__, __LINE__)
end
Warning.ignore(:void_context, __FILE__)
assert_warning '' do
instance_eval('::Object; nil', __FILE__, __LINE__)
end
assert_warning '' do
instance_eval('Object; nil', __FILE__, __LINE__)
end
assert_warning '' do
instance_eval('v = 0; v; nil', __FILE__, __LINE__)
end
assert_warning '' do
instance_eval('1 > 1; nil', __FILE__, __LINE__)
end
assert_warning '' do
instance_eval('defined? C; nil', __FILE__, __LINE__)
end
if RUBY_VERSION >= '2.6'
assert_warning '' do
instance_eval('1..; nil', __FILE__, __LINE__)
end
end
end
def test_warning_ignore_ambiguous_slash
def self.d(re); end
assert_warning(/warning: ambi/) do
instance_eval('d /a/', __FILE__)
end
Warning.ignore(:ambiguous_slash, __FILE__)
assert_warning '' do
instance_eval('d /a/', __FILE__)
end
end
def test_warning_ignore_unused_var
assert_warning(/warning: assigned but unused variable - \w+/) do
instance_eval('def self.e; b = 1; 2 end', __FILE__)
end
Warning.ignore(:unused_var, __FILE__)
assert_warning '' do
instance_eval('def self.f; b = 1; 2 end', __FILE__)
end
end
def test_warning_ignore_useless_operator
assert_warning(/warning: possibly useless use of == in void context/) do
instance_eval('1 == 2; true', __FILE__)
end
Warning.ignore(:useless_operator, __FILE__)
assert_warning '' do
instance_eval('1 == 2; true', __FILE__)
end
end
def test_warning_ignore_arg_prefix
assert_warning(/: warning: ([`']\*'|ambiguous `\*` has been) interpreted as( an)? argument prefix/) do
instance_eval('Array *[nil]', __FILE__)
end
assert_warning(/: warning: ([`']&'|ambiguous `&` has been) interpreted as( an)? argument prefix/) do
instance_eval('tap &proc{}', __FILE__)
end
Warning.ignore(:arg_prefix, __FILE__)
assert_warning '' do
instance_eval('Array *[nil]', __FILE__)
instance_eval('tap &proc{}', __FILE__)
end
end
def test_warning_ignore_shadow
assert_warning(/warning: shadowing outer local variable - a/) do
instance_eval('lambda{|a| lambda{|a|}}', __FILE__)
end
Warning.ignore(:shadow, __FILE__)
assert_warning '' do
instance_eval('lambda{|a| lambda{|a|}}', __FILE__)
end
end if RUBY_VERSION < '2.6'
if RUBY_VERSION > '2.7' && RUBY_VERSION < '2.8'
def h2kw(**kw)
end
def kw2h(h, **kw)
end
def skw(h=1, a: 1)
end
def test_warning_ignore_keyword
assert_warning(/warning: Using the last argument as keyword parameters is deprecated; maybe \*\* should be added to the call.*The called method [`']h2kw' is defined here/m) do
h2kw({})
end
assert_warning(/warning: Passing the keyword argument as the last hash parameter is deprecated.*The called method [`']kw2h' is defined here/m) do
kw2h(a: 1)
end
assert_warning(/warning: Splitting the last argument into positional and keyword parameters is deprecated.*The called method [`']skw' is defined here/m) do
skw("b" => 1, a: 2)
end
assert_warning(/warning: Splitting the last argument into positional and keyword parameters is deprecated.*The called method [`']skw' is defined here/m) do
skw({"b" => 1, a: 2})
end
Warning.ignore(:keyword_separation, __FILE__)
assert_warning '' do
h2kw({})
kw2h(a: 1)
skw("b" => 1, a: 2)
skw({"b" => 1, a: 2})
end
end
def test_warning_ignore_safe
assert_warning(/\$SAFE will become a normal global variable in Ruby 3\.0/) do
$SAFE = 0
end
Warning.ignore(:safe, __FILE__)
assert_warning("") do
$SAFE = 0
end
end
end
if RUBY_VERSION > '2.7' && RUBY_VERSION < '3.2'
def test_warning_ignore_taint
o = Object.new
assert_warning(/Object#taint is deprecated and will be removed in Ruby 3\.2/) do
o.taint
end
assert_warning(/Object#untaint is deprecated and will be removed in Ruby 3\.2/) do
o.untaint
end
assert_warning(/Object#tainted\? is deprecated and will be removed in Ruby 3\.2/) do
o.tainted?
end
assert_warning(/Object#trust is deprecated and will be removed in Ruby 3\.2/) do
o.trust
end
assert_warning(/Object#untrust is deprecated and will be removed in Ruby 3\.2/) do
o.untrust
end
assert_warning(/Object#untrusted\? is deprecated and will be removed in Ruby 3\.2/) do
o.untrusted?
end
path = Pathname.new(__FILE__)
assert_warning(/Pathname#taint is deprecated and will be removed in Ruby 3\.2/) do
path.taint
end
assert_warning(/Pathname#untaint is deprecated and will be removed in Ruby 3\.2/) do
path.untaint
end
Warning.ignore(:taint, __FILE__)
assert_warning("") do
o.taint
o.untaint
o.tainted?
o.trust
o.untrust
o.untrusted?
p.taint
p.untaint
end
end
end
def test_warning_ignore_ignored_block
Warning.clear
def self.foo_test_warning_ignore_ignored_block; end
if RUBY_VERSION >= '3.4'
assert_warning(/the block passed to '.*foo_test_warning_ignore_ignored_block' defined at #{__FILE__}:#{__LINE__-3} may be ignored/) do
assert_nil(foo_test_warning_ignore_ignored_block{})
end
end
Warning.ignore(:ignored_block, __FILE__)
assert_warning '' do
assert_nil(foo_test_warning_ignore_ignored_block{})
end
end
def test_warning_standard_removal
suffix = RUBY_VERSION[0..2].sub('.', '')
filename = File.join(__dir__, "default_gem_usage_#{suffix}.rb")
if File.file?(filename)
output, status = Open3.capture2e(RbConfig.ruby, filename)
assert_empty output
assert_equal status.to_i, 0
end
end
def test_warning_ignore_symbol_array
def self.c; end
assert_warning(/statement not reached.+method redefined; discarding old c.+previous definition of c was here/m) do
instance_eval('def self.c; return; 1 end', __FILE__)
end
Warning.ignore([:method_redefined, :not_reached], __FILE__)
assert_warning '' do
instance_eval('def self.c; return; 1 end', __FILE__)
end
end
def test_warning_ignore_mismatched_indentation
assert_warning(/warning: mismatched indentations/) do
load 'test/fixtures/mismatched_indentations.rb'
end
Warning.ignore(:mismatched_indentations, 'test/fixtures/mismatched_indentations.rb')
assert_warning '' do
load 'test/fixtures/mismatched_indentations.rb'
end
end
def test_warning_process
warn = nil
Warning.process(__FILE__+'a') do |warning|
warn = [0, warning]
end
assert_warning(/global variable [`']\$test_warning_process' not initialized/) do
$test_warning_process
end
assert_nil(warn)
Warning.process(__FILE__) do |warning|
warn = [1, warning]
end
assert_warning '' do
$test_warning_process2
end
assert_equal(1, warn.first)
assert_match(/global variable [`']\$test_warning_process2' not initialized/, warn.last)
warn = nil
Warning.process(File.dirname(__FILE__)) do |warning|
warn = [2, warning]
end
assert_warning '' do
$test_warning_process3
end
assert_equal(1, warn.first)
assert_match(/global variable [`']\$test_warning_process3' not initialized/, warn.last)
warn = nil
Warning.process(__FILE__+':') do |warning|
warn = [3, warning]
end
assert_warning '' do
$test_warning_process4
end
assert_equal(3, warn.first)
assert_match(/global variable [`']\$test_warning_process4' not initialized/, warn.last)
warn = nil
Warning.clear
assert_warning(/global variable [`']\$test_warning_process5' not initialized/) do
$test_warning_process5
end
assert_nil(warn)
Warning.process do |warning|
warn = [4, warning]
end
assert_warning '' do
$test_warning_process6
end
assert_equal(4, warn.first)
assert_match(/global variable [`']\$test_warning_process6' not initialized/, warn.last)
assert_raises(TypeError) do
Warning.process('', Object.new=>:raise)
end
end
def test_warning_process_block_return_default
w = nil
Warning.process(__FILE__) do |warning|
w = warning
:default
end
assert_warning(/global variable [`']\$test_warning_process_block_return_default' not initialized/) do
$test_warning_process_block_return_default
end
assert_match(/global variable [`']\$test_warning_process_block_return_default' not initialized/, w)
end
def test_warning_process_block_return_backtrace
w = nil
Warning.process(__FILE__) do |warning|
w = warning
:backtrace
end
assert_warning(/global variable [`']\$test_warning_process_block_return_backtrace' not initialized.*#{__FILE__}/m) do
$test_warning_process_block_return_backtrace
end
assert_match(/global variable [`']\$test_warning_process_block_return_backtrace' not initialized/, w)
end
def test_warning_process_block_return_raise
w = nil
Warning.process(__FILE__) do |warning|
w = warning
:raise
end
assert_raises(RuntimeError) do
$test_warning_process_block_return_raise
end
assert_match(/global variable [`']\$test_warning_process_block_return_raise' not initialized/, w)
end
def test_warning_process_action
Warning.process(__FILE__, :method_redefined=>:default, :missing_gvar=>:backtrace, :ambiguous_slash=>:raise)
Warning.process(__FILE__, :not_reached=>proc do |warning|
:raise
end)
assert_warning(/warning: method redefined/) do
Class.new do
def a; end
def a; end
end
end
assert_warning(/global variable [`']\$test_warning_process_action' not initialized.*#{__FILE__}/m) do
$test_warning_process_action
end
e = assert_raises(RuntimeError) do
EnvUtil.verbose_warning{instance_eval('d /a/', __FILE__)}
end
assert_includes(e.message, "warning: ambi")
e = assert_raises(RuntimeError) do
EnvUtil.verbose_warning{instance_eval('def self.b; return; 1 end', __FILE__)}
end
assert_includes(e.message, "warning: statement not reached")
end
def test_warning_process_action_and_block
assert_raises(ArgumentError) do
Warning.process(__FILE__)
end
end
def test_warning_process_no_action_and_no_block
assert_raises(ArgumentError) do
Warning.process(__FILE__, :missing_ivar=>:default){}
end
end
def test_warning_process_path_no_string
e = assert_raises(ArgumentError) do
Warning.process(/foo/) { :raise }
end
assert_includes(e.message, "path must be a String (given an instance of Regexp)")
end
if RUBY_VERSION >= '3.0'
def test_warning_warn_category_keyword
assert_warning('foo') do
Warning.warn("foo", category: :deprecated)
end
end
end
end
ruby-warning-1.5.0/warning.gemspec 0000664 0000000 0000000 00000002612 14730577022 0017163 0 ustar 00root root 0000000 0000000 spec = Gem::Specification.new do |s|
s.name = 'warning'
s.version = '1.5.0'
s.platform = Gem::Platform::RUBY
s.extra_rdoc_files = ["README.rdoc", "CHANGELOG", "MIT-LICENSE"]
s.rdoc_options += ["--quiet", "--line-numbers", "--inline-source", '--title', 'ruby-warning: Add custom processing for warnings', '--main', 'README.rdoc']
s.license = "MIT"
s.summary = "Add custom processing for warnings"
s.author = "Jeremy Evans"
s.email = "code@jeremyevans.net"
s.homepage = "https://github.com/jeremyevans/ruby-warning"
s.required_ruby_version = ">= 2.4.0"
s.files = %w(MIT-LICENSE CHANGELOG README.rdoc) + Dir["lib/**/*.rb"]
s.description = < 'https://github.com/jeremyevans/ruby-warning/issues',
'changelog_uri' => 'https://github.com/jeremyevans/ruby-warning/blob/master/CHANGELOG',
'documentation_uri' => 'https://github.com/jeremyevans/ruby-warning/blob/master/README.rdoc',
'source_code_uri' => 'https://github.com/jeremyevans/ruby-warning',
}
end