ruby-changes:33889
From: hsbt <ko1@a...>
Date: Sat, 17 May 2014 15:27:04 +0900 (JST)
Subject: [ruby-changes:33889] hsbt:r45970 (trunk): * test/runner.rb: remove dependency test-unit and minitest
hsbt 2014-05-17 15:26:51 +0900 (Sat, 17 May 2014) New Revision: 45970 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45970 Log: * test/runner.rb: remove dependency test-unit and minitest from stdlib when running with test-all. [Feature #9711][ruby-core:61890] * test/testunit/*.rb: ditto. * test/lib: ditto. Added directories: trunk/test/lib/ trunk/test/lib/minitest/ trunk/test/lib/test/ trunk/test/lib/test/unit/ Added files: trunk/test/lib/minitest/.document trunk/test/lib/minitest/README.txt trunk/test/lib/minitest/autorun.rb trunk/test/lib/minitest/benchmark.rb trunk/test/lib/minitest/hell.rb trunk/test/lib/minitest/mock.rb trunk/test/lib/minitest/parallel_each.rb trunk/test/lib/minitest/pride.rb trunk/test/lib/minitest/spec.rb trunk/test/lib/minitest/unit.rb trunk/test/lib/test/unit/assertions.rb trunk/test/lib/test/unit/parallel.rb trunk/test/lib/test/unit/test-unit.gemspec trunk/test/lib/test/unit/testcase.rb trunk/test/lib/test/unit.rb Modified files: trunk/ChangeLog trunk/test/runner.rb trunk/test/testunit/test4test_hideskip.rb trunk/test/testunit/test4test_redefinition.rb trunk/test/testunit/test4test_sorting.rb trunk/test/testunit/test_parallel.rb trunk/test/testunit/test_rake_integration.rb trunk/test/testunit/tests_for_parallel/runner.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 45969) +++ ChangeLog (revision 45970) @@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat May 17 15:06:40 2014 SHIBATA Hiroshi <shibata.hiroshi@g...> + + * test/runner.rb: remove dependency test-unit and minitest + from stdlib when running with test-all. + [Feature #9711][ruby-core:61890] + * test/testunit/*.rb: ditto. + * test/lib: ditto. + Sat May 17 11:02:49 2014 Nobuyoshi Nakada <nobu@r...> * dir.c (glob_helper): try match PLAIN as well as ALPHA, which are Index: test/testunit/test4test_redefinition.rb =================================================================== --- test/testunit/test4test_redefinition.rb (revision 45969) +++ test/testunit/test4test_redefinition.rb (revision 45970) @@ -1,3 +1,5 @@ https://github.com/ruby/ruby/blob/trunk/test/testunit/test4test_redefinition.rb#L1 +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" + require 'test/unit' class TestForTestRedefinition < Test::Unit::TestCase Index: test/testunit/tests_for_parallel/runner.rb =================================================================== --- test/testunit/tests_for_parallel/runner.rb (revision 45969) +++ test/testunit/tests_for_parallel/runner.rb (revision 45970) @@ -1,4 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/test/testunit/tests_for_parallel/runner.rb#L1 require 'rbconfig' + +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../../lib" + require 'test/unit' src_testdir = File.dirname(File.expand_path(__FILE__)) Index: test/testunit/test4test_hideskip.rb =================================================================== --- test/testunit/test4test_hideskip.rb (revision 45969) +++ test/testunit/test4test_hideskip.rb (revision 45970) @@ -1,3 +1,5 @@ https://github.com/ruby/ruby/blob/trunk/test/testunit/test4test_hideskip.rb#L1 +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" + require 'test/unit' class TestForTestHideSkip < Test::Unit::TestCase Index: test/testunit/test_rake_integration.rb =================================================================== --- test/testunit/test_rake_integration.rb (revision 45969) +++ test/testunit/test_rake_integration.rb (revision 45970) @@ -18,6 +18,7 @@ class RakeIntegration < MiniTest::Unit:: https://github.com/ruby/ruby/blob/trunk/test/testunit/test_rake_integration.rb#L18 filename = File.join dir, 'testing.rb' File.open(filename, 'wb') do |f| f.write <<-eotest +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" require 'test/unit' raise 'loaded twice' if defined?(FooTest) class FooTest; end Index: test/testunit/test4test_sorting.rb =================================================================== --- test/testunit/test4test_sorting.rb (revision 45969) +++ test/testunit/test4test_sorting.rb (revision 45970) @@ -1,3 +1,5 @@ https://github.com/ruby/ruby/blob/trunk/test/testunit/test4test_sorting.rb#L1 +$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib" + require 'test/unit' class TestForTestHideSkip < Test::Unit::TestCase Index: test/testunit/test_parallel.rb =================================================================== --- test/testunit/test_parallel.rb (revision 45969) +++ test/testunit/test_parallel.rb (revision 45970) @@ -2,10 +2,9 @@ require 'test/unit' https://github.com/ruby/ruby/blob/trunk/test/testunit/test_parallel.rb#L2 require 'timeout' module TestParallel - PARALLEL_RB = "#{File.dirname(__FILE__)}/../../lib/test/unit/parallel.rb" + PARALLEL_RB = "#{File.dirname(__FILE__)}/../lib/test/unit/parallel.rb" TESTS = "#{File.dirname(__FILE__)}/tests_for_parallel" - class TestParallelWorker < Test::Unit::TestCase def setup i, @worker_in = IO.pipe Index: test/runner.rb =================================================================== --- test/runner.rb (revision 45969) +++ test/runner.rb (revision 45970) @@ -1,9 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/test/runner.rb#L1 require 'rbconfig' -require 'test/unit' - src_testdir = File.dirname(File.realpath(__FILE__)) $LOAD_PATH << src_testdir +$LOAD_PATH.unshift "#{src_testdir}/lib" + +require 'test/unit' + module Gem end class Gem::TestCase < MiniTest::Unit::TestCase Index: test/lib/test/unit/assertions.rb =================================================================== --- test/lib/test/unit/assertions.rb (revision 0) +++ test/lib/test/unit/assertions.rb (revision 45970) @@ -0,0 +1,461 @@ https://github.com/ruby/ruby/blob/trunk/test/lib/test/unit/assertions.rb#L1 +require 'minitest/unit' +require 'pp' + +module Test + module Unit + module Assertions + include MiniTest::Assertions + + def mu_pp(obj) #:nodoc: + obj.pretty_inspect.chomp + end + + MINI_DIR = File.join(File.dirname(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_block( failure_message = nil ) + # + #Tests the result of the given block. If the block does not return true, + #the assertion will fail. The optional +failure_message+ argument is the same as in + #Assertions#assert. + # + # assert_block do + # [1, 2, 3].any? { |num| num < 1 } + # end + def assert_block(*msgs) + assert yield, *msgs + 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 MiniTest::Skip => e + return e if exp.include? MiniTest::Skip + 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 { + exception_details(e, message(msg) {"#{mu_pp(exp)} exception expected, not"}.call) + } + + return e + end + + exp = exp.first if exp.size == 1 + + flunk(message(msg) {"#{mu_pp(exp)} expected but nothing was raised"}) + 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 = assert_raise(exception, *msg) {yield} + msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"} + + if assert == :assert_equal + assert_equal(expected, ex.message, msg) + else + msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp ex.message}" } + assert expected =~ ex.message, msg + block.binding.eval("proc{|_|$~=_}").call($~) + end + ex + 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 MiniTest::Skip + raise + rescue Exception => e + bt = e.backtrace + as = e.instance_of?(MiniTest::Assertion) + 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)}>" } + raise MiniTest::Assertion, msg.call, bt + else + raise + end + end + nil + end + + # :call-seq: + # assert_nothing_thrown( failure_message = nil, &block ) + # + #Fails if the given block uses a call to Kernel#throw, and + #returns the result of the block otherwise. + # + #An optional failure message may be provided as the final argument. + # + # assert_nothing_thrown "Something was thrown!" do + # throw :problem? + # end + def assert_nothing_thrown(msg=nil) + begin + ret = yield + rescue ArgumentError => error + raise error if /\Auncaught throw (.+)\z/m !~ error.message + msg = message(msg) { "<#{$1}> was thrown when nothing was expected" } + flunk(msg) + end + assert(true, "Expected nothing to be thrown") + ret + 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 ArgumentError => e + raise unless thrown = e.message[/\Auncaught throw (.+)\z/m, 1] + end + msg = message(msg) { + "Expected #{mu_pp(tag)} to have been thrown"\ + "#{", not #{thrown}" if thrown}" + } + assert(false, msg) + end + assert(true) + ret + end + + # :call-seq: + # assert_equal( expected, actual, failure_message = nil ) + # + #Tests if +expected+ is equal to +actual+. + # + #An optional failure message may be provided as the final argument. + def assert_equal(exp, act, msg = nil) + msg = message(msg) { + exp_str = mu_pp(exp) + act_str = mu_pp(act) + exp_comment = '' + act_comment = '' + if exp_str == act_str + if (exp.is_a?(String) && act.is_a?(String)) || + (exp.is_a?(Regexp) && act.is_a?(Regexp)) + exp_comment = " (#{exp.encoding})" + act_comment = " (#{act.encoding})" + elsif exp.is_a?(Float) && act.is_a?(Float) + exp_str = "%\#.#{Float::DIG+2}g" % exp + act_str = "%\#.#{Float::DIG+2}g" % act + elsif exp.is_a?(Time) && act.is_a?(Time) + if exp.subsec * 1000_000_000 == exp.nsec + exp_comment = " (#{exp.nsec}[ns])" + else + exp_comment = " (subsec=#{exp.subsec})" + end + if act.subsec * 1000_000_000 == act.nsec + act_comment = " (#{act.nsec}[ns])" + else + act_comment = " (subsec=#{act.subsec})" + end + elsif exp.class != act.class + # a subclass of Range, for example. + exp_comment = " (#{exp.class})" + act_comment = " (#{act.class})" + end + elsif !Encoding.compatible?(exp_str, act_str) + if exp.is_a?(String) && act.is_a?(String) + exp_str = exp.dump + act_str = act.dump + exp_comment = " (#{exp.encoding})" + act_comment = " (#{act.encoding})" + else + exp_str = exp_str.dump + act_str = act_str.dump + end + end + "<#{exp_str}>#{exp_comment} expected but was\n<#{act_str}>#{act_comment}" + } + assert(exp == act, msg) + end + + # :call-seq: + # assert_not_nil( expression, failure_message = nil ) + # + #Tests if +expression+ is not nil. + # + #An optional failure message may be provided as the final argument. + def assert_not_nil(exp, msg=nil) + msg = message(msg) { "<#{mu_pp(exp)}> expected to not be nil" } + assert(!exp.nil?, msg) + end + + # :call-seq: + # assert_not_equal( expected, actual, failure_message = nil ) + # + #Tests if +expected+ is not equal to +actual+. + # + #An optional failure message may be provided as the final argument. + def assert_not_equal(exp, act, msg=nil) + msg = message(msg) { "<#{mu_pp(exp)}> expected to be != to\n<#{mu_pp(act)}>" } + assert(exp != act, msg) + end + + # :call-seq: + # assert_no_match( regexp, string, failure_message = nil ) + # + #Tests if the given Regexp does not match a given String. + # + #An optional failure message may be provided as the final argument. + def assert_no_match(regexp, string, msg=nil) + assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.") + self._assertions -= 1 + msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" } + assert(regexp !~ string, msg) + end + + # :call-seq: + # assert_not_same( expected, actual, failure_message = nil ) + # + #Tests if +expected+ is not the same object as +actual+. + #This test uses Object#equal? to test equality. + # + #An optional failure message may be provided as the final argument. + # + # assert_not_same("x", "x") #Succeeds + def assert_not_same(expected, actual, message="") + msg = message(msg) { build_message(message, <<EOT, expected, expected.__id__, actual, actual.__id__) } +<?> +with id <?> expected to not be equal\\? to +<?> +with id <?>. +EOT + assert(!actual.equal?(expected), msg) + 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 + if priv + msg = message(msg) { + "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}#{" privately" if priv}" + } + return assert obj.respond_to?(meth, priv), msg + end + #get rid of overcounting + super if !caller[0].rindex(MINI_DIR, 0) || !obj.respond_to?(meth) + end + + # :call-seq: + # assert_send( +send_array+, failure_message = nil ) + # + # Passes if the method send returns a true value. + # + # +send_array+ is composed of: + # * A receiver + # * A method + # * Arguments to the method + # + # Example: + # assert_send(["Hello world", :include?, "Hello"]) # -> pass + # assert_send(["Hello world", :include?, "Goodbye"]) # -> fail + def assert_send send_ary, m = nil + recv, msg, *args = send_ary + m = message(m) { + if args.empty? + argsstr = "" + else + (argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/m, '(\1)') + end + "Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return true" + } + assert recv.__send__(msg, *args), m + end + + # :call-seq: + # assert_not_send( +send_array+, failure_message = nil ) + # + # Passes if the method send doesn't return a true value. + # + # +send_array+ is composed of: + # * A receiver + # * A method + # * Arguments to the method + # + # Example: + # assert_not_send([[1, 2], :member?, 1]) # -> fail + # assert_not_send([[1, 2], :member?, 4]) # -> pass + def assert_not_send send_ary, m = nil + recv, msg, *args = send_ary + m = message(m) { + if args.empty? + argsstr = "" + else + (argsstr = mu_pp(args)).sub!(/\A\[(.*)\]\z/m, '(\1)') + end + "Expected #{mu_pp(recv)}.#{msg}#{argsstr} to return false" + } + assert !recv.__send__(msg, *args), m + end + + ms = instance_methods(true).map {|sym| sym.to_s } + ms.grep(/\Arefute_/) do |m| + mname = ('assert_not_' << m.to_s[/.*?_(.*)/, 1]) + alias_method(mname, m) unless ms.include? mname + end + alias assert_include assert_includes + alias assert_not_include assert_not_includes + + 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_not_all?(obj, m = nil, &blk) + failed = [] + obj.each do |*a, &b| + if blk.call(*a, &b) + failed << a.size > 1 ? a : a[0] + end + end + assert(failed.empty?, message(m) {failed.pretty_inspect}) + end + + def build_message(head, template=nil, *arguments) #:nodoc: + template &&= template.chomp + template.gsub(/\G((?:[^\\]|\\.)*?)(\\)?\?/) { $1 + ($2 ? "?" : mu_pp(arguments.shift)) } + end + + def message(msg = nil, *args, &default) # :nod (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/