rubocop 1.7.0 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +4 -3
  4. data/config/default.yml +137 -31
  5. data/config/obsoletion.yml +4 -0
  6. data/lib/rubocop.rb +14 -1
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +5 -4
  8. data/lib/rubocop/comment_config.rb +6 -6
  9. data/lib/rubocop/config.rb +5 -2
  10. data/lib/rubocop/config_loader.rb +7 -14
  11. data/lib/rubocop/config_store.rb +12 -1
  12. data/lib/rubocop/cop/base.rb +2 -1
  13. data/lib/rubocop/cop/exclude_limit.rb +26 -0
  14. data/lib/rubocop/cop/gemspec/date_assignment.rb +56 -0
  15. data/lib/rubocop/cop/generator.rb +1 -3
  16. data/lib/rubocop/cop/internal_affairs.rb +5 -1
  17. data/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb +68 -0
  18. data/lib/rubocop/cop/internal_affairs/example_description.rb +89 -0
  19. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +61 -0
  20. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +64 -0
  21. data/lib/rubocop/cop/layout/class_structure.rb +7 -2
  22. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +38 -18
  23. data/lib/rubocop/cop/layout/first_argument_indentation.rb +16 -2
  24. data/lib/rubocop/cop/layout/line_length.rb +2 -1
  25. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +26 -0
  26. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
  27. data/lib/rubocop/cop/layout/space_before_brackets.rb +19 -16
  28. data/lib/rubocop/cop/lint/debugger.rb +58 -14
  29. data/lib/rubocop/cop/lint/deprecated_constants.rb +80 -0
  30. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +13 -4
  31. data/lib/rubocop/cop/lint/duplicate_require.rb +2 -2
  32. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  33. data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
  34. data/lib/rubocop/cop/lint/multiple_comparison.rb +4 -4
  35. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -6
  36. data/lib/rubocop/cop/lint/number_conversion.rb +41 -6
  37. data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +47 -0
  38. data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +39 -0
  39. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -1
  40. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +50 -0
  41. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +5 -3
  42. data/lib/rubocop/cop/lint/symbol_conversion.rb +103 -0
  43. data/lib/rubocop/cop/lint/triple_quotes.rb +71 -0
  44. data/lib/rubocop/cop/message_annotator.rb +4 -1
  45. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  46. data/lib/rubocop/cop/metrics/parameter_lists.rb +5 -2
  47. data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
  48. data/lib/rubocop/cop/mixin/check_line_breakable.rb +5 -0
  49. data/lib/rubocop/cop/mixin/code_length.rb +3 -1
  50. data/lib/rubocop/cop/mixin/comments_help.rb +1 -11
  51. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
  52. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  53. data/lib/rubocop/cop/mixin/method_complexity.rb +3 -1
  54. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +2 -2
  55. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +5 -1
  56. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +38 -5
  57. data/lib/rubocop/cop/naming/variable_name.rb +2 -0
  58. data/lib/rubocop/cop/naming/variable_number.rb +2 -9
  59. data/lib/rubocop/cop/registry.rb +1 -1
  60. data/lib/rubocop/cop/severity.rb +3 -3
  61. data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
  62. data/lib/rubocop/cop/style/constant_visibility.rb +27 -0
  63. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +49 -9
  64. data/lib/rubocop/cop/style/double_negation.rb +2 -2
  65. data/lib/rubocop/cop/style/empty_literal.rb +6 -2
  66. data/lib/rubocop/cop/style/endless_method.rb +102 -0
  67. data/lib/rubocop/cop/style/eval_with_location.rb +138 -49
  68. data/lib/rubocop/cop/style/explicit_block_argument.rb +11 -1
  69. data/lib/rubocop/cop/style/exponential_notation.rb +6 -7
  70. data/lib/rubocop/cop/style/float_division.rb +3 -0
  71. data/lib/rubocop/cop/style/format_string_token.rb +18 -2
  72. data/lib/rubocop/cop/style/hash_conversion.rb +81 -0
  73. data/lib/rubocop/cop/style/hash_like_case.rb +2 -1
  74. data/lib/rubocop/cop/style/if_inside_else.rb +22 -10
  75. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +120 -0
  76. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +4 -0
  77. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -0
  78. data/lib/rubocop/cop/style/nil_comparison.rb +3 -0
  79. data/lib/rubocop/cop/style/non_nil_check.rb +23 -13
  80. data/lib/rubocop/cop/style/numeric_literals.rb +6 -9
  81. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  82. data/lib/rubocop/cop/style/raise_args.rb +3 -2
  83. data/lib/rubocop/cop/style/redundant_return.rb +1 -1
  84. data/lib/rubocop/cop/style/single_line_methods.rb +32 -2
  85. data/lib/rubocop/cop/style/sole_nested_conditional.rb +29 -5
  86. data/lib/rubocop/cop/style/special_global_vars.rb +3 -3
  87. data/lib/rubocop/cop/style/string_concatenation.rb +1 -1
  88. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  89. data/lib/rubocop/cop/style/while_until_modifier.rb +2 -4
  90. data/lib/rubocop/formatter/git_hub_actions_formatter.rb +1 -0
  91. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
  92. data/lib/rubocop/formatter/simple_text_formatter.rb +2 -1
  93. data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
  94. data/lib/rubocop/magic_comment.rb +30 -1
  95. data/lib/rubocop/options.rb +1 -1
  96. data/lib/rubocop/rspec/expect_offense.rb +5 -2
  97. data/lib/rubocop/runner.rb +1 -0
  98. data/lib/rubocop/target_ruby.rb +47 -11
  99. data/lib/rubocop/version.rb +2 -2
  100. metadata +24 -7
