rubocop 0.83.0 → 0.84.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +20 -3
  4. data/lib/rubocop.rb +6 -59
  5. data/lib/rubocop/ast_aliases.rb +8 -0
  6. data/lib/rubocop/cli/command/show_cops.rb +2 -6
  7. data/lib/rubocop/config.rb +1 -3
  8. data/lib/rubocop/config_loader.rb +3 -9
  9. data/lib/rubocop/config_loader_resolver.rb +2 -6
  10. data/lib/rubocop/cop/autocorrect_logic.rb +1 -2
  11. data/lib/rubocop/cop/corrector.rb +1 -3
  12. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -6
  13. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +1 -3
  14. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -3
  15. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -3
  16. data/lib/rubocop/cop/generator.rb +1 -1
  17. data/lib/rubocop/cop/ignored_node.rb +1 -3
  18. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -6
  19. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +62 -4
  20. data/lib/rubocop/cop/layout/first_argument_indentation.rb +0 -2
  21. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -3
  22. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -3
  23. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -6
  24. data/lib/rubocop/cop/layout/indentation_width.rb +1 -3
  25. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -3
  26. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -3
  27. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +2 -6
  28. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -3
  29. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +1 -3
  30. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -6
  31. data/lib/rubocop/cop/lint/ambiguous_operator.rb +4 -2
  32. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +133 -0
  33. data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -6
  34. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +11 -3
  35. data/lib/rubocop/cop/lint/percent_string_array.rb +1 -3
  36. data/lib/rubocop/cop/lint/suppressed_exception.rb +12 -1
  37. data/lib/rubocop/cop/lint/syntax.rb +1 -3
  38. data/lib/rubocop/cop/lint/useless_access_modifier.rb +1 -3
  39. data/lib/rubocop/cop/migration/department_name.rb +5 -9
  40. data/lib/rubocop/cop/mixin/alignment.rb +1 -3
  41. data/lib/rubocop/cop/mixin/array_min_size.rb +2 -6
  42. data/lib/rubocop/cop/mixin/check_line_breakable.rb +4 -12
  43. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -3
  44. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -3
  45. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -3
  46. data/lib/rubocop/cop/mixin/surrounding_space.rb +1 -3
  47. data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -3
  48. data/lib/rubocop/cop/naming/file_name.rb +1 -3
  49. data/lib/rubocop/cop/registry.rb +2 -6
  50. data/lib/rubocop/cop/severity.rb +1 -3
  51. data/lib/rubocop/cop/style/and_or.rb +2 -2
  52. data/lib/rubocop/cop/style/attr.rb +1 -3
  53. data/lib/rubocop/cop/style/block_delimiters.rb +2 -8
  54. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -3
  55. data/lib/rubocop/cop/style/double_negation.rb +41 -4
  56. data/lib/rubocop/cop/style/empty_literal.rb +1 -3
  57. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -4
  58. data/lib/rubocop/cop/style/hash_syntax.rb +12 -5
  59. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +1 -3
  60. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -3
  61. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -6
  62. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -6
  63. data/lib/rubocop/cop/style/safe_navigation.rb +2 -6
  64. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  65. data/lib/rubocop/cop/style/special_global_vars.rb +2 -6
  66. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -3
  67. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +2 -6
  68. data/lib/rubocop/cop/variable_force.rb +3 -9
  69. data/lib/rubocop/cop/variable_force/branch.rb +2 -6
  70. data/lib/rubocop/cop/variable_force/variable.rb +2 -6
  71. data/lib/rubocop/ext/processed_source.rb +18 -0
  72. data/lib/rubocop/formatter/base_formatter.rb +0 -4
  73. data/lib/rubocop/formatter/disabled_config_formatter.rb +4 -12
  74. data/lib/rubocop/formatter/formatter_set.rb +1 -3
  75. data/lib/rubocop/options.rb +2 -8
  76. data/lib/rubocop/remote_config.rb +1 -3
  77. data/lib/rubocop/result_cache.rb +1 -3
  78. data/lib/rubocop/rspec/cop_helper.rb +1 -3
  79. data/lib/rubocop/rspec/expect_offense.rb +3 -9
  80. data/lib/rubocop/rspec/shared_contexts.rb +54 -16
  81. data/lib/rubocop/runner.rb +8 -10
  82. data/lib/rubocop/target_finder.rb +2 -6
  83. data/lib/rubocop/version.rb +5 -3
  84. metadata +19 -56
  85. data/lib/rubocop/ast/builder.rb +0 -85
  86. data/lib/rubocop/ast/node.rb +0 -637
  87. data/lib/rubocop/ast/node/alias_node.rb +0 -24
  88. data/lib/rubocop/ast/node/and_node.rb +0 -29
  89. data/lib/rubocop/ast/node/args_node.rb +0 -29
  90. data/lib/rubocop/ast/node/array_node.rb +0 -70
  91. data/lib/rubocop/ast/node/block_node.rb +0 -121
  92. data/lib/rubocop/ast/node/break_node.rb +0 -17
  93. data/lib/rubocop/ast/node/case_match_node.rb +0 -56
  94. data/lib/rubocop/ast/node/case_node.rb +0 -56
  95. data/lib/rubocop/ast/node/class_node.rb +0 -31
  96. data/lib/rubocop/ast/node/def_node.rb +0 -82
  97. data/lib/rubocop/ast/node/defined_node.rb +0 -17
  98. data/lib/rubocop/ast/node/ensure_node.rb +0 -17
  99. data/lib/rubocop/ast/node/float_node.rb +0 -12
  100. data/lib/rubocop/ast/node/for_node.rb +0 -53
  101. data/lib/rubocop/ast/node/forward_args_node.rb +0 -18
  102. data/lib/rubocop/ast/node/hash_node.rb +0 -109
  103. data/lib/rubocop/ast/node/if_node.rb +0 -175
  104. data/lib/rubocop/ast/node/int_node.rb +0 -12
  105. data/lib/rubocop/ast/node/keyword_splat_node.rb +0 -45
  106. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +0 -16
  107. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +0 -43
  108. data/lib/rubocop/ast/node/mixin/collection_node.rb +0 -15
  109. data/lib/rubocop/ast/node/mixin/conditional_node.rb +0 -45
  110. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +0 -125
  111. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -269
  112. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +0 -114
  113. data/lib/rubocop/ast/node/mixin/modifier_node.rb +0 -17
  114. data/lib/rubocop/ast/node/mixin/numeric_node.rb +0 -21
  115. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +0 -61
  116. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +0 -35
  117. data/lib/rubocop/ast/node/module_node.rb +0 -24
  118. data/lib/rubocop/ast/node/or_node.rb +0 -29
  119. data/lib/rubocop/ast/node/pair_node.rb +0 -63
  120. data/lib/rubocop/ast/node/range_node.rb +0 -18
  121. data/lib/rubocop/ast/node/regexp_node.rb +0 -33
  122. data/lib/rubocop/ast/node/resbody_node.rb +0 -24
  123. data/lib/rubocop/ast/node/retry_node.rb +0 -17
  124. data/lib/rubocop/ast/node/return_node.rb +0 -24
  125. data/lib/rubocop/ast/node/self_class_node.rb +0 -24
  126. data/lib/rubocop/ast/node/send_node.rb +0 -17
  127. data/lib/rubocop/ast/node/str_node.rb +0 -16
  128. data/lib/rubocop/ast/node/super_node.rb +0 -21
  129. data/lib/rubocop/ast/node/symbol_node.rb +0 -12
  130. data/lib/rubocop/ast/node/until_node.rb +0 -35
  131. data/lib/rubocop/ast/node/when_node.rb +0 -53
  132. data/lib/rubocop/ast/node/while_node.rb +0 -35
  133. data/lib/rubocop/ast/node/yield_node.rb +0 -21
  134. data/lib/rubocop/ast/sexp.rb +0 -16
  135. data/lib/rubocop/ast/traversal.rb +0 -202
  136. data/lib/rubocop/node_pattern.rb +0 -887
  137. data/lib/rubocop/processed_source.rb +0 -213
  138. data/lib/rubocop/token.rb +0 -114
