From 771d6faa46ca22b39109c3cae8b4b7c553fb6c70 Mon Sep 17 00:00:00 2001 From: Daniel Vandersluis Date: Mon, 8 Mar 2021 12:44:03 -0500 Subject: [PATCH] [Fix #9558] Fix inconsistency when dealing with URIs that are wrapped in single quotes vs double quotes. --- ...ix_inconsistency_when_dealing_with_uris.md | 1 + lib/rubocop/cop/mixin/line_length_help.rb | 12 ++++-- spec/rubocop/cop/layout/line_length_spec.rb | 41 +++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 changelog/fix_fix_inconsistency_when_dealing_with_uris.md diff --git a/changelog/fix_fix_inconsistency_when_dealing_with_uris.md b/changelog/fix_fix_inconsistency_when_dealing_with_uris.md new file mode 100644 index 00000000000..d27bef0319f --- /dev/null +++ b/changelog/fix_fix_inconsistency_when_dealing_with_uris.md @@ -0,0 +1 @@ +* [#9558](https://github.com/rubocop/rubocop/issues/9558): Fix inconsistency when dealing with URIs that are wrapped in single quotes vs double quotes. ([@dvandersluis][]) diff --git a/lib/rubocop/cop/mixin/line_length_help.rb b/lib/rubocop/cop/mixin/line_length_help.rb index db25d317da1..5bcfbfc224f 100644 --- a/lib/rubocop/cop/mixin/line_length_help.rb +++ b/lib/rubocop/cop/mixin/line_length_help.rb @@ -24,9 +24,7 @@ def allow_uri? end def allowed_uri_position?(line, uri_range) - uri_range.begin < max_line_length && - (uri_range.end == line_length(line) || - uri_range.end == line_length(line) - 1) + uri_range.begin < max_line_length && uri_range.end == line_length(line) end def line_length(line) @@ -40,6 +38,14 @@ def find_excessive_uri_range(line) begin_position, end_position = last_uri_match.offset(0).map do |pos| pos + indentation_difference(line) end + + # Extend the end position until the start of the next word, if any. + # This allows for URIs that are wrapped in quotes or parens to be handled properly + # while not allowing additional words to be added after the URL. + if (match = line[end_position..line_length(line)]&.match(/^\S+(?=\s|$)/)) + end_position += match.offset(0).last + end + return nil if begin_position < max_line_length && end_position < max_line_length diff --git a/spec/rubocop/cop/layout/line_length_spec.rb b/spec/rubocop/cop/layout/line_length_spec.rb index dd2e6bac71f..5a99694b6e5 100644 --- a/spec/rubocop/cop/layout/line_length_spec.rb +++ b/spec/rubocop/cop/layout/line_length_spec.rb @@ -124,6 +124,27 @@ end end + context 'and the excessive characters include part of a URL in double quotes' do + it 'does not include the quote as part of the offense' do + expect_offense(<<-RUBY) + # See: "https://github.com/rubocop/rubocop/commit/3b48d8bdf5b1c2e05e35061837309890f04ab08c" and + ^^^^ Line is too long. [105/80] + # "http://google.com/" + RUBY + end + end + + context 'and the excessive characters include part of a URL ' \ + 'and trailing whitespace' do + it 'registers an offense for the line' do + expect_offense(<<-RUBY) + # See: https://github.com/rubocop/rubocop/commit/3b48d8bdf5b1c2e05e35061837309890f04ab08c#{trailing_whitespace} + ^ Line is too long. [100/80] + # http://google.com/ + RUBY + end + end + context 'and an error other than URI::InvalidURIError is raised ' \ 'while validating a URI-ish string' do let(:cop_config) do @@ -160,6 +181,26 @@ end end end + + context 'and the URI is assigned' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + #{'x' * 40} = 'https://a.very.long.line.which.violates.LineLength/sadf' + #{'x' * 40} = "https://a.very.long.line.which.violates.LineLength/sadf" + RUBY + end + end + + context 'and the URI is an argument' do + it 'does not register an offense' do + expect_no_offenses(<<~RUBY) + #{'x' * 40}("https://a.very.long.line.which.violates.LineLength/sadf") + #{'x' * 40} "https://a.very.long.line.which.violates.LineLength/sadf" + #{'x' * 40}('https://a.very.long.line.which.violates.LineLength/sadf') + #{'x' * 40} 'https://a.very.long.line.which.violates.LineLength/sadf' + RUBY + end + end end context 'when IgnoredPatterns option is set' do