covet 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|