class MiniTest::Unit

def self.autorun

def self.autorun
  at_exit {
    next if $! # don't run if there was an exception
    exit_code = MiniTest::Unit.new.run(ARGV)
    exit false if exit_code && exit_code != 0
  } unless @@installed_at_exit
  @@installed_at_exit = true
end

def self.output= stream

def self.output= stream
  @@out = stream
end

def initialize

def initialize
  @report = []
  @errors = @failures = @skips = 0
  @verbose = false
end

def location e

def location e
  last_before_assertion = ""
  e.backtrace.reverse_each do |s|
    break if s =~ /in .(assert|refute|flunk|pass|fail|raise|must|wont)/
    last_before_assertion = s
  end
  last_before_assertion.sub(/:in .*$/, '')
end

def puke klass, meth, e

def puke klass, meth, e
  e = case e
      when MiniTest::Skip then
        @skips += 1
        "Skipped:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
      when MiniTest::Assertion then
        @failures += 1
        "Failure:\n#{meth}(#{klass}) [#{location e}]:\n#{e.message}\n"
      else
        @errors += 1
        bt = MiniTest::filter_backtrace(e.backtrace).join("\n    ")
        "Error:\n#{meth}(#{klass}):\n#{e.class}: #{e.message}\n    #{bt}\n"
      end
  @report << e
  e[0, 1]
end

def run args = []

def run args = []
  @verbose = args.delete('-v')
  filter = if args.first =~ /^(-n|--name)$/ then
             args.shift
             arg = args.shift
             arg =~ /\/(.*)\// ? Regexp.new($1) : arg
           else
             /./ # anything - ^test_ already filtered by #tests
           end
  @@out.puts "Loaded suite #{$0.sub(/\.rb$/, '')}\nStarted"
  start = Time.now
  run_test_suites filter
  @@out.puts
  @@out.puts "Finished in #{'%.6f' % (Time.now - start)} seconds."
  @report.each_with_index do |msg, i|
    @@out.puts "\n%3d) %s" % [i + 1, msg]
  end
  @@out.puts
  status
  return failures + errors if @test_count > 0 # or return nil...
rescue Interrupt
  abort 'Interrupted'
end

def run_test_suites filter = /./

def run_test_suites filter = /./
  @test_count, @assertion_count = 0, 0
  old_sync, @@out.sync = @@out.sync, true if @@out.respond_to? :sync=
  TestCase.test_suites.each do |suite|
    suite.test_methods.grep(filter).each do |test|
      inst = suite.new test
      inst._assertions = 0
      @@out.print "#{suite}##{test}: " if @verbose
      @start_time = Time.now
      result = inst.run(self)
      @@out.print "%.2f s: " % (Time.now - @start_time) if @verbose
      @@out.print result
      @@out.puts if @verbose
      @test_count += 1
      @assertion_count += inst._assertions
    end
  end
  @@out.sync = old_sync if @@out.respond_to? :sync=
  [@test_count, @assertion_count]
end

def status io = @@out

def status io = @@out
  format = "%d tests, %d assertions, %d failures, %d errors, %d skips"
  io.puts format % [test_count, assertion_count, failures, errors, skips]
end