rubocop-rails 2.17.2 → 2.17.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/config/default.yml +1 -1
  3. data/lib/rubocop/cop/mixin/active_record_helper.rb +2 -2
  4. data/lib/rubocop/cop/mixin/index_method.rb +1 -1
  5. data/lib/rubocop/cop/mixin/migrations_helper.rb +1 -1
  6. data/lib/rubocop/cop/rails/action_controller_flash_before_render.rb +7 -4
  7. data/lib/rubocop/cop/rails/action_controller_test_case.rb +1 -1
  8. data/lib/rubocop/cop/rails/action_order.rb +39 -3
  9. data/lib/rubocop/cop/rails/application_controller.rb +1 -1
  10. data/lib/rubocop/cop/rails/application_job.rb +1 -1
  11. data/lib/rubocop/cop/rails/application_mailer.rb +1 -1
  12. data/lib/rubocop/cop/rails/application_record.rb +1 -1
  13. data/lib/rubocop/cop/rails/content_tag.rb +1 -1
  14. data/lib/rubocop/cop/rails/dot_separated_keys.rb +1 -1
  15. data/lib/rubocop/cop/rails/duration_arithmetic.rb +2 -2
  16. data/lib/rubocop/cop/rails/dynamic_find_by.rb +16 -6
  17. data/lib/rubocop/cop/rails/file_path.rb +3 -3
  18. data/lib/rubocop/cop/rails/freeze_time.rb +7 -5
  19. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +1 -1
  20. data/lib/rubocop/cop/rails/helper_instance_variable.rb +1 -1
  21. data/lib/rubocop/cop/rails/i18n_lazy_lookup.rb +2 -0
  22. data/lib/rubocop/cop/rails/index_by.rb +1 -1
  23. data/lib/rubocop/cop/rails/index_with.rb +1 -1
  24. data/lib/rubocop/cop/rails/mailer_name.rb +3 -3
  25. data/lib/rubocop/cop/rails/migration_class_name.rb +1 -1
  26. data/lib/rubocop/cop/rails/output.rb +1 -1
  27. data/lib/rubocop/cop/rails/require_dependency.rb +1 -1
  28. data/lib/rubocop/cop/rails/root_pathname_methods.rb +18 -7
  29. data/lib/rubocop/cop/rails/short_i18n.rb +1 -1
  30. data/lib/rubocop/cop/rails/skips_model_validations.rb +1 -1
  31. data/lib/rubocop/cop/rails/time_zone_assignment.rb +1 -1
  32. data/lib/rubocop/cop/rails/to_s_with_argument.rb +38 -1
  33. data/lib/rubocop/rails/version.rb +1 -1
  34. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97069bbada22491ece697f32f933ce8dc5274c18ad2782bb832cd83b168874a3
4
- data.tar.gz: 4a691068f93c7be89e9cf695c3be16fe183cb23be4b187e822a9bf9d896c9af7
3
+ metadata.gz: e1cd420a9b6ec0e14a26063533cf9db61a81a43e44bec26a8b98e577cf761e49
4
+ data.tar.gz: 73918575c04e0f9ee8390d3efc0a4eb49b1cb4093695ecbafddbf995c406869d
5
5
  SHA512:
6
- metadata.gz: 213e3da3d5e23338c53ee9428d8d44a57123fa8a239c3974e5eb0181797555639da23ed7e09336e906e14ba3c99c46e33efba18db44646f0efe86913dc0b7847
7
- data.tar.gz: ed27cd2b9106a650b01fc700e9c2511971853412f49aa93876589dfa67e77c7a246fa364dd4682747fc97ffe8121d286a4096e6ef0b257483668c36f99fec9e1
6
+ metadata.gz: 93fffc6d3f6cbb781692725c13eb6f049e3106f2fb7ccb43a48fdf7c0d85a189914740d2ef743b0642eaa94ae0fc584ec1a32be53095a12167b3c02db2b035d4
7
+ data.tar.gz: 05ac2a5767f2c65437629fa623b3b4506547227c5b608a7ebc4e29a91b831e794ac6ee7c62a55b1573f3b228d40b6aaaedbda1fb7b81481c51f9c0df6884f389
data/config/default.yml CHANGED
@@ -540,7 +540,7 @@ Rails/I18nLazyLookup:
540
540
  Enabled: pending