@@ -167,9 +167,7 @@ module RuboCop
167
167
  checked_variable, matching_receiver, method =
168
168
  extract_common_parts(receiver, variable)
169
169
 
170
- if receiver && LOGIC_JUMP_KEYWORDS.include?(receiver.type)
171
- matching_receiver = nil
172
- end
170
+ matching_receiver = nil if receiver && LOGIC_JUMP_KEYWORDS.include?(receiver.type)
173
171
 
174
172
  [checked_variable, matching_receiver, receiver, method]
175
173
  end
@@ -221,9 +219,7 @@ module RuboCop
221
219
  return true if unsafe_method?(method)
222
220
 
223
221
  method.each_ancestor(:send).any? do |ancestor|
224
- unless config.for_cop('Lint/SafeNavigationChain')['Enabled']
225
- break true
226
- end
222
+ break true unless config.for_cop('Lint/SafeNavigationChain')['Enabled']
227
223
 
228
224
  break true if unsafe_method?(ancestor)
229
225
  break true if nil_methods.include?(ancestor.method_name)
@@ -19,7 +19,7 @@ module RuboCop
19
19
 
20
20
  MSG = 'Prefer ary[n..] over ary[n..-1].'
21
21
 
22
- def_node_matcher :range_till_minus_one?, '(irange (int _) (int -1))'
22
+ def_node_matcher :range_till_minus_one?, '(irange !nil? (int -1))'
23
23
 
