Skip to content

Commit 9febbb6

Browse files
committed
filter out files ignored by simplecov
1 parent 155025d commit 9febbb6

15 files changed

Lines changed: 389 additions & 61 deletions

lib/undercover.rb

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Report
2525

2626
attr_reader :changeset,
2727
:lcov,
28-
:simplecov_resultset,
28+
:coverage_adapter,
2929
:results,
3030
:code_dir,
3131
:filter_set,
@@ -35,15 +35,16 @@ class Report
3535
#
3636
# @param changeset [Undercover::Changeset]
3737
# @param opts [Undercover::Options]
38-
def initialize(changeset, opts)
39-
if opts.simplecov_resultset
40-
@simplecov_resultset = SimplecovResultAdapter.parse(File.open(opts.simplecov_resultset), opts)
41-
end
42-
@lcov = LcovParser.parse(File.open(opts.lcov), opts) if opts.lcov
38+
# @param coverage_adapter [Undercover::SimplecovResultAdapter|Undercover::LcovParser] pre-parsed coverage adapter
39+
def initialize(changeset, opts, coverage_adapter)
40+
@coverage_adapter = coverage_adapter
4341

4442
@code_dir = opts.path
4543
@changeset = changeset
46-
@filter_set = FilterSet.new(opts.glob_allow_filters, opts.glob_reject_filters)
44+
45+
ignored_files = coverage_adapter.ignored_files || []
46+
@filter_set = FilterSet.new(opts.glob_allow_filters, opts.glob_reject_filters, ignored_files)
47+
changeset.filter_with(filter_set)
4748
@max_warnings_limit = opts.max_warnings_limit
4849
@loaded_files = {}
4950
@results = {}
@@ -106,29 +107,21 @@ def inspect
106107

107108
attr_reader :loaded_files
108109

