From 4e90145e65aa88734fdd3145adf5586ac78b4523 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 4 Jan 2021 13:25:58 +0900 Subject: [PATCH 01/15] Switch to use GitHub Actions --- .github/workflows/test.yml | 24 ++++++++++++++++++++++++ .travis.yml | 15 --------------- 2 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/test.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..10ce052 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,24 @@ +name: build + +on: [push, pull_request] + +jobs: + build: + name: build (${{ matrix.ruby }} / ${{ matrix.os }}) + strategy: + matrix: + ruby: [ 3.0, 2.7, 2.6, 2.5, 2.4, head ] + os: [ ubuntu-latest, macos-latest ] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@master + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: Install dependencies + run: | + gem install bundler --no-document + bundle install + - name: Run test + run: rake test diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f443f2d..0000000 --- a/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: ruby - -matrix: - include: - - rvm: 2.3 - - rvm: 2.4 - - rvm: 2.5 - - rvm: 2.6 - - rvm: 2.6 - os: osx - - rvm: ruby-head - allow_failures: - - rvm: 2.3 - -script: rake test From 1278524fca3566fc39c346101b22d43b32c44003 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 4 Jan 2021 13:32:37 +0900 Subject: [PATCH 02/15] Try to use 2.3 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 10ce052..c28ff21 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ 3.0, 2.7, 2.6, 2.5, 2.4, head ] + ruby: [ 3.0, 2.7, 2.6, 2.5, 2.4, 2.3, head ] os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: From c6f560e413766f92a581dfdacdb55b448daaa0f5 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Mon, 4 Jan 2021 13:40:18 +0900 Subject: [PATCH 03/15] Revert "Try to use 2.3" This reverts commit 1278524fca3566fc39c346101b22d43b32c44003. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c28ff21..10ce052 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ 3.0, 2.7, 2.6, 2.5, 2.4, 2.3, head ] + ruby: [ 3.0, 2.7, 2.6, 2.5, 2.4, head ] os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: From db61703187bf16285acdaad9ecd583f4b4c7b69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20=C5=A0im=C3=A1nek?= Date: Wed, 6 Jan 2021 02:54:25 +0100 Subject: [PATCH 04/15] Fix example in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4087db3..9dbfc63 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Or install it yourself as: # Create a Logger that prints to STDERR error_log = Logger.new(STDERR) - error_log = Logger.error("fatal error") + error_log = error_log.error("fatal error") ## Development From 4fa0c28e00ac705f7518fea4f409a0f4ca7ad298 Mon Sep 17 00:00:00 2001 From: Gannon McGibbon Date: Tue, 19 Jan 2021 17:13:53 -0500 Subject: [PATCH 05/15] Replace "iff" with "if and only if" iff means if and only if, but readers without that knowledge might assume this to be a spelling mistake. To me, this seems like exclusionary language that is unnecessary. Simply using "if and only if" instead should suffice. --- lib/logger.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/logger.rb b/lib/logger.rb index 5e88574..4205380 100644 --- a/lib/logger.rb +++ b/lib/logger.rb @@ -302,35 +302,35 @@ def datetime_format alias sev_threshold level alias sev_threshold= level= - # Returns +true+ iff the current severity level allows for the printing of + # Returns +true+ if and only if the current severity level allows for the printing of # +DEBUG+ messages. def debug?; level <= DEBUG; end # Sets the severity to DEBUG. def debug!; self.level = DEBUG; end - # Returns +true+ iff the current severity level allows for the printing of + # Returns +true+ if and only if the current severity level allows for the printing of # +INFO+ messages. def info?; level <= INFO; end # Sets the severity to INFO. def info!; self.level = INFO; end - # Returns +true+ iff the current severity level allows for the printing of + # Returns +true+ if and only if the current severity level allows for the printing of # +WARN+ messages. def warn?; level <= WARN; end # Sets the severity to WARN. def warn!; self.level = WARN; end - # Returns +true+ iff the current severity level allows for the printing of + # Returns +true+ if and only if the current severity level allows for the printing of # +ERROR+ messages. def error?; level <= ERROR; end # Sets the severity to ERROR. def error!; self.level = ERROR; end - # Returns +true+ iff the current severity level allows for the printing of + # Returns +true+ if and only if the current severity level allows for the printing of # +FATAL+ messages. def fatal?; level <= FATAL; end From 117747c76f8b829ee02e95a48e1f752eba701bdd Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 30 Mar 2021 11:43:25 +0900 Subject: [PATCH 06/15] Use stable version of actions/checkout --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 10ce052..08ca745 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@master + - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: From c9acc7830f85b79e73d347ba6b0364a67819dd30 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 30 Mar 2021 11:44:29 +0900 Subject: [PATCH 07/15] Don't need to install bundler manually --- .github/workflows/test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 08ca745..1e4300c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,8 +17,6 @@ jobs: with: ruby-version: ${{ matrix.ruby }} - name: Install dependencies - run: | - gem install bundler --no-document - bundle install + run: bundle install - name: Run test run: rake test From f394c2a96db5d1af10a32c84c18c53f9bcf4cd74 Mon Sep 17 00:00:00 2001 From: Olle Jonsson Date: Wed, 31 Mar 2021 15:13:56 +0200 Subject: [PATCH 08/15] README: Remove unused build status badge [ci skip] --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 9dbfc63..45583df 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Logger -[![Build Status](https://travis-ci.com/ruby/logger.svg?branch=master)](https://travis-ci.com/ruby/logger) - Logger is a simple but powerful logging utility to output messages in your Ruby program. Logger has the following features: From e95ee34839f84c79fc5ee41c0d6d44ab4c13e192 Mon Sep 17 00:00:00 2001 From: Olle Jonsson Date: Wed, 31 Mar 2021 15:15:05 +0200 Subject: [PATCH 09/15] CI: Use "3.0" in YAML See https://github.com/actions/runner/issues/849 for notes about floats in YAML. --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1e4300c..3eaf4a3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ 3.0, 2.7, 2.6, 2.5, 2.4, head ] + ruby: [ '3.0', 2.7, 2.6, 2.5, 2.4, head ] os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: From 7ea5a59c7a5abda54af8c803e7f7eae55b65676d Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sat, 11 Sep 2021 13:35:53 +0900 Subject: [PATCH 10/15] Bump up the latest version of CoreAssertions --- Rakefile | 7 + test/lib/core_assertions.rb | 670 ++++++++++++++++++++++++++++++++---- test/lib/envutil.rb | 84 ++++- 3 files changed, 675 insertions(+), 86 deletions(-) diff --git a/Rakefile b/Rakefile index 743c169..65bb8dd 100644 --- a/Rakefile +++ b/Rakefile @@ -25,4 +25,11 @@ task "gh-pages" => :rdoc do FileUtils.cp_r Dir.glob("/tmp/html/*"), "." end +task :sync_tool do + require 'fileutils' + FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib" + FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib" + FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib" +end + task :default => :test diff --git a/test/lib/core_assertions.rb b/test/lib/core_assertions.rb index 9a5fcd5..4471525 100644 --- a/test/lib/core_assertions.rb +++ b/test/lib/core_assertions.rb @@ -2,35 +2,30 @@ module Test module Unit - module CoreAssertions - if defined?(MiniTest) - require_relative '../../envutil' - # for ruby core testing - include MiniTest::Assertions - else - require 'pp' - require_relative 'envutil' - include Test::Unit::Assertions - - def _assertions= n # :nodoc: - @_assertions = n - end + module Assertions + def _assertions= n # :nodoc: + @_assertions = n + end - def _assertions # :nodoc: - @_assertions ||= 0 - end + def _assertions # :nodoc: + @_assertions ||= 0 + end - ## - # Returns a proc that will output +msg+ along with the default message. + ## + # Returns a proc that will output +msg+ along with the default message. - def message msg = nil, ending = nil, &default - proc { - msg = msg.call.chomp(".") if Proc === msg - custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? - "#{custom_message}#{default.call}#{ending || "."}" - } - end + def message msg = nil, ending = nil, &default + proc { + msg = msg.call.chomp(".") if Proc === msg + custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? + "#{custom_message}#{default.call}#{ending || "."}" + } end + end + + module CoreAssertions + require_relative 'envutil' + require 'pp' def mu_pp(obj) #:nodoc: obj.pretty_inspect.chomp @@ -41,38 +36,10 @@ def assert_file end FailDesc = proc do |status, message = "", out = ""| - pid = status.pid now = Time.now - faildesc = proc do - if signo = status.termsig - signame = Signal.signame(signo) - sigdesc = "signal #{signo}" - end - log = EnvUtil.diagnostic_reports(signame, pid, now) - if signame - sigdesc = "SIG#{signame} (#{sigdesc})" - end - if status.coredump? - sigdesc = "#{sigdesc} (core dumped)" - end - full_message = ''.dup - message = message.call if Proc === message - if message and !message.empty? - full_message << message << "\n" - end - full_message << "pid #{pid}" - full_message << " exit #{status.exitstatus}" if status.exited? - full_message << " killed by #{sigdesc}" if sigdesc - if out and !out.empty? - full_message << "\n" << out.b.gsub(/^/, '| ') - full_message.sub!(/(? 0 and b > 0 + assert_operator(a.fdiv(b), :<, limit, message(message) {"#{n}: #{b} => #{a}"}) + end + rescue LoadError + pend + end + + # :call-seq: + # assert_nothing_raised( *args, &block ) + # + #If any exceptions are given as arguments, the assertion will + #fail if one of those exceptions are raised. Otherwise, the test fails + #if any exceptions are raised. + # + #The final argument may be a failure message. + # + # assert_nothing_raised RuntimeError do + # raise Exception #Assertion passes, Exception is not a RuntimeError + # end + # + # assert_nothing_raised do + # raise Exception #Assertion fails + # end + def assert_nothing_raised(*args) + self._assertions += 1 + if Module === args.last + msg = nil + else + msg = args.pop + end + begin + line = __LINE__; yield + rescue Test::Unit::PendedError + raise + rescue Exception => e + bt = e.backtrace + as = e.instance_of?(Test::Unit::AssertionFailedError) + if as + ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /o + bt.reject! {|ln| ans =~ ln} + end + if ((args.empty? && !as) || + args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a }) + msg = message(msg) { + "Exception raised:\n<#{mu_pp(e)}>\n" + + "Backtrace:\n" + + e.backtrace.map{|frame| " #{frame}"}.join("\n") + } + raise Test::Unit::AssertionFailedError, msg.call, bt + else + raise + end + end + end + + def prepare_syntax_check(code, fname = nil, mesg = nil, verbose: nil) + fname ||= caller_locations(2, 1)[0] + mesg ||= fname.to_s + verbose, $VERBOSE = $VERBOSE, verbose + case + when Array === fname + fname, line = *fname + when defined?(fname.path) && defined?(fname.lineno) + fname, line = fname.path, fname.lineno + else + line = 1 + end + yield(code, fname, line, message(mesg) { + if code.end_with?("\n") + "```\n#{code}```\n" + else + "```\n#{code}\n```\n""no-newline" + end + }) + ensure + $VERBOSE = verbose + end + + def assert_valid_syntax(code, *args, **opt) + prepare_syntax_check(code, *args, **opt) do |src, fname, line, mesg| + yield if defined?(yield) + assert_nothing_raised(SyntaxError, mesg) do + assert_equal(:ok, syntax_check(src, fname, line), mesg) + end + end + end + + def assert_normal_exit(testsrc, message = '', child_env: nil, **opt) + assert_valid_syntax(testsrc, caller_locations(1, 1)[0]) + if child_env + child_env = [child_env] + else + child_env = [] + end + out, _, status = EnvUtil.invoke_ruby(child_env + %W'-W0', testsrc, true, :merge_to_stdout, **opt) + assert !status.signaled?, FailDesc[status, message, out] + end + + def assert_ruby_status(args, test_stdin="", message=nil, **opt) + out, _, status = EnvUtil.invoke_ruby(args, test_stdin, true, :merge_to_stdout, **opt) + desc = FailDesc[status, message, out] + assert(!status.signaled?, desc) + message ||= "ruby exit status is not success:" + assert(status.success?, desc) + end + ABORT_SIGNALS = Signal.list.values_at(*%w"ILL ABRT BUS SEGV TERM") + def separated_runner(out = nil) + include(*Test::Unit::TestCase.ancestors.select {|c| !c.is_a?(Class) }) + out = out ? IO.new(out, 'w') : STDOUT + at_exit { + out.puts [Marshal.dump($!)].pack('m'), "assertions=#{self._assertions}" + } + Test::Unit::Runner.class_variable_set(:@@stop_auto_run, true) if defined?(Test::Unit::Runner) + end + def assert_separately(args, file = nil, line = nil, src, ignore_stderr: nil, **opt) unless file and line loc, = caller_locations(1,1) file ||= loc.path line ||= loc.lineno end + capture_stdout = true + unless /mswin|mingw/ =~ RUBY_PLATFORM + capture_stdout = false + opt[:out] = Test::Unit::Runner.output if defined?(Test::Unit::Runner) + res_p, res_c = IO.pipe + opt[:ios] = [res_c] + end src = < marshal_error ignore_stderr = nil + res = nil end - if res + if res and !(SystemExit === res) if bt = res.backtrace bt.each do |l| l.sub!(/\A-:(\d+)/){"#{file}:#{line + $1.to_i}"} @@ -154,7 +304,7 @@ class Test::Unit::Runner else res.set_backtrace(caller) end - raise res unless SystemExit === res + raise res end # really is it succeed? @@ -166,7 +316,300 @@ class Test::Unit::Runner raise marshal_error if marshal_error end + # Run Ractor-related test without influencing the main test suite + def assert_ractor(src, args: [], require: nil, require_relative: nil, file: nil, line: nil, ignore_stderr: nil, **opt) + return unless defined?(Ractor) + + require = "require #{require.inspect}" if require + if require_relative + dir = File.dirname(caller_locations[0,1][0].absolute_path) + full_path = File.expand_path(require_relative, dir) + require = "#{require}; require #{full_path.inspect}" + end + + assert_separately(args, file, line, <<~RUBY, ignore_stderr: ignore_stderr, **opt) + #{require} + previous_verbose = $VERBOSE + $VERBOSE = nil + Ractor.new {} # trigger initial warning + $VERBOSE = previous_verbose + #{src} + RUBY + end + + # :call-seq: + # assert_throw( tag, failure_message = nil, &block ) + # + #Fails unless the given block throws +tag+, returns the caught + #value otherwise. + # + #An optional failure message may be provided as the final argument. + # + # tag = Object.new + # assert_throw(tag, "#{tag} was not thrown!") do + # throw tag + # end + def assert_throw(tag, msg = nil) + ret = catch(tag) do + begin + yield(tag) + rescue UncaughtThrowError => e + thrown = e.tag + end + msg = message(msg) { + "Expected #{mu_pp(tag)} to have been thrown"\ + "#{%Q[, not #{thrown}] if thrown}" + } + assert(false, msg) + end + assert(true) + ret + end + + # :call-seq: + # assert_raise( *args, &block ) + # + #Tests if the given block raises an exception. Acceptable exception + #types may be given as optional arguments. If the last argument is a + #String, it will be used as the error message. + # + # assert_raise do #Fails, no Exceptions are raised + # end + # + # assert_raise NameError do + # puts x #Raises NameError, so assertion succeeds + # end + def assert_raise(*exp, &b) + case exp.last + when String, Proc + msg = exp.pop + end + + begin + yield + rescue Test::Unit::PendedError => e + return e if exp.include? Test::Unit::PendedError + raise e + rescue Exception => e + expected = exp.any? { |ex| + if ex.instance_of? Module then + e.kind_of? ex + else + e.instance_of? ex + end + } + + assert expected, proc { + flunk(message(msg) {"#{mu_pp(exp)} exception expected, not #{mu_pp(e)}"}) + } + + return e + ensure + unless e + exp = exp.first if exp.size == 1 + + flunk(message(msg) {"#{mu_pp(exp)} expected but nothing was raised"}) + end + end + end + + # :call-seq: + # assert_raise_with_message(exception, expected, msg = nil, &block) + # + #Tests if the given block raises an exception with the expected + #message. + # + # assert_raise_with_message(RuntimeError, "foo") do + # nil #Fails, no Exceptions are raised + # end + # + # assert_raise_with_message(RuntimeError, "foo") do + # raise ArgumentError, "foo" #Fails, different Exception is raised + # end + # + # assert_raise_with_message(RuntimeError, "foo") do + # raise "bar" #Fails, RuntimeError is raised but the message differs + # end + # + # assert_raise_with_message(RuntimeError, "foo") do + # raise "foo" #Raises RuntimeError with the message, so assertion succeeds + # end + def assert_raise_with_message(exception, expected, msg = nil, &block) + case expected + when String + assert = :assert_equal + when Regexp + assert = :assert_match + else + raise TypeError, "Expected #{expected.inspect} to be a kind of String or Regexp, not #{expected.class}" + end + + ex = m = nil + EnvUtil.with_default_internal(expected.encoding) do + ex = assert_raise(exception, msg || proc {"Exception(#{exception}) with message matches to #{expected.inspect}"}) do + yield + end + m = ex.message + end + msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"} + + if assert == :assert_equal + assert_equal(expected, m, msg) + else + msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp m}" } + assert expected =~ m, msg + block.binding.eval("proc{|_|$~=_}").call($~) + end + ex + end + + MINI_DIR = File.join(File.dirname(File.expand_path(__FILE__)), "minitest") #:nodoc: + + # :call-seq: + # assert(test, [failure_message]) + # + #Tests if +test+ is true. + # + #+msg+ may be a String or a Proc. If +msg+ is a String, it will be used + #as the failure message. Otherwise, the result of calling +msg+ will be + #used as the message if the assertion fails. + # + #If no +msg+ is given, a default message will be used. + # + # assert(false, "This was expected to be true") + def assert(test, *msgs) + case msg = msgs.first + when String, Proc + when nil + msgs.shift + else + bt = caller.reject { |s| s.start_with?(MINI_DIR) } + raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt + end unless msgs.empty? + super + end + + # :call-seq: + # assert_respond_to( object, method, failure_message = nil ) + # + #Tests if the given Object responds to +method+. + # + #An optional failure message may be provided as the final argument. + # + # assert_respond_to("hello", :reverse) #Succeeds + # assert_respond_to("hello", :does_not_exist) #Fails + def assert_respond_to(obj, (meth, *priv), msg = nil) + unless priv.empty? + msg = message(msg) { + "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}#{" privately" if priv[0]}" + } + return assert obj.respond_to?(meth, *priv), msg + end + #get rid of overcounting + if caller_locations(1, 1)[0].path.start_with?(MINI_DIR) + return if obj.respond_to?(meth) + end + super(obj, meth, msg) + end + + # :call-seq: + # assert_not_respond_to( object, method, failure_message = nil ) + # + #Tests if the given Object does not respond to +method+. + # + #An optional failure message may be provided as the final argument. + # + # assert_not_respond_to("hello", :reverse) #Fails + # assert_not_respond_to("hello", :does_not_exist) #Succeeds + def assert_not_respond_to(obj, (meth, *priv), msg = nil) + unless priv.empty? + msg = message(msg) { + "Expected #{mu_pp(obj)} (#{obj.class}) to not respond to ##{meth}#{" privately" if priv[0]}" + } + return assert !obj.respond_to?(meth, *priv), msg + end + #get rid of overcounting + if caller_locations(1, 1)[0].path.start_with?(MINI_DIR) + return unless obj.respond_to?(meth) + end + refute_respond_to(obj, meth, msg) + end + + # pattern_list is an array which contains regexp and :*. + # :* means any sequence. + # + # pattern_list is anchored. + # Use [:*, regexp, :*] for non-anchored match. + def assert_pattern_list(pattern_list, actual, message=nil) + rest = actual + anchored = true + pattern_list.each_with_index {|pattern, i| + if pattern == :* + anchored = false + else + if anchored + match = /\A#{pattern}/.match(rest) + else + match = pattern.match(rest) + end + unless match + msg = message(msg) { + expect_msg = "Expected #{mu_pp pattern}\n" + if /\n[^\n]/ =~ rest + actual_mesg = +"to match\n" + rest.scan(/.*\n+/) { + actual_mesg << ' ' << $&.inspect << "+\n" + } + actual_mesg.sub!(/\+\n\z/, '') + else + actual_mesg = "to match " + mu_pp(rest) + end + actual_mesg << "\nafter #{i} patterns with #{actual.length - rest.length} characters" + expect_msg + actual_mesg + } + assert false, msg + end + rest = match.post_match + anchored = true + end + } + if anchored + assert_equal("", rest) + end + end + + def assert_warning(pat, msg = nil) + result = nil + stderr = EnvUtil.with_default_internal(pat.encoding) { + EnvUtil.verbose_warning { + result = yield + } + } + msg = message(msg) {diff pat, stderr} + assert(pat === stderr, msg) + result + end + + def assert_warn(*args) + assert_warning(*args) {$VERBOSE = false; yield} + end + + def assert_deprecated_warning(mesg = /deprecated/) + assert_warning(mesg) do + Warning[:deprecated] = true + yield + end + end + + def assert_deprecated_warn(mesg = /deprecated/) + assert_warn(mesg) do + Warning[:deprecated] = true + yield + end + end + class << (AssertFile = Struct.new(:failure_message).new) + include Assertions include CoreAssertions def assert_file_predicate(predicate, *args) if /\Anot_/ =~ predicate @@ -229,6 +672,48 @@ def pass? end end + # threads should respond to shift method. + # Array can be used. + def assert_join_threads(threads, message = nil) + errs = [] + values = [] + while th = threads.shift + begin + values << th.value + rescue Exception + errs << [th, $!] + th = nil + end + end + values + ensure + if th&.alive? + th.raise(Timeout::Error.new) + th.join rescue errs << [th, $!] + end + if !errs.empty? + msg = "exceptions on #{errs.length} threads:\n" + + errs.map {|t, err| + "#{t.inspect}:\n" + + RUBY_VERSION >= "2.5.0" ? err.full_message(highlight: false, order: :top) : err.message + }.join("\n---\n") + if message + msg = "#{message}\n#{msg}" + end + raise Test::Unit::AssertionFailedError, msg + end + end + + def assert_all?(obj, m = nil, &blk) + failed = [] + obj.each do |*a, &b| + unless blk.call(*a, &b) + failed << (a.size > 1 ? a : a[0]) + end + end + assert(failed.empty?, message(m) {failed.pretty_inspect}) + end + def assert_all_assertions(msg = nil) all = AllFailures.new yield all @@ -237,6 +722,47 @@ def assert_all_assertions(msg = nil) end alias all_assertions assert_all_assertions + def assert_all_assertions_foreach(msg = nil, *keys, &block) + all = AllFailures.new + all.foreach(*keys, &block) + ensure + assert(all.pass?, message(msg) {all.message.chomp(".")}) + end + alias all_assertions_foreach assert_all_assertions_foreach + + def message(msg = nil, *args, &default) # :nodoc: + if Proc === msg + super(nil, *args) do + ary = [msg.call, (default.call if default)].compact.reject(&:empty?) + if 1 < ary.length + ary[0...-1] = ary[0...-1].map {|str| str.sub(/(? Date: Tue, 14 Sep 2021 19:39:00 +0900 Subject: [PATCH 11/15] Drop to support Ruby 2.4 --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3eaf4a3..6fb0a11 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ jobs: name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: - ruby: [ '3.0', 2.7, 2.6, 2.5, 2.4, head ] + ruby: [ '3.0', 2.7, 2.6, 2.5, head ] os: [ ubuntu-latest, macos-latest ] runs-on: ${{ matrix.os }} steps: From 958f4ba37dd4c7d85621fa24eea5dceed52d7a5f Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 14 Sep 2021 19:39:11 +0900 Subject: [PATCH 12/15] Rename job name --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6fb0a11..9ae4c1a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,9 +1,9 @@ -name: build +name: test on: [push, pull_request] jobs: - build: + test: name: build (${{ matrix.ruby }} / ${{ matrix.os }}) strategy: matrix: From fbd9315393aa08f6c5dd78cf22309ef1a3166263 Mon Sep 17 00:00:00 2001 From: Olle Jonsson Date: Tue, 14 Sep 2021 13:27:09 +0200 Subject: [PATCH 13/15] gemspec: Drop unused "executables" configuration This gem exposes 0 executables. --- logger.gemspec | 2 -- 1 file changed, 2 deletions(-) diff --git a/logger.gemspec b/logger.gemspec index cd6d97d..ccd4e70 100644 --- a/logger.gemspec +++ b/logger.gemspec @@ -16,8 +16,6 @@ Gem::Specification.new do |spec| spec.licenses = ["Ruby", "BSD-2-Clause"] spec.files = Dir.glob("lib/**/*.rb") + ["logger.gemspec"] - spec.bindir = "exe" - spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] spec.required_ruby_version = ">= 2.3.0" From 2fd5401ad69e440fe5d5bd19b7edc77d823da30b Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 14 Sep 2021 20:53:07 +0900 Subject: [PATCH 14/15] Ignored loading CoreAssertions in test runner --- Rakefile | 2 ++ test/lib/helper.rb | 5 +++++ test/logger/helper.rb | 13 ------------- test/logger/test_logdevice.rb | 2 +- test/logger/test_logger.rb | 2 +- test/logger/test_logperiod.rb | 2 +- test/logger/test_severity.rb | 2 +- 7 files changed, 11 insertions(+), 17 deletions(-) create mode 100644 test/lib/helper.rb delete mode 100644 test/logger/helper.rb diff --git a/Rakefile b/Rakefile index 65bb8dd..24b1b37 100644 --- a/Rakefile +++ b/Rakefile @@ -5,6 +5,8 @@ end require "rake/testtask" Rake::TestTask.new(:test) do |t| + t.libs << "test/lib" + t.ruby_opts << "-rhelper" t.test_files = FileList["test/**/test_*.rb"] end diff --git a/test/lib/helper.rb b/test/lib/helper.rb new file mode 100644 index 0000000..62a7542 --- /dev/null +++ b/test/lib/helper.rb @@ -0,0 +1,5 @@ +require 'test/unit' +# for standalone test suite on ruby/logger +require_relative 'core_assertions' + +Test::Unit::TestCase.include Test::Unit::CoreAssertions diff --git a/test/logger/helper.rb b/test/logger/helper.rb deleted file mode 100644 index 9eaeb20..0000000 --- a/test/logger/helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -ROOT_DIR = File.dirname(__dir__) -$LOAD_PATH.unshift File.join(ROOT_DIR, 'lib') # to use logger in this repo instead of ruby built-in logger -$LOAD_PATH.unshift File.join(ROOT_DIR, 'test', 'lib') # to use custom test-unit in this repo -require 'logger' -require 'test/unit' - -begin - # for standalone test suite on ruby/logger - require 'core_assertions' - - Test::Unit::TestCase.include Test::Unit::CoreAssertions -rescue LoadError -end diff --git a/test/logger/test_logdevice.rb b/test/logger/test_logdevice.rb index 6fefd35..d360fa2 100644 --- a/test/logger/test_logdevice.rb +++ b/test/logger/test_logdevice.rb @@ -1,6 +1,6 @@ # coding: US-ASCII # frozen_string_literal: false -require_relative 'helper' +require 'logger' require 'tempfile' require 'tmpdir' diff --git a/test/logger/test_logger.rb b/test/logger/test_logger.rb index 4bbfd52..3281d17 100644 --- a/test/logger/test_logger.rb +++ b/test/logger/test_logger.rb @@ -1,6 +1,6 @@ # coding: US-ASCII # frozen_string_literal: false -require_relative 'helper' +require 'logger' require 'tempfile' class TestLogger < Test::Unit::TestCase diff --git a/test/logger/test_logperiod.rb b/test/logger/test_logperiod.rb index 3c5cbbc..6e6e5e9 100644 --- a/test/logger/test_logperiod.rb +++ b/test/logger/test_logperiod.rb @@ -1,6 +1,6 @@ # coding: US-ASCII # frozen_string_literal: false -require_relative 'helper' +require 'logger' require 'time' class TestLogPeriod < Test::Unit::TestCase diff --git a/test/logger/test_severity.rb b/test/logger/test_severity.rb index 1197e8a..dad6347 100644 --- a/test/logger/test_severity.rb +++ b/test/logger/test_severity.rb @@ -1,6 +1,6 @@ # coding: US-ASCII # frozen_string_literal: false -require_relative 'helper' +require 'logger' class TestLoggerSeverity < Test::Unit::TestCase def test_enum From 82a59c8d3ff3763ccb43e78c5cb827ba384aa532 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 19 Oct 2021 21:08:04 +0900 Subject: [PATCH 15/15] Bump up logger version to 1.4.4 --- lib/logger/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/logger/version.rb b/lib/logger/version.rb index e0f7183..b2e6909 100644 --- a/lib/logger/version.rb +++ b/lib/logger/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class Logger - VERSION = "1.4.3" + VERSION = "1.4.4" end