541
541
  VersionAdded: '2.14'
542
542
  Include:
543
- - 'controllers/**/*'
543
+ - 'app/controllers/**/*.rb'
544
544
 
545
545
  Rails/I18nLocaleAssignment:
546
546
  Description: 'Prefer the usage of `I18n.with_locale` instead of manually updating `I18n.locale` value.'
@@ -10,8 +10,8 @@ module RuboCop
10
10
 
11
11
  def_node_matcher :active_record?, <<~PATTERN
12
12
  {
13
- (const nil? :ApplicationRecord)
14
- (const (const nil? :ActiveRecord) :Base)
13
+ (const {nil? cbase} :ApplicationRecord)
14
+ (const (const {nil? cbase} :ActiveRecord) :Base)
15
15
  }
16
16
  PATTERN
17
17
 
@@ -134,7 +134,7 @@ module RuboCop
134
134
  end
135
135
 
136
136
  def self.from_hash_brackets_map(node, match)
137
- new(match, node.children.last, 'Hash['.length, ']'.length)
137
+ new(match, node.children.last, "#{node.receiver.source}[".length, ']'.length)
138
138
  end
139
139
 
140
140
  def strip_prefix_and_suffix(node, corrector)
@@ -8,7 +8,7 @@ module RuboCop
8
8
 
9
9
  def_node_matcher :migration_class?, <<~PATTERN
