rubocop 1.31.2 → 1.32.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +23 -0
  4. data/lib/rubocop/cli.rb +1 -0
  5. data/lib/rubocop/config.rb +1 -1
  6. data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +7 -1
  7. data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +57 -13
  8. data/lib/rubocop/cop/layout/line_length.rb +2 -0
  9. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -1
  10. data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +45 -0
  11. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -0
  12. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +10 -4
  13. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +55 -24
  14. data/lib/rubocop/cop/lint/number_conversion.rb +7 -1
  15. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +7 -0
  16. data/lib/rubocop/cop/lint/require_range_parentheses.rb +57 -0
  17. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +35 -1
  18. data/lib/rubocop/cop/metrics/block_length.rb +1 -0
  19. data/lib/rubocop/cop/metrics/method_length.rb +1 -0
  20. data/lib/rubocop/cop/mixin/check_line_breakable.rb +4 -0
  21. data/lib/rubocop/cop/mixin/percent_array.rb +60 -1
  22. data/lib/rubocop/cop/naming/predicate_name.rb +8 -0
  23. data/lib/rubocop/cop/style/class_equality_comparison.rb +22 -0
  24. data/lib/rubocop/cop/style/empty_else.rb +37 -0
  25. data/lib/rubocop/cop/style/empty_heredoc.rb +59 -0
  26. data/lib/rubocop/cop/style/fetch_env_var.rb +10 -177
  27. data/lib/rubocop/cop/style/format_string_token.rb +6 -0
  28. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  29. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +12 -0
  30. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +9 -0
  31. data/lib/rubocop/cop/style/numeric_predicate.rb +20 -6
  32. data/lib/rubocop/cop/style/semicolon.rb +27 -3
  33. data/lib/rubocop/cop/style/symbol_array.rb +2 -3
  34. data/lib/rubocop/cop/style/symbol_proc.rb +9 -1
  35. data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -0
  36. data/lib/rubocop/cop/style/trivial_accessors.rb +3 -0
  37. data/lib/rubocop/cop/style/word_array.rb +2 -3
  38. data/lib/rubocop/options.rb +3 -6
  39. data/lib/rubocop/rspec/shared_contexts.rb +14 -14
  40. data/lib/rubocop/rspec/support.rb +14 -0
  41. data/lib/rubocop/runner.rb +4 -0
  42. data/lib/rubocop/server/client_command/base.rb +1 -1
  43. data/lib/rubocop/version.rb +1 -1
  44. data/lib/rubocop.rb +3 -0
  45. metadata +8 -5
@@ -46,6 +46,8 @@ module RuboCop
46
46
  if node.send_type?
47
47
  args = process_args(node.arguments)
48
48
  return extract_breakable_node_from_elements(node, args, max)
49
+ elsif node.def_type?
50
+ return extract_breakable_node_from_elements(node, node.arguments, max)
49
51
  elsif node.array_type? || node.hash_type?
50
52
  return extract_breakable_node_from_elements(node, node.children, max)
51
53
  end
@@ -216,6 +218,8 @@ module RuboCop
216
218
 
217
219
  # @api private
218
220
  def already_on_multiple_lines?(node)
221
+ return node.first_line != node.arguments.last.last_line if node.def_type?
222
+
219
223
  node.first_line != node.last_line
220
224
  end
221
225
  end
@@ -44,13 +44,26 @@ module RuboCop
44
44
  no_acceptable_style! if brackets_required
45
45
 
46
46
  bracketed_array = build_bracketed_array(node)
47
- message = format(self.class::ARRAY_MSG, prefer: bracketed_array)
47
+ message = build_message_for_bracketed_array(bracketed_array)
48
48
 
49
49
  add_offense(node, message: message) do |corrector|
50
50
  corrector.replace(node, bracketed_array)
51
51
  end
52
52
  end
53
53
 
54
+ # @param [String] preferred_array_code
55
+ # @return [String]
56
+ def build_message_for_bracketed_array(preferred_array_code)
57
+ format(
58
+ self.class::ARRAY_MSG,
59
+ prefer: if preferred_array_code.include?("\n")
60
+ 'an array literal `[...]`'
61
+ else
62
+ "`#{preferred_array_code}`"
63
+ end
64
+ )
65
+ end
66
+
54
67
  def check_bracketed_array(node, literal_prefix)
55
68
  return if allowed_bracket_array?(node)
56
69
 
@@ -63,6 +76,52 @@ module RuboCop
63
76
  percent_literal_corrector.correct(corrector, node, literal_prefix)
