rubocop-rails 2.7.1 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +18 -2
  4. data/config/default.yml +144 -6
  5. data/config/obsoletion.yml +7 -0
  6. data/lib/rubocop/cop/mixin/active_record_helper.rb +16 -3
  7. data/lib/rubocop/cop/mixin/enforce_superclass.rb +40 -0
  8. data/lib/rubocop/cop/mixin/index_method.rb +25 -11
  9. data/lib/rubocop/cop/rails/action_filter.rb +10 -14
  10. data/lib/rubocop/cop/rails/active_record_aliases.rb +13 -17
  11. data/lib/rubocop/cop/rails/active_record_callbacks_order.rb +19 -16
  12. data/lib/rubocop/cop/rails/active_record_override.rb +1 -1
  13. data/lib/rubocop/cop/rails/active_support_aliases.rb +12 -21
  14. data/lib/rubocop/cop/rails/after_commit_override.rb +91 -0
  15. data/lib/rubocop/cop/rails/application_controller.rb +3 -7
  16. data/lib/rubocop/cop/rails/application_job.rb +2 -1
  17. data/lib/rubocop/cop/rails/application_mailer.rb +2 -7
  18. data/lib/rubocop/cop/rails/application_record.rb +2 -7
  19. data/lib/rubocop/cop/rails/arel_star.rb +41 -0
  20. data/lib/rubocop/cop/rails/assert_not.rb +8 -10
  21. data/lib/rubocop/cop/rails/attribute_default_block_value.rb +90 -0
  22. data/lib/rubocop/cop/rails/belongs_to.rb +10 -19
  23. data/lib/rubocop/cop/rails/blank.rb +31 -27
  24. data/lib/rubocop/cop/rails/bulk_change_table.rb +1 -1
  25. data/lib/rubocop/cop/rails/content_tag.rb +34 -19
  26. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +2 -1
  27. data/lib/rubocop/cop/rails/date.rb +10 -11
  28. data/lib/rubocop/cop/rails/default_scope.rb +11 -4
  29. data/lib/rubocop/cop/rails/delegate.rb +9 -9
  30. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +7 -8
  31. data/lib/rubocop/cop/rails/dynamic_find_by.rb +15 -12
  32. data/lib/rubocop/cop/rails/enum_hash.rb +11 -10
  33. data/lib/rubocop/cop/rails/enum_uniqueness.rb +2 -1
  34. data/lib/rubocop/cop/rails/environment_comparison.rb +18 -14
  35. data/lib/rubocop/cop/rails/environment_variable_access.rb +67 -0
  36. data/lib/rubocop/cop/rails/exit.rb +4 -10
  37. data/lib/rubocop/cop/rails/file_path.rb +7 -8
  38. data/lib/rubocop/cop/rails/find_by.rb +13 -13
  39. data/lib/rubocop/cop/rails/find_by_id.rb +12 -21
  40. data/lib/rubocop/cop/rails/find_each.rb +19 -18
  41. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  42. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +37 -10
  43. data/lib/rubocop/cop/rails/helper_instance_variable.rb +30 -2
  44. data/lib/rubocop/cop/rails/http_positional_arguments.rb +32 -21
  45. data/lib/rubocop/cop/rails/http_status.rb +7 -9
  46. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +8 -6
  47. data/lib/rubocop/cop/rails/index_by.rb +11 -2
  48. data/lib/rubocop/cop/rails/index_with.rb +11 -2
  49. data/lib/rubocop/cop/rails/inquiry.rb +7 -2
  50. data/lib/rubocop/cop/rails/inverse_of.rb +3 -2
  51. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +17 -15
  52. data/lib/rubocop/cop/rails/link_to_blank.rb +25 -23
  53. data/lib/rubocop/cop/rails/mailer_name.rb +19 -13
  54. data/lib/rubocop/cop/rails/match_route.rb +14 -13
  55. data/lib/rubocop/cop/rails/negate_include.rb +10 -8
  56. data/lib/rubocop/cop/rails/not_null_column.rb +2 -1
  57. data/lib/rubocop/cop/rails/order_by_id.rb +52 -0
  58. data/lib/rubocop/cop/rails/output.rb +5 -2
  59. data/lib/rubocop/cop/rails/output_safety.rb +3 -2
  60. data/lib/rubocop/cop/rails/pick.rb +14 -12
  61. data/lib/rubocop/cop/rails/pluck.rb +6 -9
  62. data/lib/rubocop/cop/rails/pluck_id.rb +4 -6
  63. data/lib/rubocop/cop/rails/pluck_in_where.rb +39 -5
  64. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -14
  65. data/lib/rubocop/cop/rails/presence.rb +12 -13
  66. data/lib/rubocop/cop/rails/present.rb +30 -24
  67. data/lib/rubocop/cop/rails/rake_environment.rb +8 -10
  68. data/lib/rubocop/cop/rails/read_write_attribute.rb +12 -11
  69. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +29 -31
  70. data/lib/rubocop/cop/rails/redundant_foreign_key.rb +9 -12
  71. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +11 -10
  72. data/lib/rubocop/cop/rails/reflection_class_name.rb +18 -4
  73. data/lib/rubocop/cop/rails/refute_methods.rb +9 -10
  74. data/lib/rubocop/cop/rails/relative_date_constant.rb +34 -22
  75. data/lib/rubocop/cop/rails/render_inline.rb +2 -1
  76. data/lib/rubocop/cop/rails/render_plain_text.rb +9 -14
  77. data/lib/rubocop/cop/rails/request_referer.rb +7 -7
  78. data/lib/rubocop/cop/rails/require_dependency.rb +38 -0
  79. data/lib/rubocop/cop/rails/reversible_migration.rb +83 -8
  80. data/lib/rubocop/cop/rails/reversible_migration_method_definition.rb +75 -0
  81. data/lib/rubocop/cop/rails/safe_navigation.rb +30 -11
  82. data/lib/rubocop/cop/rails/safe_navigation_with_blank.rb +5 -10
  83. data/lib/rubocop/cop/rails/save_bang.rb +19 -22
  84. data/lib/rubocop/cop/rails/scope_args.rb +2 -1
  85. data/lib/rubocop/cop/rails/short_i18n.rb +7 -9
  86. data/lib/rubocop/cop/rails/skips_model_validations.rb +4 -4
  87. data/lib/rubocop/cop/rails/squished_sql_heredocs.rb +82 -0
  88. data/lib/rubocop/cop/rails/time_zone.rb +35 -25
  89. data/lib/rubocop/cop/rails/time_zone_assignment.rb +37 -0
  90. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +6 -6
  91. data/lib/rubocop/cop/rails/unique_validation_without_index.rb +18 -8
  92. data/lib/rubocop/cop/rails/unknown_env.rb +3 -3
  93. data/lib/rubocop/cop/rails/validation.rb +15 -14
  94. data/lib/rubocop/cop/rails/where_equals.rb +98 -0
  95. data/lib/rubocop/cop/rails/where_exists.rb +85 -16
  96. data/lib/rubocop/cop/rails/where_not.rb +101 -0
  97. data/lib/rubocop/cop/rails_cops.rb +12 -0
  98. data/lib/rubocop/rails.rb +2 -0
  99. data/lib/rubocop/rails/schema_loader.rb +4 -4
  100. data/lib/rubocop/rails/schema_loader/schema.rb +4 -8
  101. data/lib/rubocop/rails/version.rb +5 -1
  102. metadata +33 -14