@@ -9,6 +9,7 @@ module RuboCop
9
9
  self.command_name = :auto_gen_config
10
10
 
11
11
  AUTO_GENERATED_FILE = '.rubocop_todo.yml'
12
+ YAML_OPTIONAL_DOC_START = /\A---(\s+#|\s*\z)/.freeze
12
13
 
13
14
  PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop'
14
15
  PHASE_2 = 'Phase 2 of 2: run all cops'
@@ -130,10 +131,10 @@ module RuboCop
130
131
  end
131
132
 
132
133
  def write_config_file(file_name, file_string, rubocop_yml_contents)
133
- File.open(file_name, 'w') do |f|
134
- f.write "inherit_from:#{file_string}\n"
135
- f.write "\n#{rubocop_yml_contents}" if /\S/.match?(rubocop_yml_contents)
136
- end
134
+ lines = /\S/.match?(rubocop_yml_contents) ? rubocop_yml_contents.split("\n", -1) : []
135
+ doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1
136
+ lines.insert(doc_start_index + 1, "inherit_from:#{file_string}\n")
137
+ File.open(file_name, 'w') { |f| f.write lines.join("\n") }
137
138
  end
138
139
  end
139
140
  end
@@ -47,6 +47,12 @@ module RuboCop
47
47
  )
48
48
  end
49
49
 
50
+ def comment_only_line?(line_number)
51
+ non_comment_token_line_numbers.none? do |non_comment_line_number|
52
+ non_comment_line_number == line_number
53
+ end
54
+ end
55
+
50
56
  private
51
57
 
52
58
  def extra_enabled_comments_with_names(extras:, names:)
@@ -166,12 +172,6 @@ module RuboCop
166
172
  @all_cop_names ||= Cop::Registry.global.names - [REDUNDANT_DISABLE]
167
173
  end
168
174
 
169
- def comment_only_line?(line_number)
170
- non_comment_token_line_numbers.none? do |non_comment_line_number|
171
- non_comment_line_number == line_number
172
- end
173
- end
174
-
175
175
  def non_comment_token_line_numbers
176
176
  @non_comment_token_line_numbers ||= begin
177
177
  non_comment_tokens = processed_source.tokens.reject(&:comment?)
@@ -33,8 +33,11 @@ module RuboCop
33
33
  @validator = ConfigValidator.new(self)
34
34
  end
35
35
 
36
- def self.create(hash, path)
37
- new(hash, path).check
36
+ def self.create(hash, path, check: true)
37
+ config = new(hash, path)
38
+ config.check if check
39
+
40
+ config
38
41
  end
39
42
 
40
43
  def loaded_features
@@ -25,17 +25,18 @@ module RuboCop
25
25
  attr_accessor :debug, :ignore_parent_exclusion,
26
26
  :disable_pending_cops, :enable_pending_cops
27
27
  attr_writer :default_configuration, :project_root
28
+ attr_reader :loaded_features
28
29
 
29
30
  alias debug? debug
30
31
  alias ignore_parent_exclusion? ignore_parent_exclusion
31
32
 