64
77
  end
65
78
  end
79
+
80
+ # @param [RuboCop::AST::ArrayNode] node
81
+ # @param [Array<String>] elements
82
+ # @return [String]
83
+ def build_bracketed_array_with_appropriate_whitespace(elements:, node:)
84
+ [
85
+ '[',
86
+ whitespace_leading(node),
87
+ elements.join(",#{whitespace_between(node)}"),
88
+ whitespace_trailing(node),
89
+ ']'
90
+ ].join
91
+ end
92
+
93
+ # Provides whitespace between elements for building a bracketed array.
94
+ # %w[ a b c ]
95
+ # ^^^
96
+ # @param [RuboCop::AST::ArrayNode] node
97
+ # @return [String]
98
+ def whitespace_between(node)
99
+ if node.children.length >= 2
100
+ node.source[
101
+ node.children[0].loc.expression.end_pos...node.children[1].loc.expression.begin_pos
102
+ ]
103
+ else
104
+ ' '
105
+ end
106
+ end
107
+
108
+ # Provides leading whitespace for building a bracketed array.
109
+ # %w[ a b c ]
110
+ # ^^
111
+ # @param [RuboCop::AST::ArrayNode] node
112
+ # @return [String]
113
+ def whitespace_leading(node)
114
+ node.source[node.loc.begin.end_pos...node.children[0].loc.expression.begin_pos]
115
+ end
116
+
117
+ # Provides trailing whitespace for building a bracketed array.
118
+ # %w[ a b c ]
119
+ # ^^^^
120
+ # @param [RuboCop::AST::ArrayNode] node
121
+ # @return [String]
122
+ def whitespace_trailing(node)
123
+ node.source[node.children[-1].loc.expression.end_pos...node.loc.end.begin_pos]
124
+ end
66
125
  end
67
126
  end
68
127
  end
@@ -4,6 +4,8 @@ module RuboCop
4
4
  module Cop
5
5
  module Naming
6
6
  # Makes sure that predicates are named properly.
7
+ # `is_a?` method is allowed by default.
8
+ # These are customizable with `AllowedMethods` option.
7
9
  #
8
10
  # @example
9
11
  # # bad
@@ -27,6 +29,12 @@ module RuboCop
27
29
  # # good
28
30
  # def value?
29
31
  # end
32
+ #
33
+ # @example AllowedMethods: ['is_a?'] (default)
34
+ # # good
35
+ # def is_a?(value)
36
+ # end
37
+ #
30
38
  class PredicateName < Base
31
39
  include AllowedMethods
32
40
 
@@ -5,6 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # Enforces the use of `Object#instance_of?` instead of class comparison
7
7
  # for equality.
8
+ # `==`, `equal?`, and `eql?` methods are ignored by default.
9
+ # These are customizable with `IgnoredMethods` option.
8
10
  #
9
11
  # @example
10
12
  # # bad
@@ -16,6 +18,26 @@ module RuboCop
16
18
  # # good
17
19
  # var.instance_of?(Date)
18
20
  #
21
+ # @example IgnoreMethods: [] (default)
22
+ # # good
23
+ # var.instance_of?(Date)
24
+ #
25
+ # # bad
26
+ # var.class == Date
27
+ # var.class.equal?(Date)
28
+ # var.class.eql?(Date)
29
+ # var.class.name == 'Date'
30
+ #
31
+ # @example IgnoreMethods: [`==`]
32
+ # # good
33
+ # var.instance_of?(Date)
34
+ # var.class == Date
35
+ # var.class.name == 'Date'
36
+ #
37
+ # # bad
38
+ # var.class.equal?(Date)
39
+ # var.class.eql?(Date)
40
+ #
19
41
  class ClassEqualityComparison < Base
20
42
  include RangeHelp
21
43
  include IgnoredMethods
@@ -89,6 +89,41 @@ module RuboCop
89
89
  # if condition
90
90
  # statement
91
91
  # end
92
+ #
93
+ # @example AllowComments: false (default)
94
+ #
95
+ # # bad
96
+ # if condition
97
+ # statement
98
+ # else
99
+ # # something comment
100
+ # nil
101
+ # end
102
+ #
103
+ # # bad
104
+ # if condition
105
+ # statement
106
+ # else
107
+ # # something comment
108
+ # end
109
+ #
110
+ # @example AllowComments: true
111
+ #
112
+ # # good
113
+ # if condition
114
+ # statement
115
+ # else
116
+ # # something comment
117
+ # nil
118
+ # end
119
+ #
120
+ # # good
121
+ # if condition
122
+ # statement
123
+ # else
124
+ # # something comment
125
+ # end
126
+ #
92
127
  class EmptyElse < Base