@@ -13,8 +13,9 @@ module RuboCop
13
13
  #
14
14
  # # good
15
15
  # scope :something, -> { where(something: true) }
16
- class ScopeArgs < Cop
16
+ class ScopeArgs < Base
17
17
  MSG = 'Use `lambda`/`proc` instead of a plain method call.'
18
+ RESTRICT_ON_SEND = %i[scope].freeze
18
19
 
19
20
  def_node_matcher :scope?, '(send nil? :scope _ $send)'
20
21
 
@@ -38,8 +38,9 @@ module RuboCop
38
38
  # t :key
39
39
  # l Time.now
40
40
  #
41
- class ShortI18n < Cop
41
+ class ShortI18n < Base
42
42
  include ConfigurableEnforcedStyle
43
+ extend AutoCorrector
43
44
 
44
45
  MSG = 'Use `%<good_method>s` instead of `%<bad_method>s`.'
45
46
 
@@ -48,6 +49,8 @@ module RuboCop
48
49
  localize: :l
49
50
  }.freeze
50
51
 
52
+ RESTRICT_ON_SEND = PREFERRED_METHODS.keys.freeze
53
+
51
54
  def_node_matcher :long_i18n?, <<~PATTERN
52
55
  (send {nil? (const nil? :I18n)} ${:translate :localize} ...)
