simplecov 0.17.1 → 0.18.0.beta1
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/CHANGELOG.md +25 -1
- data/CODE_OF_CONDUCT.md +76 -0
- data/README.md +167 -63
- data/doc/alternate-formatters.md +5 -0
- data/lib/simplecov.rb +147 -65
- data/lib/simplecov/combine.rb +30 -0
- data/lib/simplecov/combine/branches_combiner.rb +32 -0
- data/lib/simplecov/combine/files_combiner.rb +25 -0
- data/lib/simplecov/combine/lines_combiner.rb +43 -0
- data/lib/simplecov/combine/results_combiner.rb +60 -0
- data/lib/simplecov/command_guesser.rb +6 -3
- data/lib/simplecov/configuration.rb +77 -8
- data/lib/simplecov/defaults.rb +1 -1
- data/lib/simplecov/file_list.rb +30 -3
- data/lib/simplecov/filter.rb +2 -1
- data/lib/simplecov/formatter/multi_formatter.rb +2 -2
- data/lib/simplecov/formatter/simple_formatter.rb +4 -4
- data/lib/simplecov/last_run.rb +2 -0
- data/lib/simplecov/lines_classifier.rb +2 -2
- data/lib/simplecov/profiles.rb +9 -7
- data/lib/simplecov/result.rb +21 -4
- data/lib/simplecov/result_adapter.rb +30 -0
- data/lib/simplecov/result_merger.rb +12 -11
- data/lib/simplecov/simulate_coverage.rb +29 -0
- data/lib/simplecov/source_file.rb +219 -109
- data/lib/simplecov/source_file/branch.rb +106 -0
- data/lib/simplecov/source_file/line.rb +72 -0
- data/lib/simplecov/useless_results_remover.rb +16 -0
- data/lib/simplecov/version.rb +1 -1
- metadata +33 -168
- data/lib/simplecov/jruby_fix.rb +0 -44
- data/lib/simplecov/railtie.rb +0 -9
- data/lib/simplecov/railties/tasks.rake +0 -13
- data/lib/simplecov/raw_coverage.rb +0 -41
data/doc/alternate-formatters.md
CHANGED
@@ -54,3 +54,8 @@ A formatter that prints the coverage of the file under test when you run a singl
|
|
54
54
|
*by [Yosuke Kabuto](https://github.com/ysksn)*
|
55
55
|
|
56
56
|
t_wada AA formatter for SimpleCov
|
57
|
+
|
58
|
+
#### [simplecov-material(https://github.com/chiefpansancolt/simplecov-material)
|
59
|
+
*by [Chiefpansancolt](https://github.com/chiefpansancolt)*
|
60
|
+
|
61
|
+
A Material Designed HTML formatter with clean and easy search of files with a tabular left Navigation.
|
data/lib/simplecov.rb
CHANGED
@@ -2,9 +2,6 @@
|
|
2
2
|
|
3
3
|
require "English"
|
4
4
|
|
5
|
-
#
|
6
|
-
# Code coverage for ruby 1.9. Please check out README for a full introduction.
|
7
|
-
#
|
8
5
|
# Coverage may be inaccurate under JRUBY.
|
9
6
|
if defined?(JRUBY_VERSION) && defined?(JRuby)
|
10
7
|
|
@@ -20,6 +17,10 @@ if defined?(JRUBY_VERSION) && defined?(JRuby)
|
|
20
17
|
' or set the "debug.fullTrace=true" option in your .jrubyrc'
|
21
18
|
end
|
22
19
|
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Code coverage for ruby. Please check out README for a full introduction.
|
23
|
+
#
|
23
24
|
module SimpleCov
|
24
25
|
class << self
|
25
26
|
attr_accessor :running
|
@@ -44,35 +45,14 @@ module SimpleCov
|
|
44
45
|
# Please check out the RDoc for SimpleCov::Configuration to find about available config options
|
45
46
|
#
|
46
47
|
def start(profile = nil, &block)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
Coverage.start
|
54
|
-
else
|
55
|
-
warn "WARNING: SimpleCov is activated, but you're not running Ruby 1.9+ - no coverage analysis will happen"
|
56
|
-
warn "Starting with SimpleCov 1.0.0, even no-op compatibility with Ruby <= 1.8 will be entirely dropped."
|
57
|
-
false
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
#
|
62
|
-
# Finds files that were to be tracked but were not loaded and initializes
|
63
|
-
# the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
|
64
|
-
#
|
65
|
-
def add_not_loaded_files(result)
|
66
|
-
if tracked_files
|
67
|
-
result = result.dup
|
68
|
-
Dir[tracked_files].each do |file|
|
69
|
-
absolute = File.expand_path(file)
|
70
|
-
|
71
|
-
result[absolute] ||= LinesClassifier.new.classify(File.foreach(absolute))
|
72
|
-
end
|
73
|
-
end
|
48
|
+
require "coverage"
|
49
|
+
load_profile(profile) if profile
|
50
|
+
configure(&block) if block_given?
|
51
|
+
@result = nil
|
52
|
+
self.running = true
|
53
|
+
self.pid = Process.pid
|
74
54
|
|
75
|
-
|
55
|
+
start_coverage_measurment
|
76
56
|
end
|
77
57
|
|
78
58
|
#
|
@@ -83,9 +63,8 @@ module SimpleCov
|
|
83
63
|
return @result if result?
|
84
64
|
|
85
65
|
# Collect our coverage result
|
86
|
-
|
87
|
-
|
88
|
-
end
|
66
|
+
|
67
|
+
process_coverage_result if running
|
89
68
|
|
90
69
|
# If we're using merging of results, store the current result
|
91
70
|
# first (if there is one), then merge the results and return those
|
@@ -147,22 +126,6 @@ module SimpleCov
|
|
147
126
|
load_profile(name)
|
148
127
|
end
|
149
128
|
|
150
|
-
#
|
151
|
-
# Checks whether we're on a proper version of Ruby (likely 1.9+) which
|
152
|
-
# provides coverage support
|
153
|
-
#
|
154
|
-
def usable?
|
155
|
-
return @usable if defined?(@usable) && !@usable.nil?
|
156
|
-
|
157
|
-
@usable = begin
|
158
|
-
require "coverage"
|
159
|
-
require "simplecov/jruby_fix"
|
160
|
-
true
|
161
|
-
rescue LoadError
|
162
|
-
false
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
129
|
#
|
167
130
|
# Clear out the previously cached .result. Primarily useful in testing
|
168
131
|
#
|
@@ -206,8 +169,8 @@ module SimpleCov
|
|
206
169
|
|
207
170
|
# Force exit with stored status (see github issue #5)
|
208
171
|
# unless it's nil or 0 (see github issue #281)
|
209
|
-
if exit_status
|
210
|
-
$stderr.printf("SimpleCov failed with exit
|
172
|
+
if exit_status&.positive?
|
173
|
+
$stderr.printf("SimpleCov failed with exit %<exit_status>d\n", :exit_status => exit_status) if print_error_status
|
211
174
|
Kernel.exit exit_status
|
212
175
|
end
|
213
176
|
end
|
@@ -220,11 +183,9 @@ module SimpleCov
|
|
220
183
|
def process_result(result, exit_status)
|
221
184
|
return exit_status if exit_status != SimpleCov::ExitCodes::SUCCESS # Existing errors
|
222
185
|
|
223
|
-
covered_percent = result.covered_percent.
|
186
|
+
covered_percent = result.covered_percent.floor(2)
|
224
187
|
result_exit_status = result_exit_status(result, covered_percent)
|
225
|
-
if result_exit_status == SimpleCov::ExitCodes::SUCCESS # No result errors
|
226
|
-
write_last_run(covered_percent)
|
227
|
-
end
|
188
|
+
write_last_run(covered_percent) if result_exit_status == SimpleCov::ExitCodes::SUCCESS # No result errors
|
228
189
|
final_result_process? ? result_exit_status : SimpleCov::ExitCodes::SUCCESS
|
229
190
|
end
|
230
191
|
|
@@ -232,17 +193,30 @@ module SimpleCov
|
|
232
193
|
#
|
233
194
|
# rubocop:disable Metrics/MethodLength
|
234
195
|
def result_exit_status(result, covered_percent)
|
235
|
-
covered_percentages = result.covered_percentages.map { |percentage| percentage.
|
196
|
+
covered_percentages = result.covered_percentages.map { |percentage| percentage.floor(2) }
|
236
197
|
if covered_percent < SimpleCov.minimum_coverage
|
237
|
-
$stderr.printf(
|
198
|
+
$stderr.printf(
|
199
|
+
"Coverage (%<covered>.2f%%) is below the expected minimum coverage (%<minimum_coverage>.2f%%).\n",
|
200
|
+
:covered => covered_percent,
|
201
|
+
:minimum_coverage => SimpleCov.minimum_coverage
|
202
|
+
)
|
238
203
|
SimpleCov::ExitCodes::MINIMUM_COVERAGE
|
239
204
|
elsif covered_percentages.any? { |p| p < SimpleCov.minimum_coverage_by_file }
|
240
|
-
$stderr.printf(
|
205
|
+
$stderr.printf(
|
206
|
+
"File (%<file>s) is only (%<least_covered_percentage>.2f%%) covered. This is below the expected minimum coverage per file of (%<min_coverage>.2f%%).\n",
|
207
|
+
:file => result.least_covered_file,
|
208
|
+
:least_covered_percentage => covered_percentages.min,
|
209
|
+
:min_coverage => SimpleCov.minimum_coverage_by_file
|
210
|
+
)
|
241
211
|
SimpleCov::ExitCodes::MINIMUM_COVERAGE
|
242
212
|
elsif (last_run = SimpleCov::LastRun.read)
|
243
213
|
coverage_diff = last_run["result"]["covered_percent"] - covered_percent
|
244
214
|
if coverage_diff > SimpleCov.maximum_coverage_drop
|
245
|
-
$stderr.printf(
|
215
|
+
$stderr.printf(
|
216
|
+
"Coverage has dropped by %<drop_percent>.2f%% since the last time (maximum allowed: %<max_drop>.2f%%).\n",
|
217
|
+
:drop_percent => coverage_diff,
|
218
|
+
:max_drop => SimpleCov.maximum_coverage_drop
|
219
|
+
)
|
246
220
|
SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
|
247
221
|
else
|
248
222
|
SimpleCov::ExitCodes::SUCCESS
|
@@ -266,6 +240,7 @@ module SimpleCov
|
|
266
240
|
#
|
267
241
|
def wait_for_other_processes
|
268
242
|
return unless defined?(ParallelTests) && final_result_process?
|
243
|
+
|
269
244
|
ParallelTests.wait_for_other_processes_to_finish
|
270
245
|
end
|
271
246
|
|
@@ -275,14 +250,117 @@ module SimpleCov
|
|
275
250
|
def write_last_run(covered_percent)
|
276
251
|
SimpleCov::LastRun.write(:result => {:covered_percent => covered_percent})
|
277
252
|
end
|
253
|
+
|
254
|
+
private
|
255
|
+
|
256
|
+
#
|
257
|
+
# Trigger Coverage.start depends on given config coverage_criterion
|
258
|
+
#
|
259
|
+
# With Positive branch it supports all coverage measurement types
|
260
|
+
# With Negative branch it supports only line coverage measurement type
|
261
|
+
#
|
262
|
+
def start_coverage_measurment
|
263
|
+
# This blog post gives a good run down of the coverage criterias introduced
|
264
|
+
# in Ruby 2.5: https://blog.bigbinary.com/2018/04/11/ruby-2-5-supports-measuring-branch-and-method-coverages.html
|
265
|
+
# There is also a nice writeup of the different coverage criteria made in this
|
266
|
+
# comment https://github.com/colszowka/simplecov/pull/692#discussion_r281836176 :
|
267
|
+
# Ruby < 2.5:
|
268
|
+
# https://github.com/ruby/ruby/blob/v1_9_3_374/ext/coverage/coverage.c
|
269
|
+
# traditional mode (Array)
|
270
|
+
#
|
271
|
+
# Ruby 2.5:
|
272
|
+
# https://bugs.ruby-lang.org/issues/13901
|
273
|
+
# https://github.com/ruby/ruby/blob/v2_5_3/ext/coverage/coverage.c
|
274
|
+
# default: traditional/compatible mode (Array)
|
275
|
+
# :lines - like traditional mode but using Hash
|
276
|
+
# :branches
|
277
|
+
# :methods
|
278
|
+
# :all - same as lines + branches + methods
|
279
|
+
#
|
280
|
+
# Ruby >= 2.6:
|
281
|
+
# https://bugs.ruby-lang.org/issues/15022
|
282
|
+
# https://github.com/ruby/ruby/blob/v2_6_3/ext/coverage/coverage.c
|
283
|
+
# default: traditional/compatible mode (Array)
|
284
|
+
# :lines - like traditional mode but using Hash
|
285
|
+
# :branches
|
286
|
+
# :methods
|
287
|
+
# :oneshot_lines - can not be combined with lines
|
288
|
+
# :all - same as lines + branches + methods
|
289
|
+
#
|
290
|
+
if branch_coverage?
|
291
|
+
Coverage.start(:all)
|
292
|
+
else
|
293
|
+
Coverage.start
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
#
|
298
|
+
# Finds files that were to be tracked but were not loaded and initializes
|
299
|
+
# the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
|
300
|
+
#
|
301
|
+
def add_not_loaded_files(result)
|
302
|
+
if tracked_files
|
303
|
+
result = result.dup
|
304
|
+
Dir[tracked_files].each do |file|
|
305
|
+
absolute_path = File.expand_path(file)
|
306
|
+
result[absolute_path] ||= SimulateCoverage.call(absolute_path)
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
result
|
311
|
+
end
|
312
|
+
|
313
|
+
#
|
314
|
+
# Call steps that handle process coverage result
|
315
|
+
#
|
316
|
+
# @return [Hash]
|
317
|
+
#
|
318
|
+
def process_coverage_result
|
319
|
+
adapt_coverage_result
|
320
|
+
remove_useless_results
|
321
|
+
result_with_not_loaded_files
|
322
|
+
end
|
323
|
+
|
324
|
+
#
|
325
|
+
# Unite the result so it wouldn't matter what coverage type was called
|
326
|
+
#
|
327
|
+
# @return [Hash]
|
328
|
+
#
|
329
|
+
def adapt_coverage_result
|
330
|
+
@result = SimpleCov::ResultAdapter.call(Coverage.result)
|
331
|
+
end
|
332
|
+
|
333
|
+
#
|
334
|
+
# Filter coverage result
|
335
|
+
# The result before filter also has result of coverage for files
|
336
|
+
# are not related to the project like loaded gems coverage.
|
337
|
+
#
|
338
|
+
# @return [Hash]
|
339
|
+
#
|
340
|
+
def remove_useless_results
|
341
|
+
@result = SimpleCov::UselessResultsRemover.call(@result)
|
342
|
+
end
|
343
|
+
|
344
|
+
#
|
345
|
+
# Initialize result with files that are not included by coverage
|
346
|
+
# and added inside the config block
|
347
|
+
#
|
348
|
+
# @return [Hash]
|
349
|
+
#
|
350
|
+
def result_with_not_loaded_files
|
351
|
+
@result = SimpleCov::Result.new(add_not_loaded_files(@result))
|
352
|
+
end
|
278
353
|
end
|
279
354
|
end
|
280
355
|
|
281
356
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
|
357
|
+
require "set"
|
282
358
|
require "simplecov/configuration"
|
283
|
-
SimpleCov.
|
359
|
+
SimpleCov.extend SimpleCov::Configuration
|
284
360
|
require "simplecov/exit_codes"
|
285
361
|
require "simplecov/profiles"
|
362
|
+
require "simplecov/source_file/line"
|
363
|
+
require "simplecov/source_file/branch"
|
286
364
|
require "simplecov/source_file"
|
287
365
|
require "simplecov/file_list"
|
288
366
|
require "simplecov/result"
|
@@ -290,13 +368,17 @@ require "simplecov/filter"
|
|
290
368
|
require "simplecov/formatter"
|
291
369
|
require "simplecov/last_run"
|
292
370
|
require "simplecov/lines_classifier"
|
293
|
-
require "simplecov/raw_coverage"
|
294
371
|
require "simplecov/result_merger"
|
295
372
|
require "simplecov/command_guesser"
|
296
373
|
require "simplecov/version"
|
374
|
+
require "simplecov/result_adapter"
|
375
|
+
require "simplecov/combine"
|
376
|
+
require "simplecov/combine/branches_combiner"
|
377
|
+
require "simplecov/combine/files_combiner"
|
378
|
+
require "simplecov/combine/lines_combiner"
|
379
|
+
require "simplecov/combine/results_combiner"
|
380
|
+
require "simplecov/useless_results_remover"
|
381
|
+
require "simplecov/simulate_coverage"
|
297
382
|
|
298
383
|
# Load default config
|
299
384
|
require "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
|
300
|
-
|
301
|
-
# Load Rails integration (only for Rails 3, see #113)
|
302
|
-
require "simplecov/railtie" if defined? Rails::Railtie
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleCov
|
4
|
+
# Functionally for combining coverage results
|
5
|
+
#
|
6
|
+
module Combine
|
7
|
+
module_function
|
8
|
+
|
9
|
+
#
|
10
|
+
# Combine two coverage based on the given combiner_module.
|
11
|
+
#
|
12
|
+
# Combiners should always be called throught his interface,
|
13
|
+
# as it takes care of short circuting of one of the coverages is nil.
|
14
|
+
#
|
15
|
+
# @return [Hash]
|
16
|
+
def combine(combiner_module, coverage_a, coverage_b)
|
17
|
+
return existing_coverage(coverage_a, coverage_b) if empty_coverage?(coverage_a, coverage_b)
|
18
|
+
|
19
|
+
combiner_module.combine(coverage_a, coverage_b)
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty_coverage?(coverage_a, coverage_b)
|
23
|
+
!(coverage_a && coverage_b)
|
24
|
+
end
|
25
|
+
|
26
|
+
def existing_coverage(coverage_a, coverage_b)
|
27
|
+
coverage_a || coverage_b
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleCov
|
4
|
+
module Combine
|
5
|
+
#
|
6
|
+
# Combine different branch coverage results on single file.
|
7
|
+
#
|
8
|
+
# Should be called through `SimpleCov.combine`.
|
9
|
+
module BranchesCombiner
|
10
|
+
module_function
|
11
|
+
|
12
|
+
#
|
13
|
+
# Return merged branches or the existed branche if other is missing.
|
14
|
+
#
|
15
|
+
# Branches inside files are always same if they exists, the difference only in coverage count.
|
16
|
+
# Branch coverage report for any conditional case is built from hash, it's key is a condition and
|
17
|
+
# it's body is a hash << keys from condition and value is coverage rate >>.
|
18
|
+
# ex: branches =>{ [:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36]=>2}, other conditions...}
|
19
|
+
# We create copy of result and update it values depending on the combined branches coverage values.
|
20
|
+
#
|
21
|
+
# @return [Hash]
|
22
|
+
#
|
23
|
+
def combine(coverage_a, coverage_b)
|
24
|
+
coverage_a.merge(coverage_b) do |_condition, branches_inside_a, branches_inside_b|
|
25
|
+
branches_inside_a.merge(branches_inside_b) do |_branch, a_count, b_count|
|
26
|
+
a_count + b_count
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleCov
|
4
|
+
module Combine
|
5
|
+
#
|
6
|
+
# Handle combining two coverage results for same file
|
7
|
+
#
|
8
|
+
# Should be called through `SimpleCov.combine`.
|
9
|
+
module FilesCombiner
|
10
|
+
module_function
|
11
|
+
|
12
|
+
#
|
13
|
+
# Combines the results for 2 coverages of a file.
|
14
|
+
#
|
15
|
+
# @return [Hash]
|
16
|
+
#
|
17
|
+
def combine(coverage_a, coverage_b)
|
18
|
+
{
|
19
|
+
:lines => Combine.combine(LinesCombiner, coverage_a[:lines], coverage_b[:lines]),
|
20
|
+
:branches => Combine.combine(BranchesCombiner, coverage_a[:branches], coverage_b[:branches])
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleCov
|
4
|
+
module Combine
|
5
|
+
#
|
6
|
+
# Combine two different lines coverage results on same file
|
7
|
+
#
|
8
|
+
# Should be called through `SimpleCov.combine`.
|
9
|
+
module LinesCombiner
|
10
|
+
module_function
|
11
|
+
|
12
|
+
def combine(coverage_a, coverage_b)
|
13
|
+
coverage_a
|
14
|
+
.zip(coverage_b)
|
15
|
+
.map do |coverage_a_val, coverage_b_val|
|
16
|
+
merge_line_coverage(coverage_a_val, coverage_b_val)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Return depends on coverage in a specific line
|
21
|
+
#
|
22
|
+
# @param [Integer || nil] first_val
|
23
|
+
# @param [Integer || nil] second_val
|
24
|
+
#
|
25
|
+
# Logic:
|
26
|
+
#
|
27
|
+
# => nil + 0 = nil
|
28
|
+
# => nil + nil = nil
|
29
|
+
# => int + int = int
|
30
|
+
#
|
31
|
+
# @return [Integer || nil]
|
32
|
+
def merge_line_coverage(first_val, second_val)
|
33
|
+
sum = first_val.to_i + second_val.to_i
|
34
|
+
|
35
|
+
if sum.zero? && (first_val.nil? || second_val.nil?)
|
36
|
+
nil
|
37
|
+
else
|
38
|
+
sum
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SimpleCov
|
4
|
+
module Combine
|
5
|
+
# There might be reports from different kinds of tests,
|
6
|
+
# e.g. RSpec and Cucumber. We need to combine their results
|
7
|
+
# into unified one. This class does that.
|
8
|
+
# To unite the results on file basis, it leverages
|
9
|
+
# the combine of lines and branches inside each file within given results.
|
10
|
+
module ResultsCombiner
|
11
|
+
module_function
|
12
|
+
|
13
|
+
#
|
14
|
+
# Combine process explanation
|
15
|
+
# => ResultCombiner: define all present files between results and start combine on file level.
|
16
|
+
# ==> FileCombiner: collect result of next combine levels lines and branches.
|
17
|
+
# ===> LinesCombiner: combine lines results.
|
18
|
+
# ===> BranchesCombiner: combine branches results.
|
19
|
+
#
|
20
|
+
# @return [Hash]
|
21
|
+
#
|
22
|
+
def combine(*results)
|
23
|
+
results.reduce({}) do |result, next_result|
|
24
|
+
combine_result_sets(result, next_result)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Manage combining results on files level
|
30
|
+
#
|
31
|
+
# @param [Hash] result_a
|
32
|
+
# @param [Hash] result_b
|
33
|
+
#
|
34
|
+
# @return [Hash]
|
35
|
+
#
|
36
|
+
def combine_result_sets(result_a, result_b)
|
37
|
+
results_files = result_a.keys | result_b.keys
|
38
|
+
|
39
|
+
results_files.each_with_object({}) do |file_name, combined_results|
|
40
|
+
combined_results[file_name] = combine_file_coverage(
|
41
|
+
result_a[file_name],
|
42
|
+
result_b[file_name]
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Combine two files coverage results
|
49
|
+
#
|
50
|
+
# @param [Hash] coverage_a
|
51
|
+
# @param [Hash] coverage_b
|
52
|
+
#
|
53
|
+
# @return [Hash]
|
54
|
+
#
|
55
|
+
def combine_file_coverage(coverage_a, coverage_b)
|
56
|
+
Combine.combine(Combine::FilesCombiner, coverage_a, coverage_b)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|