24
24
  def on_send(node)
25
25
  return unless node.method?(:[]) && node.arguments.count == 1
@@ -181,13 +181,9 @@ module RuboCop
181
181
  parent_type = node.parent&.type
182
182
  preferred_name = preferred_names(global_var).first
183
183
 
184
- unless %i[dstr xstr regexp].include?(parent_type)
185
- return preferred_name.to_s
186
- end
184
+ return preferred_name.to_s unless %i[dstr xstr regexp].include?(parent_type)
187
185
 
188
- if style == :use_english_names
189
- return english_name_replacement(preferred_name, node)
190
- end
186
+ return english_name_replacement(preferred_name, node) if style == :use_english_names
191
187
 
192
188
  "##{preferred_name}"
193
189
  end
@@ -199,9 +199,7 @@ module RuboCop
199
199
  # Ruby allows no space between the question mark and parentheses.
200
200
  # If we remove the parentheses, we need to add a space or we'll
201
201
  # generate invalid code.
202
- unless whitespace_after?(condition)
203
- corrector.insert_after(condition.loc.end, ' ')
204
- end
202
+ corrector.insert_after(condition.loc.end, ' ') unless whitespace_after?(condition)
205
203
  end
206
204
  end
207
205
 
@@ -122,13 +122,9 @@ module RuboCop
122
122
 
123
123
  return unless first_offense
124
124
 
125
- if unused_variables_only?(first_offense, variables)
126
- return unused_range(node.type, mlhs_node, right)
127
- end
125
+ return unused_range(node.type, mlhs_node, right) if unused_variables_only?(first_offense, variables)
128
126
 
129
- if Util.parentheses?(mlhs_node)
130
- return range_for_parentheses(first_offense, mlhs_node)
131
- end
127
+ return range_for_parentheses(first_offense, mlhs_node) if Util.parentheses?(mlhs_node)
132
128
 
133
129
  range_between(first_offense.source_range.begin_pos,
134
130
  node.loc.operator.begin_pos)
@@ -152,9 +152,7 @@ module RuboCop
152
152
  def process_variable_assignment(node)
153
153
  name = node.children.first
154
154
 
155
- unless variable_table.variable_exist?(name)
156
- variable_table.declare_variable(name, node)
157
- end
155
+ variable_table.declare_variable(name, node) unless variable_table.variable_exist?(name)
158
156
 
159
157
  # Need to scan rhs before assignment so that we can mark previous
160
158
  # assignments as referenced if rhs has referencing to the variable
@@ -211,9 +209,7 @@ module RuboCop
211
209
 
212
210
  name = asgn_node.children.first
213
211
 
214
- unless variable_table.variable_exist?(name)
215
- variable_table.declare_variable(name, asgn_node)
216
- end
212
+ variable_table.declare_variable(name, asgn_node) unless variable_table.variable_exist?(name)
217
213
 
218
214
  # The following statements:
219
215
  #
@@ -369,9 +365,7 @@ module RuboCop
369
365
  AssignmentReference.new(node)
370
366
  when *OPERATOR_ASSIGNMENT_TYPES
371
367
  asgn_node = node.children.first
372
- if asgn_node.lvasgn_type?
373
- VariableReference.new(asgn_node.children.first)
374
- end
368
+ VariableReference.new(asgn_node.children.first) if asgn_node.lvasgn_type?
375
369
  end
376
370
  end
377
371
 
@@ -81,9 +81,7 @@ module RuboCop
81
81
  end
82
82
 
83
83
  def each_ancestor(include_self: false, &block)
84
- unless block_given?
85
- return to_enum(__method__, include_self: include_self)
86
- end
84
+ return to_enum(__method__, include_self: include_self) unless block_given?
87
85
 
88
86
  yield self if include_self
89
87
  scan_ancestors(&block)
@@ -111,9 +109,7 @@ module RuboCop
111
109
  return false if may_jump_to_other_branch?
112
110
 
113
111
  other.each_ancestor(include_self: true) do |other_ancestor|
114
- if control_node.equal?(other_ancestor.control_node)
115
- return !child_node.equal?(other_ancestor.child_node)
116
- end
112
+ return !child_node.equal?(other_ancestor.child_node) if control_node.equal?(other_ancestor.control_node)
117
113
  end
118
114
 
119
115
  if parent
@@ -47,9 +47,7 @@ module RuboCop
47
47
  @assignments.reverse_each do |assignment|
48
48
  next if consumed_branches.include?(assignment.branch)
49
49
 
50
- unless assignment.run_exclusively_with?(reference)
51
- assignment.reference!(node)
52
- end
50
+ assignment.reference!(node) unless assignment.run_exclusively_with?(reference)
53
51
 
54
52
  # Modifier if/unless conditions are special. Assignments made in
55
53
  # them do not put the assigned variable in scope to the left of the
@@ -60,9 +58,7 @@ module RuboCop
60
58
 
61
59
  break if !assignment.branch || assignment.branch == reference.branch
62
60
 
63
- unless assignment.branch.may_run_incompletely?
64
- consumed_branches << assignment.branch
65
- end
61
+ consumed_branches << assignment.branch unless assignment.branch.may_run_incompletely?
66
62
  end
67
63
  end
68
64
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Ext
5
+ # Extensions to AST::ProcessedSource for our cached comment_config
6
+ module ProcessedSource
7
+ def comment_config
8
+ @comment_config ||= CommentConfig.new(self)
9
+ end
10
+
11
+ def disabled_line_ranges
12
+ comment_config.cop_disabled_line_ranges
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ RuboCop::ProcessedSource.include RuboCop::Ext::ProcessedSource
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Layout/LineLength
4
-
5
3
  module RuboCop
6
4
  module Formatter
7
5
  # Abstract base class for formatter, implements all public API methods.
@@ -41,8 +39,6 @@ module RuboCop
41
39
  # * `#finished`
42
40
  #
43
41
  class BaseFormatter
44
- # rubocop:enable Layout/LineLength
45
-
46
42
  # @api public
47
43
  #
48
44
  # @!attribute [r] output
@@ -59,9 +59,7 @@ module RuboCop
59
59
  def command
60
60
  command = 'rubocop --auto-gen-config'
61
61
 