10
10
  (class
11
- (const nil? _)
11
+ (const {nil? cbase} _)
12
12
  (send
13
13
  (const (const {nil? cbase} :ActiveRecord) :Migration)
14
14
  :[]
@@ -43,8 +43,8 @@ module RuboCop
43
43
 
44
44
  def_node_search :action_controller?, <<~PATTERN
45
45
  {
46
- (const nil? :ApplicationController)
47
- (const (const nil? :ActionController) :Base)
46
+ (const {nil? cbase} :ApplicationController)
47
+ (const (const {nil? cbase} :ActionController) :Base)
48
48
  }
49
49
  PATTERN
50
50
 
@@ -69,9 +69,12 @@ module RuboCop
69
69
  def followed_by_render?(flash_node)
70
70
  flash_assigment_node = find_ancestor(flash_node, type: :send)
71
71
  context = flash_assigment_node
72
- context = context.parent if context.parent.if_type?
72
+ if (if_node = context.each_ancestor(:if).first)
73
+ context = if_node
74
+ elsif context.right_siblings.empty?
75
+ return true
76
+ end
73
77
  context = context.right_siblings
74
- return true if context.empty?
75
78
 
76
79
  context.compact.any? do |node|
77
80
  render?(node)
@@ -30,7 +30,7 @@ module RuboCop
30
30
 
31
31
  def_node_matcher :action_controller_test_case?, <<~PATTERN
32
32
  (class
33
- (const nil? _)
33
+ (const {nil? cbase} _)
34
34
  (const (const {nil? cbase} :ActionController) :TestCase) _)
35
35
  PATTERN
36
36
 
@@ -6,7 +6,8 @@ module RuboCop
6
6
  # Enforces consistent ordering of the standard Rails RESTful controller actions.
7
7
  #
8
8
  # The cop is configurable and can enforce any ordering of the standard actions.
9
- # All other methods are ignored.
9
+ # All other methods are ignored. So, the actions specified in `ExpectedOrder` should be
10
+ # defined before actions not specified.
10
11
  #
11
12
  # [source,yaml]
12
13
  # ----
@@ -35,6 +36,7 @@ module RuboCop
35
36
  extend AutoCorrector
36
37
  include VisibilityHelp
37
38
  include DefNode
39
+ include RangeHelp
38
40
 
39
41
  MSG = 'Action `%<current>s` should appear before `%<previous>s`.'
40
42
 
@@ -71,9 +73,43 @@ module RuboCop
71
73
  current: current.method_name
72
74
  )
73
75
  add_offense(current, message: message) do |corrector|
74
- corrector.replace(current, previous.source)
75
- corrector.replace(previous, current.source)
76
+ current = correction_target(current)
77
+ previous = correction_target(previous)
78
+
79
+ swap_range(corrector, current, previous)
80
+ end
81
+ end
82
+
83
+ def correction_target(def_node)
84
+ range_with_comments_and_lines(def_node.each_ancestor(:if).first || def_node)
85
+ end
86
+
87
+ def add_range(range1, range2)
88
+ range1.with(
89
+ begin_pos: [range1.begin_pos, range2.begin_pos].min,
90
+ end_pos: [range1.end_pos, range2.end_pos].max
91
+ )
92
+ end
93
+
94
+ def range_with_comments(node)
95
+ ranges = [
96
+ node,
97
+ *processed_source.ast_with_comments[node]
98
+ ].map do |element|
99
+ element.location.expression
76
100
  end
101
+ ranges.reduce do |result, range|
102
+ add_range(result, range)
103
+ end
104
+ end
105
+
106
+ def range_with_comments_and_lines(node)
107
+ range_by_whole_lines(range_with_comments(node), include_final_newline: true)
108
+ end
109
+
110
+ def swap_range(corrector, range1, range2)
111
+ corrector.insert_before(range2, range1.source)
112
+ corrector.remove(range1)
77
113
  end
78
114
  end
79
115
  end
@@ -25,7 +25,7 @@ module RuboCop
25
25
 
26
26
  MSG = 'Controllers should subclass `ApplicationController`.'
27
27
  SUPERCLASS = 'ApplicationController'
28
- BASE_PATTERN = '(const (const nil? :ActionController) :Base)'
28
+ BASE_PATTERN = '(const (const {nil? cbase} :ActionController) :Base)'
29
29
 
30
30
  # rubocop:disable Layout/ClassStructure
31
31
  include RuboCop::Cop::EnforceSuperclass
@@ -28,7 +28,7 @@ module RuboCop
28
28
 
29
29
  MSG = 'Jobs should subclass `ApplicationJob`.'
30
30
  SUPERCLASS = 'ApplicationJob'
31
- BASE_PATTERN = '(const (const nil? :ActiveJob) :Base)'
31
+ BASE_PATTERN = '(const (const {nil? cbase} :ActiveJob) :Base)'
32
32
 
33
33
  # rubocop:disable Layout/ClassStructure
34
34
  include RuboCop::Cop::EnforceSuperclass
@@ -28,7 +28,7 @@ module RuboCop
28
28
 
29
29
  MSG = 'Mailers should subclass `ApplicationMailer`.'
30
30
  SUPERCLASS = 'ApplicationMailer'
31
- BASE_PATTERN = '(const (const nil? :ActionMailer) :Base)'
31
+ BASE_PATTERN = '(const (const {nil? cbase} :ActionMailer) :Base)'
32
32
 
33
33
  # rubocop:disable Layout/ClassStructure
34
34
  include RuboCop::Cop::EnforceSuperclass
@@ -29,7 +29,7 @@ module RuboCop
29
29
 
30
30
  MSG = 'Models should subclass `ApplicationRecord`.'
31
31
  SUPERCLASS = 'ApplicationRecord'
32
- BASE_PATTERN = '(const (const nil? :ActiveRecord) :Base)'
32
+ BASE_PATTERN = '(const (const {nil? cbase} :ActiveRecord) :Base)'
33
33
 
34
34
  # rubocop:disable Layout/ClassStructure
35
35
  include RuboCop::Cop::EnforceSuperclass
@@ -81,7 +81,7 @@ module RuboCop
81
81
  def allowed_name?(argument)
82
82
  return false unless argument.str_type? || argument.sym_type?
83
83
 
84
- !/^[a-zA-Z\-][a-zA-Z\-0-9]*$/.match?(argument.value)
84
+ !/^[a-zA-Z-][a-zA-Z\-0-9]*$/.match?(argument.value)
85
85
  end
86
86
 
87
87
  def correction_range(node)
@@ -24,7 +24,7 @@ module RuboCop
24
24
  TRANSLATE_METHODS = %i[translate t].freeze
25
25
 
26
26
  def_node_matcher :translate_with_scope?, <<~PATTERN
27
- (send {nil? (const nil? :I18n)} {:translate :t} ${sym_type? str_type?}
27
+ (send {nil? (const {nil? cbase} :I18n)} {:translate :t} ${sym_type? str_type?}
28
28
  (hash <$(pair (sym :scope) ${array_type? sym_type?}) ...>)
29
29
  )
30
30
  PATTERN
@@ -70,8 +70,8 @@ module RuboCop
70
70
  # @return [Boolean] true if matches
71
71
  def_node_matcher :time_current?, <<~PATTERN
72
72
  {
73
- (send (const _ :Time) :current)
74
- (send (send (const _ :Time) :zone) :now)
73
+ (send (const {nil? cbase} :Time) :current)
74
+ (send (send (const {nil? cbase} :Time) :zone) :now)
75
75
  }
76
76
  PATTERN
77
77
 
@@ -53,7 +53,7 @@ module RuboCop
53
53
  method_name = node.method_name
54
54
  static_name = static_method_name(method_name)
55
55
  return unless static_name
56
- return if node.arguments.any? { |argument| IGNORED_ARGUMENT_TYPES.include?(argument.type) }
56
+ return unless dynamic_find_by_arguments?(node)
57
57
 
58
58
  message = format(MSG, static_name: static_name, method: method_name)
59
59
  add_offense(node, message: message) do |corrector|
@@ -65,12 +65,8 @@ module RuboCop
65
65
  private
66
66
 
67
67
  def autocorrect(corrector, node)
68
- keywords = column_keywords(node.method_name)
69
-
70
- return if keywords.size != node.arguments.size
71
-
72
68
  autocorrect_method_name(corrector, node)
73
- autocorrect_argument_keywords(corrector, node, keywords)
69
+ autocorrect_argument_keywords(corrector, node, column_keywords(node.method_name))
74
70
  end
75
71
 
76
72
  def allowed_invocation?(node)
@@ -120,6 +116,20 @@ module RuboCop
120
116
 
121
117
  match[2] ? 'find_by!' : 'find_by'
122
118
  end
119
+
120
+ def dynamic_find_by_arguments?(node)
121
+ dynamic_find_by_arguments_count?(node) && dynamic_find_by_arguments_type?(node)
122
+ end
123
+
124
+ def dynamic_find_by_arguments_count?(node)
125
+ column_keywords(node.method_name).size == node.arguments.size
126
+ end
127
+
128
+ def dynamic_find_by_arguments_type?(node)
129
+ node.arguments.none? do |argument|
130
+ IGNORED_ARGUMENT_TYPES.include?(argument.type)
131
+ end
132
+ end
123
133
  end
124
134
  end
125
135
  end
@@ -34,15 +34,15 @@ module RuboCop
34
34
  RESTRICT_ON_SEND = %i[join].freeze
35
35
 
36
36
  def_node_matcher :file_join_nodes?, <<~PATTERN
37
- (send (const nil? :File) :join ...)
37
+ (send (const {nil? cbase} :File) :join ...)
38
38
  PATTERN
39
39
 
40
40
  def_node_search :rails_root_nodes?, <<~PATTERN
41
- (send (const nil? :Rails) :root)
41
+ (send (const {nil? cbase} :Rails) :root)
42
42
  PATTERN
43
43
 
44
44
  def_node_matcher :rails_root_join_nodes?, <<~PATTERN
45
- (send (send (const nil? :Rails) :root) :join ...)
45
+ (send #rails_root_nodes? :join ...)
46
46
  PATTERN
47
47
 
48
48
  def on_dstr(node)
@@ -29,17 +29,17 @@ module RuboCop
29
29
 
30
30
  MSG = 'Use `freeze_time` instead of `travel_to`.'
31
31
  NOW_METHODS = %i[now new current].freeze
32
- CONV_METHODS = %i[to_time in_time_zone].freeze
32
+ CONVERT_METHODS = %i[to_time in_time_zone].freeze
33
33
  RESTRICT_ON_SEND = %i[travel_to].freeze
34
34
 
35
35
  # @!method time_now?(node)
36
36
  def_node_matcher :time_now?, <<~PATTERN
37
- (const nil? {:Time :DateTime})
37
+ (const {nil? cbase} {:Time :DateTime})
38
38
  PATTERN
39
39
 
40
40
  # @!method zoned_time_now?(node)
41
41
  def_node_matcher :zoned_time_now?, <<~PATTERN
42
- (send (const nil? :Time) :zone)
42
+ (send (const {nil? cbase} :Time) :zone)
43
43
  PATTERN
44
44
 
45
45
  def on_send(node)
@@ -63,9 +63,11 @@ module RuboCop
63
63
  end
64
64
 
65
65
  def current_time_with_convert?(node, method_name)
66
- return false unless CONV_METHODS.include?(method_name)
66
+ return false unless CONVERT_METHODS.include?(method_name)
67
+
68
+ child_node, child_method_name, time_argument = *node.children
69
+ return if time_argument
67
70
 
68
- child_node, child_method_name = *node.children
69
71
  current_time?(child_node, child_method_name)
70
72
  end
71
73
  end
@@ -37,7 +37,7 @@ module RuboCop
37
37
  RESTRICT_ON_SEND = %i[has_many has_one].freeze
38
38
 
39
39
  def_node_search :active_resource_class?, <<~PATTERN
40
- (const (const nil? :ActiveResource) :Base)
40
+ (const (const {nil? cbase} :ActiveResource) :Base)
41
41
  PATTERN
42
42
 
43
43
  def_node_matcher :association_without_options?, <<~PATTERN
@@ -37,7 +37,7 @@ module RuboCop
37
37
  def_node_matcher :form_builder_class?, <<~PATTERN
38
38
  (const
39
39
  (const
40
- (const nil? :ActionView) :Helpers) :FormBuilder)
40
+ (const {nil? cbase} :ActionView) :Helpers) :FormBuilder)
41
41
  PATTERN
42
42
 
43
43
  def on_ivar(node)
@@ -34,6 +34,8 @@ module RuboCop
34
34
 
35
35
  MSG = 'Use "lazy" lookup for the text used in controllers.'
36
36
 
37
+ RESTRICT_ON_SEND = %i[translate t].freeze
38
+
37
39
  def_node_matcher :translate_call?, <<~PATTERN
38
40
  (send nil? {:translate :t} ${sym_type? str_type?} ...)
39
41
  PATTERN
@@ -46,7 +46,7 @@ module RuboCop
46
46
 
47
47
  def_node_matcher :on_bad_hash_brackets_map, <<~PATTERN
48
48
  (send
49
- (const _ :Hash)
49
+ (const {nil? cbase} :Hash)
50
50
  :[]
51
51
  (block
52
52
  (call _ {:map :collect})
@@ -49,7 +49,7 @@ module RuboCop
49
49
 
50
50
  def_node_matcher :on_bad_hash_brackets_map, <<~PATTERN
51
51
  (send
52
- (const _ :Hash)
52
+ (const {nil? cbase} :Hash)
53
53
  :[]
54
54
  (block
55
55
  (call _ {:map :collect})
@@ -34,8 +34,8 @@ module RuboCop
34
34
 
35
35
  def_node_matcher :mailer_base_class?, <<~PATTERN
36
36
  {
37
- (const (const nil? :ActionMailer) :Base)
38
- (const nil? :ApplicationMailer)
37
+ (const (const {nil? cbase} :ActionMailer) :Base)
38
+ (const {nil? cbase} :ApplicationMailer)
39
39
  }
40
40
  PATTERN
41
41
 
@@ -44,7 +44,7 @@ module RuboCop
44
44
  PATTERN
45
45
 
46
46
  def_node_matcher :class_new_definition?, <<~PATTERN
47
- (send (const nil? :Class) :new #mailer_base_class?)
47
+ (send (const {nil? cbase} :Class) :new #mailer_base_class?)
48
48
  PATTERN
49
49
 
50
50
  def on_class(node)
@@ -29,7 +29,7 @@ module RuboCop
29
29
 
30
30
  basename = basename_without_timestamp_and_suffix(processed_source.file_path)
31
31
 
32
- class_identifier = node.identifier
32
+ class_identifier = node.identifier.location.name
33
33
  camelized_basename = camelize(basename)
34
34
  return if class_identifier.source.casecmp(camelized_basename).zero?
35
35
 
@@ -32,7 +32,7 @@ module RuboCop
32
32
  (send
33
33
  {
34
34
  (gvar #match_gvar?)
35
- {(const nil? :STDOUT) (const nil? :STDERR)}
35
+ (const {nil? cbase} {:STDOUT :STDERR})
36
36
  }
37
37
  {:binwrite :syswrite :write :write_nonblock}
38
38
  ...)
@@ -26,7 +26,7 @@ module RuboCop
26
26
  RESTRICT_ON_SEND = %i[require_dependency].freeze
27
27
 
28
28
  def_node_matcher :require_dependency_call?, <<~PATTERN
29
- (send {nil? (const _ :Kernel)} :require_dependency _)
29
+ (send {nil? (const {nil? cbase} :Kernel)} :require_dependency _)
30
30
  PATTERN
31
31
 
32
32
  def on_send(node)
@@ -163,12 +163,11 @@ module RuboCop
163
163
  def on_send(node)
164
164
  evidence(node) do |method, path, args, rails_root|
165
165
  add_offense(node, message: format(MSG, method: method, rails_root: rails_root.source)) do |corrector|
166
- if dir_glob?(node)
167
- replacement = build_path_glob(path, method)
168
- else
169
- replacement = "#{path.source}.#{method}"
170
- replacement += "(#{args.map(&:source).join(', ')})" unless args.empty?
171
- end
166
+ replacement = if dir_glob?(node)
167
+ build_path_glob_replacement(path, method)
168
+ else
169
+ build_path_replacement(path, method, args)
170
+ end
172
171
 
173
172
  corrector.replace(node, replacement)
174
173
  end
@@ -184,7 +183,7 @@ module RuboCop
184
183
  yield(method, path, args, rails_root)
185
184
  end
186
185
 
187
- def build_path_glob(path, method)
186
+ def build_path_glob_replacement(path, method)
188
187
  receiver = range_between(path.loc.expression.begin_pos, path.children.first.loc.selector.end_pos).source
189
188
 
190
189
  argument = if path.arguments.one?
@@ -196,6 +195,18 @@ module RuboCop
196
195
  "#{receiver}.#{method}(#{argument})"
197
196
  end
198
197
 
198
+ def build_path_replacement(path, method, args)
199
+ path_replacement = path.source
200
+ if path.arguments? && !path.parenthesized_call?
201
+ path_replacement[' '] = '('
202
+ path_replacement << ')'
203
+ end
204
+
205
+ replacement = "#{path_replacement}.#{method}"
206
+ replacement += "(#{args.map(&:source).join(', ')})" unless args.empty?
207
+ replacement
208
+ end
209
+
199
210
  def include_interpolation?(arguments)
200
211
  arguments.any? do |argument|
201
212
  argument.children.any? { |child| child.respond_to?(:begin_type?) && child.begin_type? }
@@ -49,7 +49,7 @@ module RuboCop
49
49
  RESTRICT_ON_SEND = PREFERRED_METHODS.keys.freeze
50
50
 
51
51
  def_node_matcher :long_i18n?, <<~PATTERN
52
- (send {nil? (const nil? :I18n)} ${:translate :localize} ...)
52
+ (send {nil? (const {nil? cbase} :I18n)} ${:translate :localize} ...)
53
53
  PATTERN
54
54
 
55
55
  def on_send(node)
@@ -57,7 +57,7 @@ module RuboCop
57
57
 
58
58
  def_node_matcher :good_touch?, <<~PATTERN
59
59
  {
60
- (send (const nil? :FileUtils) :touch ...)
60
+ (send (const {nil? cbase} :FileUtils) :touch ...)
61
61
  (send _ :touch {true false})
62
62
  }
63
63
  PATTERN
@@ -23,7 +23,7 @@ module RuboCop
23
23
  RESTRICT_ON_SEND = %i[zone=].freeze
24
24
 
25
25
  def_node_matcher :time_zone_assignment?, <<~PATTERN
26
- (send (const nil? :Time) :zone= ...)
26
+ (send (const {nil? cbase} :Time) :zone= ...)
27
27
  PATTERN
28
28
 
29
29
  def on_send(node)
@@ -21,6 +21,37 @@ module RuboCop
21
21
  extend AutoCorrector
22
22
  extend TargetRailsVersion
23
23
 
24
+ # These types are defined by the following files in ActiveSupport:
25
+ # lib/active_support/core_ext/array/conversions.rb
26
+ # lib/active_support/core_ext/date/conversions.rb
27
+ # lib/active_support/core_ext/date_time/conversions.rb
28
+ # lib/active_support/core_ext/numeric/conversions.rb
29
+ # lib/active_support/core_ext/range/conversions.rb
30
+ # lib/active_support/core_ext/time/conversions.rb
31
+ # lib/active_support/time_with_zone.rb
32
+ EXTENDED_FORMAT_TYPES = Set.new(
33
+ %i[
34
+ currency
35
+ db
36
+ delimited
37
+ human
38
+ human_size
39
+ inspect
40
+ iso8601
41
+ long
42
+ long_ordinal
43
+ nsec
44
+ number
45
+ percentage
46
+ phone
47
+ rfc822
48
+ rounded
49
+ short
50
+ time
51
+ usec
52
+ ]
53
+ )
54
+
24
55
  MSG = 'Use `to_formatted_s` instead.'
25
56
 
26
57
  RESTRICT_ON_SEND = %i[to_s].freeze
@@ -28,13 +59,19 @@ module RuboCop
28
59
  minimum_target_rails_version 7.0
29
60
 
30
61
  def on_send(node)
31
- return if node.arguments.empty?
62
+ return unless rails_extended_to_s?(node)
32
63
 
33
64
  add_offense(node.loc.selector) do |corrector|
34
65
  corrector.replace(node.loc.selector, 'to_formatted_s')
35
66
  end
36
67
  end
37
68
  alias on_csend on_send
69
+
70
+ private
71
+
72
+ def rails_extended_to_s?(node)
73
+ node.first_argument&.sym_type? && EXTENDED_FORMAT_TYPES.include?(node.first_argument.value)
74
+ end
38
75
  end
39
76
  end
40
77
  end
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module Rails
5
5
  # This module holds the RuboCop Rails version information.
6
6
  module Version
7
- STRING = '2.17.2'
7
+ STRING = '2.17.3'
8
8
 
9
9
  def self.document_version
10
10
  STRING.match('\d+\.\d+').to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.17.2
4
+ version: 2.17.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-10-27 00:00:00.000000000 Z
13
+ date: 2022-11-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport