rubocop 1.14.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf17e65fbe829bbc1328bfc1898fe4df1fc1a1e9773b946e1136b3dc16625fd5
4
- data.tar.gz: a35649eeecce4e75f2fb623094b4cc5f93323c1b44393482c0b57e3b37358d86
3
+ metadata.gz: 1009c9da04982d8684219d15bcaaf8a09f5aa3523d8fb668fb47b885281e11ef
4
+ data.tar.gz: fac46c18283c960c698d18f5fd6206cef3d309b2d74bc5046c0c6ba30ca60431
5
5
  SHA512:
6
- metadata.gz: 696e932f19f9f47448de8858c7444be66fb1a58fa25588e26a8b3842a786677bcf3bd49f9f80b945cbbbed3f5826939fbdf8a8cf106e93843e9c659e20d47b10
7
- data.tar.gz: 70729c8cc362bca0ee4397881f2acd0ba088430bfc1c6867e17a9a3da61eff8a0aa911d44a673e1e70d44978638675aedd3717dccfafe3f8cfc78c3f09baeabf
6
+ metadata.gz: 292b418ad2da13f7357a6b3189128ed35a84fa662506de26d4973797e430751b158e9cb0c7a0753c0cded518ba0299cf5bcf1394abb9793aa728b4dedf36863a
7
+ data.tar.gz: cfca1c661ace6abafa34d5506c27ef48afe3ba2abc7187d3fabf41db0abce0c93d59d2f5411671d22fbadea6a09987cda71f2600cc85b5b88b18fca7f526f451
data/README.md CHANGED
@@ -29,6 +29,8 @@ RuboCop is extremely flexible and most aspects of its behavior can be tweaked vi
29
29
  [![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-sponsors)
30
30
  [![Tidelift](https://tidelift.com/badges/package/rubygems/rubocop)](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source=rubygems-rubocop&utm_medium=referral&utm_campaign=readme)
31
31
 
32
+ Working on RuboCop is often fun, but it also requires a great deal of time and energy.
33
+
32
34
  **Please consider [financially supporting its ongoing development](#funding).**
33
35
 
34
36
  ## Installation
@@ -52,7 +54,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
52
54
  in your `Gemfile`:
53
55
 
54
56
  ```rb
55
- gem 'rubocop', '~> 1.14', require: false
57
+ gem 'rubocop', '~> 1.15', require: false
56
58
  ```
57
59
 
58
60
  See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
data/config/default.yml CHANGED
@@ -1612,7 +1612,7 @@ Lint/EmptyBlock:
1612
1612
  Description: 'This cop checks for blocks without a body.'
1613
1613
  Enabled: pending
1614
1614
  VersionAdded: '1.1'
1615
- VersionChanged: '1.3'
1615
+ VersionChanged: '1.15'
1616
1616
  AllowComments: true
1617
1617
  AllowEmptyLambdas: true
1618
1618
 
@@ -3480,6 +3480,7 @@ Style/HashAsLastArrayItem:
3480
3480
 
3481
3481
  Style/HashConversion:
3482
3482
  Description: 'Avoid Hash[] in favor of ary.to_h or literal hashes.'
3483
+ StyleGuide: '#avoid-hash-constructor'
3483
3484
  Enabled: pending
3484
3485
  VersionAdded: '1.10'
3485
3486
  VersionChanged: '1.11'
@@ -3998,6 +3999,7 @@ Style/NilLambda:
3998
3999
  Description: 'Prefer `-> {}` to `-> { nil }`.'
3999
4000
  Enabled: pending
4000
4001
  VersionAdded: '1.3'
4002
+ VersionChanged: '1.15'
4001
4003
 
4002
4004
  Style/NonNilCheck:
4003
4005
  Description: 'Checks for redundant nil checks.'
@@ -4651,6 +4653,12 @@ Style/TernaryParentheses:
4651
4653
  - require_parentheses_when_complex
4652
4654
  AllowSafeAssignment: true
4653
4655
 
4656
+ Style/TopLevelMethodDefinition:
4657
+ Description: 'This cop looks for top-level method definitions.'
4658
+ StyleGuide: '#top-level-methods'
4659
+ Enabled: false
4660
+ VersionAdded: '1.15'
4661
+
4654
4662
  Style/TrailingBodyOnClass:
4655
4663
  Description: 'Class body goes below class statement.'
4656
4664
  Enabled: true
@@ -4737,7 +4745,7 @@ Style/TrivialAccessors:
4737
4745
  StyleGuide: '#attr_family'
4738
4746
  Enabled: true
4739
4747
  VersionAdded: '0.9'
4740
- VersionChanged: '0.77'
4748
+ VersionChanged: '1.15'
4741
4749
  # When set to `false` the cop will suggest the use of accessor methods
4742
4750
  # in situations like:
4743
4751
  #
@@ -4756,7 +4764,7 @@ Style/TrivialAccessors:
4756
4764
  # on_exception :restart
4757
4765
  #
4758
4766
  # Commonly used in DSLs
4759
- AllowDSLWriters: false
4767
+ AllowDSLWriters: true
4760
4768
  IgnoreClassMethods: false
4761
4769
  AllowedMethods:
4762
4770
  - to_ary
data/lib/rubocop.rb CHANGED
@@ -598,6 +598,7 @@ require_relative 'rubocop/cop/style/symbol_array'
598
598
  require_relative 'rubocop/cop/style/symbol_literal'
599
599
  require_relative 'rubocop/cop/style/symbol_proc'
600
600
  require_relative 'rubocop/cop/style/ternary_parentheses'
601
+ require_relative 'rubocop/cop/style/top_level_method_definition'
601
602
  require_relative 'rubocop/cop/style/trailing_body_on_class'
602
603
  require_relative 'rubocop/cop/style/trailing_body_on_method_definition'
603
604
  require_relative 'rubocop/cop/style/trailing_body_on_module'
@@ -41,7 +41,7 @@ module RuboCop
41
41
 
42
42
  EXPECT_NO_OFFENSES_INCORRECT_DESCRIPTIONS = [
43
43
  /^(adds|registers|reports|finds) (an? )?offense/,
44
- /^flags\b/
44
+ /^(flags|handles|works)\b/
45
45
  ].freeze
46
46
 
47
47
  EXPECT_OFFENSE_INCORRECT_DESCRIPTIONS = [
@@ -10,33 +10,39 @@ module RuboCop
10
10
  # # good
11
11
  #
12
12
  # foo :bar,
13
- # :baz
13
+ # :baz,
14
+ # key: value
14
15
  #
15
16
  # foo(
16
17
  # :bar,
17
- # :baz
18
+ # :baz,
19
+ # key: value
18
20
  # )
19
21
  #
20
22
  # # bad
21
23
  #
22
24
  # foo :bar,
23
- # :baz
25
+ # :baz,
26
+ # key: value
24
27
  #
25
28
  # foo(
26
29
  # :bar,
27
- # :baz
30
+ # :baz,
31
+ # key: value
28
32
  # )
29
33
  #
30
34
  # @example EnforcedStyle: with_fixed_indentation
31
35
  # # good
32
36
  #
33
37
  # foo :bar,
34
- # :baz
38
+ # :baz,
39
+ # key: value
35
40
  #
36
41
  # # bad
37
42
  #
38
43
  # foo :bar,
39
- # :baz
44
+ # :baz,
45
+ # key: value
40
46
  class ArgumentAlignment < Base
41
47
  include Alignment
42
48
  extend AutoCorrector
@@ -47,14 +53,25 @@ module RuboCop
47
53
  'following the first line of a multi-line method call.'
48
54
 
49
55
  def on_send(node)
50
- return if node.arguments.size < 2 || node.send_type? && node.method?(:[]=)
56
+ first_arg = node.first_argument
57
+ return if !multiple_arguments?(node, first_arg) || node.send_type? && node.method?(:[]=)
51
58
 
52
- check_alignment(node.arguments, base_column(node, node.arguments))
59
+ if first_arg.hash_type?
60
+ check_alignment(first_arg.pairs, base_column(node, first_arg.pairs.first))
61
+ else
62
+ check_alignment(node.arguments, base_column(node, first_arg))
63
+ end
53
64
  end
54
65
  alias on_csend on_send
55
66
 
56
67
  private
57
68
 
69
+ def multiple_arguments?(node, first_argument)
70
+ return true if node.arguments.size >= 2
71
+
72
+ first_argument&.hash_type? && first_argument.pairs.count >= 2
73
+ end
74
+
58
75
  def autocorrect(corrector, node)
59
76
  AlignmentCorrector.correct(corrector, processed_source, node, column_delta)
60
77
  end
@@ -67,14 +84,14 @@ module RuboCop
67
84
  cop_config['EnforcedStyle'] == 'with_fixed_indentation'
68
85
  end
69
86
 
70
- def base_column(node, args)
71
- if fixed_indentation?
87
+ def base_column(node, first_argument)
88
+ if fixed_indentation? || first_argument.nil?
72
89
  lineno = target_method_lineno(node)
73
90
  line = node.source_range.source_buffer.source_line(lineno)
74
91
  indentation_of_line = /\S.*/.match(line).begin(0)
75
92
  indentation_of_line + configured_indentation_width
76
93
  else
77
- display_column(args.first.source_range)
94
+ display_column(first_argument.source_range)
78
95
  end
79
96
  end
80
97
 
@@ -91,6 +91,8 @@ module RuboCop
91
91
  end
92
92
 
93
93
  def on_send(node)
94
+ return if enforce_first_argument_with_fixed_indentation?
95
+
94
96
  each_argument_node(node, :hash) do |hash_node, left_parenthesis|
95
97
  check(hash_node, left_parenthesis)
96
98
  end
@@ -182,6 +184,16 @@ module RuboCop
182
184
  'where the left brace is.'
183
185
  end
184
186
  end
187
+
188
+ def enforce_first_argument_with_fixed_indentation?
189
+ return false unless argument_alignment_config['Enabled']
190
+
191
+ argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
192
+ end
193
+
194
+ def argument_alignment_config
195
+ config.for_cop('Layout/ArgumentAlignment')
196
+ end
185
197
  end
186
198
  end
187
199
  end
@@ -200,14 +200,12 @@ module RuboCop
200
200
  alias on_super on_send
201
201
  alias on_yield on_send
202
202
 
203
- def on_hash(node) # rubocop:todo Metrics/CyclomaticComplexity
204
- return if ignored_node?(node)
205
- return if node.pairs.empty? || node.single_line?
203
+ def on_hash(node)
204
+ return if enforce_first_argument_with_fixed_indentation? || ignored_node?(node) ||
205
+ node.pairs.empty? || node.single_line?
206
206
 
207
- return unless alignment_for_hash_rockets
208
- .any? { |a| a.checkable_layout?(node) } &&
209
- alignment_for_colons
210
- .any? { |a| a.checkable_layout?(node) }
207
+ proc = ->(a) { a.checkable_layout?(node) }
208
+ return unless alignment_for_hash_rockets.any?(proc) && alignment_for_colons.any?(proc)
211
209
 
212
210
  check_pairs(node)
213
211
  end
@@ -353,6 +351,16 @@ module RuboCop
353
351
  def good_alignment?(column_deltas)
354
352
  column_deltas.values.all?(&:zero?)
355
353
  end
354
+
355
+ def enforce_first_argument_with_fixed_indentation?
356
+ return false unless argument_alignment_config['Enabled']
357
+
358
+ argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
359
+ end
360
+
361
+ def argument_alignment_config
362
+ config.for_cop('Layout/ArgumentAlignment')
363
+ end
356
364
  end
357
365
  end
358
366
  end
@@ -313,9 +313,12 @@ module RuboCop
313
313
  check_rescue?(body_node)
314
314
  elsif body_node.ensure_type?
315
315
  block_body, = *body_node
316
- return unless block_body
317
316
 
318
- check_rescue?(block_body) if block_body.rescue_type?
317
+ if block_body&.rescue_type?
318
+ check_rescue?(block_body)
319
+ else
320
+ !block_body.nil?
321
+ end
319
322
  else
320
323
  true
321
324
  end
@@ -12,6 +12,8 @@ module RuboCop
12
12
  # File.exists?(some_path)
13
13
  # Dir.exists?(some_path)
14
14
  # iterator?
15
+ # Socket.gethostbyname(host)
16
+ # Socket.gethostbyaddr(host)
15
17
  #
16
18
  # @example
17
19
  #
@@ -20,6 +22,8 @@ module RuboCop
20
22
  # File.exist?(some_path)
21
23
  # Dir.exist?(some_path)
22
24
  # block_given?
25
+ # Addrinfo.getaddrinfo(nodename, service)
26
+ # Addrinfo.tcp(host, port).getnameinfo
23
27
  class DeprecatedClassMethods < Base
24
28
  extend AutoCorrector
25
29
 
@@ -7,7 +7,11 @@ module RuboCop
7
7
  # Such empty blocks are typically an oversight or we should provide a comment
8
8
  # be clearer what we're aiming for.
9
9
  #
10
- # Empty lambdas are ignored by default.
10
+ # Empty lambdas and procs are ignored by default.
11
+ #
12
+ # NOTE: For backwards compatibility, the configuration that allows/disallows
13
+ # empty lambdas and procs is called `AllowEmptyLambdas`, even though it also
14
+ # applies to procs.
11
15
  #
12
16
  # @example
13
17
  # # bad
@@ -40,6 +44,10 @@ module RuboCop
40
44
  # end
41
45
  # (callable || placeholder).call
42
46
  #
47
+ # proc { }
48
+ #
49
+ # Proc.new { }
50
+ #
43
51
  # @example AllowEmptyLambdas: false
44
52
  # # bad
45
53
  # allow(subject).to receive(:callable).and_return(-> {})
@@ -48,12 +56,16 @@ module RuboCop
48
56
  # end
49
57
  # (callable || placeholder).call
50
58
  #
59
+ # proc { }
60
+ #
61
+ # Proc.new { }
62
+ #
51
63
  class EmptyBlock < Base
52
64
  MSG = 'Empty block detected.'
53
65
 
54
66
  def on_block(node)
55
67
  return if node.body
56
- return if allow_empty_lambdas? && node.lambda?
68
+ return if allow_empty_lambdas? && lambda_or_proc?(node)
57
69
  return if cop_config['AllowComments'] && allow_comment?(node)
58
70
 
59
71
  add_offense(node)
@@ -76,6 +88,10 @@ module RuboCop
76
88
  regexp_pattern = "# rubocop : (disable|todo) ([^,],)* (all|#{cop_name})"
77
89
  Regexp.new(regexp_pattern.gsub(' ', '\s*')).match?(comment)
78
90
  end
91
+
92
+ def lambda_or_proc?(node)
93
+ node.lambda? || node.proc?
94
+ end
79
95
  end
80
96
  end
81
97
  end
@@ -104,7 +104,7 @@ module RuboCop
104
104
  end
105
105
 
106
106
  def check_literal(node)
107
- return if !node.literal? || node.xstr_type?
107
+ return if !node.literal? || node.xstr_type? || node.range_type?
108
108
 
109
109
  add_offense(node, message: format(LIT_MSG, lit: node.source))
110
110
  end
@@ -70,17 +70,33 @@ module RuboCop
70
70
  def extract_first_element_over_column_limit(node, elements, max)
71
71
  line = node.first_line
72
72
 
73
- # If the first argument is a hash pair but the method is not parenthesized,
74
- # the argument cannot be moved to another line because it cause a syntax error.
75
- elements.shift if node.send_type? && !node.parenthesized? && elements.first.pair_type?
73
+ # If a `send` node is not parenthesized, don't move the first element, because it
74
+ # can result in changed behavior or a syntax error.
75
+ elements = elements.drop(1) if node.send_type? && !node.parenthesized?
76
76
 
77
77
  i = 0
78
78
  i += 1 while within_column_limit?(elements[i], max, line)
79
+ i = shift_elements_for_heredoc_arg(node, elements, i)
80
+
81
+ return if i.nil?
79
82
  return elements.first if i.zero?
80
83
 
81
84
  elements[i - 1]
82
85
  end
83
86
 
87
+ # @api private
88
+ # If a send node contains a heredoc argument, splitting cannot happen
89
+ # after the heredoc or else it will cause a syntax error.
90
+ def shift_elements_for_heredoc_arg(node, elements, index)
91
+ return index unless node.send_type?
92
+
93
+ heredoc_index = elements.index { |arg| (arg.str_type? || arg.dstr_type?) && arg.heredoc? }
94
+ return index unless heredoc_index
95
+ return nil if heredoc_index.zero?
96
+
97
+ heredoc_index >= index ? index : heredoc_index + 1
98
+ end
99
+
84
100
  # @api private
85
101
  def within_column_limit?(element, max, line)
86
102
  element && element.loc.column <= max && element.loc.line == line
@@ -35,6 +35,12 @@ module RuboCop
35
35
  leading_comment_lines.any? { |line| MagicComment.parse(line).frozen_string_literal? }
36
36
  end
37
37
 
38
+ def frozen_string_literals_disabled?
39
+ leading_comment_lines.any? do |line|
40
+ MagicComment.parse(line).frozen_string_literal == false
41
+ end
42
+ end
43
+
38
44
  def frozen_string_literal_specified?
39
45
  leading_comment_lines.any? do |line|
40
46
  MagicComment.parse(line).frozen_string_literal_specified?
@@ -87,9 +87,18 @@ module RuboCop
87
87
  end
88
88
 
89
89
  def compact_node(corrector, node)
90
- replacement = "#{node.body.type} #{compact_identifier_name(node)}"
91
90
  range = range_between(node.loc.keyword.begin_pos, node.body.loc.name.end_pos)
92
- corrector.replace(range, replacement)
91
+ corrector.replace(range, compact_replacement(node))
92
+ end
93
+
94
+ def compact_replacement(node)
95
+ replacement = "#{node.body.type} #{compact_identifier_name(node)}"
96
+
97
+ body_comments = processed_source.ast_with_comments[node.body]
98
+ unless body_comments.empty?
99
+ replacement = body_comments.map(&:text).push(replacement).join("\n")
100
+ end
101
+ replacement
93
102
  end
94
103
 
95
104
  def compact_identifier_name(node)
@@ -132,6 +141,9 @@ module RuboCop
132
141
  end
133
142
 
134
143
  def check_compact_style(node, body)
144
+ parent = node.parent
145
+ return if parent&.class_type? || parent&.module_type?
146
+
135
147
  return unless needs_compacting?(body)
136
148
 
137
149
  add_offense(node.loc.name, message: COMPACT_MSG) do |corrector|
@@ -62,7 +62,7 @@ module RuboCop
62
62
  ARR_MSG
63
63
  elsif offense_hash_node?(node)
64
64
  HASH_MSG
65
- elsif str_node(node) && !frozen_string_literals_enabled?
65
+ elsif str_node(node) && !frozen_strings?
66
66
  format(STR_MSG, prefer: preferred_string_literal)
67
67
  end
68
68
  end
@@ -125,6 +125,13 @@ module RuboCop
125
125
  end
126
126
  end
127
127
  end
128
+
129
+ def frozen_strings?
130
+ return true if frozen_string_literals_enabled?
131
+
132
+ frozen_string_cop_enabled = config.for_cop('Style/FrozenStringLiteral')['Enabled']
133
+ frozen_string_cop_enabled && !frozen_string_literals_disabled?
134
+ end
128
135
  end
129
136
  end
130
137
  end
@@ -3,8 +3,8 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks for lambdas that always return nil, which can be replaced
7
- # with an empty lambda instead.
6
+ # This cop checks for lambdas and procs that always return nil,
7
+ # which can be replaced with an empty lambda or proc instead.
8
8
  #
9
9
  # @example
10
10
  # # bad
@@ -14,6 +14,12 @@ module RuboCop
14
14
  # next nil
15
15
  # end
16
16
  #
17
+ # proc { nil }
18
+ #
19
+ # Proc.new do
20
+ # break nil
21
+ # end
22
+ #
17
23
  # # good
18
24
  # -> {}
19
25
  #
@@ -22,11 +28,15 @@ module RuboCop
22
28
  #
23
29
  # -> (x) { nil if x }
24
30
  #
31
+ # proc {}
32
+ #
33
+ # Proc.new { nil if x }
34
+ #
25
35
  class NilLambda < Base
26
36
  extend AutoCorrector
27
37
  include RangeHelp
28
38
 
29
- MSG = 'Use an empty lambda instead of always returning nil.'
39
+ MSG = 'Use an empty %<type>s instead of always returning nil.'
30
40
 
31
41
  # @!method nil_return?(node)
32
42
  def_node_matcher :nil_return?, <<~PATTERN
@@ -34,19 +44,26 @@ module RuboCop
34
44
  PATTERN
35
45
 
36
46
  def on_block(node)
37
- return unless node.lambda?
47
+ return unless node.lambda? || node.proc?
38
48
  return unless nil_return?(node.body)
39
49
 
40
- add_offense(node) do |corrector|
41
- range = if node.single_line?
42
- range_with_surrounding_space(range: node.body.loc.expression)
43
- else
44
- range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
45
- end
46
-
47
- corrector.remove(range)
50
+ message = format(MSG, type: node.lambda? ? 'lambda' : 'proc')
51
+ add_offense(node, message: message) do |corrector|
52
+ autocorrect(corrector, node)
48
53
  end
49
54
  end
55
+
56
+ private
57
+
58
+ def autocorrect(corrector, node)
59
+ range = if node.single_line?
60
+ range_with_surrounding_space(range: node.body.loc.expression)
61
+ else
62
+ range_by_whole_lines(node.body.loc.expression, include_final_newline: true)
63
+ end
64
+
65
+ corrector.remove(range)
66
+ end
50
67
  end
51
68
  end
52
69
  end
@@ -110,7 +110,7 @@ module RuboCop
110
110
  first_child = node.children.first
111
111
 
112
112
  source = first_child.source
113
- source = "(#{source})" if first_child.if_type?
113
+ source = "(#{source})" if first_child.if_type? && first_child.modifier_form?
114
114
 
115
115
  corrector.replace(offense_range, source)
116
116
  corrector.remove(range_between(offense_range.end_pos, first_child.source_range.end_pos))
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # Newcomers to ruby applications may write top-level methods,
7
+ # when ideally they should be organized in appropriate classes or modules.
8
+ # This cop looks for definitions of top-level methods and warns about them.
9
+ #
10
+ # However for ruby scripts it is perfectly fine to use top-level methods.
11
+ # Hence this cop is disabled by default.
12
+ #
13
+ # @example
14
+ # # bad
15
+ # def some_method
16
+ # end
17
+ #
18
+ # # bad
19
+ # def self.some_method
20
+ # end
21
+ #
22
+ # # bad
23
+ # define_method(:foo) { puts 1 }
24
+ #
25
+ # # good
26
+ # module Foo
27
+ # def some_method
28
+ # end
29
+ # end
30
+ #
31
+ # # good
32
+ # class Foo
33
+ # def self.some_method
34
+ # end
35
+ # end
36
+ #
37
+ # # good
38
+ # Struct.new do
39
+ # def some_method
40
+ # end
41
+ # end
42
+ #
43
+ # # good
44
+ # class Foo
45
+ # define_method(:foo) { puts 1 }
46
+ # end
47
+ class TopLevelMethodDefinition < Base
48
+ MSG = 'Do not define methods at the top-level.'
49
+
50
+ RESTRICT_ON_SEND = %i[define_method].freeze
51
+
52
+ def on_def(node)
53
+ return unless node.root?
54
+
55
+ add_offense(node)
56
+ end
57
+ alias on_defs on_def
58
+ alias on_send on_def
59
+
60
+ def on_block(node)
61
+ return unless define_method_block?(node) && node.root?
62
+
63
+ add_offense(node)
64
+ end
65
+
66
+ private
67
+
68
+ # @!method define_method_block?(node)
69
+ def_node_matcher :define_method_block?, <<~PATTERN
70
+ (block (send _ {:define_method} _) ...)
71
+ PATTERN
72
+ end
73
+ end
74
+ end
75
+ end
@@ -27,6 +27,71 @@ module RuboCop
27
27
  # class << self
28
28
  # attr_reader :baz
29
29
  # end
30
+ #
31
+ # @example ExactNameMatch: true (default)
32
+ # # good
33
+ # def name
34
+ # @other_name
35
+ # end
36
+ #
37
+ # @example ExactNameMatch: false
38
+ # # bad
39
+ # def name
40
+ # @other_name
41
+ # end
42
+ #
43
+ # @example AllowPredicates: true (default)
44
+ # # good
45
+ # def foo?
46
+ # @foo
47
+ # end
48
+ #
49
+ # @example AllowPredicates: false
50
+ # # bad
51
+ # def foo?
52
+ # @foo
53
+ # end
54
+ #
55
+ # # good
56
+ # attr_reader :foo
57
+ #
58
+ # @example AllowDSLWriters: true (default)
59
+ # # good
60
+ # def on_exception(action)
61
+ # @on_exception=action
62
+ # end
63
+ #
64
+ # @example AllowDSLWriters: false
65
+ # # bad
66
+ # def on_exception(action)
67
+ # @on_exception=action
68
+ # end
69
+ #
70
+ # # good
71
+ # attr_writer :on_exception
72
+ #
73
+ # @example IgnoreClassMethods: false (default)
74
+ # # bad
75
+ # def self.foo
76
+ # @foo
77
+ # end
78
+ #
79
+ # # good
80
+ # class << self
81
+ # attr_reader :foo
82
+ # end
83
+ #
84
+ # @example IgnoreClassMethods: true
85
+ # # good
86
+ # def self.foo
87
+ # @foo
88
+ # end
89
+ #
90
+ # @example AllowedMethods: ['allowed_method']
91
+ # # good
92
+ # def allowed_method
93
+ # @foo
94
+ # end
30
95
  class TrivialAccessors < Base
31
96
  include AllowedMethods
32
97
  extend AutoCorrector
@@ -22,9 +22,13 @@ module RuboCop
22
22
  testsuites = REXML::Element.new('testsuites', @document)
23
23
  testsuite = REXML::Element.new('testsuite', testsuites)
24
24
  @testsuite = testsuite.tap { |element| element.add_attributes('name' => 'rubocop') }
25
+
26
+ reset_count
25
27
  end
26
28
 
27
29
  def file_finished(file, offenses)
30
+ @inspected_file_count += 1
31
+
28
32
  # TODO: Returns all cops with the same behavior as
29
33
  # the original rubocop-junit-formatter.
30
34
  # https://github.com/mikian/rubocop-junit-formatter/blob/v0.1.4/lib/rubocop/formatter/junit_formatter.rb#L9
@@ -32,15 +36,11 @@ module RuboCop
32
36
  # In the future, it would be preferable to return only enabled cops.
33
37
  Cop::Registry.all.each do |cop|
34
38
  target_offenses = offenses_for_cop(offenses, cop)
39
+ @offense_count += target_offenses.count
35
40
 
36
41
  next unless relevant_for_output?(options, target_offenses)
37
42
 
38
- REXML::Element.new('testcase', @testsuite).tap do |testcase|
39
- testcase.attributes['classname'] = classname_attribute_value(file)
40
- testcase.attributes['name'] = cop.cop_name
41
-
42
- add_failure_to(testcase, target_offenses, cop.cop_name)
43
- end
43
+ add_testcase_element_to_testsuite_element(file, target_offenses, cop)
44
44
  end
45
45
  end
46
46
 
@@ -52,16 +52,31 @@ module RuboCop
52
52
  all_offenses.select { |offense| offense.cop_name == cop.cop_name }
53
53
  end
54
54
 
55
+ def add_testcase_element_to_testsuite_element(file, target_offenses, cop)
56
+ REXML::Element.new('testcase', @testsuite).tap do |testcase|
57
+ testcase.attributes['classname'] = classname_attribute_value(file)
58
+ testcase.attributes['name'] = cop.cop_name
59
+
60
+ add_failure_to(testcase, target_offenses, cop.cop_name)
61
+ end
62
+ end
63
+
55
64
  def classname_attribute_value(file)
56
65
  file.gsub(/\.rb\Z/, '').gsub("#{Dir.pwd}/", '').tr('/', '.')
57
66
  end
58
67
 
59
68
  def finished(_inspected_files)
69
+ @testsuite.add_attributes('tests' => @inspected_file_count, 'failures' => @offense_count)
60
70
  @document.write(output, 2)
61
71
  end
62
72
 
63
73
  private
64
74
 
75
+ def reset_count
76
+ @inspected_file_count = 0
77
+ @offense_count = 0
78
+ end
79
+
65
80
  def add_failure_to(testcase, offenses, cop_name)
66
81
  # One failure per offense. Zero failures is a passing test case,
67
82
  # for most surefire/nUnit parsers.
@@ -297,7 +297,7 @@ module RuboCop
297
297
  validate_auto_gen_config
298
298
  validate_auto_correct
299
299
  validate_display_only_failed
300
- validate_parallel
300
+ disable_parallel_when_invalid_option_combo
301
301
 
302
302
  return if incompatible_options.size <= 1
303
303
 
@@ -334,33 +334,27 @@ module RuboCop
334
334
  format('--disable-uncorrectable can only be used together with --auto-correct.')
335
335
  end
336
336
 
337
- def validate_parallel
337
+ def disable_parallel_when_invalid_option_combo
338
338
  return unless @options.key?(:parallel)
339
339
 
340
- if @options[:cache] == 'false'
341
- raise OptionArgumentError, '-P/--parallel uses caching to speed up ' \
342
- 'execution, so combining with --cache ' \
343
- 'false is not allowed.'
344
- end
345
-
346
- disable_parallel_when_invalid_combo
347
- end
340
+ invalid_options = [
341
+ { name: :auto_gen_config, value: true, flag: '--auto-gen-config' },
342
+ { name: :fail_fast, value: true, flag: '-F/--fail-fast.' },
343
+ { name: :auto_correct, value: true, flag: '--auto-correct.' },
344
+ { name: :cache, value: 'false', flag: '--cache false' }
345
+ ]
348
346
 
349
- def disable_parallel_when_invalid_combo
350
- combos = {
351
- auto_gen_config: '--auto-gen-config',
352
- fail_fast: '-F/--fail-fast.',
353
- auto_correct: '--auto-correct.'
354
- }
355
-
356
- invalid_combos = combos.select { |key, _flag| @options.key?(key) }
347
+ invalid_flags = invalid_options.each_with_object([]) do |option, flags|
348
+ # `>` rather than `>=` because `@options` will also contain `parallel: true`
349
+ flags << option[:flag] if @options > { option[:name] => option[:value] }
350
+ end
357
351
 
358
- return if invalid_combos.empty?
352
+ return if invalid_flags.empty?
359
353
 
360
354
  @options.delete(:parallel)
361
355
 
362
356
  puts '-P/--parallel is being ignored because ' \
363
- "it is not compatible with #{invalid_combos.values.join(', ')}"
357
+ "it is not compatible with #{invalid_flags.join(', ')}"
364
358
  end
365
359
 
366
360
  def only_includes_redundant_disable?
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '1.14.0'
6
+ STRING = '1.15.0'
7
7
 
8
8
  MSG = '%<version>s (using Parser %<parser_version>s, '\
9
9
  'rubocop-ast %<rubocop_ast_version>s, ' \
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.14.0
4
+ version: 1.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-05-05 00:00:00.000000000 Z
13
+ date: 2021-05-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: parallel
@@ -786,6 +786,7 @@ files:
786
786
  - lib/rubocop/cop/style/symbol_literal.rb
787
787
  - lib/rubocop/cop/style/symbol_proc.rb
788
788
  - lib/rubocop/cop/style/ternary_parentheses.rb
789
+ - lib/rubocop/cop/style/top_level_method_definition.rb
789
790
  - lib/rubocop/cop/style/trailing_body_on_class.rb
790
791
  - lib/rubocop/cop/style/trailing_body_on_method_definition.rb
791
792
  - lib/rubocop/cop/style/trailing_body_on_module.rb
@@ -875,7 +876,7 @@ metadata:
875
876
  homepage_uri: https://rubocop.org/
876
877
  changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
877
878
  source_code_uri: https://github.com/rubocop/rubocop/
878
- documentation_uri: https://docs.rubocop.org/rubocop/1.14/
879
+ documentation_uri: https://docs.rubocop.org/rubocop/1.15/
879
880
  bug_tracker_uri: https://github.com/rubocop/rubocop/issues
880
881
  post_install_message:
881
882
  rdoc_options: []