32
33
  def clear_options
33
34
  @debug = nil
34
- @loaded_features = []
35
+ @loaded_features = Set.new
35
36
  FileFinder.root_level = nil
36
37
  end
37
38
 
38
- def load_file(file)
39
+ def load_file(file, check: true)
39
40
  path = file_path(file)
40
41
 
41
42
  hash = load_yaml_configuration(path)
@@ -52,7 +53,7 @@ module RuboCop
52
53
 
53
54
  hash.delete('inherit_from')
54
55
 
55
- Config.create(hash, path)
56
+ Config.create(hash, path, check: check)
56
57
  end
57
58
 
58
59
  def load_yaml_configuration(absolute_path)
@@ -99,10 +100,10 @@ module RuboCop
99
100
  find_user_xdg_config || DEFAULT_FILE
100
101
  end
101
102
 
102
- def configuration_from_file(config_file)
103
+ def configuration_from_file(config_file, check: true)
103
104
  return default_configuration if config_file == DEFAULT_FILE
104
105
 
105
- config = load_file(config_file)
106
+ config = load_file(config_file, check: check)
106
107
  if ignore_parent_exclusion?
107
108
  print 'Ignoring AllCops/Exclude from parent folders' if debug?
108
109
  else
@@ -174,19 +175,11 @@ module RuboCop
174
175
  resolver.merge_with_default(config, config_file, unset_nil: unset_nil)
175
176
  end
176
177
 
177
- def loaded_features
178
- @loaded_features.flatten.compact
179
- end
180
-
181
178
  # @api private
182
179
  # Used to add features that were required inside a config or from
183
180
  # the CLI using `--require`.
184
181
  def add_loaded_features(loaded_features)
185
- if instance_variable_defined?(:@loaded_features)
186
- instance_variable_get(:@loaded_features) << loaded_features
187
- else
188
- instance_variable_set(:@loaded_features, [loaded_features])
189
- end
182
+ @loaded_features.merge(Array(loaded_features))
190
183
  end
191
184
 
192
185
  private
@@ -4,6 +4,9 @@ module RuboCop
4
4
  # Handles caching of configurations and association of inspected
5
5
  # ruby files to configurations.
6
6
  class ConfigStore
7
+ attr_reader :validated
8
+ alias validated? validated
9
+
7
10
  def initialize
8
11
  # @options_config stores a config that is specified in the command line.
9
12
  # This takes precedence over configs located in any directories
@@ -17,6 +20,9 @@ module RuboCop
17
20
  # @object_cache maps configuration file paths to
18
21
  # configuration objects so we only need to load them once.
19
22
  @object_cache = {}
23
+
24
+ # By default the config is validated before it can be used.
25
+ @validated = true
20
26
  end
21
27
 
22
28
  def options_config=(options_config)
@@ -29,6 +35,11 @@ module RuboCop
29
35
  @options_config = ConfigLoader.default_configuration
30
36
  end
31
37
 
38
+ def unvalidated
39
+ @validated = false
40
+ self
41
+ end
42
+
32
43
  def for_file(file)
33
44
  for_dir(File.dirname(file))
34
45
  end
@@ -55,7 +66,7 @@ module RuboCop
55
66
  path = @path_cache[dir]
56
67
  @object_cache[path] ||= begin
57
68
  print "For #{dir}: " if ConfigLoader.debug?
58
- ConfigLoader.configuration_from_file(path)
69
+ ConfigLoader.configuration_from_file(path, check: validated?)
59
70
  end
60
71
  end
61
72
  end
@@ -34,6 +34,7 @@ module RuboCop
34
34
  class Base # rubocop:disable Metrics/ClassLength
35
35
  extend RuboCop::AST::Sexp
36
36
  extend NodePattern::Macros
37
+ extend ExcludeLimit
37
38
  include RuboCop::AST::Sexp
38
39
  include Util
39
40
  include IgnoredNode
@@ -351,7 +352,7 @@ module RuboCop
351
352
  def use_corrector(range, corrector)
352
353
  if autocorrect?
353
354
  attempt_correction(range, corrector)
354
- elsif corrector
355
+ elsif corrector && cop_config.fetch('AutoCorrect', true)
355
356
  :uncorrected
356
357
  else