109-
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
110+
# rubocop:disable Metrics/AbcSize
110111
def load_and_parse_file(filepath)
111112
key = filepath.gsub(/^\.\//, '')
112113
return if loaded_files[key]
113-
return unless include_file?(filepath)
114114

115115
root_ast = Imagen::Node::Root.new.build_from_file(
116116
File.join(code_dir, filepath)
117117
)
118118
return if root_ast.children.empty?
119119

120-
# lcov will be deprecated at some point and we'll be able to refactor harder
121-
coverage = simplecov_resultset || lcov
122-
123120
loaded_files[key] = []
124121
root_ast.find_all(->(node) { !node.is_a?(Imagen::Node::Root) }).each do |imagen_node|
125-
loaded_files[key] << Result.new(imagen_node, coverage, filepath)
122+
loaded_files[key] << Result.new(imagen_node, coverage_adapter, filepath)
126123
end
127124
end
128-
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
129-
130-
def include_file?(filepath)
131-
filter_set.include?(filepath)
132-
end
125+
# rubocop:enable Metrics/AbcSize
133126
end
134127
end

lib/undercover/changeset.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def validate(lcov_report_path)
4949
:stale_coverage if last_modified > File.mtime(lcov_report_path)
5050
end
5151

52+
def filter_with(filter_set)
53+
@filter_set = filter_set
54+
end
55+
5256
private
5357

5458
# Diffs `head` or `head` + `compare_base` (if exists),

lib/undercover/cli.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55

66
module Undercover
77
module CLI
8-
# TODO: Report calls >parser< for each file instead of
9-
# traversing the whole project at first!
10-
118
WARNINGS_TO_S = {
129
stale_coverage: Rainbow('🚨 WARNING: Coverage data is older than your ' \
1310
'latest changes and results might be incomplete. ' \
@@ -21,12 +18,20 @@ def self.run(args)
2118
run_report(opts)
2219
end
2320

24-
def self.run_report(opts)
21+
def self.run_report(opts) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
2522
coverage_path = opts.simplecov_resultset || opts.lcov
2623
return handle_missing_coverage_path(opts) if coverage_path.nil?
2724
return handle_missing_file(coverage_path) unless File.exist?(coverage_path)
2825

29-
report = Undercover::Report.new(changeset(opts), opts).build
26+
simplecov_adapter = if opts.simplecov_resultset
27+
SimplecovResultAdapter.parse(File.open(opts.simplecov_resultset), opts)
28+
else
29+
# TODO: lcov will be deprecated end of 2025 and we'll be able to refactor harder
30+
LcovParser.parse(File.open(opts.lcov), opts)
31+
end
32+
33+
changeset_obj = changeset(opts)
34+
report = Undercover::Report.new(changeset_obj, opts, simplecov_adapter).build
3035
handle_report_validation(report, coverage_path)
3136
end
3237

@@ -63,8 +68,7 @@ def self.syntax_version(version)
6368

6469
def self.changeset(opts)
6570
git_dir = File.join(opts.path, opts.git_dir)
66-
filter_set = Undercover::FilterSet.new(opts.glob_allow_filters, opts.glob_reject_filters)
67-
Undercover::Changeset.new(git_dir, opts.compare, filter_set)
71+
Undercover::Changeset.new(git_dir, opts.compare)
6872
end
6973
end
7074
end

lib/undercover/filter_set.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@
22

33
module Undercover
44
class FilterSet
5-
attr_reader :allow_filters, :reject_filters
5+
attr_reader :allow_filters, :reject_filters, :simplecov_ignored_files
66

7-
def initialize(allow_filters, reject_filters)
7+
def initialize(allow_filters, reject_filters, simplecov_ignored_files)
88
@allow_filters = allow_filters || []
99
@reject_filters = reject_filters || []
10+
@simplecov_ignored_files = simplecov_ignored_files
1011
end
1112

1213
def include?(filepath)
1314
fnmatch = proc { |glob| File.fnmatch(glob, filepath, File::FNM_EXTGLOB) }
15+
16+
# Check if file was ignored by SimpleCov filters
17+
return false if simplecov_ignored_files.include?(filepath)
18+
19+
# Apply Undercover's own filters
1420
allow_filters.any?(fnmatch) && reject_filters.none?(fnmatch)
1521
end
1622
end

lib/undercover/lcov_parser.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ def skipped?(_filepath, _line_no)
5757
false
5858
end
5959

60+
def ignored_files
61+
# supported by SimplecovResultAdapter only
62+
[]
63+
end
64+
6065
private
6166

6267
# rubocop:disable Metrics/MethodLength, Style/SpecialGlobalVars, Metrics/AbcSize

lib/undercover/simplecov_formatter.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,29 @@ def export_path
1313
end
1414
end
1515

16+
module SimpleCov
17+
class << self
18+
attr_accessor :filtered_files
19+
20+
alias filtered_uncached filtered
21+
22+
def filtered(files)
23+
@filtered_files ||= Set.new
24+
original_files = files.dup
25+
filtered_uncached(files).tap do |filtered_files|
26+
@filtered_files += (original_files.map(&:filename) - filtered_files.map(&:filename))
27+
end
28+
end
29+
end
30+
end
31+
1632
module Undercover
1733
class ResultHashFormatterWithRoot < SimpleCovJSONFormatter::ResultHashFormatter
1834
def format
1935
formatted_result[:meta] = {timestamp: @result.created_at.to_i}
2036
format_files
2137
add_undercover_meta_fields
38+
add_ignored_files
2239
formatted_result
2340
end
2441

@@ -30,6 +47,14 @@ def add_undercover_meta_fields
3047
end
3148
end
3249

50+
def add_ignored_files
51+
ignored_files = SimpleCov.filtered_files&.map do |file|
52+
file.delete_prefix("#{SimpleCov.root}/")
53+
end || []
54+
55+
formatted_result[:meta][:ignored_files] = ignored_files
56+
end
57+
3358
# format_files uses relative path as keys, as opposed to the superclass method
3459
def format_files
3560
formatted_result[:coverage] ||= {}

lib/undercover/simplecov_result_adapter.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ def skipped?(filepath, line_no)
5656
def total_coverage; end
5757
def total_branch_coverage; end
5858

59+
def ignored_files
60+
@ignored_files ||= simplecov_result.dig('meta', 'ignored_files') || []
61+
end
62+
5963
private
6064

6165
def find_file(filepath)

spec/changeset_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262

6363
describe 'filtering' do
6464
it 'filters files using FilterSet in each_changed_line' do
65-
filter_set = Undercover::FilterSet.new(['*.rb'], ['*_spec.rb'])
65+
filter_set = Undercover::FilterSet.new(['*.rb'], ['*_spec.rb'], [])
6666
changeset = Undercover::Changeset.new('spec/fixtures/test.git', 'master', filter_set)
6767

6868
yielded_files = []
@@ -75,7 +75,7 @@
7575
end
7676

7777
it 'filters files using FilterSet with brace expansion' do
78-
filter_set = Undercover::FilterSet.new(['*.{rb,js}'], ['*_spec.rb'])
78+
filter_set = Undercover::FilterSet.new(['*.{rb,js}'], ['*_spec.rb'], [])
7979
changeset = Undercover::Changeset.new('spec/fixtures/test.git', 'master', filter_set)
8080

8181
yielded_files = []

0 commit comments

Comments
 (0)