module Covet

Constants

BASE_COVERAGE
VALID_TEST_ORDERS

Tell `covet` the order in which your tests are run, which allows it to save space and time during the coverage collection phase in certain situations.

VERSION

Public Class Methods

cmdline_for_run_list(run_list) click to toggle source

Returns the command line to run the tests given in `run_list`. @return String

# File lib/covet.rb, line 145
def self.cmdline_for_run_list(run_list)
  Covet::TestRunners.const_get(
    @test_runner.to_s.capitalize
  ).cmdline_for_run_list(run_list)
end
coverage_before_and_after() { || ... } click to toggle source

Returns coverage information for before block ran, and after block ran for the codebase in its current state. @return Array

# File lib/covet.rb, line 154
def self.coverage_before_and_after # yields
  before = CovetCoverage.peek_result
  yield
  after = CovetCoverage.peek_result
  before = normalize_coverage_info(before)
  if Covet::BASE_COVERAGE.any?
    before = diff_coverages(Covet::BASE_COVERAGE, before)
  end
  after = normalize_coverage_info(after)
  after = diff_coverages(before, after)
  [before, after]
end
coverage_collection_registered?() click to toggle source
# File lib/covet.rb, line 139
def self.coverage_collection_registered?
  @coverage_collection_registered
end
diff_coverages(before, after) click to toggle source

Get the difference between `before`'s coverage info and `after`'s coverage info. @param [Hash] before @param [Hash] after @return Hash

# File lib/covet.rb, line 197
def self.diff_coverages(before, after)
  ret = after.each_with_object({}) do |(file_name, after_line_cov), res|
    before_line_cov = before[file_name] || {}
    next if before_line_cov == after_line_cov

    cov = {}

    after_line_cov.each do |lineno, exec_times|
      # no change
      if (before_exec_times = before_line_cov[lineno]) == exec_times
        next
      end

      # execution of previous line number
      if before_exec_times && exec_times
        cov[lineno] = exec_times - before_exec_times
      elsif exec_times
        cov[lineno] = exec_times
      else
        raise "shouldn't get here"
      end
    end

    # add the "diffed" coverage to the hash
    res[file_name] = cov
  end
  ret
end
generate_run_list_for_method(before, after, options = {}) click to toggle source

Generates a mapping of filenames to the lines and test methods that caused the changes. @return Hash, example:

{ "/home/me/workspace/myproj/myproj.rb" => { 1 => ['test_method_that_caused_changed']} }
# File lib/covet.rb, line 178
def self.generate_run_list_for_method(before, after, options = {})
  cov_map = Hash.new { |h, file| h[file] = Hash.new { |i, line| i[line] = [] } }
  after.each do |file, lines_hash|
    file_map = cov_map[file]

    lines_hash.each do |lineno, exec_times|
      # add the test name to the map. Multiple tests can execute the same
      # line, so we need to use an array.
      file_map[lineno] << (options[:method_name] || '???').to_s
    end
  end
  cov_map
end
log_collection() click to toggle source

Singleton for collecting and writing log information during the collection phase.

# File lib/covet.rb, line 44
def self.log_collection
  @log_collection
end
normalize_coverage_info(coverage_info) click to toggle source

Filter and compress `coverage_info` to make it more manageable to log to the collection file, and so that processing it will be faster.

# File lib/covet.rb, line 169
def self.normalize_coverage_info(coverage_info)
  filtered = CollectionFilter.filter(coverage_info)
  CollectionCompressor.compress(filtered)
end
options() click to toggle source

@return Hash

# File lib/covet.rb, line 39
def self.options
  CLI.options || Options::DEFAULTS
end
register_coverage_collection!() click to toggle source

Register coverage collection with the test library `Covet.test_runner`. This happens during the collection phase.

# File lib/covet.rb, line 122
def self.register_coverage_collection!
  # stdlib Coverage can't run at the same time as CovetCoverage or
  # bad things will happen
  if defined?(Coverage) && !Coverage.respond_to?(:peek_result)
    warn "The 'coverage' library is already loaded. It could cause issues with this library."
    # There's no way to tell if coverage is enabled or not, and
    # if we try stopping the coverage and it's not enabled, it raises
    # a RuntimeError.
    Coverage.stop rescue nil
  end
  CovetCoverage.start # needs to be called before any application code gets required
  Covet::TestRunners.const_get(
    @test_runner.to_s.capitalize
  ).hook_into_test_methods!
  @coverage_collection_registered = true
end
test_directories() click to toggle source
# File lib/covet.rb, line 108
def self.test_directories; @test_directories.dup; end
test_directories=(*dirs) click to toggle source
# File lib/covet.rb, line 98
def self.test_directories=(*dirs)
  dirs = dirs.flatten
  dirs.each do |dir|
    unless Dir.exist?(dir)
      raise Errno::ENOENT, %Q(invalid directory given: "#{dir}" ) +
        %Q{("#{File.join(Dir.pwd, dir)}")}
    end
  end
  @test_directories = dirs
end
test_order() click to toggle source
# File lib/covet.rb, line 94
def self.test_order; @test_order; end
test_order=(order) click to toggle source
# File lib/covet.rb, line 87
def self.test_order=(order)
  unless VALID_TEST_ORDERS.include?(order.intern)
    raise ArgumentError, "Invalid test order given. Expected one of " \
      "#{VALID_TEST_ORDERS.map(&:inspect).join(", ")} - #{order.intern.inspect} given"
  end
  @test_order = order
end
test_runner() click to toggle source
# File lib/covet.rb, line 76
def self.test_runner; @test_runner; end
test_runner=(runner) click to toggle source

Set the test runner library to hook into, gathering and logging coverage information during the collection phase for each test method.

# File lib/covet.rb, line 69
def self.test_runner=(runner)
  @test_runner = runner.intern
  require_relative "covet/test_runners/#{runner}"
rescue LoadError
  raise ArgumentError, "invalid test runner given: '#{runner}'. " \
    "Expected 'rspec' or 'minitest'"
end
vcs() click to toggle source
# File lib/covet.rb, line 63
def self.vcs; @vcs; end
vcs=(vcs) click to toggle source

Set the version control system to use for seeing which files have changed since a certain version.

# File lib/covet.rb, line 57
def self.vcs=(vcs)
  @vcs = vcs.intern
  if @vcs != :git
    raise NotImplementedError, "Can only use git as the VCS for now."
  end
end