Allow ActiveSupport's isolation tests to run with MiniTest on 1.9

This commit is contained in:
Carl Lerche 2009-12-30 20:48:15 -08:00
parent 1fbd02e446
commit d39d7f5f44
2 changed files with 208 additions and 160 deletions

View File

@ -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
yield(Test::Unit::TestCase::STARTED, name)
@_result = result
serialized = run_in_isolation do |proxy|
begin
super(proxy) { }
rescue Exception => e
proxy.add_error(Test::Unit::Error.new(name, e))
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)
@_result = result
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

View File

@ -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
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
def setup
@instance = "HELLO"
end
def teardown
raise if @boom
end
test "runs the test" do
assert true
end
test "captures errors" do
raise
end
test "captures failures" do
assert false
end
test "first runs in isolation" do
assert_nil $x
$x = 1
end
test "second runs in isolation" do
assert_nil $x
$x = 2
end
test "runs with slow tests" do
sleep 0.3
assert true
sleep 0.2
end
test "runs setup" do
assert "HELLO", @instance
end
test "runs teardown" do
@boom = true
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 "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"))
def self.setup
File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "a") do |f|
f.puts "hello"
end
end
else
class ParentIsolationTest < ActiveSupport::TestCase
File.open(File.join(File.dirname(__FILE__), "fixtures", "isolation_test"), "w") {}
def setup
@instance = "HELLO"
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")
def teardown
raise if @boom
end
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
test "runs the test" do
assert true
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
test "captures errors" do
raise
end
def assert_failing(name)
assert_equal :failure, @results[name.to_s], "Test #{name} did not fail"
end
test "captures failures" do
assert false
end
def assert_passing(name)
assert_equal :success, @results[name.to_s], "Test #{name} did not pass"
end
test "first runs in isolation" do
assert_nil $x
$x = 1
end
def assert_erroring(name)
assert_equal :error, @results[name.to_s], "Test #{name} did not error"
end
test "second runs in isolation" do
assert_nil $x
$x = 2
end
test "has all tests" do
assert_equal 10, @results.length
end
test "runs with slow tests" do
sleep 0.3
assert true
sleep 0.2
end
test "passing tests are still reported" do
assert_passing :test_runs_the_test
assert_passing :test_runs_with_slow_tests
end
test "runs setup" do
assert "HELLO", @instance
end
test "resets global variables" do
assert_passing :test_first_runs_in_isolation
assert_passing :test_second_runs_in_isolation
end
test "runs teardown" do
@boom = true
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+:in `test_captures_errors'}, @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+:in `test_captures_failures'}, @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
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 "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
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
defined?(::MiniTest) ? parse_minitest : parse_testunit
end
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
# 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 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')
@results[$1] = val
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} failed"
end
def assert_passing(name)
assert_equal :success, @results[name.to_s], "Test #{name} passed"
end
def assert_erroring(name)
assert_equal :error, @results[name.to_s], "Test #{name} errored"
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