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
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
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
# File lib/covet.rb, line 139 def self.coverage_collection_registered? @coverage_collection_registered end
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
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
Singleton for collecting and writing log information during the collection phase.
# File lib/covet.rb, line 44 def self.log_collection @log_collection end
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
@return Hash
# File lib/covet.rb, line 39 def self.options CLI.options || Options::DEFAULTS end
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
# File lib/covet.rb, line 108 def self.test_directories; @test_directories.dup; end
# 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
# File lib/covet.rb, line 94 def self.test_order; @test_order; end
# 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
# File lib/covet.rb, line 76 def self.test_runner; @test_runner; end
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
# File lib/covet.rb, line 63 def self.vcs; @vcs; end
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