Skip to content

Commit 8d3de8e

Browse files
authored
Merge pull request #747 from r7kamura/feature/to-s-with-argument
Add `Rails/ToSWithArgument` cop
2 parents f500a79 + 4f08fc2 commit 8d3de8e

File tree

5 files changed

+107
-0
lines changed

5 files changed

+107
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#747](https://github.com/rubocop/rubocop-rails/pull/747): Add `Rails/ToSWithArgument` cop. ([@r7kamura][])

config/default.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,12 @@ Rails/ToFormattedS:
952952
- to_formatted_s
953953
VersionAdded: '2.15'
954954

955+
Rails/ToSWithArgument:
956+
Description: 'Identifies passing any argument to `#to_s`.'
957+
Enabled: pending
958+
Safe: false
959+
VersionAdded: '<<next>>'
960+
955961
Rails/TransactionExitStatement:
956962
Description: 'Avoid the usage of `return`, `break` and `throw` in transaction blocks.'
957963
Enabled: pending
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Rails
6+
# Identifies passing any argument to `#to_s`.
7+
#
8+
# @safety
9+
# This cop is marked as unsafe because it may detect `#to_s` calls
10+
# that are not related to Active Support implementation.
11+
#
12+
# @example
13+
#
14+
# # bad
15+
# obj.to_s(:delimited)
16+
#
17+
# # good
18+
# obj.to_formatted_s(:delimited)
19+
#
20+
class ToSWithArgument < Base
21+
extend AutoCorrector
22+
extend TargetRailsVersion
23+
24+
MSG = 'Use `to_formatted_s` instead.'
25+
26+
RESTRICT_ON_SEND = %i[to_s].freeze
27+
28+
minimum_target_rails_version 7.0
29+
30+
def on_send(node)
31+
return if node.arguments.empty?
32+
33+
add_offense(node.loc.selector) do |corrector|
34+
corrector.replace(node.loc.selector, 'to_formatted_s')
35+
end
36+
end
37+
alias on_csend on_send
38+
end
39+
end
40+
end
41+
end

lib/rubocop/cop/rails_cops.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
require_relative 'rails/time_zone'
114114
require_relative 'rails/time_zone_assignment'
115115
require_relative 'rails/to_formatted_s'
116+
require_relative 'rails/to_s_with_argument'
116117
require_relative 'rails/transaction_exit_statement'
117118
require_relative 'rails/uniq_before_pluck'
118119
require_relative 'rails/unique_validation_without_index'
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RuboCop::Cop::Rails::ToSWithArgument, :config, :rails70 do
4+
context 'without argument' do
5+
it 'does not register an offense' do
6+
expect_no_offenses(<<~RUBY)
7+
to_s
8+
RUBY
9+
end
10+
end
11+
12+
context 'with argument' do
13+
it 'registers an offense' do
14+
expect_offense(<<~RUBY)
15+
to_s(:delimited)
16+
^^^^ Use `to_formatted_s` instead.
17+
RUBY
18+
19+
expect_correction(<<~RUBY)
20+
to_formatted_s(:delimited)
21+
RUBY
22+
end
23+
end
24+
25+
context 'with argument and receiver' do
26+
it 'registers an offense' do
27+
expect_offense(<<~RUBY)
28+
1.to_s(:delimited)
29+
^^^^ Use `to_formatted_s` instead.
30+
RUBY
31+
32+
expect_correction(<<~RUBY)
33+
1.to_formatted_s(:delimited)
34+
RUBY
35+
end
36+
end
37+
38+
context 'with argument and safe navigation operator' do
39+
it 'registers an offense' do
40+
expect_offense(<<~RUBY)
41+
1&.to_s(:delimited)
42+
^^^^ Use `to_formatted_s` instead.
43+
RUBY
44+
45+
expect_correction(<<~RUBY)
46+
1&.to_formatted_s(:delimited)
47+
RUBY
48+
end
49+
end
50+
51+
context 'with argument on Rails 6.1', :rails61 do
52+
it 'does not register an offense' do
53+
expect_no_offenses(<<~RUBY)
54+
to_s
55+
RUBY
56+
end
57+
end
58+
end

0 commit comments

Comments
 (0)