93
128
  include OnNormalIfUnless
94
129
  include ConfigurableEnforcedStyle
@@ -108,6 +143,8 @@ module RuboCop
108
143
  private
109
144
 
110
145
  def check(node)
146
+ return if cop_config['AllowComments'] && comment_in_else?(node.loc)
147
+
111
148
  empty_check(node) if empty_style?
112
149
  nil_check(node) if nil_style?
113
150
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Checks for using empty heredoc to reduce redundancy.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # <<~EOS
12
+ # EOS
13
+ #
14
+ # <<-EOS
15
+ # EOS
16
+ #
17
+ # <<EOS
18
+ # EOS
19
+ #
20
+ # # good
21
+ # ''
22
+ #
23
+ # # bad
24
+ # do_something(<<~EOS)
25
+ # EOS
26
+ #
27
+ # do_something(<<-EOS)
28
+ # EOS
29
+ #
30
+ # do_something(<<EOS)
31
+ # EOS
32
+ #
33
+ # # good
34
+ # do_something('')
35
+ #
36
+ class EmptyHeredoc < Base
37
+ include Heredoc
38
+ include RangeHelp
39
+ extend AutoCorrector
40
+
41
+ MSG = 'Use an empty string literal instead of heredoc.'
42
+
43
+ def on_heredoc(node)
44
+ heredoc_body = node.loc.heredoc_body
45
+
46
+ return unless heredoc_body.source.empty?
47
+
48
+ add_offense(node) do |corrector|
49
+ heredoc_end = node.loc.heredoc_end
50
+
51
+ corrector.replace(node, "''")
52
+ corrector.remove(range_by_whole_lines(heredoc_body, include_final_newline: true))
53
+ corrector.remove(range_by_whole_lines(heredoc_end, include_final_newline: true))
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -9,32 +9,15 @@ module RuboCop
9
9
  # On the other hand, `ENV.fetch` raises KeyError or returns the explicitly
10
10
  # specified default value.
11
11
  #
12
- # When an `ENV[]` is the LHS of `||`, the autocorrect makes the RHS
13
- # the default value of `ENV.fetch`.
14
- #
15
12
  # @example
16
13
  # # bad
17
14
  # ENV['X']
18
- # ENV['X'] || 'string literal'
19
- # ENV['X'] || some_method
20
15
  # x = ENV['X']
21
16
  #
22
- # ENV['X'] || y.map do |a|
23
- # puts a * 2
24
- # end
25
- #
26
17
  # # good
27
18
  # ENV.fetch('X')
28
- # ENV.fetch('X', 'string literal')
29
- # ENV.fetch('X') { some_method }
30
19
  # x = ENV.fetch('X')
31
20
  #
32
- # ENV.fetch('X') do
33
- # y.map do |a|
34
- # puts a * 2
35
- # end
36
- # end
37
- #
38
21
  # # also good
39
22
  # !ENV['X']
40
23
  # ENV['X'].some_method # (e.g. `.nil?`)
@@ -42,48 +25,20 @@ module RuboCop
42
25
  class FetchEnvVar < Base
43
26
  extend AutoCorrector
44
27
 
45
- # rubocop:disable Layout/LineLength
46
- MSG_DEFAULT_NIL = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
47
- MSG_DEFAULT_RHS_SECOND_ARG_OF_FETCH = 'Use `ENV.fetch(%<key>s, %<default>s)` instead of `ENV[%<key>s] || %<default>s`.'
48
- MSG_DEFAULT_RHS_SINGLE_LINE_BLOCK = 'Use `ENV.fetch(%<key>s) { %<default>s }` instead of `ENV[%<key>s] || %<default>s`.'
49
- MSG_DEFAULT_RHS_MULTILINE_BLOCK = 'Use `ENV.fetch(%<key>s)` with a block containing `%<default>s ...`'
50
- # rubocop:enable Layout/LineLength
28
+ MSG = 'Use `ENV.fetch(%<key>s)` or `ENV.fetch(%<key>s, nil)` instead of `ENV[%<key>s]`.'
51
29
 
52
30
  # @!method env_with_bracket?(node)
53
31
  def_node_matcher :env_with_bracket?, <<~PATTERN