53
56
  PATTERN
@@ -58,15 +61,10 @@ module RuboCop
58
61
  long_i18n?(node) do |method_name|
59
62
  good_method = PREFERRED_METHODS[method_name]
60
63
  message = format(MSG, good_method: good_method, bad_method: method_name)
64
+ range = node.loc.selector
61
65
 
62
- add_offense(node, location: :selector, message: message)
63
- end
64
- end
65
-
66
- def autocorrect(node)
67
- long_i18n?(node) do |method_name|
68
- lambda do |corrector|
69
- corrector.replace(node.loc.selector, PREFERRED_METHODS[method_name])
66
+ add_offense(range, message: message) do |corrector|
67
+ corrector.replace(range, PREFERRED_METHODS[method_name])
70
68
  end
71
69
  end
72
70
  end
@@ -7,7 +7,7 @@ module RuboCop
7
7
  # validations which are listed in
8
8
  # https://guides.rubyonrails.org/active_record_validations.html#skipping-validations
9
9
  #
10
- # Methods may be ignored from this rule by configuring a `Whitelist`.
10
+ # Methods may be ignored from this rule by configuring a `AllowedMethods`.
11
11
  #
12
12
  # @example
13
13
  # # bad
@@ -26,7 +26,7 @@ module RuboCop
26
26
  # user.update(website: 'example.com')
27
27
  # FileUtils.touch('file')
28
28
  #
29
- # @example Whitelist: ["touch"]
29
+ # @example AllowedMethods: ["touch"]
30
30
  # # bad
31
31
  # DiscussionBoard.decrement_counter(:post_count, 5)
32
32
  # DiscussionBoard.increment_counter(:post_count, 5)
@@ -35,7 +35,7 @@ module RuboCop
35
35
  # # good
36
36
  # user.touch
37
37
  #
38
- class SkipsModelValidations < Cop
38
+ class SkipsModelValidations < Base
39
39
  MSG = 'Avoid using `%<method>s` because it skips validations.'
40
40
 