62
- if @options[:auto_gen_only_exclude]
63
- command += ' --auto-gen-only-exclude'
64
- end
62
+ command += ' --auto-gen-only-exclude' if @options[:auto_gen_only_exclude]
65
63
 
66
64
  if @exclude_limit_option
67
65
  command +=
@@ -70,9 +68,7 @@ module RuboCop
70
68
  end
71
69
  command += ' --no-offense-counts' if @options[:no_offense_counts]
72
70
 
73
- if @options[:no_auto_gen_timestamp]
74
- command += ' --no-auto-gen-timestamp'
75
- end
71
+ command += ' --no-auto-gen-timestamp' if @options[:no_auto_gen_timestamp]
76
72
 
77
73
  command
78
74
  end
@@ -116,14 +112,10 @@ module RuboCop
116
112
  end
117
113
 
118
114
  def output_cop_comments(output_buffer, cfg, cop_name, offense_count)
119
- if @show_offense_counts
120
- output_buffer.puts "# Offense count: #{offense_count}"
121
- end
115
+ output_buffer.puts "# Offense count: #{offense_count}" if @show_offense_counts
122
116
 
123
117
  cop_class = Cop::Cop.registry.find_by_cop_name(cop_name)
124
- if cop_class&.new&.support_autocorrect?
125
- output_buffer.puts '# Cop supports --auto-correct.'
126
- end
118
+ output_buffer.puts '# Cop supports --auto-correct.' if cop_class&.new&.support_autocorrect?
127
119
 
128
120
  default_cfg = default_config(cop_name)
129
121
  return unless default_cfg
@@ -87,9 +87,7 @@ module RuboCop
87
87
 
88
88
  raise %(No formatter for "#{specified_key}") if matching_keys.empty?
89
89
 
90
- if matching_keys.size > 1
91
- raise %(Cannot determine formatter for "#{specified_key}")
92
- end
90
+ raise %(Cannot determine formatter for "#{specified_key}") if matching_keys.size > 1
93
91
 
94
92
  BUILTIN_FORMATTERS_FOR_KEYS[matching_keys.first]
95
93
  end
@@ -275,12 +275,8 @@ module RuboCop
275
275
  raise OptionArgumentError, 'Lint/RedundantCopDisableDirective cannot ' \
276
276
  'be used with --only.'
277
277
  end
278
- if except_syntax?
279
- raise OptionArgumentError, 'Syntax checking cannot be turned off.'
280
- end
281
- unless boolean_or_empty_cache?
282
- raise OptionArgumentError, '-C/--cache argument must be true or false'
283
- end
278
+ raise OptionArgumentError, 'Syntax checking cannot be turned off.' if except_syntax?
279
+ raise OptionArgumentError, '-C/--cache argument must be true or false' unless boolean_or_empty_cache?
284
280
 
285
281
  if display_only_fail_level_offenses_with_autocorrect?
286
282
  raise OptionArgumentError, '--autocorrect cannot be used with ' \
@@ -381,7 +377,6 @@ module RuboCop
381
377
  # This module contains help texts for command line options.
382
378
  module OptionsHelp
383
379
  MAX_EXCL = RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS.to_s
384
- # rubocop:disable Layout/LineLength
385
380
  FORMATTER_OPTION_LIST = RuboCop::Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS.keys
386
381
 
387
382
  TEXT = {
@@ -468,6 +463,5 @@ module RuboCop
468
463
  'reports. This is useful for editor integration.'],
469
464
  init: 'Generate a .rubocop.yml file in the current directory.'
470
465
  }.freeze
471
- # rubocop:enable Layout/LineLength
472
466
  end
473
467
  end
@@ -56,9 +56,7 @@ module RuboCop
56
56
  def generate_request(uri)
57
57
  request = Net::HTTP::Get.new(uri.request_uri)
58
58
 
59
- if cache_path_exists?
60
- request['If-Modified-Since'] = File.stat(cache_path).mtime.rfc2822
61
- end
59
+ request['If-Modified-Since'] = File.stat(cache_path).mtime.rfc2822 if cache_path_exists?
62
60
 