357
358
  :unsupported
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # Allows specified configuration options to have an exclude limit
5
+ # ie. a maximum value tracked that it can be used by `--auto-gen-config`.
6
+ module ExcludeLimit
7
+ # Sets up a configuration option to have an exclude limit tracked.
8
+ # The parameter name given is transformed into a method name (eg. `Max`
9
+ # becomes `self.max=` and `MinDigits` becomes `self.min_digits=`).
10
+ def exclude_limit(parameter_name, method_name: transform(parameter_name))
11
+ define_method("#{method_name}=") do |value|
12
+ cfg = config_to_allow_offenses
13
+ cfg[:exclude_limit] ||= {}
14
+ current_max = cfg[:exclude_limit][parameter_name]
15
+ value = [current_max, value].max if current_max
16
+ cfg[:exclude_limit][parameter_name] = value
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def transform(parameter_name)
23
+ parameter_name.gsub(/(?<!\A)(?=[A-Z])/, '_').downcase
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Gemspec
6
+ # This cop checks that `date =` is not used in gemspec file.
7
+ # It is set automatically when the gem is packaged.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ # Gem::Specification.new do |spec|
13
+ # s.name = 'your_cool_gem_name'
14
+ # spec.date = Time.now.strftime('%Y-%m-%d')
15
+ # end
16
+ #
17
+ # # good
18
+ # Gem::Specification.new do |spec|
19
+ # s.name = 'your_cool_gem_name'
20
+ # end
21
+ #
22
+ class DateAssignment < Base
23
+ include RangeHelp
24
+ extend AutoCorrector
25
+
26
+ MSG = 'Do not use `date =` in gemspec, it is set automatically when the gem is packaged.'
27
+
28
+ def_node_matcher :gem_specification, <<~PATTERN
29
+ (block
30
+ (send
31
+ (const
32
+ (const {cbase nil?} :Gem) :Specification) :new)
33
+ ...)
34
+ PATTERN
35
+
36
+ def on_block(block_node)
37
+ return unless gem_specification(block_node)
38
+
39
+ block_parameter = block_node.arguments.first.source
40
+
41
+ date_assignment = block_node.descendants.detect do |node|
42
+ node.send_type? && node.receiver&.source == block_parameter && node.method?(:date=)
43
+ end
44
+
45
+ return unless date_assignment
46
+
47
+ add_offense(date_assignment) do |corrector|
48
+ range = range_by_whole_lines(date_assignment.source_range, include_final_newline: true)
49
+
50
+ corrector.remove(range)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -81,9 +81,7 @@ module RuboCop
81
81
  SPEC_TEMPLATE = <<~SPEC
82
82
  # frozen_string_literal: true
83
83
 
84
- RSpec.describe RuboCop::Cop::%<department>s::%<cop_name>s do
85
- subject(:cop) { described_class.new(config) }
86
-
84
+ RSpec.describe RuboCop::Cop::%<department>s::%<cop_name>s, :config do
87
85
  let(:config) { RuboCop::Config.new }
88
86
 
89
87
  # TODO: Write test code
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'internal_affairs/empty_line_between_expect_offense_and_correction'
4
+ require_relative 'internal_affairs/example_description'
3
5
  require_relative 'internal_affairs/method_name_equal'
4
6
  require_relative 'internal_affairs/node_destructuring'
5
7
  require_relative 'internal_affairs/node_type_predicate'
6
8
  require_relative 'internal_affairs/offense_location_keyword'
7
- require_relative 'internal_affairs/redundant_message_argument'
9
+ require_relative 'internal_affairs/redundant_described_class_as_subject'
10
+ require_relative 'internal_affairs/redundant_let_rubocop_config_new'
8
11
  require_relative 'internal_affairs/redundant_location_argument'
12
+ require_relative 'internal_affairs/redundant_message_argument'
9
13
  require_relative 'internal_affairs/style_detected_api_use'
