Module: Covet
- Defined in:
- lib/covet.rb,
lib/covet/cli.rb,
lib/covet/vcs/git.rb,
lib/covet/version.rb,
lib/covet/log_file.rb,
lib/covet/log_collection.rb,
lib/covet/collection_task.rb,
lib/covet/line_changes_vcs.rb,
lib/covet/collection_filter.rb,
lib/covet/test_runners/rspec.rb,
lib/covet/collection_compressor.rb,
lib/covet/test_runners/minitest.rb
Defined Under Namespace
Modules: CollectionCompressor, CollectionFilter, LineChangesVCS, Options, TestRunners, VCS Classes: CLI, CollectionTask, LogCollection, LogFile, LogFileIndex
Constant Summary collapse
- 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.
[:random_seeded, :random, :ordered].freeze
- VERSION =
'0.1.1'.freeze
Class Method Summary collapse
-
.cmdline_for_run_list(run_list) ⇒ Object
Returns the command line to run the tests given in ‘run_list`.
-
.coverage_before_and_after ⇒ Object
Returns coverage information for before block ran, and after block ran for the codebase in its current state.
- .coverage_collection_registered? ⇒ Boolean
-
.diff_coverages(before, after) ⇒ Object
Get the difference between ‘before`’s coverage info and ‘after`’s coverage info.
-
.generate_run_list_for_method(before, after, options = {}) ⇒ Object
Generates a mapping of filenames to the lines and test methods that caused the changes.
-
.log_collection ⇒ Object
Singleton for collecting and writing log information during the collection phase.
-
.normalize_coverage_info(coverage_info) ⇒ Object
Filter and compress ‘coverage_info` to make it more manageable to log to the collection file, and so that processing it will be faster.
-
.options ⇒ Object
Hash.
-
.register_coverage_collection! ⇒ Object
Register coverage collection with the test library ‘Covet.test_runner`.
- .test_directories ⇒ Object
- .test_directories=(*dirs) ⇒ Object
- .test_order ⇒ Object
- .test_order=(order) ⇒ Object
- .test_runner ⇒ Object
-
.test_runner=(runner) ⇒ Object
Set the test runner library to hook into, gathering and logging coverage information during the collection phase for each test method.
- .vcs ⇒ Object
-
.vcs=(vcs) ⇒ Object
Set the version control system to use for seeing which files have changed since a certain version.
Class Method Details
.cmdline_for_run_list(run_list) ⇒ Object
Returns the command line to run the tests given in ‘run_list`.
145 146 147 148 149 |
# 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 ⇒ Object
Returns coverage information for before block ran, and after block ran for the codebase in its current state.
154 155 156 157 158 159 160 161 162 163 164 165 |
# 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? ⇒ Boolean
139 140 141 |
# File 'lib/covet.rb', line 139 def self.coverage_collection_registered? @coverage_collection_registered end |
.diff_coverages(before, after) ⇒ Object
Get the difference between ‘before`’s coverage info and ‘after`’s coverage info.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# 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 = {}) ⇒ Object
Generates a mapping of filenames to the lines and test methods that caused the changes.
178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/covet.rb', line 178 def self.generate_run_list_for_method(before, after, = {}) 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] << ([:method_name] || '???').to_s end end cov_map end |
.log_collection ⇒ Object
Singleton for collecting and writing log information during the collection phase.
44 45 46 |
# File 'lib/covet.rb', line 44 def self.log_collection @log_collection end |
.normalize_coverage_info(coverage_info) ⇒ Object
Filter and compress ‘coverage_info` to make it more manageable to log to the collection file, and so that processing it will be faster.
169 170 171 172 |
# File 'lib/covet.rb', line 169 def self.normalize_coverage_info(coverage_info) filtered = CollectionFilter.filter(coverage_info) CollectionCompressor.compress(filtered) end |
.options ⇒ Object
Returns Hash.
39 40 41 |
# File 'lib/covet.rb', line 39 def self. CLI. || Options::DEFAULTS end |
.register_coverage_collection! ⇒ Object
Register coverage collection with the test library ‘Covet.test_runner`. This happens during the collection phase.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# 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 ⇒ Object
108 |
# File 'lib/covet.rb', line 108 def self.test_directories; @test_directories.dup; end |
.test_directories=(*dirs) ⇒ Object
98 99 100 101 102 103 104 105 106 107 |
# 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 ⇒ Object
94 |
# File 'lib/covet.rb', line 94 def self.test_order; @test_order; end |
.test_order=(order) ⇒ Object
87 88 89 90 91 92 93 |
# 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 ⇒ Object
76 |
# File 'lib/covet.rb', line 76 def self.test_runner; @test_runner; end |
.test_runner=(runner) ⇒ Object
Set the test runner library to hook into, gathering and logging coverage information during the collection phase for each test method.
69 70 71 72 73 74 75 |
# 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 ⇒ Object
63 |
# File 'lib/covet.rb', line 63 def self.vcs; @vcs; end |
.vcs=(vcs) ⇒ Object
Set the version control system to use for seeing which files have changed since a certain version.
57 58 59 60 61 62 |
# 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 |