63
61
  yield request
64
62
  end
@@ -40,9 +40,7 @@ module RuboCop
40
40
  # Add 1 to half the number of files, so that we remove the file if
41
41
  # there's only 1 left.
42
42
  remove_count = 1 + files.length / 2
43
- if verbose
44
- puts "Removing the #{remove_count} oldest files from #{cache_root}"
45
- end
43
+ puts "Removing the #{remove_count} oldest files from #{cache_root}" if verbose
46
44
  sorted = files.sort_by { |path| File.mtime(path) }
47
45
  remove_files(sorted, dirs, remove_count)
48
46
  rescue Errno::ENOENT
@@ -57,9 +57,7 @@ module CopHelper
57
57
 
58
58
  source = new_source
59
59
  cnt += 1
60
- if cnt > RuboCop::Runner::MAX_ITERATIONS
61
- raise RuboCop::Runner::InfiniteCorrectionLoop.new(file, [])
62
- end
60
+ raise RuboCop::Runner::InfiniteCorrectionLoop.new(file, []) if cnt > RuboCop::Runner::MAX_ITERATIONS
63
61
  end
64
62
  end
65
63
 
@@ -88,9 +88,7 @@ module RuboCop
88
88
  @processed_source = parse_source(expected_annotations.plain_source,
89
89
  file)
90
90
 
91
- unless @processed_source.valid_syntax?
92
- raise 'Error parsing example code'
93
- end
91
+ raise 'Error parsing example code' unless @processed_source.valid_syntax?
94
92
 
95
93
  _investigate(cop, @processed_source)
96
94
  actual_annotations =
@@ -101,9 +99,7 @@ module RuboCop
101
99
  # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
102
100
 
103
101
  def expect_correction(correction)
104
- unless @processed_source
105
- raise '`expect_correction` must follow `expect_offense`'
106
- end
102
+ raise '`expect_correction` must follow `expect_offense`' unless @processed_source
107
103
 
108
104
  corrector =
109
105
  RuboCop::Cop::Corrector.new(@processed_source.buffer, cop.corrections)
@@ -113,9 +109,7 @@ module RuboCop
113
109
  end
114
110
 
115
111
  def expect_no_corrections
116
- unless @processed_source
117
- raise '`expect_no_corrections` must follow `expect_offense`'
118
- end
112
+ raise '`expect_no_corrections` must follow `expect_offense`' unless @processed_source
119
113
 
120
114
  return if cop.corrections.empty?
121
115
 
@@ -38,28 +38,66 @@ RSpec.shared_context 'isolated environment', :isolated_environment do
38
38
  end
39
39
  end
40
40
 
41
- # `cop_config` must be declared with #let.
42
- RSpec.shared_context 'config', :config do
43
- let(:config) do
44
- # Module#<
45
- unless described_class < RuboCop::Cop::Cop
46
- raise '`config` must be used in `describe SomeCopClass do .. end`'
47
- end
41
+ # This context assumes nothing and defines `cop`, among others.
42
+ RSpec.shared_context 'config', :config do # rubocop:disable Metrics/BlockLength
43
+ ### Meant to be overriden at will
44
+
45
+ let(:source) { 'code = {some: :ruby}' }
48
46
 
49
- hash = { 'AllCops' => { 'TargetRubyVersion' => ruby_version } }
50
- hash['AllCops']['TargetRailsVersion'] = rails_version if rails_version
51
- if respond_to?(:cop_config)
52
- cop_name = described_class.cop_name
53
- hash[cop_name] = RuboCop::ConfigLoader
54
- .default_configuration[cop_name]
55
- .merge('Enabled' => true) # in case it is 'pending'
56
- .merge(cop_config)
47
+ let(:cop_class) do
48
+ if described_class.is_a?(Class) && described_class < RuboCop::Cop::Cop
49
+ described_class
50
+ else
51
+ RuboCop::Cop::Cop
57
52
  end