10
14
  require_relative 'internal_affairs/useless_message_assertion'
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # This cop checks whether `expect_offense` and correction expectation methods
7
+ # (i.e. `expect_correction` and `expect_no_corrections`) are separated by empty line.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # it 'registers and corrects an offense' do
12
+ # expect_offense(<<~RUBY)
13
+ # bad_method
14
+ # ^^^^^^^^^^ Use `good_method`.
15
+ # RUBY
16
+ # expect_correction(<<~RUBY)
17
+ # good_method
18
+ # RUBY
19
+ # end
20
+ #
21
+ # # good
22
+ # it 'registers and corrects an offense' do
23
+ # expect_offense(<<~RUBY)
24
+ # bad_method
25
+ # ^^^^^^^^^^ Use `good_method`.
26
+ # RUBY
27
+ #
28
+ # expect_correction(<<~RUBY)
29
+ # good_method
30
+ # RUBY
31
+ # end
32
+ #
33
+ class EmptyLineBetweenExpectOffenseAndCorrection < Base
34
+ extend AutoCorrector
35
+
36
+ MSG = 'Add empty line between `expect_offense` and `%<expect_correction>s`.'
37
+ RESTRICT_ON_SEND = %i[expect_offense].freeze
38
+ CORRECTION_EXPECTATION_METHODS = %i[expect_correction expect_no_corrections].freeze
39
+
40
+ def on_send(node)
41
+ return unless (next_sibling = node.right_sibling) && next_sibling.send_type?
42
+
43
+ method_name = next_sibling.method_name
44
+ return unless CORRECTION_EXPECTATION_METHODS.include?(method_name)
45
+
46
+ range = offense_range(node)
47
+ return unless range.last_line + 1 == next_sibling.loc.line
48
+
49
+ add_offense(range, message: format(MSG, expect_correction: method_name)) do |corrector|
50
+ corrector.insert_after(range, "\n")
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def offense_range(node)
57
+ first_argument = node.first_argument
58
+
59
+ if first_argument.respond_to?(:heredoc?) && first_argument.heredoc?
60
+ first_argument.loc.heredoc_end
61
+ else
62
+ node
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module InternalAffairs
6
+ # Checks that RSpec examples that use `expects_offense`
7
+ # or `expects_no_offenses` do not have conflicting
8
+ # descriptions.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # it 'does not register an offense' do
13
+ # expect_offense('...')
14
+ # end
15
+ #
16
+ # it 'registers an offense' do
17
+ # expect_no_offenses('...')
18
+ # end
19
+ #
20
+ # # good
21
+ # it 'registers an offense' do
22
+ # expect_offense('...')
23
+ # end
24
+ #
25
+ # it 'does not register an offense' do
26
+ # expect_no_offenses('...')
27
+ # end
28
+ class ExampleDescription < Base
29
+ class << self
30
+ attr_accessor :descriptions
31
+ end
32
+
33
+ MSG = 'Description does not match use of `%<method_name>s`.'
34
+
35
+ RESTRICT_ON_SEND = %i[
36
+ expect_offense
37
+ expect_no_offenses
38
+ expect_correction
39
+ expect_no_corrections
40
+ ].to_set.freeze
41
+
42
+ EXPECT_NO_OFFENSES_INCORRECT_DESCRIPTIONS = [
43
+ /^(adds|registers|reports|finds) (an? )?offense/,
44
+ /^flags\b/
45
+ ].freeze
46
+
47
+ EXPECT_OFFENSE_INCORRECT_DESCRIPTIONS = [
48
+ /^(does not|doesn't) (register|find|flag|report)/,
49
+ /^(does not|doesn't) add (a|an|any )?offense/
50
+ ].freeze
51
+
52
+ EXPECT_NO_CORRECTIONS_INCORRECT_DESCRIPTIONS = [
53
+ /^(auto[- ]?)?correct/
54
+ ].freeze
55
+
56
+ EXPECT_CORRECTION_INCORRECT_DESCRIPTIONS = [
57
+ /\b(does not|doesn't) (auto[- ]?)?correct/
58
+ ].freeze
59
+
60
+ def_node_matcher :offense_example?, <<~PATTERN
61
+ (block
62
+ (send _ {:it :specify} $_description)
63
+ _args
64
+ `(send nil? %RESTRICT_ON_SEND ...)
65
+ )
66
+ PATTERN
67
+
68
+ def on_send(node)
69
+ parent = node.each_ancestor(:block).first
70
+ return unless parent && (description = offense_example?(parent))
71
+
72
+ method_name = node.method_name
73
+ message = format(MSG, method_name: method_name)
74
+
75
+ regexp_group = self.class.const_get("#{method_name}_incorrect_descriptions".upcase)
76
+ check_description(description, regexp_group, message)
77
+ end
78
+
79
+ private
80
+
81
+ def check_description(description, regexps, message)
82
+ return unless regexps.any? { |regexp| regexp.match?(description.value) }
83
+
84
+ add_offense(description, message: message)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end