coverband 4.2.0 → 4.2.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +29 -9
  3. data/.travis.yml +9 -1
  4. data/Gemfile +2 -1
  5. data/Gemfile.rails4 +1 -0
  6. data/README.md +34 -13
  7. data/Rakefile +10 -2
  8. data/changes.md +25 -10
  9. data/coverband.gemspec +5 -1
  10. data/lib/coverband.rb +30 -18
  11. data/lib/coverband/adapters/base.rb +2 -7
  12. data/lib/coverband/adapters/file_store.rb +1 -1
  13. data/lib/coverband/at_exit.rb +2 -11
  14. data/lib/coverband/collectors/coverage.rb +29 -32
  15. data/lib/coverband/collectors/delta.rb +20 -24
  16. data/lib/coverband/configuration.rb +49 -19
  17. data/lib/coverband/integrations/background.rb +6 -4
  18. data/lib/coverband/integrations/{middleware.rb → background_middleware.rb} +2 -6
  19. data/lib/coverband/integrations/bundler.rb +8 -0
  20. data/lib/coverband/integrations/report_middleware.rb +15 -0
  21. data/lib/coverband/integrations/resque.rb +3 -5
  22. data/lib/coverband/reporters/base.rb +39 -13
  23. data/lib/coverband/reporters/html_report.rb +21 -27
  24. data/lib/coverband/reporters/web.rb +2 -21
  25. data/lib/coverband/utils/file_list.rb +16 -5
  26. data/lib/coverband/utils/file_path_helper.rb +2 -0
  27. data/lib/coverband/utils/html_formatter.rb +25 -8
  28. data/lib/coverband/utils/lines_classifier.rb +5 -0
  29. data/lib/coverband/utils/railtie.rb +11 -12
  30. data/lib/coverband/utils/result.rb +5 -44
  31. data/lib/coverband/utils/results.rb +51 -0
  32. data/lib/coverband/utils/source_file.rb +29 -5
  33. data/lib/coverband/utils/tasks.rb +11 -2
  34. data/lib/coverband/version.rb +1 -1
  35. data/public/application.js +27 -0
  36. data/test/benchmarks/benchmark.rake +10 -20
  37. data/test/coverband/adapters/file_store_test.rb +5 -5
  38. data/test/coverband/adapters/redis_store_test.rb +8 -7
  39. data/test/coverband/at_exit_test.rb +0 -2
  40. data/test/coverband/collectors/coverage_test.rb +57 -9
  41. data/test/coverband/collectors/delta_test.rb +27 -6
  42. data/test/coverband/configuration_test.rb +47 -7
  43. data/test/coverband/coverband_test.rb +0 -1
  44. data/test/coverband/integrations/background_middleware_test.rb +44 -0
  45. data/test/coverband/integrations/background_test.rb +1 -3
  46. data/test/coverband/integrations/report_middleware_test.rb +44 -0
  47. data/test/coverband/integrations/resque_worker_test.rb +4 -3
  48. data/test/coverband/integrations/test_resque_job.rb +3 -1
  49. data/test/coverband/reporters/base_test.rb +4 -4
  50. data/test/coverband/reporters/console_test.rb +1 -2
  51. data/test/coverband/reporters/html_test.rb +79 -16
  52. data/test/coverband/reporters/web_test.rb +0 -10
  53. data/test/coverband/utils/file_groups_test.rb +1 -1
  54. data/test/coverband/utils/file_list_test.rb +5 -5
  55. data/test/coverband/utils/html_formatter_test.rb +45 -0
  56. data/test/coverband/utils/result_test.rb +27 -47
  57. data/test/coverband/utils/results_test.rb +54 -0
  58. data/test/coverband/utils/s3_report_test.rb +2 -0
  59. data/test/coverband/utils/source_file_test.rb +50 -0
  60. data/test/forked/rails_full_stack_test.rb +101 -0
  61. data/test/forked/rails_rake_full_stack_test.rb +32 -0
  62. data/test/integration/full_stack_test.rb +17 -15
  63. data/test/rails4_dummy/Rakefile +6 -0
  64. data/test/rails4_dummy/config/application.rb +8 -9
  65. data/test/rails4_dummy/config/coverband.rb +3 -3
  66. data/test/rails5_dummy/Rakefile +6 -0
  67. data/test/rails5_dummy/config/application.rb +6 -10
  68. data/test/rails5_dummy/config/coverband.rb +2 -2
  69. data/test/rails_test_helper.rb +23 -4
  70. data/test/test_helper.rb +26 -1
  71. data/test/unique_files.rb +6 -5
  72. data/views/file_list.erb +2 -2
  73. data/views/gem_list.erb +10 -1
  74. data/views/layout.erb +10 -3
  75. data/views/source_file.erb +13 -4
  76. data/views/source_file_loader.erb +1 -1
  77. metadata +79 -9
  78. data/test/coverband/integrations/middleware_test.rb +0 -96
  79. data/test/integration/rails_full_stack_test.rb +0 -95
