class Test::Unit::AutoRunner - test-unit: Ruby Standard Library Documentation

# class Test::Unit::AutoRunner

### Constants

ADDITIONAL_OPTIONS
COLLECTORS
PREPARE_HOOKS
RUNNERS

### Attributes

base[RW]
collector[W]
color_scheme[RW]
debug_on_failure[W]
default_test_paths[RW]
exclude[RW]
filters[RW]
gc_stress[W]
listeners[RW]
pattern[RW]
runner[W]
runner_options[R]
stop_on_failure[W]
suite[R]
to_run[RW]
workdir[RW]

### Public Class Methods

collector(id) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 44
    def collector(id)
      COLLECTORS[id.to_s]
    end

default_runner() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 30
    def default_runner
      runner(@@default_runner)
    end

default_runner=(id) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 34
    def default_runner=(id)
      @@default_runner = id
    end

need_auto_run=(need) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 83
    def need_auto_run=(need)
      @@need_auto_run = need
    end

need_auto_run?() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 79
    def need_auto_run?
      @@need_auto_run
    end

new(standalone) { |self| ... } click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 152
    def initialize(standalone)
      @standalone = standalone
      @runner = default_runner
      @collector = default_collector
      @filters = []
      @to_run = []
      @default_test_paths = []
      @color_scheme = ColorScheme.default
      @runner_options = {}
      @default_arguments = []
      @workdir = nil
      @listeners = []
      @stop_on_failure = false
      @debug_on_failure = false
      @gc_stress = false
      @test_suite_runner_class = TestSuiteRunner
      config_file = "test-unit.yml"
      if File.exist?(config_file)
        load_config(config_file)
      else
        load_global_config
      end
      yield(self) if block_given?
    end

prepare(hook=nil, &block) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 57
    def prepare(hook=nil, &block)
      hook ||= Proc.new(&block)
      PREPARE_HOOKS << hook
    end

register_collector(id, collector_builder=nil, &block) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 38
    def register_collector(id, collector_builder=nil, &block)
      collector_builder ||= Proc.new(&block)
      COLLECTORS[id] = collector_builder
      COLLECTORS[id.to_s] = collector_builder
    end

register_color_scheme(id, scheme) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 48
    def register_color_scheme(id, scheme)
      ColorScheme[id] = scheme
    end

register_runner(id, runner_builder=nil, &block) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 19
    def register_runner(id, runner_builder=nil, &block)
      runner_builder ||= Proc.new(&block)
      RUNNERS[id] = runner_builder
      RUNNERS[id.to_s] = runner_builder
    end

run(force_standalone=false, default_dir=nil, argv=ARGV, &block) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 62
    def run(force_standalone=false, default_dir=nil, argv=ARGV, &block)
      r = new(force_standalone || standalone?, &block)
      r.base = default_dir
      r.prepare
      r.process_args(argv)
      r.run
    end

runner(id) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 25
    def runner(id)
      RUNNERS[id.to_s]
    end

setup_option(option_builder=nil, &block) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 52
    def setup_option(option_builder=nil, &block)
      option_builder ||= Proc.new(&block)
      ADDITIONAL_OPTIONS << option_builder
    end

standalone?() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 70
    def standalone?
      return false unless("-e" == $0)
      ObjectSpace.each_object(Class) do |klass|
        return false if(klass < TestCase)
      end
      true
    end

### Public Instance Methods

debug_on_failure?() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 181
    def debug_on_failure?
      @debug_on_failure
    end

