covet 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +13 -0
- data/.travis.yml +10 -0
- data/Gemfile +7 -5
- data/README.md +4 -0
- data/Rakefile +7 -2
- data/ext/covet_coverage/covet_coverage.c +1 -1
- data/gemfiles/minitest4-0-0.gemfile +9 -0
- data/gemfiles/minitest5-0-8.gemfile +9 -0
- data/gemfiles/minitest5-3-3.gemfile +9 -0
- data/gemfiles/minitest5-7-0.gemfile +9 -0
- data/lib/covet.rb +32 -9
- data/lib/covet/collection_filter.rb +1 -1
- data/lib/covet/collection_task.rb +60 -0
- data/lib/covet/log_file.rb +2 -2
- data/lib/covet/test_runners/minitest.rb +273 -40
- data/lib/covet/vcs/git.rb +1 -1
- data/lib/covet/version.rb +1 -1
- data/spec/rspec_collection_hook_spec.rb +12 -0
- data/spec/spec_helper.rb +75 -0
- data/test/coverage_peek_result_test.rb +34 -0
- data/test/fakelib.rb +9 -0
- data/test/fakelib2.rb +6 -0
- data/test/log_collection_test.rb +26 -0
- data/test/log_file_test.rb +50 -0
- data/test/minitest_collection_hooks_test.rb +19 -0
- data/test/run_list_test.rb +32 -0
- data/test/skips_test.rb +23 -0
- data/test/test_helper.rb +88 -0
- metadata +62 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 904a67d9659b9da5e67d2c640d3deb68c2ce8e2d
|
4
|
+
data.tar.gz: a0a689a74a1048a23e87a331bb6b53104512549b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e31c2ff532fdbfb83a785508705073224113a551ccdd7f8724ee606a4ae6e3bc9d47660fad219679e33f1259da947f5a41008ebada1b0e9518da100333766ec4
|
7
|
+
data.tar.gz: b52e7e4ce821ad4d399fcae3d017d541606e49e2ea0dddaee2be2f32c3104b3fe59f1f311ab50b259e3790ac10dfcedb62ce71d3460f935efc11515feeed192b
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -4,9 +4,11 @@ gemspec
|
|
4
4
|
group :test, :development do
|
5
5
|
gem 'rspec'
|
6
6
|
gem 'minitest'
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
if ENV['COVET_DEBUG']
|
8
|
+
if RUBY_VERSION.to_i < 2
|
9
|
+
gem 'debugger'
|
10
|
+
else
|
11
|
+
gem 'byebug'
|
12
|
+
end
|
13
|
+
end
|
12
14
|
end
|
data/README.md
CHANGED
@@ -26,6 +26,10 @@ certain lines of the application code.
|
|
26
26
|
Usage
|
27
27
|
-----
|
28
28
|
|
29
|
+
Add `covet` to your Gemfile in your test or development `:group`, or:
|
30
|
+
|
31
|
+
$ gem install covet
|
32
|
+
|
29
33
|
Coverage Collection:
|
30
34
|
|
31
35
|
Run your test suite with coverage collection on. To enable this,
|
data/Rakefile
CHANGED
@@ -2,8 +2,10 @@ require 'rake/testtask'
|
|
2
2
|
require 'rake/extensiontask'
|
3
3
|
require 'rspec/core/rake_task'
|
4
4
|
require 'rake/clean'
|
5
|
+
require 'wwtd/tasks'
|
5
6
|
|
6
7
|
task :default => [:tests_and_specs]
|
8
|
+
task :travis => [:clobber, :compile, :wwtd] # run travis builds locally
|
7
9
|
|
8
10
|
Rake::TestTask.new(:test) do |t|
|
9
11
|
t.test_files = FileList['test/**/*_test.rb'].to_a
|
@@ -23,7 +25,9 @@ desc 'Run minitest and rspec tests (default)'
|
|
23
25
|
task :tests_and_specs => [:test, :spec]
|
24
26
|
|
25
27
|
desc 'compile internal coverage C extension'
|
26
|
-
Rake::ExtensionTask.new('covet_coverage')
|
28
|
+
Rake::ExtensionTask.new('covet_coverage') do |ext| # rake compile
|
29
|
+
ext.lib_dir = 'lib' # output covet_coverage.so to 'lib' directory
|
30
|
+
end
|
27
31
|
|
28
32
|
desc 'recompile internal coverage C extension'
|
29
33
|
task :recompile => [:clobber, :compile, :tests_and_specs]
|
@@ -32,6 +36,7 @@ task :recompile => [:clobber, :compile, :tests_and_specs]
|
|
32
36
|
CLOBBER.include(
|
33
37
|
'run_log.json',
|
34
38
|
'run_log_index.json',
|
35
|
-
'
|
39
|
+
'lib/*.{so,o,bundle}',
|
36
40
|
'ext/covet_coverage/Makefile',
|
41
|
+
'gemfiles/*.lock',
|
37
42
|
)
|
@@ -114,7 +114,7 @@ rb_coverage_result(void)
|
|
114
114
|
VALUE coverages = rb_get_coverages();
|
115
115
|
VALUE ncoverages = rb_hash_new();
|
116
116
|
if (!RTEST(coverages)) {
|
117
|
-
rb_raise(rb_eRuntimeError, "coverage measurement is not enabled");
|
117
|
+
rb_raise(rb_eRuntimeError, "coverage measurement is not enabled (covet)");
|
118
118
|
}
|
119
119
|
st_foreach(RHASH_TBL(coverages), coverage_result_i, ncoverages);
|
120
120
|
rb_hash_freeze(ncoverages);
|
data/lib/covet.rb
CHANGED
@@ -4,7 +4,7 @@ if defined?(Coverage) && Coverage.respond_to?(:peek_result)
|
|
4
4
|
else
|
5
5
|
# TODO: error out if non-mri ruby
|
6
6
|
begin
|
7
|
-
require_relative 'covet_coverage
|
7
|
+
require_relative 'covet_coverage'
|
8
8
|
rescue Exception # re-raised
|
9
9
|
$stderr.puts "Error loading 'covet' C extension.\n" \
|
10
10
|
"Please report this bug along with a backtrace. Thanks :)"
|
@@ -26,20 +26,21 @@ if ENV['COVET_DEBUG']
|
|
26
26
|
gem 'byebug'
|
27
27
|
require 'byebug'
|
28
28
|
end
|
29
|
-
else
|
30
|
-
if !defined?(debugger)
|
31
|
-
def debugger; end
|
32
|
-
end
|
29
|
+
#else
|
30
|
+
#if !defined?(debugger)
|
31
|
+
#def debugger; end
|
32
|
+
#end
|
33
33
|
end
|
34
34
|
|
35
35
|
module Covet
|
36
36
|
BASE_COVERAGE = {}
|
37
37
|
|
38
|
-
# @return Hash
|
38
|
+
# @return Hash
|
39
39
|
def self.options
|
40
40
|
CLI.options || Options::DEFAULTS
|
41
41
|
end
|
42
42
|
|
43
|
+
# Singleton for collecting and writing log information during the collection phase.
|
43
44
|
def self.log_collection
|
44
45
|
@log_collection
|
45
46
|
end
|
@@ -51,6 +52,8 @@ module Covet
|
|
51
52
|
:bufsize => 50,
|
52
53
|
)
|
53
54
|
|
55
|
+
# Set the version control system to use for seeing which files have changed
|
56
|
+
# since a certain version.
|
54
57
|
def self.vcs=(vcs)
|
55
58
|
@vcs = vcs.intern
|
56
59
|
if @vcs != :git
|
@@ -61,6 +64,8 @@ module Covet
|
|
61
64
|
|
62
65
|
self.vcs = :git # default
|
63
66
|
|
67
|
+
# Set the test runner library to hook into, gathering and logging coverage
|
68
|
+
# information during the collection phase for each test method.
|
64
69
|
def self.test_runner=(runner)
|
65
70
|
@test_runner = runner.intern
|
66
71
|
require_relative "covet/test_runners/#{runner}"
|
@@ -76,6 +81,8 @@ module Covet
|
|
76
81
|
self.test_runner = :minitest # default
|
77
82
|
end
|
78
83
|
|
84
|
+
# Tell `covet` the order in which your tests are run, which allows it to
|
85
|
+
# save space and time during the coverage collection phase in certain situations.
|
79
86
|
VALID_TEST_ORDERS = [:random_seeded, :random, :ordered].freeze
|
80
87
|
def self.test_order=(order)
|
81
88
|
unless VALID_TEST_ORDERS.include?(order.intern)
|
@@ -109,10 +116,14 @@ module Covet
|
|
109
116
|
self.test_directories = self.test_directories + ['spec']
|
110
117
|
end
|
111
118
|
|
119
|
+
@coverage_collection_registered = false
|
120
|
+
# Register coverage collection with the test library `Covet.test_runner`.
|
121
|
+
# This happens during the collection phase.
|
112
122
|
def self.register_coverage_collection!
|
113
123
|
# stdlib Coverage can't run at the same time as CovetCoverage or
|
114
124
|
# bad things will happen
|
115
125
|
if defined?(Coverage) && !Coverage.respond_to?(:peek_result)
|
126
|
+
warn "The 'coverage' library is already loaded. It could cause issues with this library."
|
116
127
|
# There's no way to tell if coverage is enabled or not, and
|
117
128
|
# if we try stopping the coverage and it's not enabled, it raises
|
118
129
|
# a RuntimeError.
|
@@ -122,8 +133,14 @@ module Covet
|
|
122
133
|
Covet::TestRunners.const_get(
|
123
134
|
@test_runner.to_s.capitalize
|
124
135
|
).hook_into_test_methods!
|
136
|
+
@coverage_collection_registered = true
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.coverage_collection_registered?
|
140
|
+
@coverage_collection_registered
|
125
141
|
end
|
126
142
|
|
143
|
+
# Returns the command line to run the tests given in `run_list`.
|
127
144
|
# @return String
|
128
145
|
def self.cmdline_for_run_list(run_list)
|
129
146
|
Covet::TestRunners.const_get(
|
@@ -131,12 +148,12 @@ module Covet
|
|
131
148
|
).cmdline_for_run_list(run_list)
|
132
149
|
end
|
133
150
|
|
134
|
-
# Returns coverage information for before
|
151
|
+
# Returns coverage information for before block ran, and after block ran
|
135
152
|
# for the codebase in its current state.
|
136
153
|
# @return Array
|
137
154
|
def self.coverage_before_and_after # yields
|
138
155
|
before = CovetCoverage.peek_result
|
139
|
-
yield
|
156
|
+
yield
|
140
157
|
after = CovetCoverage.peek_result
|
141
158
|
before = normalize_coverage_info(before)
|
142
159
|
if Covet::BASE_COVERAGE.any?
|
@@ -147,6 +164,8 @@ module Covet
|
|
147
164
|
[before, after]
|
148
165
|
end
|
149
166
|
|
167
|
+
# Filter and compress `coverage_info` to make it more manageable to log
|
168
|
+
# to the collection file, and so that processing it will be faster.
|
150
169
|
def self.normalize_coverage_info(coverage_info)
|
151
170
|
filtered = CollectionFilter.filter(coverage_info)
|
152
171
|
CollectionCompressor.compress(filtered)
|
@@ -170,6 +189,10 @@ module Covet
|
|
170
189
|
cov_map
|
171
190
|
end
|
172
191
|
|
192
|
+
# Get the difference between `before`'s coverage info and `after`'s coverage
|
193
|
+
# info.
|
194
|
+
# @param [Hash] before
|
195
|
+
# @param [Hash] after
|
173
196
|
# @return Hash
|
174
197
|
def self.diff_coverages(before, after)
|
175
198
|
ret = after.each_with_object({}) do |(file_name, after_line_cov), res|
|
@@ -201,6 +224,6 @@ module Covet
|
|
201
224
|
end
|
202
225
|
end
|
203
226
|
|
204
|
-
if ENV['COVET_COLLECT'] == '1'
|
227
|
+
if ENV['COVET_COLLECT'] == '1' && !Covet.coverage_collection_registered?
|
205
228
|
Covet.register_coverage_collection!
|
206
229
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rake/tasklib'
|
2
|
+
|
3
|
+
module Covet
|
4
|
+
# Define a new rake task to collect coverage information for a `TestTask`.
|
5
|
+
# Usage (in Rakefile):
|
6
|
+
#
|
7
|
+
# require 'rake/testtask'
|
8
|
+
# require 'covet/collection_task'
|
9
|
+
#
|
10
|
+
# Rake::TestTask.new(:my_tests) do |t|
|
11
|
+
# t.verbose = true
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# Covet::CollectionTask.new(:collect) do |t|
|
15
|
+
# t.test_task = :my_tests
|
16
|
+
# t.description = "Collect coverage information for my_tests"
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Now, we can can run '$ rake collect'.
|
20
|
+
class CollectionTask < Rake::TaskLib
|
21
|
+
|
22
|
+
attr_accessor :name
|
23
|
+
attr_accessor :description
|
24
|
+
attr_accessor :test_task # Rake::TestTask or Symbol
|
25
|
+
attr_accessor :covet_opts # Array of cmdline covet options
|
26
|
+
|
27
|
+
def initialize(name = :covet_collect) # yields
|
28
|
+
@name = name
|
29
|
+
@description = nil
|
30
|
+
@test_task = nil
|
31
|
+
@covet_opts = []
|
32
|
+
yield self if block_given?
|
33
|
+
define
|
34
|
+
end
|
35
|
+
|
36
|
+
# Define the task
|
37
|
+
def define
|
38
|
+
if @test_task.nil?
|
39
|
+
raise "#{self.class} '#{@name}' is not properly set up. " \
|
40
|
+
"This task needs a `test_task` that's either the `Rake::TestTask` " \
|
41
|
+
"object to test or the name of that `TestTask` object. You can assign " \
|
42
|
+
"it using the `test_task=` method on the instance of #{self.class}."
|
43
|
+
end
|
44
|
+
@description ||= "Collect coverage information for task '#{test_task_name}'"
|
45
|
+
desc @description
|
46
|
+
task @name do
|
47
|
+
cmd = %Q(covet -c "rake #{test_task_name}" #{@covet_opts.join(' ')}).strip
|
48
|
+
puts cmd
|
49
|
+
system cmd
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def test_task_name
|
56
|
+
@test_task.respond_to?(:name) ? @test_task.name : @test_task
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
data/lib/covet/log_file.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'json'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'fileutils'
|
2
4
|
|
3
5
|
module Covet
|
4
6
|
# Represents log file of JSON coverage information for each test method.
|
@@ -9,8 +11,6 @@ module Covet
|
|
9
11
|
# disk at certain intervals. This way, we can also load the information in
|
10
12
|
# chunks as well, using the same index file.
|
11
13
|
class LogFile
|
12
|
-
require 'tempfile'
|
13
|
-
require 'fileutils'
|
14
14
|
|
15
15
|
LoadError = Class.new(StandardError)
|
16
16
|
|
@@ -3,49 +3,284 @@ require 'rake/testtask'
|
|
3
3
|
module Covet
|
4
4
|
module TestRunners
|
5
5
|
module Minitest
|
6
|
-
@
|
6
|
+
@hooked = false
|
7
7
|
@create_collection_file_on_exit = true
|
8
8
|
class << self
|
9
9
|
attr_accessor :create_collection_file_on_exit
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.hook_into_test_methods!
|
13
|
-
if @
|
13
|
+
if @hooked
|
14
14
|
warn "Warning - Covet.register_coverage_collection! called multiple times"
|
15
15
|
return
|
16
16
|
end
|
17
17
|
gem 'minitest'
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
diff_t = after_t - ::Minitest::Runnable.covet_start_time
|
23
|
-
time_taken = sprintf("%.2f", diff_t)
|
24
|
-
Covet.log_collection << ['stats', {
|
25
|
-
:time_taken => time_taken,
|
26
|
-
:files_filtered => CollectionFilter.files_filtered,
|
27
|
-
}]
|
28
|
-
if Covet::TestRunners::Minitest.create_collection_file_on_exit
|
29
|
-
Covet.log_collection.finish!
|
30
|
-
else
|
31
|
-
$stderr.puts "Covet: skipped writing to collection file"
|
32
|
-
end
|
18
|
+
begin
|
19
|
+
require 'minitest' # minitest 5
|
20
|
+
rescue LoadError
|
21
|
+
require 'minitest/unit' # minitest 4
|
33
22
|
end
|
23
|
+
version = defined?(::Minitest::VERSION) ?
|
24
|
+
::Minitest::VERSION : # v >= 5
|
25
|
+
::Minitest::Unit::VERSION # v < 5
|
26
|
+
|
27
|
+
if version.to_f >= 5.0
|
28
|
+
::Minitest.after_run do
|
29
|
+
after_t = Time.now
|
30
|
+
diff_t = after_t - ::Minitest::Runnable.covet_start_time
|
31
|
+
time_taken = sprintf("%.2f", diff_t)
|
32
|
+
Covet.log_collection << ['stats', {
|
33
|
+
:time_taken => time_taken,
|
34
|
+
:files_filtered => CollectionFilter.files_filtered,
|
35
|
+
}]
|
36
|
+
if Covet::TestRunners::Minitest.create_collection_file_on_exit
|
37
|
+
Covet.log_collection.finish!
|
38
|
+
else
|
39
|
+
$stderr.puts "Covet: skipped writing to collection file"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
if ::Minitest::Runnable.respond_to?(:run_one_method) # minitest > 5.0.8
|
44
|
+
::Minitest::Runnable.class_eval do
|
45
|
+
@@covet_run_num = 0
|
46
|
+
@@covet_skips = 0
|
47
|
+
@@covet_failures = 0
|
48
|
+
@@covet_start_time = nil
|
49
|
+
|
50
|
+
class << self
|
51
|
+
def covet_start_time
|
52
|
+
@@covet_start_time
|
53
|
+
end
|
54
|
+
|
55
|
+
alias :covet_old_run_one_method :run_one_method
|
56
|
+
|
57
|
+
def run_one_method(klass, method_name, reporter)
|
58
|
+
# first run, collect coverage 'base' coverage information
|
59
|
+
# (coverage information for before any tests get run).
|
60
|
+
if @@covet_run_num == 0
|
61
|
+
@@covet_start_time = Time.now
|
62
|
+
base_coverage = CovetCoverage.peek_result
|
63
|
+
base_coverage = Covet.normalize_coverage_info(base_coverage)
|
64
|
+
if base_coverage.empty?
|
65
|
+
warn "Warning - covet is not properly set up, as it must be required " \
|
66
|
+
"before other libraries to work correctly.\nTry adding\n require 'covet'\n" \
|
67
|
+
"to the top of your test helper file."
|
68
|
+
end
|
69
|
+
Covet::BASE_COVERAGE.update base_coverage
|
70
|
+
Covet.log_collection << ['base', base_coverage, {
|
71
|
+
:version => Covet::VERSION,
|
72
|
+
:options => Covet.options,
|
73
|
+
:seed => Random::DEFAULT.seed,
|
74
|
+
}]
|
75
|
+
end
|
76
|
+
|
77
|
+
@@covet_run_num += 1
|
78
|
+
file = nil
|
79
|
+
begin
|
80
|
+
file = klass.instance_method(method_name).source_location[0]
|
81
|
+
rescue
|
82
|
+
warn "\nWarning - Skipping collecting test coverage for method #{klass}##{method_name}\n"
|
83
|
+
return
|
84
|
+
end
|
85
|
+
|
86
|
+
before = CovetCoverage.peek_result
|
87
|
+
|
88
|
+
# Run test method
|
89
|
+
before_t = Time.now
|
90
|
+
result = covet_old_run_one_method(klass, method_name, reporter)
|
91
|
+
after_t = Time.now
|
34
92
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
93
|
+
summary_reporter = result.first
|
94
|
+
skips = summary_reporter.results.select(&:skipped?).size
|
95
|
+
|
96
|
+
# test was skipped, don't record coverage info
|
97
|
+
if @@covet_skips != skips
|
98
|
+
@@covet_skips = skips
|
99
|
+
@@covet_failures += 1
|
100
|
+
return result
|
101
|
+
end
|
102
|
+
|
103
|
+
# test failed, don't record coverage info
|
104
|
+
failures = summary_reporter.results.select(&:failures).size
|
105
|
+
if @@covet_failures != failures
|
106
|
+
@@covet_failures = failures
|
107
|
+
return result
|
108
|
+
end
|
109
|
+
|
110
|
+
after = CovetCoverage.peek_result
|
111
|
+
|
112
|
+
before_orig = Covet.normalize_coverage_info(before)
|
113
|
+
if Covet::BASE_COVERAGE.any?
|
114
|
+
before = Covet.diff_coverages(Covet::BASE_COVERAGE, before_orig)
|
115
|
+
end
|
116
|
+
|
117
|
+
after_orig = Covet.normalize_coverage_info(after)
|
118
|
+
after = Covet.diff_coverages(before_orig, after_orig)
|
119
|
+
if @@covet_run_num > 1
|
120
|
+
if [:random_seeded, :ordered].include?(Covet.options[:test_order])
|
121
|
+
Covet::BASE_COVERAGE.update(after_orig)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if after == before
|
126
|
+
after = nil
|
127
|
+
end
|
128
|
+
Covet.log_collection << ["#{file}##{method_name}", after, {
|
129
|
+
:time => sprintf("%.2f", after_t - before_t),
|
130
|
+
}]
|
131
|
+
result
|
132
|
+
# NOTE: if the interrupt is fired outside of `Minitest.run_one_method`, then the
|
133
|
+
# collection file gets logged to even on interrupt :(
|
134
|
+
rescue Interrupt, SystemExit
|
135
|
+
Covet::TestRunners::Minitest.create_collection_file_on_exit = false
|
136
|
+
raise
|
137
|
+
end
|
40
138
|
|
41
|
-
class << self
|
42
|
-
def covet_start_time
|
43
|
-
@@covet_start_time
|
44
139
|
end
|
140
|
+
end
|
141
|
+
elsif ::Minitest::Runnable.respond_to?(:run)
|
142
|
+
# minitest ~ 5.0.8
|
143
|
+
::Minitest::Runnable.class_eval do
|
144
|
+
@@covet_run_num = 0
|
145
|
+
@@covet_skips = 0
|
146
|
+
@@covet_failures = 0
|
147
|
+
@@covet_start_time = nil
|
148
|
+
class << self
|
149
|
+
def covet_start_time
|
150
|
+
@@covet_start_time
|
151
|
+
end
|
152
|
+
|
153
|
+
alias :covet_old_run :run
|
154
|
+
|
155
|
+
def run(reporter, options = {})
|
156
|
+
filter = options[:filter] || '/./'
|
157
|
+
filter = Regexp.new $1 if filter =~ /\/(.*)\//
|
158
|
+
filtered_methods = self.runnable_methods.find_all { |m|
|
159
|
+
filter === m || filter === "#{self}##{m}"
|
160
|
+
}
|
161
|
+
|
162
|
+
failures = 0
|
163
|
+
with_info_handler reporter do
|
164
|
+
filtered_methods.each do |method_name|
|
165
|
+
|
166
|
+
# first run, collect coverage 'base' coverage information
|
167
|
+
# (coverage information for before any tests get run).
|
168
|
+
if @@covet_run_num == 0
|
169
|
+
@@covet_start_time = Time.now
|
170
|
+
base_coverage = CovetCoverage.peek_result
|
171
|
+
base_coverage = Covet.normalize_coverage_info(base_coverage)
|
172
|
+
if base_coverage.empty?
|
173
|
+
warn "Warning - covet is not properly set up, as it must be required " \
|
174
|
+
"before other libraries to work correctly.\nTry adding\n require 'covet'\n" \
|
175
|
+
"to the top of your test helper file."
|
176
|
+
end
|
177
|
+
Covet::BASE_COVERAGE.update base_coverage
|
178
|
+
Covet.log_collection << ['base', base_coverage, {
|
179
|
+
:version => Covet::VERSION,
|
180
|
+
:options => Covet.options,
|
181
|
+
:seed => Random::DEFAULT.seed,
|
182
|
+
}]
|
183
|
+
end
|
184
|
+
|
185
|
+
@@covet_run_num += 1
|
186
|
+
file = nil
|
187
|
+
begin
|
188
|
+
file = instance_method(method_name).source_location[0]
|
189
|
+
rescue
|
190
|
+
warn "\nWarning - Skipping collecting test coverage for method #{klass}##{method_name}\n"
|
191
|
+
next
|
192
|
+
end
|
193
|
+
|
194
|
+
before = CovetCoverage.peek_result
|
195
|
+
|
196
|
+
# Run test method
|
197
|
+
before_t = Time.now
|
198
|
+
result = self.new(method_name).run
|
199
|
+
after_t = Time.now
|
200
|
+
raise "#{self}#run _must_ return self" unless self === result
|
201
|
+
ret = reporter.record result
|
202
|
+
|
203
|
+
if result.skipped?
|
204
|
+
@@covet_skips += 1
|
205
|
+
next
|
206
|
+
end
|
207
|
+
|
208
|
+
# test failed, don't record coverage info
|
209
|
+
new_failures = result.failures.size
|
210
|
+
if new_failures > failures
|
211
|
+
@@covet_failures += 1
|
212
|
+
failures += 1
|
213
|
+
next
|
214
|
+
end
|
215
|
+
|
216
|
+
after = CovetCoverage.peek_result
|
217
|
+
|
218
|
+
before_orig = Covet.normalize_coverage_info(before)
|
219
|
+
if Covet::BASE_COVERAGE.any?
|
220
|
+
before = Covet.diff_coverages(Covet::BASE_COVERAGE, before_orig)
|
221
|
+
end
|
222
|
+
|
223
|
+
after_orig = Covet.normalize_coverage_info(after)
|
224
|
+
after = Covet.diff_coverages(before_orig, after_orig)
|
225
|
+
if @@covet_run_num > 1
|
226
|
+
if [:random_seeded, :ordered].include?(Covet.options[:test_order])
|
227
|
+
Covet::BASE_COVERAGE.update(after_orig)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
if after == before
|
232
|
+
after = nil
|
233
|
+
end
|
45
234
|
|
46
|
-
|
235
|
+
Covet.log_collection << ["#{file}##{method_name}", after, {
|
236
|
+
:time => sprintf("%.2f", after_t - before_t),
|
237
|
+
}]
|
47
238
|
|
48
|
-
|
239
|
+
ret
|
240
|
+
end
|
241
|
+
end
|
242
|
+
# NOTE: if the interrupt is fired outside of `Minitest.run_one_method`, then the
|
243
|
+
# collection file gets logged to even on interrupt :(
|
244
|
+
rescue Interrupt, SystemExit
|
245
|
+
Covet::TestRunners::Minitest.create_collection_file_on_exit = false
|
246
|
+
raise
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
end
|
251
|
+
else
|
252
|
+
raise "Minitest version #{::Minitest::VERSION rescue '?'} not supported."
|
253
|
+
end
|
254
|
+
elsif defined?(::Minitest::Unit::TestCase) && ::Minitest::Unit::TestCase.method_defined?(:run)
|
255
|
+
::Minitest::Unit.after_tests do
|
256
|
+
after_t = Time.now
|
257
|
+
diff_t = after_t - ::Minitest::Unit::TestCase.covet_start_time
|
258
|
+
time_taken = sprintf("%.2f", diff_t)
|
259
|
+
Covet.log_collection << ['stats', {
|
260
|
+
:time_taken => time_taken,
|
261
|
+
:files_filtered => CollectionFilter.files_filtered,
|
262
|
+
}]
|
263
|
+
if Covet::TestRunners::Minitest.create_collection_file_on_exit
|
264
|
+
Covet.log_collection.finish!
|
265
|
+
else
|
266
|
+
$stderr.puts "Covet: skipped writing to collection file"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
::Minitest::Unit::TestCase.class_eval do
|
270
|
+
@@covet_run_num = 0
|
271
|
+
@@covet_skips = 0
|
272
|
+
@@covet_failures = 0
|
273
|
+
@@covet_start_time = nil
|
274
|
+
|
275
|
+
class << self
|
276
|
+
def covet_start_time
|
277
|
+
@@covet_start_time
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
alias :covet_old_run :run
|
282
|
+
|
283
|
+
def run(runner)
|
49
284
|
# first run, collect coverage 'base' coverage information
|
50
285
|
# (coverage information for before any tests get run).
|
51
286
|
if @@covet_run_num == 0
|
@@ -58,8 +293,6 @@ module Covet
|
|
58
293
|
"to the top of your test helper file."
|
59
294
|
end
|
60
295
|
Covet::BASE_COVERAGE.update base_coverage
|
61
|
-
# TODO: save Random::DEFAULT.seed in run log file if Covet.options[:test_order] == :random_seeded,
|
62
|
-
# then we can run the methods in the same order as before.
|
63
296
|
Covet.log_collection << ['base', base_coverage, {
|
64
297
|
:version => Covet::VERSION,
|
65
298
|
:options => Covet.options,
|
@@ -70,21 +303,19 @@ module Covet
|
|
70
303
|
@@covet_run_num += 1
|
71
304
|
file = nil
|
72
305
|
begin
|
73
|
-
file =
|
306
|
+
file = method(self.__name__).source_location[0]
|
74
307
|
rescue
|
75
|
-
warn "\nWarning - Skipping collecting test coverage for method #{
|
308
|
+
warn "\nWarning - Skipping collecting test coverage for method #{self.class}##{self.__name__}\n"
|
76
309
|
return
|
77
310
|
end
|
78
|
-
|
79
311
|
before = CovetCoverage.peek_result
|
80
312
|
|
81
313
|
# Run test method
|
82
314
|
before_t = Time.now
|
83
|
-
result =
|
315
|
+
result = covet_old_run(runner)
|
84
316
|
after_t = Time.now
|
85
317
|
|
86
|
-
|
87
|
-
skips = summary_reporter.results.select(&:skipped?).size
|
318
|
+
skips = runner.skips
|
88
319
|
|
89
320
|
# test was skipped, don't record coverage info
|
90
321
|
if @@covet_skips != skips
|
@@ -94,7 +325,7 @@ module Covet
|
|
94
325
|
end
|
95
326
|
|
96
327
|
# test failed, don't record coverage info
|
97
|
-
failures =
|
328
|
+
failures = runner.failures
|
98
329
|
if @@covet_failures != failures
|
99
330
|
@@covet_failures = failures
|
100
331
|
return result
|
@@ -118,20 +349,22 @@ module Covet
|
|
118
349
|
if after == before
|
119
350
|
after = nil
|
120
351
|
end
|
121
|
-
Covet.log_collection << ["#{file}##{
|
352
|
+
Covet.log_collection << ["#{file}##{self.__name__}", after, {
|
122
353
|
:time => sprintf("%.2f", after_t - before_t),
|
123
354
|
}]
|
124
355
|
result
|
125
|
-
# NOTE: if the interrupt is fired outside of `Minitest.
|
356
|
+
# NOTE: if the interrupt is fired outside of `Minitest::Unit::TestCase.run`, then the
|
126
357
|
# collection file gets logged even on interrupt :(
|
127
|
-
rescue Interrupt
|
358
|
+
rescue Interrupt, SystemExit
|
128
359
|
Covet::TestRunners::Minitest.create_collection_file_on_exit = false
|
129
360
|
raise
|
130
361
|
end
|
131
362
|
|
132
363
|
end
|
364
|
+
else
|
365
|
+
raise "Minitest version #{::Minitest::VERSION rescue '?'} not supported."
|
133
366
|
end
|
134
|
-
@
|
367
|
+
@hooked = true
|
135
368
|
end
|
136
369
|
|
137
370
|
def self.cmdline_for_run_list(run_list)
|
data/lib/covet/vcs/git.rb
CHANGED
@@ -18,7 +18,7 @@ module Covet
|
|
18
18
|
# raises Rugged::Error or TypeError if `revision` is invalid Git object id
|
19
19
|
# (tag name or sha1, etc.)
|
20
20
|
commit = Rugged::Commit.new(repo, revision)
|
21
|
-
repo.index.diff(commit, {}) # NOTE: for some reason, this call doesn't work properly if the second
|
21
|
+
repo.index.diff(commit, {}) # NOTE: for some reason, this call doesn't work properly if the second argument isn't given. Bug in rugged?
|
22
22
|
end
|
23
23
|
diff.each_patch { |patch|
|
24
24
|
file = patch.delta.old_file[:path] # NOTE: old file is the index's version
|
data/lib/covet/version.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
first_logs_size = 0
|
4
|
+
RSpec.describe do "Each spec method"
|
5
|
+
it "1. should be wrapped in coverage collection" do
|
6
|
+
first_logs_size = Covet.log_collection.size
|
7
|
+
end
|
8
|
+
|
9
|
+
it "2. should be wrapped in coverage collection" do
|
10
|
+
Covet.log_collection.size.should_not equal(first_logs_size)
|
11
|
+
end
|
12
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../lib/covet'
|
2
|
+
require_relative '../test/fakelib'
|
3
|
+
gem 'rspec'
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
Covet.test_runner = :rspec
|
7
|
+
Covet::CollectionFilter.whitelist_gem('covet')
|
8
|
+
Covet.register_coverage_collection!
|
9
|
+
|
10
|
+
module CovetTestHelpers
|
11
|
+
|
12
|
+
def coverage_before_and_after(&block)
|
13
|
+
Covet.coverage_before_and_after(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_run_list_for_method(before, after, options = {})
|
17
|
+
Covet.generate_run_list_for_method(before, after, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def change_file(fname, lineno, new_line) # yields
|
21
|
+
check_file_exists!(fname)
|
22
|
+
new_line << "\n" unless new_line.end_with?("\n")
|
23
|
+
contents = File.read(fname).lines.to_a
|
24
|
+
old_contents = contents.dup
|
25
|
+
old_line = contents[lineno - 1]
|
26
|
+
if old_line.nil?
|
27
|
+
raise ArgumentError, "invalid line number for #{fname}: #{lineno}"
|
28
|
+
end
|
29
|
+
contents[lineno - 1] = new_line
|
30
|
+
File.open(fname, 'w') { |f| f.write contents.join }
|
31
|
+
yield
|
32
|
+
ensure
|
33
|
+
if old_contents
|
34
|
+
File.open(fname, 'w') {|f| f.write old_contents.join }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def remove_file(fname) # yields
|
39
|
+
check_file_exists!(fname)
|
40
|
+
# TODO
|
41
|
+
end
|
42
|
+
|
43
|
+
def rename_file(fname, new_name) # yields
|
44
|
+
check_file_exists!(fname)
|
45
|
+
# TODO
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_file(fname, contents) # yields
|
49
|
+
check_file_doesnt_exist!(fname)
|
50
|
+
# TODO
|
51
|
+
end
|
52
|
+
|
53
|
+
def with_collection_filter(filter) # yields
|
54
|
+
# TODO
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def check_file_exists!(fname)
|
60
|
+
unless File.exist?(fname)
|
61
|
+
raise ArgumentError, "file doesn't exist: #{fname}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def check_file_doesnt_exist!(fname)
|
66
|
+
if File.exist?(fname)
|
67
|
+
raise ArgumentError, "file already exists: #{fname}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
RSpec.configure do |c|
|
74
|
+
c.include CovetTestHelpers
|
75
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
class CoveragePeekResultTest < CovetTest
|
5
|
+
# Aaron's original test for `Coverage::peek_result` in
|
6
|
+
# https://github.com/ruby/ruby/commit/a86eacf552c0f3a7862d6891cf174007d96f656a
|
7
|
+
def test_coverage_peek_result
|
8
|
+
loaded_features = $".dup
|
9
|
+
|
10
|
+
Dir.mktmpdir {|tmp|
|
11
|
+
Dir.chdir(tmp) {
|
12
|
+
File.open("test.rb", "w") do |f|
|
13
|
+
f.puts <<-EOS
|
14
|
+
def coverage_test_method
|
15
|
+
:ok
|
16
|
+
end
|
17
|
+
EOS
|
18
|
+
end
|
19
|
+
require tmp + '/test.rb'
|
20
|
+
cov = CovetCoverage.peek_result[tmp + '/test.rb']
|
21
|
+
coverage_test_method
|
22
|
+
cov2 = CovetCoverage.peek_result[tmp + '/test.rb']
|
23
|
+
assert_equal cov[1] + 1, cov2[1]
|
24
|
+
begin
|
25
|
+
assert_equal cov2, CovetCoverage.result[tmp + '/test.rb']
|
26
|
+
ensure # `CovetCoverage#result` stops coverage collection
|
27
|
+
CovetCoverage.start
|
28
|
+
end
|
29
|
+
}
|
30
|
+
}
|
31
|
+
ensure
|
32
|
+
$".replace loaded_features
|
33
|
+
end
|
34
|
+
end
|
data/test/fakelib.rb
ADDED
data/test/fakelib2.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
class LogCollectionTest < CovetTest
|
5
|
+
@@tempfile = Tempfile.new('test')
|
6
|
+
@@tempfile.close
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@logs = Covet::LogCollection.new(
|
10
|
+
:filename => @@tempfile.path,
|
11
|
+
:bufsize => 20
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_append_and_finish
|
16
|
+
100.times do |i|
|
17
|
+
@logs << [i]
|
18
|
+
end
|
19
|
+
assert_equal 5, @logs.flushes
|
20
|
+
@logs << [42]
|
21
|
+
assert @logs.finish!
|
22
|
+
assert_equal 6, @logs.flushes
|
23
|
+
assert !File.read(@@tempfile.path).empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
class LogFileTest < CovetTest
|
5
|
+
@@tempfile = Tempfile.new('test')
|
6
|
+
@@tempfile.close
|
7
|
+
|
8
|
+
def test_write_buf_uses_index_file
|
9
|
+
index_fname = @@tempfile.path + 'index'
|
10
|
+
logfile = Covet::LogFile.new(
|
11
|
+
:filename => @@tempfile.path,
|
12
|
+
:index_filename => index_fname
|
13
|
+
)
|
14
|
+
logfile.write_start
|
15
|
+
100.times do |i|
|
16
|
+
buf = Array.new(100, i)
|
17
|
+
logfile.write_buf(buf)
|
18
|
+
end
|
19
|
+
logfile.write_end
|
20
|
+
assert_equal 102, logfile.writes
|
21
|
+
ary = logfile.load!
|
22
|
+
assert_equal 100, ary.size
|
23
|
+
assert_equal 100, ary[0].size
|
24
|
+
assert_equal 0, ary[0][0]
|
25
|
+
assert_kind_of Array, ary
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_each_buf_using_index_file
|
29
|
+
index_fname = @@tempfile.path + 'index'
|
30
|
+
logfile = Covet::LogFile.new(
|
31
|
+
:filename => @@tempfile.path,
|
32
|
+
:index_filename => index_fname
|
33
|
+
)
|
34
|
+
|
35
|
+
logfile.write_start
|
36
|
+
100.times do |i|
|
37
|
+
buf = Array.new(100, i)
|
38
|
+
logfile.write_buf(buf)
|
39
|
+
end
|
40
|
+
logfile.write_end
|
41
|
+
|
42
|
+
all_bufs = []
|
43
|
+
logfile.load_each_buf! do |buf|
|
44
|
+
all_bufs << buf
|
45
|
+
end
|
46
|
+
assert_equal 100, all_bufs.size
|
47
|
+
assert all_bufs.all? { |buf| buf.size == 100 }
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class MinitestCollectionHooks < CovetTest
|
4
|
+
@@first_logs = []
|
5
|
+
|
6
|
+
def self.test_order
|
7
|
+
:sorted
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_1_collect_for_next_test
|
11
|
+
@@first_logs = Covet.log_collection.instance_variable_get("@buf").dup
|
12
|
+
# do nothing, assertion(s) are in next test
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_2_log_collection_size_increases_after_test
|
16
|
+
assert Covet.log_collection.size > 0
|
17
|
+
assert Covet.log_collection.size != @@first_logs.size
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class RunListTest < CovetTest
|
4
|
+
def test_empty_run_list_for_method
|
5
|
+
before, after = coverage_before_and_after { }
|
6
|
+
list = generate_run_list_for_method(before, after, :method_name => __method__)
|
7
|
+
assert_equal Hash, list.class
|
8
|
+
methods_to_run = list.values.map(&:values).flatten.uniq
|
9
|
+
assert list.empty? || methods_to_run == [__method__.to_s]
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_non_empty_run_list_for_method_due_to_changed_lib_file
|
13
|
+
obj = MyClass.new
|
14
|
+
assert_equal :hi, obj.hello?
|
15
|
+
fname = File.expand_path('../fakelib.rb', __FILE__)
|
16
|
+
|
17
|
+
before, after = coverage_before_and_after do
|
18
|
+
change_file(fname, 8, "def goodbye; 'bye'; end") do
|
19
|
+
load fname
|
20
|
+
end
|
21
|
+
obj = MyClass.new
|
22
|
+
assert_equal 'bye', obj.goodbye
|
23
|
+
end
|
24
|
+
MyClass.class_eval { undef :goodbye }
|
25
|
+
|
26
|
+
refute_equal before, after
|
27
|
+
list = generate_run_list_for_method(before, after, :method_name => __method__)
|
28
|
+
assert_equal Hash, list.class
|
29
|
+
assert !list.empty?
|
30
|
+
assert list[fname]
|
31
|
+
end
|
32
|
+
end
|
data/test/skips_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
class SkipsTest < CovetTest
|
4
|
+
def self.test_order
|
5
|
+
:sorted
|
6
|
+
end
|
7
|
+
|
8
|
+
@@collections = nil
|
9
|
+
|
10
|
+
def setup
|
11
|
+
# ... do nothing. Don't call `super` to make sure coverage information isn't cleared before each new test
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_1_skip
|
15
|
+
@@collections = Covet.log_collection.instance_variable_get("@buf").dup
|
16
|
+
skip 'for next test'
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_2_skips_dont_update_coverage_collection
|
20
|
+
assert_equal @@collections, Covet.log_collection.instance_variable_get("@buf")
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require_relative '../lib/covet'
|
2
|
+
require_relative 'fakelib'
|
3
|
+
gem 'minitest'
|
4
|
+
begin
|
5
|
+
require 'minitest' # minitest 5
|
6
|
+
Minitest.autorun
|
7
|
+
rescue LoadError
|
8
|
+
require 'minitest/unit' # minitest 4
|
9
|
+
require 'minitest/autorun'
|
10
|
+
end
|
11
|
+
|
12
|
+
Covet::CollectionFilter.whitelist_gem('covet')
|
13
|
+
Covet.register_coverage_collection!
|
14
|
+
|
15
|
+
class CovetTest < defined?(Minitest::Test) ? Minitest::Test : Minitest::Unit::TestCase
|
16
|
+
|
17
|
+
def setup
|
18
|
+
Covet::BASE_COVERAGE.update({})
|
19
|
+
end
|
20
|
+
|
21
|
+
def coverage_before_and_after(&block)
|
22
|
+
Covet.coverage_before_and_after(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def generate_run_list_for_method(before, after, options = {})
|
26
|
+
Covet.generate_run_list_for_method(before, after, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def change_file(fname, lineno, new_line) # yields
|
30
|
+
check_file_exists!(fname)
|
31
|
+
new_line << "\n" unless new_line.end_with?("\n")
|
32
|
+
contents = File.read(fname).lines.to_a
|
33
|
+
old_contents = contents.dup
|
34
|
+
old_line = contents[lineno - 1]
|
35
|
+
if old_line.nil?
|
36
|
+
raise ArgumentError, "invalid line number for #{fname}: #{lineno}"
|
37
|
+
end
|
38
|
+
contents[lineno - 1] = new_line
|
39
|
+
File.open(fname, 'w') do |f|
|
40
|
+
f.write contents.join
|
41
|
+
end
|
42
|
+
yield
|
43
|
+
ensure
|
44
|
+
if old_contents
|
45
|
+
File.open(fname, 'w') do |f|
|
46
|
+
f.write old_contents.join
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def method_in_coverage_info?(info, method)
|
52
|
+
# TODO
|
53
|
+
end
|
54
|
+
|
55
|
+
def remove_file(fname) # yields
|
56
|
+
check_file_exists!(fname)
|
57
|
+
# TODO
|
58
|
+
end
|
59
|
+
|
60
|
+
def rename_file(fname, new_name) # yields
|
61
|
+
check_file_exists!(fname)
|
62
|
+
# TODO
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_file(fname, contents) # yields
|
66
|
+
check_file_doesnt_exist!(fname)
|
67
|
+
# TODO
|
68
|
+
end
|
69
|
+
|
70
|
+
def with_collection_filter(filter) # yields
|
71
|
+
# TODO
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def check_file_exists!(fname)
|
77
|
+
unless File.exist?(fname)
|
78
|
+
raise ArgumentError, "file doesn't exist: #{fname}"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def check_file_doesnt_exist!(fname)
|
83
|
+
if File.exist?(fname)
|
84
|
+
raise ArgumentError, "file already exists: #{fname}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: covet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Gruber
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rugged
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: wwtd
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
description: Uses git and ruby coverage information to determine which tests to run
|
42
70
|
from your test suite
|
43
71
|
email: luke.gru@gmail.com
|
@@ -47,16 +75,23 @@ extensions:
|
|
47
75
|
- ext/covet_coverage/extconf.rb
|
48
76
|
extra_rdoc_files: []
|
49
77
|
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- ".travis.yml"
|
50
80
|
- Gemfile
|
51
81
|
- README.md
|
52
82
|
- Rakefile
|
53
83
|
- bin/covet
|
54
84
|
- ext/covet_coverage/covet_coverage.c
|
55
85
|
- ext/covet_coverage/extconf.rb
|
86
|
+
- gemfiles/minitest4-0-0.gemfile
|
87
|
+
- gemfiles/minitest5-0-8.gemfile
|
88
|
+
- gemfiles/minitest5-3-3.gemfile
|
89
|
+
- gemfiles/minitest5-7-0.gemfile
|
56
90
|
- lib/covet.rb
|
57
91
|
- lib/covet/cli.rb
|
58
92
|
- lib/covet/collection_compressor.rb
|
59
93
|
- lib/covet/collection_filter.rb
|
94
|
+
- lib/covet/collection_task.rb
|
60
95
|
- lib/covet/line_changes_vcs.rb
|
61
96
|
- lib/covet/log_collection.rb
|
62
97
|
- lib/covet/log_file.rb
|
@@ -65,7 +100,18 @@ files:
|
|
65
100
|
- lib/covet/vcs/git.rb
|
66
101
|
- lib/covet/version.rb
|
67
102
|
- lib/covet_collect.rb
|
68
|
-
|
103
|
+
- spec/rspec_collection_hook_spec.rb
|
104
|
+
- spec/spec_helper.rb
|
105
|
+
- test/coverage_peek_result_test.rb
|
106
|
+
- test/fakelib.rb
|
107
|
+
- test/fakelib2.rb
|
108
|
+
- test/log_collection_test.rb
|
109
|
+
- test/log_file_test.rb
|
110
|
+
- test/minitest_collection_hooks_test.rb
|
111
|
+
- test/run_list_test.rb
|
112
|
+
- test/skips_test.rb
|
113
|
+
- test/test_helper.rb
|
114
|
+
homepage: https://github.com/luke-gru/covet
|
69
115
|
licenses:
|
70
116
|
- MIT
|
71
117
|
metadata: {}
|
@@ -85,8 +131,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
131
|
version: '0'
|
86
132
|
requirements: []
|
87
133
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.4.
|
134
|
+
rubygems_version: 2.4.5
|
89
135
|
signing_key:
|
90
136
|
specification_version: 4
|
91
137
|
summary: Regression test selection tool based on coverage information
|
92
|
-
test_files:
|
138
|
+
test_files:
|
139
|
+
- test/log_collection_test.rb
|
140
|
+
- test/skips_test.rb
|
141
|
+
- test/fakelib.rb
|
142
|
+
- test/run_list_test.rb
|
143
|
+
- test/test_helper.rb
|
144
|
+
- test/coverage_peek_result_test.rb
|
145
|
+
- test/log_file_test.rb
|
146
|
+
- test/fakelib2.rb
|
147
|
+
- test/minitest_collection_hooks_test.rb
|
148
|
+
- spec/spec_helper.rb
|
149
|
+
- spec/rspec_collection_hook_spec.rb
|