53
+ end
54
+
55
+ let(:cop_config) { {} }
56
+
57
+ let(:other_cops) { {} }
58
+
59
+ let(:cop_options) { {} }
60
+
61
+ ### Utilities
62
+
63
+ def source_range(range, buffer: source_buffer)
64
+ Parser::Source::Range.new(buffer, range.begin,
65
+ range.exclude_end? ? range.end : range.end + 1)
66
+ end
58
67
 
59
- hash = other_cops.merge hash if respond_to?(:other_cops)
68
+ ### Usefull intermediary steps (less likely to be overriden)
69
+
70
+ let(:processed_source) { parse_source(source, 'test') }
71
+
72
+ let(:source_buffer) { processed_source.buffer }
73
+
74
+ let(:all_cops_config) do
75
+ rails = { 'TargetRubyVersion' => ruby_version }
76
+ rails['TargetRailsVersion'] = rails_version if rails_version
77
+ rails
78
+ end
79
+
80
+ let(:cur_cop_config) do
81
+ RuboCop::ConfigLoader
82
+ .default_configuration.for_cop(cop_class)
83
+ .merge({
84
+ 'Enabled' => true, # in case it is 'pending'
85
+ 'AutoCorrect' => true # in case defaults set it to false
86
+ })
87
+ .merge(cop_config)
88
+ end
89
+
90
+ let(:config) do
91
+ hash = { 'AllCops' => all_cops_config,
92
+ cop_class.cop_name => cur_cop_config }.merge!(other_cops)
60
93
 
61
94
  RuboCop::Config.new(hash, "#{Dir.pwd}/.rubocop.yml")
62
95
  end
96
+
97
+ let(:cop) do
98
+ cop_class.new(config, cop_options)
99
+ .tap { |cop| cop.processed_source = processed_source }
100
+ end
63
101
  end
64
102
 
65
103
  RSpec.shared_context 'mock console output' do
@@ -80,9 +80,7 @@ module RuboCop
80
80
  # OPTIMIZE: Calling `ResultCache.cleanup` takes time. This optimization
81
81
  # mainly targets editors that integrates RuboCop. When RuboCop is run
82
82
  # by an editor, it should be inspecting only one file.
83
- if files.size > 1 && cached_run?
84
- ResultCache.cleanup(@config_store, @options[:debug])
85
- end
83
+ ResultCache.cleanup(@config_store, @options[:debug]) if files.size > 1 && cached_run?
86
84
  formatter_set.finished(inspected_files.freeze)
87
85
  formatter_set.close_output_files
88
86
  end
@@ -206,9 +204,7 @@ module RuboCop
206
204
  end
207
205
 
208
206
  def file_finished(file, offenses)
209
- if @options[:display_only_fail_level_offenses]
210
- offenses = offenses.select { |o| considered_failure?(o) }
211
- end
207
+ offenses = offenses.select { |o| considered_failure?(o) } if @options[:display_only_fail_level_offenses]
212
208
  formatter_set.file_finished(file, offenses)
213
209
  end
214
210
 
@@ -288,9 +284,7 @@ module RuboCop
288
284
  def check_for_infinite_loop(processed_source, offenses)
289
285
  checksum = processed_source.checksum
290
286
 
291
- if @processed_sources.include?(checksum)
292
- raise InfiniteCorrectionLoop.new(processed_source.path, offenses)
293
- end
287
+ raise InfiniteCorrectionLoop.new(processed_source.path, offenses) if @processed_sources.include?(checksum)
294
288
 
295
289
  @processed_sources << checksum
296
290
  end
@@ -367,7 +361,11 @@ module RuboCop
367
361
  if @options[:stdin]
368
362
  ProcessedSource.new(@options[:stdin], ruby_version, file)
369
363
  else
370
- ProcessedSource.from_file(file, ruby_version)
364
+ begin
365
+ ProcessedSource.from_file(file, ruby_version)
366
+ rescue Errno::ENOENT
367
+ raise RuboCop::Error, "No such file or directory: #{file}"
368
+ end
371
369
  end
372
370
  end
373
371