Skip to content

Commit

Permalink
[Fix #7452] Support IgnoredMethods option for `Style/FormatStringTo…
Browse files Browse the repository at this point in the history
…ken`

Fixes #7452.

This PR supports `IgnoredMethods` option for `Style/FormatStringToken`.

It solves library-specific issues as follows:

```Ruby
# config/routes.rb
get '/catalogue/:book_id/book', to: redirect('book/%{book_id}', status: 301)
                                                   ^^^^^^^^^^ Prefer annotated tokens ...
```

The default is empty for RuboCop cores. I will set `redirect` to `IgnoredMethods`
in RuboCop Rails by default.

```yaml
# config/default.yml of rubocop-rails
Style/FormatStringToken:
  IgnoredMethod:
    - redirect
```
  • Loading branch information
koic authored and bbatsov committed Jan 15, 2021
1 parent d939849 commit 66bf1e7
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* [#7452](https://github.com/rubocop-hq/rubocop/issues/7452): Support `IgnoredMethods` option for `Style/FormatStringToken`. ([@koic][])
1 change: 1 addition & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3355,6 +3355,7 @@ Style/FormatStringToken:
MaxUnannotatedPlaceholdersAllowed: 1
VersionAdded: '0.49'
VersionChanged: '1.0'
IgnoredMethods: []

Style/FrozenStringLiteralComment:
Description: >-
Expand Down
20 changes: 18 additions & 2 deletions lib/rubocop/cop/style/format_string_token.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ module Style
# The reason is that _unannotated_ format is very similar
# to encoded URLs or Date/Time formatting strings.
#
# This cop can be customized ignored methods with `IgnoredMethods`.
#
# @example EnforcedStyle: annotated (default)
#
# # bad
Expand Down Expand Up @@ -58,12 +60,18 @@ module Style
#
# # good
# format('%06d', 10)
#
# @example IgnoredMethods: [redirect]
#
# # good
# redirect('foo/%{bar_id}')
#
class FormatStringToken < Base
include ConfigurableEnforcedStyle
include IgnoredMethods

def on_str(node)
return unless node.value.include?('%')
return if node.each_ancestor(:xstr, :regexp).any?
return if format_string_token?(node) || use_ignored_method?(node)

detections = collect_detections(node)
return if detections.empty?
Expand All @@ -88,6 +96,14 @@ def on_str(node)
}
PATTERN

def format_string_token?(node)
!node.value.include?('%') || node.each_ancestor(:xstr, :regexp).any?
end

def use_ignored_method?(node)
(parent = node.parent) && parent.send_type? && ignored_method?(parent.method_name)
end

def unannotated_format?(node, detected_style)
detected_style == :unannotated && !format_string_in_typical_context?(node)
end
Expand Down
25 changes: 24 additions & 1 deletion spec/rubocop/cop/style/format_string_token_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

RSpec.describe RuboCop::Cop::Style::FormatStringToken, :config do
let(:enforced_style) { :annotated }
let(:ignored_methods) { [] }

let(:cop_config) do
{
'EnforcedStyle' => enforced_style,
'SupportedStyles' => %i[annotated template unannotated],
'MaxUnannotatedPlaceholdersAllowed' => 0
'MaxUnannotatedPlaceholdersAllowed' => 0,
'IgnoredMethods' => ignored_methods
}
end

Expand Down Expand Up @@ -248,6 +250,27 @@
RUBY
expect_no_corrections
end

context 'when `IgnoredMethods: redirect`' do
let(:ignored_methods) { ['redirect'] }

it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
redirect("%{foo}")
RUBY
end
end

context 'when `IgnoredMethods: []`' do
let(:ignored_methods) { [] }

it 'does not register an offense' do
expect_offense(<<~RUBY)
redirect("%{foo}")
^^^^^^ Prefer annotated tokens (like `%<foo>s`) over template tokens (like `%{foo}`).
RUBY
end
end
end

context 'when enforced style is template' do
Expand Down

0 comments on commit 66bf1e7

Please sign in to comment.