@@ -20,6 +20,41 @@ module Coverband
20
20
  get_results(results_type).source_files.find { |file| file.filename == source_file.filename }
21
21
  end
22
22
 
23
+ def runtime_relevant_coverage(source_file)
24
+ return unless eager_loading_coverage && runtime_coverage
25
+
26
+ eager_file = get_eager_file(source_file)
27
+ runtime_file = get_runtime_file(source_file)
28
+
29
+ return 0.0 unless runtime_file
30
+
31
+ return runtime_file.formatted_covered_percent unless eager_file
32
+
33
+ runtime_relavant_lines = eager_file.relevant_lines - eager_file.covered_lines_count
34
+ runtime_file.runtime_relavant_calculations(runtime_relavant_lines) { |file| file.formatted_covered_percent }
35
+ end
36
+
37
+ def runtime_relavent_lines(source_file)
38
+ return 0 unless runtime_coverage
39
+
40
+ eager_file = get_eager_file(source_file)
41
+ runtime_file = get_runtime_file(source_file)
42
+
43
+ return runtime_file.covered_lines_count unless eager_file
44
+
45
+ eager_file.relevant_lines - eager_file.covered_lines_count
46
+ end
47
+
48
+ ###
49
+ # TODO: Groups still have some issues, this should be generic for groups, but right now gem_name
50
+ # is specifically called out, need to revisit all gorups code.
51
+ ###
52
+ def group_file_list_with_type(group, file_list, results_type)
53
+ return unless get_results(results_type)
54
+
55
+ get_results(results_type).groups[group].find { |gem_files| gem_files.first.gem_name == file_list.first.gem_name }
56
+ end
57
+
23
58
  def file_from_path_with_type(full_path, results_type = :merged)
24
59
  return unless get_results(results_type)
25
60
 
@@ -44,6 +79,22 @@ module Coverband
44
79
 
45
80
  private
46
81
 
82
+ def get_eager_file(source_file)
83
+ eager_loading_coverage.source_files.find { |file| file.filename == source_file.filename }
84
+ end
85
+
86
+ def get_runtime_file(source_file)
87
+ runtime_coverage.source_files.find { |file| file.filename == source_file.filename }
88
+ end
89
+
90
+ def eager_loading_coverage
91
+ get_results(Coverband::EAGER_TYPE)
92
+ end
93
+
94
+ def runtime_coverage
95
+ get_results(Coverband::RUNTIME_TYPE)
96
+ end
97
+
47
98
  ###
48
99
  # This is a first version of lazy loading the results
49
100
  # for the full advantage we need to push lazy loading to the file level
@@ -11,6 +11,8 @@ module Coverband
11
11
  module Utils
12
12
  class SourceFile
13
13
  include Coverband::Utils::FilePathHelper
14
+
15
+ # TODO: Refactor Line into its own file
14
16
  # Representation of a single line in a source file including
15
17
  # this specific line's source code, line_number and code coverage,
16
18
  # with the coverage being either nil (coverage not applicable, e.g. comment
@@ -35,6 +37,7 @@ module Coverband
35
37
  raise ArgumentError, 'Only String accepted for source' unless src.is_a?(String)
