From d39d7f5f444db724ddfb2dc5c15177e519b349f0 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 30 Dec 2009 20:48:15 -0800 Subject: Allow ActiveSupport's isolation tests to run with MiniTest on 1.9 --- .../lib/active_support/testing/isolation.rb | 64 +++-- activesupport/test/isolation_test.rb | 266 +++++++++++---------- 2 files changed, 189 insertions(+), 141 deletions(-) diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb index 81f7e3c9df..453f4fcc0f 100644 --- a/activesupport/lib/active_support/testing/isolation.rb +++ b/activesupport/lib/active_support/testing/isolation.rb @@ -36,28 +36,56 @@ module ActiveSupport !ENV["NO_FORK"] && RUBY_PLATFORM !~ /mswin|mingw|java/ end - def run(result) - unless defined?(@@ran_class_setup) - self.class.setup if self.class.respond_to?(:setup) - @@ran_class_setup = true + def self.included(base) + if defined?(::MiniTest) && base < ::MiniTest::Unit::TestCase + base.send :include, MiniTest + elsif defined?(Test::Unit) + base.send :include, TestUnit end + end + + module TestUnit + def run(result) + unless defined?(@@ran_class_setup) + self.class.setup if self.class.respond_to?(:setup) + @@ran_class_setup = true + end - yield(Test::Unit::TestCase::STARTED, name) + yield(Test::Unit::TestCase::STARTED, name) - @_result = result + @_result = result - serialized = run_in_isolation do |proxy| - begin - super(proxy) { } - rescue Exception => e - proxy.add_error(Test::Unit::Error.new(name, e)) + serialized = run_in_isolation do |proxy| + begin + super(proxy) { } + rescue Exception => e + proxy.add_error(Test::Unit::Error.new(name, e)) + end end + + retval, proxy = Marshal.load(serialized) + proxy.__replay__(@_result) + + yield(Test::Unit::TestCase::FINISHED, name) + retval end + end - proxy = Marshal.load(serialized) - proxy.__replay__(@_result) + module MiniTest + def run(runner) + unless defined?(@@ran_class_setup) + self.class.setup if self.class.respond_to?(:setup) + @@ran_class_setup = true + end - yield(Test::Unit::TestCase::FINISHED, name) + serialized = run_in_isolation do |runner| + super(runner) + end + + retval, proxy = Marshal.load(serialized) + proxy.__replay__(runner) + retval + end end module Forking @@ -67,8 +95,8 @@ module ActiveSupport pid = fork do read.close proxy = ProxyTestResult.new - yield proxy - write.puts [Marshal.dump(proxy)].pack("m") + retval = yield proxy + write.puts [Marshal.dump([retval, proxy])].pack("m") exit! end @@ -87,9 +115,9 @@ module ActiveSupport if ENV["ISOLATION_TEST"] proxy = ProxyTestResult.new - yield proxy + retval = yield proxy File.open(ENV["ISOLATION_OUTPUT"], "w") do |file| - file.puts [Marshal.dump(proxy)].pack("m") + file.puts [Marshal.dump([retval, proxy])].pack("m") end exit! else diff --git a/activesupport/test/isolation_test.rb b/activesupport/test/isolation_test.rb index 20e11df1dd..39c2166016 100644 --- a/activesupport/test/isolation_test.rb +++ b/activesupport/test/isolation_test.rb @@ -1,162 +1,182 @@ require 'abstract_unit' require 'rbconfig' -if defined?(MiniTest) || defined?(Test::Unit::TestResultFailureSupport) - $stderr.puts "Isolation tests can test test-unit 1 only" +# if defined?(MiniTest) || defined?(Test::Unit::TestResultFailureSupport) +# $stderr.puts "Isolation tests can test test-unit 1 only" -else - # Does awesome - if ENV['CHILD'] - class ChildIsolationTest < ActiveSupport::TestCase - include ActiveSupport::Testing::Isolation - - def self.setup - File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f| - f.puts "hello" - end - end +if ENV['CHILD'] + class ChildIsolationTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation - def setup - @instance = "HELLO" + def self.setup + File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f| + f.puts "hello" end + end - def teardown - raise if @boom - end + def setup + @instance = "HELLO" + end - test "runs the test" do - assert true - end + def teardown + raise if @boom + end - test "captures errors" do - raise - end + test "runs the test" do + assert true + end - test "captures failures" do - assert false - end + test "captures errors" do + raise + end - test "first runs in isolation" do - assert_nil $x - $x = 1 - end + test "captures failures" do + assert false + end - test "second runs in isolation" do - assert_nil $x - $x = 2 - end + test "first runs in isolation" do + assert_nil $x + $x = 1 + end - test "runs with slow tests" do - sleep 0.3 - assert true - sleep 0.2 - end + test "second runs in isolation" do + assert_nil $x + $x = 2 + end - test "runs setup" do - assert "HELLO", @instance - end + test "runs with slow tests" do + sleep 0.3 + assert true + sleep 0.2 + end - test "runs teardown" do - @boom = true - end + test "runs setup" do + assert "HELLO", @instance + end - test "resets requires one" do - assert !defined?(OmgOmg) - assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size - require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) - end + test "runs teardown" do + @boom = true + end - test "resets requires two" do - assert !defined?(OmgOmg) - assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size - require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) - end + test "resets requires one" do + assert !defined?(OmgOmg) + assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size + require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) end - else - class ParentIsolationTest < ActiveSupport::TestCase - - File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {} - - ENV["CHILD"] = "1" - OUTPUT = `#{RbConfig::CONFIG["bindir"]}/#{RbConfig::CONFIG["ruby_install_name"]} -I#{File.dirname(__FILE__)} "#{File.expand_path(__FILE__)}" -v` - ENV.delete("CHILD") - - def setup - # Extract the results - @results = {} - OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result| - result =~ %r'^(\w+)\(\w+\):\s*(\.|E|F)$' - @results[$1] = { 'E' => :error, '.' => :success, 'F' => :failure }[$2] - end - - # Extract the backtraces - @backtraces = {} - OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace| - # \n 1) Error:\ntest_captures_errors(ChildIsolationTest): - backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i - @backtraces[$2] = { :type => $1, :output => backtrace } - end - end - def assert_failing(name) - assert_equal :failure, @results[name.to_s], "Test #{name} did not fail" - end + test "resets requires two" do + assert !defined?(OmgOmg) + assert_equal 0, $LOADED_FEATURES.grep(/fixtures\/omgomg/).size + require File.expand_path(File.join(File.dirname(__FILE__), "fixtures", "omgomg")) + end + end +else + class ParentIsolationTest < ActiveSupport::TestCase - def assert_passing(name) - assert_equal :success, @results[name.to_s], "Test #{name} did not pass" - end + File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {} - def assert_erroring(name) - assert_equal :error, @results[name.to_s], "Test #{name} did not error" - end + ENV["CHILD"] = "1" + OUTPUT = `#{RbConfig::CONFIG["bindir"]}/#{RbConfig::CONFIG["ruby_install_name"]} -I#{File.dirname(__FILE__)} "#{File.expand_path(__FILE__)}" -v` + ENV.delete("CHILD") - test "has all tests" do - assert_equal 10, @results.length - end + def setup + defined?(::MiniTest) ? parse_minitest : parse_testunit + end - test "passing tests are still reported" do - assert_passing :test_runs_the_test - assert_passing :test_runs_with_slow_tests + def parse_testunit + @results = {} + OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result| + result =~ %r'^(\w+)\(\w+\):\s*(\.|E|F)$' + @results[$1] = { 'E' => :error, '.' => :success, 'F' => :failure }[$2] end - test "resets global variables" do - assert_passing :test_first_runs_in_isolation - assert_passing :test_second_runs_in_isolation + # Extract the backtraces + @backtraces = {} + OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace| + # \n 1) Error:\ntest_captures_errors(ChildIsolationTest): + backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i + @backtraces[$2] = { :type => $1, :output => backtrace } end + end - test "resets requires" do - assert_passing :test_resets_requires_one - assert_passing :test_resets_requires_two - end + def parse_minitest + @results = {} + OUTPUT[/Started\n\s*(.*)\s*\nFinished/mi, 1].to_s.split(/\s*\n\s*/).each do |result| + result =~ %r'^\w+#(\w+):.*:\s*(.*Assertion.*|.*RuntimeError.*|\.\s*)$' + val = :success + val = :error if $2.include?('RuntimeError') + val = :failure if $2.include?('Assertion') - test "erroring tests are still reported" do - assert_erroring :test_captures_errors + @results[$1] = val end - test "runs setup and teardown methods" do - assert_passing :test_runs_setup - assert_erroring :test_runs_teardown + # Extract the backtraces + @backtraces = {} + OUTPUT.scan(/^\s*\d+\).*?\n\n/m).each do |backtrace| + # \n 1) Error:\ntest_captures_errors(ChildIsolationTest): + backtrace =~ %r'\s*\d+\)\s*(Error|Failure):\n(\w+)'i + @backtraces[$2] = { :type => $1, :output => backtrace } end + end - test "correct tests fail" do - assert_failing :test_captures_failures - end + def assert_failing(name) + assert_equal :failure, @results[name.to_s], "Test #{name} failed" + end - test "backtrace is printed for errors" do - assert_equal 'Error', @backtraces["test_captures_errors"][:type] - assert_match %r{isolation_test.rb:\d+:in `test_captures_errors'}, @backtraces["test_captures_errors"][:output] - end + def assert_passing(name) + assert_equal :success, @results[name.to_s], "Test #{name} passed" + end - test "backtrace is printed for failures" do - assert_equal 'Failure', @backtraces["test_captures_failures"][:type] - assert_match %r{isolation_test.rb:\d+:in `test_captures_failures'}, @backtraces["test_captures_failures"][:output] - end + def assert_erroring(name) + assert_equal :error, @results[name.to_s], "Test #{name} errored" + end - test "self.setup is run only once" do - text = File.read(File.join(File.dirname(__FILE__), "fixtures", "isolation_test")) - assert_equal "hello\n", text - end + test "has all tests" do + assert_equal 10, @results.length + end + + test "passing tests are still reported" do + assert_passing :test_runs_the_test + assert_passing :test_runs_with_slow_tests + end + test "resets global variables" do + assert_passing :test_first_runs_in_isolation + assert_passing :test_second_runs_in_isolation end + + test "resets requires" do + assert_passing :test_resets_requires_one + assert_passing :test_resets_requires_two + end + + test "erroring tests are still reported" do + assert_erroring :test_captures_errors + end + + test "runs setup and teardown methods" do + assert_passing :test_runs_setup + assert_erroring :test_runs_teardown + end + + test "correct tests fail" do + assert_failing :test_captures_failures + end + + test "backtrace is printed for errors" do + assert_equal 'Error', @backtraces["test_captures_errors"][:type] + assert_match %r{isolation_test.rb:\d+}, @backtraces["test_captures_errors"][:output] + end + + test "backtrace is printed for failures" do + assert_equal 'Failure', @backtraces["test_captures_failures"][:type] + assert_match %r{isolation_test.rb:\d+}, @backtraces["test_captures_failures"][:output] + end + + test "self.setup is run only once" do + text = File.read(File.join(File.dirname(__FILE__), "fixtures", "isolation_test")) + assert_equal "hello\n", text + end + end end -- cgit v1.2.3