module Minitest
def self.__run reporter, options
def self.__run reporter, options suites = Runnable.runnables.shuffle parallel, serial = suites.partition { |s| s.test_order == :parallel } # If we run the parallel tests before the serial tests, the parallel tests # could run in parallel with the serial tests. This would be bad because # the serial tests won't lock around Reporter#record. Run the serial tests # first, so that after they complete, the parallel tests will lock when # recording results. serial.map { |suite| suite.run reporter, options } + parallel.map { |suite| suite.run reporter, options } end
def self.after_run &block
def self.after_run &block @@after_run << block end
def self.autorun
def self.autorun if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=) Warning[:deprecated] = true end at_exit { next if $! and not ($!.kind_of? SystemExit and $!.success?) exit_code = nil pid = Process.pid at_exit { next if !Minitest.allow_fork && Process.pid != pid @@after_run.reverse_each(&:call) exit exit_code || false } exit_code = Minitest.run ARGV } unless @@installed_at_exit @@installed_at_exit = true end
def self.cattr_accessor name # :nodoc:
def self.cattr_accessor name # :nodoc: (class << self; self; end).attr_accessor name end
def self.clock_time
def self.clock_time Process.clock_gettime Process::CLOCK_MONOTONIC end
def self.clock_time
def self.clock_time Time.now end
def self.empty_run! options # :nodoc:
def self.empty_run! options # :nodoc: filter = options[:filter] return true unless filter # no filter, but nothing ran == success warn "Nothing ran for filter: %s" % [filter] require "did_you_mean" # soft dependency, punt if it doesn't load ms = Runnable.runnables.flat_map(&:runnable_methods) cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter warn DidYouMean::Formatter.message_for cs unless cs.empty? rescue LoadError # do nothing ensure return false end
def self.filter_backtrace bt # :nodoc:
def self.filter_backtrace bt # :nodoc: result = backtrace_filter.filter bt result = bt.dup if result.empty? result end
def self.init_plugins options # :nodoc:
def self.init_plugins options # :nodoc: self.extensions.each do |name| msg = "plugin_#{name}_init" send msg, options if self.respond_to? msg end end
def self.load_plugins # :nodoc:
def self.load_plugins # :nodoc: return unless self.extensions.empty? seen = {} require "rubygems" unless defined? Gem Gem.find_files("minitest/*_plugin.rb").each do |plugin_path| name = File.basename plugin_path, "_plugin.rb" next if seen[name] seen[name] = true require plugin_path self.extensions << name end end
def self.plugin_pride_init options # :nodoc:
def self.plugin_pride_init options # :nodoc: if PrideIO.pride? then klass = ENV["TERM"] =~ /^xterm|-256color$/ ? PrideLOL : PrideIO io = klass.new options[:io] self.reporter.reporters.grep(Minitest::Reporter).each do |rep| rep.io = io if rep.io.tty? end end end
def self.plugin_pride_options opts, _options # :nodoc:
def self.plugin_pride_options opts, _options # :nodoc: opts.on "-p", "--pride", "Pride. Show your testing pride!" do PrideIO.pride! end end
def self.process_args args = [] # :nodoc:
def self.process_args args = [] # :nodoc: options = { :io => $stdout, } orig_args = args.dup OptionParser.new do |opts| opts.banner = "minitest options:" opts.version = Minitest::VERSION opts.on "-h", "--help", "Display this help." do puts opts exit end opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)." desc = "Sets random seed. Also via env. Eg: SEED=n rake" opts.on "-s", "--seed SEED", Integer, desc do |m| options[:seed] = m.to_i end opts.on "-v", "--verbose", "Verbose. Show progress processing files." do options[:verbose] = true end opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do options[:quiet] = true end opts.on "--show-skips", "Show skipped at the end of run." do options[:show_skips] = true end opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a| options[:filter] = a end opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a| options[:exclude] = a end opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s| options[:skip] = s.chars.to_a end unless extensions.empty? opts.separator "" opts.separator "Known extensions: #{extensions.join(", ")}" extensions.each do |meth| msg = "plugin_#{meth}_options" send msg, opts, options if self.respond_to?(msg) end end begin opts.parse! args rescue OptionParser::InvalidOption => e puts puts e puts puts opts exit 1 end orig_args -= args end unless options[:seed] then srand options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF orig_args << "--seed" << options[:seed].to_s end options[:args] = orig_args.map { |s| s =~ /[\s|&<>$()]/ ? s.inspect : s }.join " " options end
def self.run args = []
def self.run args = [] self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"] options = process_args args Minitest.seed = options[:seed] srand Minitest.seed reporter = CompositeReporter.new reporter << SummaryReporter.new(options[:io], options) reporter << ProgressReporter.new(options[:io], options) unless options[:quiet] self.reporter = reporter # this makes it available to plugins self.init_plugins options self.reporter = nil # runnables shouldn't depend on the reporter, ever self.parallel_executor.start if parallel_executor.respond_to?(:start) reporter.start begin __run reporter, options rescue Interrupt warn "Interrupted. Exiting..." end self.parallel_executor.shutdown # might have been removed/replaced during init_plugins: summary = reporter.reporters.grep(SummaryReporter).first return empty_run! options if summary && summary.count == 0 reporter.report reporter.passed? end
def self.run_one_method klass, method_name # :nodoc:
def self.run_one_method klass, method_name # :nodoc: result = klass.new(method_name).run raise "#{klass}#run _must_ return a Result" unless Result === result result end