36
38
  raise ArgumentError, 'Only Integer accepted for line_number' unless line_number.is_a?(Integer)
37
39
  raise ArgumentError, 'Only Integer and nil accepted for coverage' unless coverage.is_a?(Integer) || coverage.nil?
40
+
38
41
  @src = src
39
42
  @line_number = line_number
40
43
  @coverage = coverage
@@ -48,7 +51,7 @@ module Coverband
48
51
 
49
52
  # Returns true if this is a line that has been covered
50
53
  def covered?
51
- !never? && !skipped? && coverage > 0
54
+ !never? && !skipped? && coverage.positive?
52
55
  end
53
56
 
54
57
  # Returns true if this line is not relevant for coverage
@@ -64,7 +67,7 @@ module Coverband
64
67
  # Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with
65
68
  # # :nocov: comment lines.
66
69
  def skipped?
67
- !!skipped
70
+ skipped
68
71
  end
69
72
 
70
73
  # The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
@@ -90,18 +93,27 @@ module Coverband
90
93
 
91
94
  def initialize(filename, file_data)
92
95
  @filename = filename
96
+ @runtime_relavant_lines = nil
93
97
  if file_data.is_a?(Hash)
94
98
  @coverage = file_data['data']
95
99
  @first_updated_at = @last_updated_at = NOT_AVAILABLE
96
100
  @first_updated_at = Time.at(file_data['first_updated_at']) if file_data['first_updated_at']
97
101
  @last_updated_at = Time.at(file_data['last_updated_at']) if file_data['last_updated_at']
98
102
  else
103
+ # TODO: Deprecate this code path this was backwards compatability from 3-4
99
104
  @coverage = file_data
100
105
  @first_updated_at = NOT_AVAILABLE
101
106
  @last_updated_at = NOT_AVAILABLE
102
107
  end
103
108
  end
104
109
 
110
+ def runtime_relavant_calculations(runtime_relavant_lines)
111
+ @runtime_relavant_lines = runtime_relavant_lines
112
+ yield self
113
+ ensure
114
+ @runtime_relavant_lines = nil
115
+ end
116
+
105
117
  # The path to this source file relative to the projects directory
106
118
  def project_filename
