warning-1.2.1/0000755000175000017500000000000014130116470011671 5ustar srudsrudwarning-1.2.1/warning.gemspec0000644000175000017500000000451714130116470014712 0ustar srudsrud######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: warning 1.2.1 ruby lib Gem::Specification.new do |s| s.name = "warning".freeze s.version = "1.2.1" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "bug_tracker_uri" => "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" } if s.respond_to? :metadata= s.require_paths = ["lib".freeze] s.authors = ["Jeremy Evans".freeze] s.date = "2021-10-04" s.description = "ruby-warning adds custom processing for warnings, including the\nability to ignore specific warning messages, ignore warnings\nin specific files/directories, include backtraces with warnings,\ntreat warnings as errors, deduplicate warnings, and add\ncustom handling for all warnings in specific files/directories.\n".freeze s.email = "code@jeremyevans.net".freeze s.extra_rdoc_files = ["CHANGELOG".freeze, "MIT-LICENSE".freeze, "README.rdoc".freeze] s.files = ["CHANGELOG".freeze, "MIT-LICENSE".freeze, "README.rdoc".freeze, "Rakefile".freeze, "lib/warning.rb".freeze, "test/fixtures/mismatched_indentations.rb".freeze, "test/test_freeze_warning.rb".freeze, "test/test_warning.rb".freeze] s.homepage = "https://github.com/jeremyevans/ruby-warning".freeze s.licenses = ["MIT".freeze] s.rdoc_options = ["--quiet".freeze, "--line-numbers".freeze, "--inline-source".freeze, "--title".freeze, "ruby-warning: Add custom processing for warnings".freeze, "--main".freeze, "README.rdoc".freeze] s.required_ruby_version = Gem::Requirement.new(">= 2.4.0".freeze) s.rubygems_version = "3.2.5".freeze s.summary = "Add custom processing for warnings".freeze if s.respond_to? :specification_version then s.specification_version = 4 end if s.respond_to? :add_runtime_dependency then s.add_development_dependency(%q.freeze, [">= 0"]) else s.add_dependency(%q.freeze, [">= 0"]) end end warning-1.2.1/Rakefile0000644000175000017500000000176014130116470013342 0ustar srudsrudrequire "rake" require "rake/clean" require 'rake/testtask' 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 test" Rake::TestTask.new do |t| t.libs.push "lib" t.test_files = FileList['test/test_warning.rb'] t.verbose = true end desc "Run test" Rake::TestTask.new(:test_freeze) do |t| t.libs.push "lib" t.test_files = FileList['test/test_freeze_warning.rb'] t.verbose = true 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-nouveau' 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 warning-1.2.1/MIT-LICENSE0000644000175000017500000000202614130116470013325 0ustar srudsrudCopyright (c) 2016-2020 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. warning-1.2.1/CHANGELOG0000644000175000017500000000357514130116470013115 0ustar srudsrud=== 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 warning-1.2.1/lib/0000755000175000017500000000000014130116470012437 5ustar srudsrudwarning-1.2.1/lib/warning.rb0000644000175000017500000002356614130116470014445 0ustar srudsrudrequire '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/, arg_prefix: /: warning: `[&\*]' interpreted as argument prefix\n\z/, bignum: /: warning: constant ::Bignum is deprecated\n\z/, fixnum: /: warning: constant ::Fixnum is deprecated\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. # :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) 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)" else super_ = "super" end class_eval(<<-END, __FILE__, __LINE__+1) def warn(str#{method_args}) synchronize{@ignore.dup}.each do |path, regexp| if str.start_with?(path) && str =~ regexp 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 str =~ regexp 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 warning-1.2.1/README.rdoc0000644000175000017500000001123514130116470013501 0ustar srudsrud= 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 * :fixnum * :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 warning-1.2.1/test/0000755000175000017500000000000014130116470012650 5ustar srudsrudwarning-1.2.1/test/fixtures/0000755000175000017500000000000014130116470014521 5ustar srudsrudwarning-1.2.1/test/fixtures/mismatched_indentations.rb0000644000175000017500000000014414130116470021742 0ustar srudsrud# Example that will trigger the "mismatched indentations" warning from Ruby if 2 > 1 true end warning-1.2.1/test/test_freeze_warning.rb0000644000175000017500000000337614130116470017252 0ustar srudsrudENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins require 'minitest/global_expectations/autorun' require 'warning' class WarningFreezeTest < Minitest::Test module EnvUtil def verbose_warning 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 warning-1.2.1/test/test_warning.rb0000644000175000017500000003415214130116470015706 0ustar srudsrudENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins require 'minitest/global_expectations/autorun' require 'warning' require 'pathname' class WarningTest < Minitest::Test module EnvUtil def verbose_warning stderr = "" 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_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 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 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 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: `\*' interpreted as argument prefix/) do instance_eval('Array *[nil]', __FILE__) end assert_warning(/: warning: `&' interpreted as 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_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) 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 w = nil Warning.process(__FILE__, :method_redefined=>:default, :missing_gvar=>:backtrace, :ambiguous_slash=>:raise) Warning.process(__FILE__, :not_reached=>proc do |warning| w = 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 Warning.process(__FILE__) do |warning| w = warning :raise end assert_raises(RuntimeError, /warning: ambi/) do EnvUtil.verbose_warning{instance_eval('d /a/', __FILE__)} end assert_raises(RuntimeError, /warning: statement not reached/) do EnvUtil.verbose_warning{instance_eval('def self.b; return; 1 end', __FILE__)} end assert_match(/warning: statement not reached/, w) 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 if RUBY_VERSION >= '3.0' def test_warning_warn_category_keyword assert_warning('foo') do Warning.warn("foo", category: :deprecated) end end end end