Skip to content

Commit 6e1703c

Browse files
authored
update PatchCop to support spanning errors
We want to keep an error if it _includes_ any lines in a given patch. We also want only the first such line, since it likely includes more than one (this singularism was implicit before, because each line was only passed through once) Also factor out some private methods to simplify the original flat_map logic.
1 parent fd3041d commit 6e1703c

2 files changed

Lines changed: 31 additions & 7 deletions

File tree

lib/pronto/rubocop/patch_cop.rb

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,9 @@ def initialize(patch, runner)
1313
def messages
1414
return [] unless valid?
1515

16-
offenses.flat_map do |offense|
17-
patch
18-
.added_lines
19-
.select { |line| line.new_lineno == offense.line }
20-
.map { |line| OffenseLine.new(self, offense, line).message }
21-
end
16+
offenses
17+
.map { |offense| first_relevant_message(patch, offense) }
18+
.compact
2219
end
2320

2421
def processed_source
@@ -67,6 +64,11 @@ def offenses
6764
.reject(&:disabled?)
6865
end
6966

67+
def offense_includes?(offense, line_number)
68+
offense_range = (offense.location.first_line..offense.location.last_line)
69+
offense_range.include?(line_number)
70+
end
71+
7072
def team
7173
@team ||=
7274
if ::RuboCop::Cop::Team.respond_to?(:mobilize)
@@ -76,6 +78,19 @@ def team
7678
::RuboCop::Cop::Team.new(registry, rubocop_config)
7779
end
7880
end
81+
82+
def first_relevant_line(patch, offense)
83+
patch.added_lines.detect do |line|
84+
offense_includes?(offense, line.new_lineno)
85+
end
86+
end
87+
88+
def first_relevant_message(patch, offense)
89+
offending_line = first_relevant_line(patch, offense)
90+
return nil unless offending_line
91+
92+
OffenseLine.new(self, offense, offending_line).message
93+
end
7994
end
8095
end
8196
end

spec/pronto/rubocop/patch_cop_spec.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
let(:ast) { double :ast, each_node: nil }
1313
let(:processed_source) { double :processed_source, ast: ast }
1414
let(:team) { double :team, inspect_file: [offense] }
15-
let(:offense) { double :offense, disabled?: false, line: 42 }
15+
let(:offense_location) { double :location, first_line: 42, last_line: 43 }
16+
let(:offense) { double :offense, disabled?: false, location: offense_location }
1617
let(:offense_line) { double :offense_line, message: 'Err' }
1718

1819
before do
@@ -31,5 +32,13 @@
3132
it do
3233
expect(patch_cop.messages).to eq(['Err'])
3334
end
35+
36+
context 'when there is an error including the patch, but not starting inside it' do
37+
let(:offense_location) { double :location, first_line: 40, last_line: 43 }
38+
39+
it do
40+
expect(patch_cop.messages).to eq(['Err'])
41+
end
42+
end
3443
end
3544
end

0 commit comments

Comments
 (0)