class MiniTest::Unit
:nodoc:
def self.after_tests &block
def self.after_tests &block @@after_tests << block end
def self.autorun
def self.autorun at_exit { next if $! # don't run if there was an exception # the order here is important. The at_exit handler must be # installed before anyone else gets a chance to install their # own, that way we can be assured that our exit will be last # to run (at_exit stacks). exit_code = nil at_exit { @@after_tests.reverse_each(&:call) exit false if exit_code && exit_code != 0 } exit_code = MiniTest::Unit.new.run ARGV } unless @@installed_at_exit @@installed_at_exit = true end
def self.out
def self.out warn "::out deprecated, use ::output instead." if $VERBOSE output end
def self.output
def self.output @@out end
def self.output= stream
def self.output= stream @@out = stream end
def self.plugins
def self.plugins @@plugins ||= (["run_tests"] + public_instance_methods(false). grep(/^run_/).map { |s| s.to_s }).uniq end
def self.runner
def self.runner @@runner ||= self.new end
def self.runner= runner
def self.runner= runner @@runner = runner end
def _run args = []
def _run args = [] self.options = process_args args puts "Run options: #{help}" self.class.plugins.each do |plugin| send plugin break unless report.empty? end return failures + errors if @test_count > 0 # or return nil... rescue Interrupt abort 'Interrupted' end
def _run_anything type
def _run_anything type suites = TestCase.send "#{type}_suites" return if suites.empty? start = Time.now puts puts "# Running #{type}s:" puts @test_count, @assertion_count = 0, 0 sync = output.respond_to? :"sync=" # stupid emacs old_sync, output.sync = output.sync, true if sync results = _run_suites suites, type @test_count = results.inject(0) { |sum, (tc, _)| sum + tc } @assertion_count = results.inject(0) { |sum, (_, ac)| sum + ac } output.sync = old_sync if sync t = Time.now - start puts puts puts "Finished #{type}s in %.6fs, %.4f tests/s, %.4f assertions/s." % [t, test_count / t, assertion_count / t] report.each_with_index do |msg, i| puts "\n%3d) %s" % [i + 1, msg] end puts status end
def _run_suite suite, type
def _run_suite suite, type header = "#{type}_suite_header" puts send(header, suite) if respond_to? header filter = options[:filter] || '/./' filter = Regexp.new $1 if filter =~ /\/(.*)\// assertions = suite.send("#{type}_methods").grep(filter).map { |method| inst = suite.new method inst._assertions = 0 print "#{suite}##{method} = " if @verbose @start_time = Time.now result = inst.run self time = Time.now - @start_time print "%.2f s = " % time if @verbose print result puts if @verbose inst._assertions } return assertions.size, assertions.inject(0) { |sum, n| sum + n } end
def _run_suites suites, type
def _run_suites suites, type suites.map { |suite| _run_suite suite, type } end
def benchmark_suite_header suite # :nodoc:
def benchmark_suite_header suite # :nodoc: "\n#{suite}\t#{suite.bench_range.join("\t")}" end
def initialize # :nodoc:
def initialize # :nodoc: @report = [] @errors = @failures = @skips = 0 @verbose = false end
def location e # :nodoc:
def location e # :nodoc: 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 options
def options @options ||= {} end
def output
def output self.class.output end
def print *a # :nodoc:
def print *a # :nodoc: output.print(*a) end
def process_args args = [] # :nodoc:
def process_args args = [] # :nodoc: options = {} orig_args = args.dup OptionParser.new do |opts| opts.banner = 'minitest options:' opts.version = MiniTest::Unit::VERSION opts.on '-h', '--help', 'Display this help.' do puts opts exit end opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m| options[:seed] = m.to_i end opts.on '-v', '--verbose', "Verbose. Show progress processing files." do options[:verbose] = true end opts.on '-n', '--name PATTERN', "Filter test names on pattern (e.g. /foo/)" do |a| options[:filter] = a end opts.parse! args orig_args -= args end unless options[:seed] then srand options[:seed] = srand % 0xFFFF orig_args << "--seed" << options[:seed].to_s end srand options[:seed] self.verbose = options[:verbose] @help = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " " options end
def puke klass, meth, e
def puke klass, meth, e e = case e when MiniTest::Skip then @skips += 1 return "S" unless @verbose "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 puts *a # :nodoc:
def puts *a # :nodoc: output.puts(*a) end
def run args = []
def run args = [] self.class.runner._run(args) end
def run_benchmarks # :nodoc:
:nodoc:
def run_benchmarks # :nodoc: _run_anything :benchmark end
def run_tests
def run_tests _run_anything :test end
def status io = self.output
def status io = self.output format = "%d tests, %d assertions, %d failures, %d errors, %d skips" io.puts format % [test_count, assertion_count, failures, errors, skips] end