123456789_123456789_123456789_123456789_123456789_

Class: Minitest::PathExpander

Relationships & Source Files
Namespace Children
Classes:
TM
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: Minitest::VendoredPathExpander
Defined in: lib/minitest/path_expander.rb

Overview

Minitest’s PathExpander to find and filter tests.

Constant Summary

Class Method Summary

VendoredPathExpander - Inherited

.new

Create a new path expander that operates on args and expands via glob as necessary.

Instance Attribute Summary

VendoredPathExpander - Inherited

#args

The args array to process.

#glob

The glob used to expand dirs to files.

#path

The path to scan if no paths are found in the initial scan.

Instance Method Summary

VendoredPathExpander - Inherited

#expand_dirs_to_files

Takes an array of paths and returns an array of paths where all directories are expanded to all files found via the glob provided to PathExpander.

#filter_files

A file filter mechanism similar to, but not as extensive as, .gitignore files:

#post_process, #pre_process,
#process

Top-level method processes args.

#process_args

Enumerate over args passed to PathExpander and return a list of files and flags to process.

#process_file

Process a file into more arguments.

#process_flags

Process over flags and treat any special ones here.

Constructor Details

.new(args = ARGV) ⇒ PathExpander

This method is for internal use only.
[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 231

def initialize args = ARGV # :nodoc:
  super args, TEST_GLOB, "test"
  self. = {}
end

Instance Attribute Details

#by_line (rw)

This method is for internal use only.
[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 227

attr_accessor : # :nodoc:

Instance Method Details

#all_tests

Find and return all known tests as a hash of klass => [TM…] pairs.

[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 300

def all_tests
  Minitest.seed = 42 # minor hack to deal with runnable_methods shuffling
  Minitest::Runnable.runnables
    .to_h { |k|
      ms = k.runnable_methods
        .sort
        .map { |m| TM.new k, m.to_sym }
        .sort_by { |t| [t.path, t.line_s] }
      [k, ms]
    }
    .reject { |k, v| v.empty? }
end

#handle_missing_tests?(tests) ⇒ Boolean

Handle the case where a line number doesn’t match any known tests. Returns true to signal that running should stop.

[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 348

def handle_missing_tests? tests
  _tests = tests.values.flatten
  not_found = 
    .flat_map { |f, ls| ls.map { |l| [f, l] } }
    .reject { |f, l|
      _tests.any? { |t| t.path == f and t.include? l }
    }

  unless not_found.empty? then
    by_path = all_tests.values.flatten.group_by(&:path)

    puts
    puts "ERROR: test(s) not found at:"
    not_found.each do |f, l|
      puts "  %s:%s" % [f, l]
      puts
      puts "Did you mean?"
      puts
      l = l.begin if l.is_a? Range
      by_path[f]
        .sort_by { |m| (m.line_s - l).abs }
        .first(2)
        .each do |m|
          puts "  %-30s (dist=%+d) (%s)" % [m, m.line_s - l, m.name]
        end
      puts
    end
    true
  end
end

#post_process

Add additional arguments to args to handle path:line argument filtering

[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 285

def post_process
  return if .empty?

  tests = tests_by_class

  exit! if handle_missing_tests? tests

  test_res = tests_to_regexp tests
  self.args << "-n" << "/#{test_res.join "|"}/"
end

#process_args

This method is for internal use only.
[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 236

def process_args # :nodoc:
  args.reject! { |arg|                # this is a good use of overriding
    case arg
    when /^(.*):([\d,-]+)$/ then
      f, ls = $1, $2
      ls = ls
        .split(/,/)
        .map { |l|
          case l
          when /^\d+$/ then
            l.to_i
          when /^(\d)-(\d)$/ then
            $1.to_i..$2.to_i
          else
            raise "unhandled argument format: %p" % [l]
          end
        }
      next unless File.exist? f
      args << f                       # push path on lest it run whole dir
      [f] = ls
    end
  }

  super
end

#process_flags(flags)

Overrides #process_flags to filter out ruby flags from minitest flags. Only supports -I<paths>, -d, and -w for ruby.

[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 267

def process_flags flags
  flags.reject { |flag| # all hits are truthy, so this works out well
    case flag
    when /^-I(.*)/ then
      $LOAD_PATH.prepend(*$1.split(/:/))
    when /^-d/ then
      $DEBUG = true
    when /^-w/ then
      $VERBOSE = true
    else
      false
    end
  }
end

#tests_by_class

Returns a hash mapping ::Minitest runnable classes to TMs

[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 316

def tests_by_class
  all_tests
    .transform_values { |ms|
      ms.select { |m|
        bl = [m.path]
        not bl or bl.any? { |l| m.include? l }
      }
    }
    .reject { |k, v| v.empty? }
end

#tests_to_regexp(tests)

Converts tests to an array of “klass#(methods+)” regexps to be used for test selection.

[ GitHub ]

  
# File 'lib/minitest/path_expander.rb', line 331

def tests_to_regexp tests
  tests                                         # { k1 => [Test(a), ...}
    .transform_values { |tms| tms.map(&:name) } # { k1 => %w[a, b], ...}
    .map { |k, ns|                              # [ "k1#(?:a|b)", "k2#c", ...]
      if ns.size > 1 then
        ns.map! { |n| Regexp.escape n }
        "%s#\(?:%s\)" % [Regexp.escape(k.name), ns.join("|")]
      else
        "%s#%s" % [Regexp.escape(k.name), ns.first]
      end
    }
end