54
32
  (send (const nil? :ENV) :[] $_)
55
33
  PATTERN
56
34
 
57
- # @!method operand_of_or?(node)
58
- def_node_matcher :operand_of_or?, <<~PATTERN
59
- (^or ...)
60
- PATTERN
61
-
62
- # @!method block_control?(node)
63
- def_node_matcher :block_control?, <<~PATTERN
64
- ({next | break | retry | redo})
65
- PATTERN
66
-
67
- # @!method offensive_nodes(node)
68
- def_node_search :offensive_nodes, <<~PATTERN
69
- [#env_with_bracket? #offensive?]
70
- PATTERN
71
-
72
35
  def on_send(node)
73
36
  env_with_bracket?(node) do |name_node|
74
37
  break unless offensive?(node)
75
38
 
76
- if operand_of_or?(node)
77
- target_node = offensive_nodes(or_chain_root(node)).to_a.last
78
- target_name_node = env_with_bracket?(target_node)
79
-
80
- if default_to_rhs?(target_node)
81
- default_rhs(target_node, target_name_node)
82
- else
83
- default_nil(target_node, target_name_node)
84
- end
85
- else
86
- default_nil(node, name_node)
39
+ message = format(MSG, key: name_node.source)
40
+ add_offense(node, message: message) do |corrector|
41
+ corrector.replace(node, new_code(name_node))
87
42
  end
88
43
  end
89
44
  end
@@ -130,17 +85,6 @@ module RuboCop
130
85
  !(allowed_var?(node) || allowable_use?(node))
131
86
  end
132
87
 
133
- def or_chain_root(node)
134
- while operand_of_or?(ancestor_or ||= node.parent)
135
- ancestor_or = ancestor_or.parent
136
- end
137
- ancestor_or
138
- end
139
-
140
- def default_to_rhs?(node)
141
- operand_of_or?(node) && !right_end_of_or_chains?(node) && rhs_can_be_default_value?(node)
142
- end
143
-
144
88
  # Check if the node is a receiver and receives a message with dot syntax.
145
89
  def message_chained_with_dot?(node)
146
90
  return false if node.root?
@@ -157,8 +101,9 @@ module RuboCop
157
101
  # it simply checks whether the variable is set.
158
102
  # - Receiving a message with dot syntax, e.g. `ENV['X'].nil?`.
159
103
  # - `ENV['key']` assigned by logical AND/OR assignment.
104
+ # - `ENV['key']` is the LHS of a `||`.
160
105
  def allowable_use?(node)
161
- used_as_flag?(node) || message_chained_with_dot?(node) || assigned?(node)
106
+ used_as_flag?(node) || message_chained_with_dot?(node) || assigned?(node) || or_lhs?(node)
162
107
  end
163
108
 
164
109
  # The following are allowed cases:
@@ -172,127 +117,15 @@ module RuboCop
172
117
  node == lhs
173
118
  end
174
119
 
175
- def left_end_of_or_chains?(node)
176
- return false unless operand_of_or?(node)
177
-
178
- node.parent.lhs == node
179
- end
180
-
181
- def right_end_of_or_chains?(node)
182
- !(left_end_of_or_chains?(node) || node.parent&.parent&.or_type?)
183
- end
184
-
185
- def conterpart_rhs_of(node)
186
- left_end_of_or_chains?(node) ? node.parent.rhs : node.parent.parent.rhs
187
- end
188
-
189
- def rhs_can_be_default_value?(node)
190
- !rhs_is_block_control?(node)
191
- end
120
+ def or_lhs?(node)
121
+ return false unless (parent = node.parent)&.or_type?
192
122
 
193
- def rhs_is_block_control?(node)
194
- block_control?(conterpart_rhs_of(node))
123
+ parent.lhs == node || parent.parent&.or_type?
195
124
  end
196
125
 
197
- def new_code_default_nil(name_node)
126
+ def new_code(name_node)
198
127
  "ENV.fetch(#{name_node.source}, nil)"
199
128
  end
200
-
201
- def new_code_default_rhs_single_line(node, name_node)
202
- parent = node.parent
203
- if parent.rhs.basic_literal?
204
- "ENV.fetch(#{name_node.source}, #{parent.rhs.source})"
205
- else
206
- "ENV.fetch(#{name_node.source}) { #{parent.rhs.source} }"
207
- end
208
- end
209
-
210
- def new_code_default_rhs_multiline(node, name_node)
211
- env_indent = indent(node.parent)
212
- default = node.parent.rhs.source.split("\n").map do |line|
213
- "#{env_indent}#{line}"
214
- end.join("\n")
215
- <<~NEW_CODE.chomp
216
- ENV.fetch(#{name_node.source}) do
217
- #{configured_indentation}#{default}
218
- #{env_indent}end
219
- NEW_CODE
220
- end
221
-
222
- def new_code_default_rhs(node, name_node)
223
- if node.parent.rhs.single_line?
224
- new_code_default_rhs_single_line(node, name_node)
225
- else
226
- new_code_default_rhs_multiline(node, name_node)
227
- end
228
- end
229
-
230
- def default_rhs(node, name_node)
231
- if left_end_of_or_chains?(node)
232
- default_rhs_in_same_or(node, name_node)
233
- else
234
- default_rhs_in_outer_or(node, name_node)
235
- end
236
- end
237
-
238
- # Adds an offense and sets `nil` to the default value of `ENV.fetch`.
239
- # `ENV['X']` --> `ENV.fetch('X', nil)`
240
- def default_nil(node, name_node)
241
- message = format(MSG_DEFAULT_NIL, key: name_node.source)
242
-
243
- add_offense(node, message: message) do |corrector|
244
- corrector.replace(node, new_code_default_nil(name_node))
245
- end
246
- end
247
-
248
- # Adds an offense and makes the RHS the default value of `ENV.fetch`.
249
- # `ENV['X'] || y` --> `ENV.fetch('X') { y }`
250
- def default_rhs_in_same_or(node, name_node)
251
- template = message_template_for(node.parent.rhs)
252
- message = format(template,
253
- key: name_node.source,
254
- default: first_line_of(node.parent.rhs.source))
255
-
256
- add_offense(node, message: message) do |corrector|
257
- corrector.replace(node.parent, new_code_default_rhs(node, name_node))
258
- end
259
- end
260
-
261
- # Adds an offense and makes the RHS the default value of `ENV.fetch`.
262
- # `z || ENV['X'] || y` --> `z || ENV.fetch('X') { y }`
263
- def default_rhs_in_outer_or(node, name_node)
264
- parent = node.parent
265
- grand_parent = parent.parent
266
-
267
- template = message_template_for(grand_parent.rhs)
268
- message = format(template,
269
- key: name_node.source,
270
- default: first_line_of(grand_parent.rhs.source))
271
-
272
- add_offense(node, message: message) do |corrector|
273
- lhs_code = parent.lhs.source
274
- rhs_code = new_code_default_rhs(parent, name_node)
275
- corrector.replace(grand_parent, "#{lhs_code} || #{rhs_code}")
276
- end
277
- end
278
-
279
- def message_template_for(rhs)
280
- if rhs.multiline?
281
- MSG_DEFAULT_RHS_MULTILINE_BLOCK
282
- elsif rhs.basic_literal?
283
- MSG_DEFAULT_RHS_SECOND_ARG_OF_FETCH
284
- else
285
- MSG_DEFAULT_RHS_SINGLE_LINE_BLOCK
286
- end
287
- end
288
-
289
- def configured_indentation
290
- ' ' * (config.for_cop('Layout/IndentationWidth')['Width'] || 2)
291
- end
292
-
293
- def first_line_of(source)
294
- source.split("\n").first
295
- end
296
129
  end
297
130
  end
298
131
  end
@@ -12,6 +12,7 @@ module RuboCop
12
12
  # to encoded URLs or Date/Time formatting strings.
13
13
  #
14
14
  # This cop can be customized ignored methods with `IgnoredMethods`.
15
+ # By default, there are no methods to ignored.
15
16
  #
16
17
  # @example EnforcedStyle: annotated (default)
17
18
  #
@@ -61,6 +62,11 @@ module RuboCop
61
62
  # # good
62
63
  # format('%06d', 10)
63
64
  #
65
+ # @example IgnoredMethods: [] (default)
66
+ #
67
+ # # bad
68
+ # redirect('foo/%{bar_id}')
69
+ #
64
70
  # @example IgnoredMethods: [redirect]
65
71
  #
66
72
  # # good
@@ -6,6 +6,8 @@ module RuboCop
6
6
  # Checks for redundant `if` with boolean literal branches.
7
7
  # It checks only conditions to return boolean value (`true` or `false`) for safe detection.
8
8
  # The conditions to be checked are comparison methods, predicate methods, and double negative.
9
+ # `nonzero?` method is allowed by default.
10
+ # These are customizable with `AllowedMethods` option.
9
11
  #
10
12
  # @safety
11
13
  # Autocorrection is unsafe because there is no guarantee that all predicate methods
@@ -5,12 +5,24 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for unwanted parentheses in parameterless method calls.
7
7
  #
8
+ # This cop can be customized ignored methods with `IgnoredMethods`.
9
+ # By default, there are no methods to ignored.
10
+ #
8
11
  # @example
9
12
  # # bad
10
13
  # object.some_method()
11
14
  #
12
15
  # # good
13
16
  # object.some_method
17
+ #
18
+ # @example IgnoredMethods: [] (default)
19
+ # # bad
20
+ # object.foo()
21
+ #
22
+ # @example IgnoredMethods: [foo]
23
+ # # good
24
+ # object.foo()
25
+ #
14
26
  class MethodCallWithoutArgsParentheses < Base
15
27
  include IgnoredMethods
16
28
  extend AutoCorrector
@@ -5,6 +5,10 @@ module RuboCop
5
5
  module Style
6
6
  # Checks for unparenthesized method calls in the argument list
7
7
  # of a parenthesized method call.
8
+ # `be`, `be_a`, `be_an`, `be_between`, `be_falsey`, `be_kind_of`, `be_instance_of`,
9
+ # `be_truthy`, `be_within`, `eq`, `eql`, `end_with`, `include`, `match`, `raise_error`,
10
+ # `respond_to`, and `start_with` methods are allowed by default.
11
+ # These are customizable with `AllowedMethods` option.
8
12
  #
9
13
  # @example
10
14
  # # good
@@ -12,6 +16,11 @@ module RuboCop
12
16
  #
13
17
  # # bad
14
18
  # method1(method2 arg)
19
+ #
20
+ # @example AllowedMethods: [foo]
21
+ # # good
22
+ # method1(foo arg)
23
+ #
15
24
  class NestedParenthesizedCalls < Base
16
25
  include RangeHelp
17
26
  include AllowedMethods
@@ -6,13 +6,16 @@ module RuboCop
6
6
  # Checks for usage of comparison operators (`==`,
7
7
  # `>`, `<`) to test numbers as zero, positive, or negative.
8
8
  # These can be replaced by their respective predicate methods.
9
- # The cop can also be configured to do the reverse.
9
+ # This cop can also be configured to do the reverse.
10
10
  #
11
- # The cop disregards `#nonzero?` as its value is truthy or falsey,
11
+ # This cop can be customized ignored methods with `IgnoredMethods`.
12
+ # By default, there are no methods to ignored.
13
+ #
14
+ # This cop disregards `#nonzero?` as its value is truthy or falsey,
12
15
  # but not `true` and `false`, and thus not always interchangeable with
13
16
  # `!= 0`.
14
17
  #
15
- # The cop ignores comparisons to global variables, since they are often
18
+ # This cop ignores comparisons to global variables, since they are often
16
19
  # populated with objects which can be compared with integers, but are
17
20
  # not themselves `Integer` polymorphic.
18
21
  #
@@ -23,29 +26,40 @@ module RuboCop
23
26
  #
24
27
  # @example EnforcedStyle: predicate (default)
25
28
  # # bad
26
- #
27
29
  # foo == 0
28
30
  # 0 > foo
29
31
  # bar.baz > 0
30
32
  #
31
33
  # # good
32
- #
33
34
  # foo.zero?
34
35
  # foo.negative?
35
36
  # bar.baz.positive?
36
37
  #
37
38
  # @example EnforcedStyle: comparison
38
39
  # # bad
39
- #
40
40
  # foo.zero?
41
41
  # foo.negative?
42
42
  # bar.baz.positive?
43
43
  #
44
44
  # # good
45
+ # foo == 0
46
+ # 0 > foo
47
+ # bar.baz > 0
48
+ #
49
+ # @example IgnoredMethods: [] (default) with EnforcedStyle: predicate
50
+ # # bad
51
+ # foo == 0
52
+ # 0 > foo
53
+ # bar.baz > 0
45
54
  #
55
+ # @example IgnoredMethods: [==] with EnforcedStyle: predicate
56
+ # # good
46
57
  # foo == 0
58
+ #
59
+ # # bad
47
60
  # 0 > foo
48
61
  # bar.baz > 0
62
+ #
49
63
  class NumericPredicate < Base
50
64
  include ConfigurableEnforcedStyle
51
65
  include IgnoredMethods