107
119
  @filename.sub(/^#{Coverband.configuration.root}/, '')
@@ -151,6 +163,10 @@ module Coverband
151
163
  Float(covered_lines.size * 100.0 / relevant_lines.to_f)
152
164
  end
153
165
 
166
+ def formatted_covered_percent
167
+ covered_percent&.round(2)
168
+ end
169
+
154
170
  def covered_strength
155
171
  return 0.0 if relevant_lines.zero?
156
172
 
@@ -166,7 +182,7 @@ module Coverband
166
182
  end
167
183
 
168
184
  def relevant_lines
169
- lines.size - never_lines.size - skipped_lines.size
185
+ @runtime_relavant_lines || (lines.size - never_lines.size - skipped_lines.size)
170
186
  end
171
187
 
172
188
  # Returns all covered lines as SimpleCov::SourceFile::Line
@@ -174,6 +190,14 @@ module Coverband
174
190
  @covered_lines ||= lines.select(&:covered?)
175
191
  end
176
192
 
193
+ def covered_lines_count
194
+ covered_lines&.count
195
+ end
196
+
197
+ def line_coverage(index)
198
+ lines[index]&.coverage
199
+ end
200
+
177
201
  # Returns all lines that should have been, but were not covered
178
202
  # as instances of SimpleCov::SourceFile::Line
179
203
  def missed_lines
@@ -216,7 +240,7 @@ module Coverband
216
240
  # I had previously patched this in my local Rails app
217
241
  def short_name
218
242
  filename.sub(/^#{Coverband.configuration.root}/, '.')
219
- .sub(%r{^.*\/gems}, '.')
243
+ .sub(%r{^.*\/gems\/}, '.')
220
244
  .gsub(%r{^\.\/}, '')
221
245
  end
222
246
 
@@ -229,7 +253,7 @@ module Coverband
229
253
  end
230
254
 
231
255
  def gem_name
232
- gem? ? short_name.split('/').first : nil
256
+ gem? ? short_name.split('/').first.gsub(/^\./, '') : nil
233
257
  end
234
258
 
235
259
  private
@@ -1,9 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  namespace :coverband do
4
- Coverband.configure
4
+ # handles configuring in require => false and COVERBAND_DISABLE_AUTO_START cases
5
+ Coverband.configure unless Coverband.configured?
5
6
 
6
7
  def environment
8
+ Coverband.configuration.report_on_exit = false
9
+ Coverband.configuration.background_reporting_enabled = false
7
10
  Rake.application['environment'].invoke if Rake::Task.task_defined?('environment')
8
11
  end
9
12
 
@@ -11,12 +14,18 @@ namespace :coverband do
11
14
  task :coverage do
12
15
  environment
13
16
  if Coverband.configuration.reporter == 'scov'
14
- Coverband::Reporters::HTMLReport.report(Coverband.configuration.store)
17
+ Coverband::Reporters::HTMLReport.new(Coverband.configuration.store).report
15
18
  else
16
19
  Coverband::Reporters::ConsoleReport.report(Coverband.configuration.store)
17
20
  end
18
21
  end
19
22
 
23
+ desc 'report runtime Coverband code coverage'
24
+ task :coverage_server do
25
+ environment
26
+ Rack::Server.start app: Coverband::Reporters::Web.new, Port: ENV.fetch('COVERBAND_COVERAGE_PORT', 1022).to_i
27
+ end
28
+
20
29
  ###
21
30
  # clear data helpful for development or after configuration issues
22
31
  ###
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coverband
4
- VERSION = '4.2.0'
4
+ VERSION = '4.2.1.rc1'
5
5
  end
@@ -1,4 +1,14 @@
1
1
  $(document).ready(function() {
2
+ // remove the url params like notice=message so they don't stick around
3
+ window.history.replaceState(
4
+ "object or string",
5
+ "Coverband",
6
+ window.location.href.replace(/notice=.*/, "")
7
+ );
8
+ $(".notice")
9
+ .delay(3000)
10
+ .fadeOut("slow");
11
+
2
12
  $(".del").click(function() {
3
13
  if (!confirm("Do you want to delete")) {
4
14
  return false;
@@ -13,8 +23,25 @@ $(document).ready(function() {
13
23
  aoColumns: [
14
24
  null,
15
25
  { sType: "percent" },
26
+ { sType: "percent" },
27
+ null,
28
+ null,
29
+ null,
16
30
  null,
17
31
  null,
32
+ null
33
+ ]
34
+ });
35
+
36
+ // Configuration for fancy sortable tables for source file groups
37
+ $(".gem_list").dataTable({
38
+ aaSorting: [[1, "asc"]],
39
+ bPaginate: false,
40
+ bJQueryUI: true,
41
+ aoColumns: [
42
+ null,
43
+ { sType: "percent" },
44
+ { sType: "percent" },
18
45
  null,
19
46
  null,
20
47
  null,
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  namespace :benchmarks do
3
4
  # https://github.com/evanphx/benchmark-ips
4
5
  # Enable and start GC before each job run. Disable GC afterwards.
@@ -13,11 +14,9 @@ namespace :benchmarks do
13
14
  run_gc
14
15
  end
15
16
 
16
- def warmup_stats(*)
17
- end
17
+ def warmup_stats(*); end
18
18
 
19
- def add_report(*)
20
- end
19
+ def add_report(*); end
21
20
 
22
21
  private
23
22
 
@@ -33,11 +32,7 @@ namespace :benchmarks do
33
32
  end
34
33
 
35
34
  def clone_classifier
36
- # rubocop:disable Style/IfUnlessModifier
37
- unless Dir.exist? classifier_dir
38
- system "git clone https://github.com/jekyll/classifier-reborn.git #{classifier_dir}"
39
- end
40
- # rubocop:enable Style/IfUnlessModifier
35
+ system "git clone https://github.com/jekyll/classifier-reborn.git #{classifier_dir}" unless Dir.exist? classifier_dir
41
36
  end
42
37
 
43
38
  # desc 'setup standard benchmark'
@@ -79,7 +74,6 @@ namespace :benchmarks do
79
74
  task :setup_redis do
80
75
  Coverband.configure do |config|
81
76
  config.root = Dir.pwd
82
- config.reporting_frequency = 100.0
83
77
  config.logger = $stdout
84
78
  config.store = benchmark_redis_store
85
79
  end
@@ -89,7 +83,6 @@ namespace :benchmarks do
89
83
  task :setup_file do
90
84
  Coverband.configure do |config|
91
85
  config.root = Dir.pwd
92
- config.reporting_frequency = 100.0
93
86
  config.logger = $stdout
94
87
  file_path = '/tmp/benchmark_store.json'
95
88
  config.store = Coverband::Adapters::FileStore.new(file_path)
@@ -134,7 +127,7 @@ namespace :benchmarks do
134
127
  x.config(time: 12, warmup: 5, suite: suite)
135
128
  x.report 'coverband' do
136
129
  work
137
- Coverband.report_coverage(true)
130
+ Coverband.report_coverage
138
131
  end
139
132
  x.report 'no coverband' do
140
133
  work
@@ -160,6 +153,7 @@ namespace :benchmarks do
160
153
  def adjust_report(report)
161
154
  report.keys.each do |file|
162
155
  next unless rand < 0.15
156
+
163
157
  report[file] = fake_line_numbers
164
158
  end
165
159
  report
@@ -170,11 +164,7 @@ namespace :benchmarks do
170
164
  # this is a hack because in the benchmark we don't have real files
171
165
  ###
172
166
  def store.file_hash(file)
173
- if @file_hash_cache[file]
174
- @file_hash_cache[file]
175
- else
176
- @file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
177
- end
167
+ @file_hash_cache[file] || @file_hash_cache[file] = Digest::MD5.file(__FILE__).hexdigest
178
168
  end
179
169
 
180
170
  def store.full_path_to_relative(file)
@@ -232,7 +222,7 @@ namespace :benchmarks do
232
222
  10.times do
233
223
  Coverband.configure do |config|
234
224
  redis_url = ENV['CACHE_REDIS_URL'] || ENV['REDIS_URL']
235
- config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: 'coverband_data')
225
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new(url: redis_url), redis_namespace: 'coverband_bench_data')
236
226
  end
237
227
  end
238
228
  end.pretty_print
@@ -269,13 +259,13 @@ namespace :benchmarks do
269
259
  end
270
260
 
271
261
  # desc 'runs benchmarks on default redis setup'
272
- task run_redis: [:setup, :setup_redis] do
262
+ task run_redis: %i[setup setup_redis] do
273
263
  puts 'Coverband configured with default Redis store'
274
264
  run_work(true)
275
265
  end
276
266
 
277
267
  # desc 'runs benchmarks file store'
278
- task run_file: [:setup, :setup_file] do
268
+ task run_file: %i[setup setup_file] do
279
269
  puts 'Coverband configured with file store'
280
270
  run_work(true)
281
271
  end
@@ -10,13 +10,13 @@ class AdaptersFileStoreTest < Minitest::Test
10
10
  @store = Coverband::Adapters::FileStore.new(@test_file_path)
11
11
  end
12
12
 
13
- def test_covered_lines_for_file
14
- assert_equal @store.covered_lines_for_file('dog.rb')[0], 1
15
- assert_equal @store.covered_lines_for_file('dog.rb')[1], 2
13
+ def test_coverage
14
+ assert_equal @store.coverage['dog.rb']['data'][0], 1
15
+ assert_equal @store.coverage['dog.rb']['data'][1], 2
16
16
  end
17
17
 
18
18
  def test_covered_lines_when_null
19
- assert_equal @store.covered_lines_for_file('none.rb'), []
19
+ assert_nil @store.coverage['none.rb']
20
20
  end
21
21
 
22
22
  def test_covered_files
@@ -31,7 +31,7 @@ class AdaptersFileStoreTest < Minitest::Test
31
31
  def test_save_report
32
32
  mock_file_hash
33
33
  @store.send(:save_report, 'cat.rb' => [0, 1])
34
- assert_equal @store.covered_lines_for_file('cat.rb')[1], 1
34
+ assert_equal @store.coverage['cat.rb']['data'][1], 1
35
35
  end
36
36
 
37
37
  private
@@ -7,8 +7,11 @@ class RedisTest < Minitest::Test
7
7
 
8
8
  def setup
9
9
  super
10
+ Coverband.configuration.redis_namespace = 'coverband_test'
10
11
  @redis = Redis.new
11
- @store = Coverband::Adapters::RedisStore.new(@redis)
12
+ @store = Coverband::Adapters::RedisStore.new(@redis, redis_namespace: 'coverband_test')
13
+ Coverband.configuration.store = @store
14
+ @store.clear!
12
15
  end
13
16
 
14
17
  def test_coverage
@@ -58,21 +61,19 @@ class RedisTest < Minitest::Test
58
61
  assert_nil @store.type
59
62
  end
60
63
 
61
- def test_covered_lines_for_file
64
+ def test_coverage_for_file
62
65
  mock_file_hash
63
66
  expected = basic_coverage
64
67
  @store.save_report(expected)
65
- assert_equal example_line, @store.covered_lines_for_file('app_path/dog.rb')
68
+ assert_equal example_line, @store.coverage['app_path/dog.rb']['data']
66
69
  end
67
70
 
68
- def test_covered_lines_when_null
69
- assert_equal [], @store.covered_lines_for_file('app_path/dog.rb')
71
+ def test_coverage_when_null
72
+ assert_nil @store.coverage['app_path/dog.rb']
70
73
  end
71
74
 
72
75
  def test_clear
73
76
  @redis.expects(:del).twice
74
77
  @store.clear!
75
78
  end
76
-
77
-
78
79
  end
@@ -9,5 +9,3 @@ class AtExitTest < Minitest::Test
9
9
  2.times { Coverband::AtExit.register }
10
10
  end
11
11
  end
12
-
13
-
@@ -8,11 +8,11 @@ class CollectorsCoverageTest < Minitest::Test
8
8
  def setup
9
9
  super
10
10
  Coverband.configure do |config|
11
- config.store = Coverband::Adapters::RedisStore.new(Redis.new)
11
+ config.store = Coverband::Adapters::RedisStore.new(Redis.new, redis_namespace: 'coverband_test')
12
12
  end
13
13
  @coverband = Coverband::Collectors::Coverage.instance.reset_instance
14
14
  # preload first coverage hit
15
- @coverband.report_coverage(true)
15
+ @coverband.report_coverage
16
16
  end
17
17
 
18
18
  def teardown
@@ -24,17 +24,31 @@ class CollectorsCoverageTest < Minitest::Test
24
24
 
25
25
  test 'Dog class coverage' do
26
26
  file = require_unique_file
27
- coverband.report_coverage(true)
27
+ coverband.report_coverage
28
28
  coverage = Coverband.configuration.store.coverage
29
- assert_equal(coverage[file]["data"], [nil, nil, 1, 1, 0, nil, nil])
29
+ assert_equal(coverage[file]['data'], [nil, nil, 1, 1, 0, nil, nil])
30
30
  end
31
31
 
32
32
  test 'Dog method and class coverage' do
33
33
  load File.expand_path('../../dog.rb', File.dirname(__FILE__))
34
34
  Dog.new.bark
35
- coverband.report_coverage(true)
35
+ coverband.report_coverage
36
36
  coverage = Coverband.configuration.store.coverage
37
- assert_equal(coverage["./test/dog.rb"]["data"], [nil, nil, 1, 1, 1, nil, nil])
37
+ assert_equal(coverage['./test/dog.rb']['data'], [nil, nil, 1, 1, 1, nil, nil])
38
+ end
39
+
40
+ test 'Dog eager load coverage' do
41
+ store = Coverband.configuration.store
42
+ assert_nil store.type
43
+ file = coverband.eager_loading do
44
+ require_unique_file
45
+ end
46
+ coverage = Coverband.configuration.store.coverage[file]
47
+ assert_nil coverage, 'No runtime coverage'
48
+ coverband.eager_loading!
49
+ coverage = Coverband.configuration.store.coverage[file]
50
+ refute_nil coverage, 'Eager load coverage is present'
51
+ assert_equal(coverage['data'], [nil, nil, 1, 1, 0, nil, nil])
38
52
  end
39
53
 
40
54
  test 'gets coverage instance' do
@@ -46,8 +60,8 @@ class CollectorsCoverageTest < Minitest::Test
46
60
  end
47
61
 
48
62
  test 'report_coverage raises errors in tests' do
63
+ Coverband::Adapters::RedisStore.any_instance.stubs(:save_report).raises('Oh no')
49
64
  @coverband.reset_instance
50
- @coverband.expects(:ready_to_report?).raises('Oh no')
51
65
  assert_raises RuntimeError do
52
66
  @coverband.report_coverage
53
67
  end
@@ -55,10 +69,10 @@ class CollectorsCoverageTest < Minitest::Test
55
69
 
56
70
  test 'report_coverage raises errors in tests with verbose enabled' do
57
71
  Coverband.configuration.verbose = true
58
- logger = mock()
72
+ logger = mock
59
73
  Coverband.configuration.logger = logger
60
74
  @coverband.reset_instance
61
- @coverband.expects(:ready_to_report?).raises('Oh no')
75
+ Coverband::Adapters::RedisStore.any_instance.stubs(:save_report).raises('Oh no')
62
76
  logger.expects(:error).times(3)
63
77
  error = assert_raises RuntimeError do
64
78
  @coverband.report_coverage
@@ -70,4 +84,38 @@ class CollectorsCoverageTest < Minitest::Test
70
84
  heroku_build_file = '/tmp/build_81feca8c72366e4edf020dc6f1937485/config/initializers/assets.rb'
71
85
  assert_equal false, @coverband.send(:track_file?, heroku_build_file)
72
86
  end
87
+
88
+ test 'one shot line coverage disabled for ruby >= 2.6' do
89
+ return unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
90
+ Coverband::Collectors::Coverage.expects(:ruby_version_greater_than_or_equal_to?).with('2.6.0').returns(true)
91
+ ::Coverage.expects(:running?).returns(false)
92
+ ::Coverage.expects(:start).with(oneshot_lines: false)
93
+ Coverband::Collectors::Coverage.send(:new)
94
+ end
95
+
96
+ test 'one shot line coverage enabled for ruby >= 2.6' do
97
+ return unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
98
+ Coverband.configuration.expects(:use_oneshot_lines_coverage).returns(true)
99
+ Coverband::Collectors::Coverage.expects(:ruby_version_greater_than_or_equal_to?).with('2.6.0').returns(true)
100
+ ::Coverage.expects(:running?).returns(false)
101
+ ::Coverage.expects(:start).with(oneshot_lines: true)
102
+ Coverband::Collectors::Coverage.send(:new)
103
+ end
104
+
105
+ test 'one shot line coverage for ruby >= 2.6 when already running' do
106
+ return unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
107
+ Coverband::Collectors::Coverage.expects(:ruby_version_greater_than_or_equal_to?).with('2.6.0').returns(true)
108
+ ::Coverage.expects(:running?).returns(true)
109
+ ::Coverage.expects(:start).never
110
+ Coverband::Collectors::Coverage.send(:new)
111
+ end
112
+
113
+ test 'no one shot line coverage for ruby < 2.6' do
114
+ return unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
115
+ Coverband::Collectors::Coverage.expects(:ruby_version_greater_than_or_equal_to?).with('2.6.0').returns(false)
116
+ Coverband::Collectors::Coverage.expects(:ruby_version_greater_than_or_equal_to?).with('2.5.0').returns(true)
117
+ ::Coverage.expects(:running?).returns(false)
118
+ ::Coverage.expects(:start).with()
119
+ Coverband::Collectors::Coverage.send(:new)
120
+ end
73
121
  end