Skip to content

Commit

Permalink
Add Rails/ToSWithArgument cop
Browse files Browse the repository at this point in the history
  • Loading branch information
r7kamura committed Jul 20, 2022
1 parent 3ad75cc commit 4f08fc2
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions changelog/new_add_railstoswithargument_cop.md
@@ -0,0 +1 @@
* [#747](https://github.com/rubocop/rubocop-rails/pull/747): Add `Rails/ToSWithArgument` cop. ([@r7kamura][])
6 changes: 6 additions & 0 deletions config/default.yml
Expand Up @@ -952,6 +952,12 @@ Rails/ToFormattedS:
- to_formatted_s
VersionAdded: '2.15'

Rails/ToSWithArgument:
Description: 'Identifies passing any argument to `#to_s`.'
Enabled: pending
Safe: false
VersionAdded: '<<next>>'

Rails/TransactionExitStatement:
Description: 'Avoid the usage of `return`, `break` and `throw` in transaction blocks.'
Enabled: pending
Expand Down
41 changes: 41 additions & 0 deletions lib/rubocop/cop/rails/to_s_with_argument.rb
@@ -0,0 +1,41 @@
# frozen_string_literal: true

module RuboCop
module Cop
module Rails
# Identifies passing any argument to `#to_s`.
#
# @safety
# This cop is marked as unsafe because it may detect `#to_s` calls
# that are not related to Active Support implementation.
#
# @example
#
# # bad
# obj.to_s(:delimited)
#
# # good
# obj.to_formatted_s(:delimited)
#
class ToSWithArgument < Base
extend AutoCorrector
extend TargetRailsVersion

MSG = 'Use `to_formatted_s` instead.'

RESTRICT_ON_SEND = %i[to_s].freeze

minimum_target_rails_version 7.0

def on_send(node)
return if node.arguments.empty?

add_offense(node.loc.selector) do |corrector|
corrector.replace(node.loc.selector, 'to_formatted_s')
end
end
alias on_csend on_send
end
end
end
end
1 change: 1 addition & 0 deletions lib/rubocop/cop/rails_cops.rb
Expand Up @@ -113,6 +113,7 @@
require_relative 'rails/time_zone'
require_relative 'rails/time_zone_assignment'
require_relative 'rails/to_formatted_s'
require_relative 'rails/to_s_with_argument'
require_relative 'rails/transaction_exit_statement'
require_relative 'rails/uniq_before_pluck'
require_relative 'rails/unique_validation_without_index'
Expand Down
58 changes: 58 additions & 0 deletions spec/rubocop/cop/rails/to_s_with_argument_spec.rb
@@ -0,0 +1,58 @@
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Rails::ToSWithArgument, :config, :rails70 do
context 'without argument' do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
to_s
RUBY
end
end

context 'with argument' do
it 'registers an offense' do
expect_offense(<<~RUBY)
to_s(:delimited)
^^^^ Use `to_formatted_s` instead.
RUBY

expect_correction(<<~RUBY)
to_formatted_s(:delimited)
RUBY
end
end

context 'with argument and receiver' do
it 'registers an offense' do
expect_offense(<<~RUBY)
1.to_s(:delimited)
^^^^ Use `to_formatted_s` instead.
RUBY

expect_correction(<<~RUBY)
1.to_formatted_s(:delimited)
RUBY
end
end

context 'with argument and safe navigation operator' do
it 'registers an offense' do
expect_offense(<<~RUBY)
1&.to_s(:delimited)
^^^^ Use `to_formatted_s` instead.
RUBY

expect_correction(<<~RUBY)
1&.to_formatted_s(:delimited)
RUBY
end
end

context 'with argument on Rails 6.1', :rails61 do
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
to_s
RUBY
end
end
end

0 comments on commit 4f08fc2

Please sign in to comment.