41
41
  METHODS_WITH_ARGUMENTS = %w[decrement!
@@ -76,7 +76,7 @@ module RuboCop
76
76
  return if good_touch?(node)
77
77
  return if good_insert?(node)
78
78
 
79
- add_offense(node, location: :selector)
79
+ add_offense(node.loc.selector, message: message(node))
80
80
  end
81
81
  alias on_csend on_send
82
82
 
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ #
7
+ # Checks SQL heredocs to use `.squish`.
8
+ # Some SQL syntax (e.g. PostgreSQL comments and functions) requires newlines
9
+ # to be preserved in order to work, thus auto-correction for this cop is not safe.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # <<-SQL
14
+ # SELECT * FROM posts;
15
+ # SQL
16
+ #
17
+ # <<-SQL
18
+ # SELECT * FROM posts
19
+ # WHERE id = 1
20
+ # SQL
21
+ #
22
+ # execute(<<~SQL, "Post Load")
23
+ # SELECT * FROM posts
24
+ # WHERE post_id = 1
25
+ # SQL
26
+ #
27
+ # # good
28
+ # <<-SQL.squish
29
+ # SELECT * FROM posts;
30
+ # SQL
31
+ #
32
+ # <<~SQL.squish
33
+ # SELECT * FROM table
34
+ # WHERE id = 1
35
+ # SQL
36
+ #
37
+ # execute(<<~SQL.squish, "Post Load")
38
+ # SELECT * FROM posts
39
+ # WHERE post_id = 1
40
+ # SQL
41
+ #
42
+ class SquishedSQLHeredocs < Base
43
+ include Heredoc
44
+ extend AutoCorrector
45
+
46
+ SQL = 'SQL'
47
+ SQUISH = '.squish'
48
+ MSG = 'Use `%<expect>s` instead of `%<current>s`.'
49
+
50
+ def on_heredoc(node)
51
+ return unless offense_detected?(node)
52
+
53
+ add_offense(node) do |corrector|
54
+ corrector.insert_after(node, SQUISH)
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def offense_detected?(node)
61
+ sql_heredoc?(node) && !using_squish?(node)
62
+ end
63
+
64
+ def sql_heredoc?(node)
65
+ delimiter_string(node) == SQL
66
+ end
67
+
68
+ def using_squish?(node)
69
+ node.parent&.send_type? && node.parent&.method?(:squish)
70
+ end
71
+
72
+ def message(node)
73
+ format(
74
+ MSG,
75
+ expect: "#{node.source}#{SQUISH}",
76
+ current: node.source
77
+ )
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  #
20
20
  # # bad
21
21
  # Time.now
22
- # Time.parse('2015-03-02 19:05:37')
22
+ # Time.parse('2015-03-02T19:05:37')
23
23
  #
24
24
  # # bad
25
25
  # Time.current
@@ -27,24 +27,26 @@ module RuboCop
27
27
  #
28
28
  # # good
29
29
  # Time.zone.now
30
- # Time.zone.parse('2015-03-02 19:05:37')
30
+ # Time.zone.parse('2015-03-02T19:05:37')
31
+ # Time.zone.parse('2015-03-02T19:05:37Z') # Respect ISO 8601 format with timezone specifier.
31
32
  #
32
33
  # @example EnforcedStyle: flexible (default)
33
34
  # # `flexible` allows usage of `in_time_zone` instead of `zone`.
34
35
  #
35
36
  # # bad
36
37
  # Time.now
37
- # Time.parse('2015-03-02 19:05:37')
38
+ # Time.parse('2015-03-02T19:05:37')
38
39
  #
39
40
  # # good
40
41
  # Time.zone.now
41
- # Time.zone.parse('2015-03-02 19:05:37')
42
+ # Time.zone.parse('2015-03-02T19:05:37')
42
43
  #
43
44
  # # good
44
45
  # Time.current
45
46
  # Time.at(timestamp).in_time_zone
46
- class TimeZone < Cop
47
+ class TimeZone < Base
47
48
  include ConfigurableEnforcedStyle
49
+ extend AutoCorrector
48
50
 
49
51
  MSG = 'Do not use `%<current>s` without zone. Use `%<prefer>s` ' \
50
52
  'instead.'
@@ -62,6 +64,8 @@ module RuboCop
62
64
  ACCEPTED_METHODS = %i[in_time_zone utc getlocal xmlschema iso8601
63
65
  jisx0301 rfc3339 httpdate to_i to_f].freeze
64
66
 
67
+ TIMEZONE_SPECIFIER = /[A-z]/.freeze
68
+
65
69
  def on_const(node)
66
70
  mod, klass = *node
67
71
  # we should only check core classes
@@ -71,26 +75,24 @@ module RuboCop
71
75
  check_time_node(klass, node.parent) if klass == :Time
72
76
  end
73
77
 
74
- def autocorrect(node)
75
- lambda do |corrector|
76
- # add `.zone`: `Time.at` => `Time.zone.at`
77
- corrector.insert_after(node.children[0].source_range, '.zone')
78
+ private
78
79
 
79
- case node.method_name
80
- when :current
81
- # replace `Time.zone.current` => `Time.zone.now`
82
- corrector.replace(node.loc.selector, 'now')
83
- when :new
84
- autocorrect_time_new(node, corrector)
85
- end
80
+ def autocorrect(corrector, node)
81
+ # add `.zone`: `Time.at` => `Time.zone.at`
82
+ corrector.insert_after(node.children[0].source_range, '.zone')
86
83
 
87
- # prefer `Time` over `DateTime` class
88
- corrector.replace(node.children.first.source_range, 'Time') if strict?
89
- remove_redundant_in_time_zone(corrector, node)
84
+ case node.method_name
85
+ when :current
86
+ # replace `Time.zone.current` => `Time.zone.now`
87
+ corrector.replace(node.loc.selector, 'now')
88
+ when :new
89
+ autocorrect_time_new(node, corrector)
90
90
  end
91
- end
92
91
 
93
- private
92
+ # prefer `Time` over `DateTime` class
93
+ corrector.replace(node.children.first.source_range, 'Time') if strict?
94
+ remove_redundant_in_time_zone(corrector, node)
95
+ end
94
96
 
95
97
  def autocorrect_time_new(node, corrector)
96
98
  if node.arguments?
@@ -117,9 +119,10 @@ module RuboCop
117
119
  end
118
120
 
119
121
  def check_time_node(klass, node)
122
+ return if attach_timezone_specifier?(node.first_argument)
123
+
120
124
  chain = extract_method_chain(node)
121
125
  return if not_danger_chain?(chain)
122
-
123
126
  return check_localtime(node) if need_check_localtime?(chain)
124
127
 
125
128
  method_name = (chain & DANGEROUS_METHODS).join('.')
@@ -128,7 +131,13 @@ module RuboCop
128
131
 
129
132
  message = build_message(klass, method_name, node)
130
133
 
131
- add_offense(node, location: :selector, message: message)
134
+ add_offense(node.loc.selector, message: message) do |corrector|
135
+ autocorrect(corrector, node)
136
+ end
137
+ end
138
+
139
+ def attach_timezone_specifier?(date)
140
+ date.respond_to?(:value) && TIMEZONE_SPECIFIER.match?(date.value.to_s[-1])
132
141
  end
133
142
 
134
143
  def build_message(klass, method_name, node)
@@ -193,8 +202,9 @@ module RuboCop
193
202
 
194
203
  return if node.arguments?
195
204
 
196
- add_offense(selector_node,
197
- location: :selector, message: MSG_LOCALTIME)
205
+ add_offense(selector_node.loc.selector, message: MSG_LOCALTIME) do |corrector|
206
+ autocorrect(corrector, selector_node)
207
+ end
198
208
  end
199
209
 
200
210
  def not_danger_chain?(chain)
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop checks for the use of `Time.zone=` method.
7
+ #
8
+ # The `zone` attribute persists for the rest of the Ruby runtime, potentially causing
9
+ # unexpected behaviour at a later time.
10
+ # Using `Time.use_zone` ensures the code passed in block is the only place Time.zone is affected.
11
+ # It eliminates the possibility of a `zone` sticking around longer than intended.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # Time.zone = 'EST'
16
+ #
17
+ # # good
18
+ # Time.use_zone('EST') do
19
+ # end
20
+ #
21
+ class TimeZoneAssignment < Base
22
+ MSG = 'Use `Time.use_zone` with blocks instead of `Time.zone=`.'
23
+ RESTRICT_ON_SEND = %i[zone=].freeze
24
+
25
+ def_node_matcher :time_zone_assignement?, <<~PATTERN
26
+ (send (const nil? :Time) :zone= ...)
27
+ PATTERN
28
+
29
+ def on_send(node)
30
+ return unless time_zone_assignement?(node)
31
+
32
+ add_offense(node)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -18,6 +18,8 @@ module RuboCop
18
18
  # ActiveRecord::Relation vs a call to pluck on an
19
19
  # ActiveRecord::Associations::CollectionProxy.
20
20
  #
21
+ # This cop is unsafe because the behavior may change depending on the
22
+ # database collation.
21
23
  # Autocorrect is disabled by default for this cop since it may generate
22
24
  # false positives.
23
25
  #
@@ -43,11 +45,13 @@ module RuboCop
43
45
  # # good
44
46
  # Model.distinct.pluck(:id)
45
47
  #
46
- class UniqBeforePluck < RuboCop::Cop::Cop
48
+ class UniqBeforePluck < Base
47
49
  include ConfigurableEnforcedStyle
48
50
  include RangeHelp
51
+ extend AutoCorrector
49
52
 
50
53
  MSG = 'Use `distinct` before `pluck`.'
54
+ RESTRICT_ON_SEND = %i[uniq distinct pluck].freeze
51
55
  NEWLINE = "\n"
52
56
  PATTERN = '[!^block (send (send %<type>s :pluck ...) ' \
53
57
  '${:uniq :distinct} ...)]'
@@ -67,11 +71,7 @@ module RuboCop
67
71
 
68
72
  return unless method
69
73
 
70
- add_offense(node, location: :selector)
71
- end
72
-
73
- def autocorrect(node)
74
- lambda do |corrector|
74
+ add_offense(node.loc.selector) do |corrector|
75
75
  method = node.method_name
76
76
 
77
77
  corrector.remove(dot_method_with_whitespace(method, node))
@@ -24,33 +24,37 @@ module RuboCop
24
24
  # # good - even if the schema does not have a unique index
25
25
  # validates :account, length: { minimum: MIN_LENGTH }
26
26
  #
27
- class UniqueValidationWithoutIndex < Cop
27
+ class UniqueValidationWithoutIndex < Base
28
28
  include ActiveRecordHelper
29
29
 
30
30
  MSG = 'Uniqueness validation should be with a unique index.'
31
+ RESTRICT_ON_SEND = %i[validates].freeze
31
32
 
32
33
  def on_send(node)
33
- return unless node.method?(:validates)
34
34
  return unless uniqueness_part(node)
35
35
  return if condition_part?(node)
36
36
  return unless schema
37
- return if with_index?(node)
37
+
38
+ klass, table, names = find_schema_information(node)
39
+ return unless names
40
+ return if with_index?(klass, table, names)
38
41
 
39
42
  add_offense(node)
40
43
  end
41
44
 
42
45
  private
43
46
 
44
- def with_index?(node)
47
+ def find_schema_information(node)
45
48
  klass = class_node(node)
46
- return true unless klass # Skip analysis
49
+ return unless klass
47
50
 
48
51
  table = schema.table_by(name: table_name(klass))
49
- return true unless table # Skip analysis if it can't find the table
50
-
51
52
  names = column_names(node)
52
- return true unless names
53
53
 
54
+ [klass, table, names]
55
+ end
56
+
57
+ def with_index?(klass, table, names)
54
58
  # Compatibility for Rails 4.2.
55
59
  add_indicies = schema.add_indicies_by(table_name: table_name(klass))
56
60
 
@@ -95,6 +99,8 @@ module RuboCop
95
99
  scope = find_scope(uniq)
96
100
  return unless scope
97
101
 
102
+ scope = unfreeze_scope(scope)
103
+
98
104
  case scope.type
99
105
  when :sym, :str
100
106
  [scope.value]
@@ -112,6 +118,10 @@ module RuboCop
112
118
  end
113
119
  end
114
120
 
121
+ def unfreeze_scope(scope)
122
+ scope.send_type? && scope.method?(:freeze) ? scope.children.first : scope
123
+ end
124
+
115
125
  def class_node(node)
116
126
  node.each_ancestor.find(&:class_type?)
117
127
  end
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # # good
18
18
  # Rails.env.production?
19
19
  # Rails.env == 'production'
20
- class UnknownEnv < Cop
20
+ class UnknownEnv < Base
21
21
  MSG = 'Unknown environment `%<name>s`.'
22
22
  MSG_SIMILAR = 'Unknown environment `%<name>s`. ' \
23
23
  'Did you mean `%<similar>s`?'
@@ -41,7 +41,7 @@ module RuboCop
41
41
 
42
42
  def on_send(node)
43
43
  unknown_environment_predicate?(node) do |name|
44
- add_offense(node, location: :selector, message: message(name))
44
+ add_offense(node.loc.selector, message: message(name))
45
45
  end
46
46
 
47
47
  unknown_environment_equal?(node) do |str_node|
@@ -62,7 +62,7 @@ module RuboCop
62
62
  # DidYouMean::SpellChecker is not available in all versions of Ruby,
63
63
  # and even on versions where it *is* available (>= 2.3), it is not
64
64
  # always required correctly. So we do a feature check first. See:
65
- # https://github.com/rubocop-hq/rubocop/issues/7979
65
+ # https://github.com/rubocop/rubocop/issues/7979
66
66
  similar_names = if defined?(DidYouMean::SpellChecker)
67
67
  spell_checker = DidYouMean::SpellChecker.new(dictionary: environments)
68
68
  spell_checker.correct(name)