keyword_display(keywords) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 456
    def keyword_display(keywords)
      keywords = keywords.collect do |keyword, _|
        keyword.to_s
      end.uniq.sort

      i = 0
      keywords.collect do |keyword|
        if (i > 0 and keyword[0] == keywords[i - 1][0]) or
            ((i < keywords.size - 1) and (keyword[0] == keywords[i + 1][0]))
          n = 2
        else
          n = 1
        end
        i += 1
        keyword.sub(/^(.{#{n}})([A-Za-z-]+)(?=\w*$)/, '\\1[\\2]')
      end.join(", ")
    end

load_config(file) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 496
    def load_config(file)
      require "yaml"
      config = YAML.load(File.read(file))
      runner_name = config["runner"]
      @runner = self.class.runner(runner_name) || @runner
      @collector = self.class.collector(config["collector"]) || @collector
      (config["color_schemes"] || {}).each do |name, options|
        ColorScheme[name] = options
      end
      runner_options = {}
      (config["#{runner_name}_options"] || {}).each do |key, value|
        key = key.to_sym
        value = ColorScheme[value] if key == :color_scheme
        if key == :arguments
          @default_arguments.concat(value.split)
        else
          runner_options[key] = value
        end
      end
      @runner_options = @runner_options.merge(runner_options)
    end

options() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 203
    def options
      @options ||= OptionParser.new do |o|
        o.banner = "Test::Unit automatic runner."
        o.banner += "\nUsage: #{$0} [options] [-- untouched arguments]"

        o.on("-r", "--runner=RUNNER", RUNNERS,
             "Use the given RUNNER.",
             "(" + keyword_display(RUNNERS) + ")") do |r|
          @runner = r
        end

        o.on("--collector=COLLECTOR", COLLECTORS,
             "Use the given COLLECTOR.",
             "(" + keyword_display(COLLECTORS) + ")") do |collector|
          @collector = collector
        end

        if (@standalone)
          o.on("-b", "--basedir=DIR", "Base directory of test suites.") do |b|
            @base = b
          end

          o.on("-w", "--workdir=DIR", "Working directory to run tests.") do |w|
            @workdir = w
          end

          o.on("--default-test-path=PATH",
               "Add PATH to the default test paths.",
               "The PATH is used when user doesn't specify any test path.",
               "You can specify this option multiple times.") do |path|
            @default_test_paths << path
          end

          o.on("-a", "--add=TORUN", Array,
               "Add TORUN to the list of things to run;",
               "can be a file or a directory.") do |paths|
            paths.each do |path|
              add_test_path(path)
            end
          end

          @pattern = []
          o.on("-p", "--pattern=PATTERN", Regexp,
               "Match files to collect against PATTERN.") do |e|
            @pattern << e
          end

          @exclude = []
          o.on("-x", "--exclude=PATTERN", Regexp,
               "Ignore files to collect against PATTERN.") do |e|
            @exclude << e
          end
        end

        o.on("-n", "--name=NAME", String,
             "Runs tests matching NAME.",
             "Use '/PATTERN/' for NAME to use regular expression.",
             "Regular expression accepts options.",
             "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
          name = prepare_name(name)
          @filters << lambda do |test|
            match_test_name(test, name)
          end
        end

        o.on("--ignore-name=NAME", String,
             "Ignores tests matching NAME.",
             "Use '/PATTERN/' for NAME to use regular expression.",
             "Regular expression accepts options.",
             "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
          name = prepare_name(name)
          @filters << lambda do |test|
            not match_test_name(test, name)
          end
        end

        o.on("-t", "--testcase=TESTCASE", String,
             "Runs tests in TestCases matching TESTCASE.",
             "Use '/PATTERN/' for TESTCASE to use regular expression.",
             "Regular expression accepts options.",
             "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
          name = prepare_name(name)
          @filters << lambda do |test|
            match_test_case_name(test, name)
          end
        end

        o.on("--ignore-testcase=TESTCASE", String,
             "Ignores tests in TestCases matching TESTCASE.",
             "Use '/PATTERN/' for TESTCASE to use regular expression.",
             "Regular expression accepts options.",
             "Example: '/taRget/i' matches 'target' and 'TARGET'") do |name|
          name = prepare_name(name)
          @filters << lambda do |test|
            not match_test_case_name(test, name)
          end
        end

        o.on("--location=LOCATION", String,
             "Runs tests that defined in LOCATION.",
             "LOCATION is one of PATH:LINE, PATH or LINE.") do |location|
          case location
          when /\A(\d+)\z/
            path = nil
            line = $1.to_i
          when /:(\d+)\z/
            path = $PREMATCH
            line = $1.to_i
          else
            path = location
            line = nil
          end
          add_location_filter(path, line)
        end

        o.on("--attribute=EXPRESSION", String,
             "Runs tests that matches EXPRESSION.",
             "EXPRESSION is evaluated as Ruby's expression.",
             "Test attribute name can be used with no receiver in EXPRESSION.",
             "EXPRESSION examples:",
             "  !slow",
             "  tag == 'important' and !slow") do |expression|
          @filters << lambda do |test|
            matcher = AttributeMatcher.new(test)
            matcher.match?(expression)
          end
        end

        priority_filter = Proc.new do |test|
          if @filters == [priority_filter]
            Priority::Checker.new(test).need_to_run?
          else
            nil
          end
        end
        o.on("--[no-]priority-mode",
             "Runs some tests based on their priority.") do |priority_mode|
          if priority_mode
            Priority.enable
            @filters |= [priority_filter]
          else
            Priority.disable
            @filters -= [priority_filter]
          end
        end

        o.on("--default-priority=PRIORITY",
             Priority.available_values,
             "Uses PRIORITY as default priority",
             "(#{keyword_display(Priority.available_values)})") do |priority|
          Priority.default = priority
        end

        o.on("-I", "--load-path=DIR[#{File::PATH_SEPARATOR}DIR...]",
             "Appends directory list to $LOAD_PATH.") do |dirs|
          $LOAD_PATH.concat(dirs.split(File::PATH_SEPARATOR))
        end

        color_schemes = ColorScheme.all
        o.on("--color-scheme=SCHEME", color_schemes,
             "Use SCHEME as color scheme.",
             "(#{keyword_display(color_schemes)})") do |scheme|
          @color_scheme = scheme
        end

        o.on("--config=FILE",
             "Use YAML format FILE content as configuration file.") do |file|
          load_config(file)
        end

        o.on("--order=ORDER", TestCase::AVAILABLE_ORDERS,
             "Run tests in a test case in ORDER order.",
             "(#{keyword_display(TestCase::AVAILABLE_ORDERS)})") do |order|
          TestCase.test_order = order
        end

        assertion_message_class = Test::Unit::Assertions::AssertionMessage
        o.on("--max-diff-target-string-size=SIZE", Integer,
             "Shows diff if both expected result string size and " +
             "actual result string size are " +
             "less than or equal SIZE in bytes.",
             "(#{assertion_message_class.max_diff_target_string_size})") do |size|
          assertion_message_class.max_diff_target_string_size = size
        end

        o.on("--[no-]stop-on-failure",
             "Stops immediately on the first non success test",
             "(#{@stop_on_failure})") do |boolean|
          @stop_on_failure = boolean
        end

        o.on("--[no-]debug-on-failure",
             "Run debugger if available on failure",
             "(#{AssertionFailedError.debug_on_failure?})") do |boolean|
          AssertionFailedError.debug_on_failure = boolean
        end

        o.on("--[no-]gc-stress",
             "Enable GC.stress only while each test is running",
             "(#{@gc_stress})") do |boolean|
          @gc_stress = boolean
        end

        parallel_options = [
          :thread,
        ]
        o.on("--[no-]parallel=[thread]", parallel_options,
             "Runs tests in parallel",
             "(#{parallel_options.first})") do |parallel|
          case parallel
          when nil, :thread
            @test_suite_runner_class = TestSuiteThreadRunner
          else
            @test_suite_runner_class = TestSuiteRunner
          end
        end

        o.on("--n-workers=N", Integer,
             "The number of parallelism",
             "(#{TestSuiteRunner.n_workers})") do |n|
          TestSuiteRunner.n_workers = n
        end

        ADDITIONAL_OPTIONS.each do |option_builder|
          option_builder.call(self, o)
        end

        o.on("--",
             "Stop processing options so that the",
             "remaining options will be passed to the",
             "test."){o.terminate}

        o.on("-h", "--help", "Display this help."){puts o; exit}

        o.on_tail
        o.on_tail("Deprecated options:")

        o.on_tail("--console", "Console runner (use --runner).") do
          warn("Deprecated option (--console).")
          @runner = self.class.runner(:console)
        end

        if RUNNERS[:fox]
          o.on_tail("--fox", "Fox runner (use --runner).") do
            warn("Deprecated option (--fox).")
            @runner = self.class.runner(:fox)
          end
        end

        o.on_tail
      end
    end

prepare() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 185
    def prepare
      PREPARE_HOOKS.each do |handler|
        handler.call(self)
      end
    end

process_args(args=ARGV) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 191
    def process_args(args=ARGV)
      begin
        args.unshift(*@default_arguments)
        options.order!(args) {|arg| add_test_path(arg)}
      rescue OptionParser::ParseError => e
        puts e
        puts options
        exit(false)
      end
      not @to_run.empty?
    end

run() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 474
    def run
      self.class.need_auto_run = false
      suite = @collector[self]
      return false if suite.nil?
      return true if suite.empty?
      runner = @runner[self]
      return false if runner.nil?
      @runner_options[:color_scheme] ||= @color_scheme
      @runner_options[:listeners] ||= []
      @runner_options[:listeners].concat(@listeners)
      if @stop_on_failure
        @runner_options[:listeners] << StopOnFailureListener.new
      end
      if @gc_stress
        @runner_options[:listeners] << GCStressListener.new
      end
      @runner_options[:test_suite_runner_class] = @test_suite_runner_class
      change_work_directory do
        runner.run(suite, @runner_options).passed?
      end
    end

stop_on_failure?() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 177
    def stop_on_failure?
      @stop_on_failure
    end

### Private Instance Methods

add_location_filter(path, line) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 594
    def add_location_filter(path, line)
      @filters << lambda do |test|
        test.class.test_defined?(:path => path,
                                 :line => line,
                                 :method_name => test.method_name)
      end
    end

add_test_path(path) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 585
    def add_test_path(path)
      if /:(\d+)\z/ =~ path
        line = $1.to_i
        path = $PREMATCH
        add_location_filter(path, line)
      end
      @to_run << path
    end

change_work_directory() { || ... } click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 544
    def change_work_directory(&block)
      if @workdir
        Dir.chdir(@workdir, &block)
      else
        yield
      end
    end

default_collector() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 529
    def default_collector
      self.class.collector(@standalone ? :load : :descendant)
    end

default_runner() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 519
    def default_runner
      runner = self.class.default_runner
      if ENV["EMACS"] == "t"
        runner ||= self.class.runner(:emacs)
      else
        runner ||= self.class.runner(:console)
      end
      runner
    end

global_config_file() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 533
    def global_config_file
      File.expand_path("~/.test-unit.yml")
    rescue ArgumentError
      nil
    end

load_global_config() click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 539
    def load_global_config
      file = global_config_file
      load_config(file) if file and File.exist?(file)
    end

match_test_case_name(test, pattern) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 577
    def match_test_case_name(test, pattern)
      test.class.ancestors.each do |test_class|
        break if test_class == TestCase
        return true if pattern === test_class.name
      end
      false
    end

match_test_name(test, pattern) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 567
    def match_test_name(test, pattern)
      return true if pattern === test.method_name
      return true if pattern === test.local_name
      if pattern.is_a?(String)
        return true if pattern === "#{test.class}##{test.method_name}"
        return true if pattern === "#{test.class}##{test.local_name}"
      end
      false
    end

prepare_name(name) click to toggle source

    # File test-unit-3.6.7/lib/test/unit/autorunner.rb, line 552
    def prepare_name(name)
      case name
      when /\A\/(.*)\/([imx]*)\z/
        pattern = $1
        options_raw = $2
        options = 0
        options |= Regexp::IGNORECASE if options_raw.include?("i")
        options |= Regexp::MULTILINE if options_raw.include?("m")
        options |= Regexp::EXTENDED if options_raw.include?("x")
        Regexp.new(pattern, options)
      else
        name
      end
    end