rubocop 0.20.0 → 0.20.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -1
  3. data/lib/rubocop.rb +1 -0
  4. data/lib/rubocop/cop/lint/space_before_first_arg.rb +2 -1
  5. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +13 -4
  6. data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -2
  7. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +24 -0
  8. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -1
  9. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  10. data/lib/rubocop/cop/mixin/space_inside.rb +4 -0
  11. data/lib/rubocop/cop/style/and_or.rb +2 -14
  12. data/lib/rubocop/cop/style/blocks.rb +6 -4
  13. data/lib/rubocop/cop/style/class_methods.rb +24 -4
  14. data/lib/rubocop/cop/style/negated_if.rb +12 -3
  15. data/lib/rubocop/cop/style/negated_while.rb +15 -3
  16. data/lib/rubocop/cop/style/nil_comparison.rb +1 -1
  17. data/lib/rubocop/cop/style/non_nil_check.rb +36 -2
  18. data/lib/rubocop/cop/style/not.rb +2 -14
  19. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +1 -0
  20. data/lib/rubocop/formatter/disabled_config_formatter.rb +4 -0
  21. data/lib/rubocop/version.rb +1 -1
  22. data/relnotes/v0.20.1.md +24 -0
  23. data/spec/rubocop/cli_spec.rb +75 -0
  24. data/spec/rubocop/cop/lint/space_before_first_arg_spec.rb +10 -0
  25. data/spec/rubocop/cop/lint/string_conversion_in_interpolation_spec.rb +14 -0
  26. data/spec/rubocop/cop/lint/useless_access_modifier_spec.rb +38 -0
  27. data/spec/rubocop/cop/style/blocks_spec.rb +6 -0
  28. data/spec/rubocop/cop/style/class_methods_spec.rb +1 -1
  29. data/spec/rubocop/cop/style/negated_if_spec.rb +17 -0
  30. data/spec/rubocop/cop/style/negated_while_spec.rb +16 -0
  31. data/spec/rubocop/cop/style/nil_comparison_spec.rb +5 -0
  32. data/spec/rubocop/cop/style/non_nil_check_spec.rb +35 -0
  33. data/spec/rubocop/cop/style/space_inside_block_braces_spec.rb +6 -0
  34. data/spec/rubocop/cop/style/space_inside_brackets_spec.rb +7 -0
  35. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +10 -1
  36. data/spec/rubocop/cop/style/space_inside_parens_spec.rb +12 -0
  37. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9bfa5cdcf23439710744d9065a22970e4c30918d
4
- data.tar.gz: c931f4765d359ef1bf54ebb76c5393e6d0c223de
3
+ metadata.gz: e091003352d55c98a9579dc743d9ab5542a32229
4
+ data.tar.gz: a1840b93e9ee0d9cac37c4a9e3749acf17fca02b
5
5
  SHA512:
6
- metadata.gz: cd67703e4e607f48f45618e3c28a250528dd658ab9d7258e93ad678978e6c17f1d0c47d57a4eafe0adbd1f796450de89f4d62fa144c008f343db8dfc314b32c6
7
- data.tar.gz: c9812cfa4889a4f15c1f81bef017f5e256551cbcc43716f501609a06ef8d518b6514ed98a7c1784cadfe805db23b6e5180932551767b8e35b88050fbde557c30
6
+ metadata.gz: 6f9ac51993ab31b7b6c0a9ffdd1ab5136a024cf5d341891e71ad5af0f1ef08cbb09f77759dbe8aefd0a64f04a306b64649f1c53c6977b0c2d4436786d04ed5ef
7
+ data.tar.gz: 8a78d285ece4159fade45e13ee06af7286632a1176130760dbd8c2599efc288ee6d7abf88775a1a3127e2879b2fe475219ed19fadd069125a7763ee00352e724
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 0.20.1 (05/04/2014)
6
+
7
+ ### Bugs fixed
8
+
9
+ * [#940](https://github.com/bbatsov/rubocop/issues/940): Fixed `UselessAccessModifier` not handling `attr_*` correctly. ([@fshowalter][])
10
+ * `NegatedIf` properly handles negated `unless` condition. ([@bbatsov][])
11
+ * `NegatedWhile` properly handles negated `until` condition. ([@bbatsov][])
12
+ * [#925](https://github.com/bbatsov/rubocop/issues/925): Do not disable the `Syntax` cop in output from `--auto-gen-config`. ([@jonas054][])
13
+ * [#943](https://github.com/bbatsov/rubocop/issues/943): Fix auto-correction interference problem between `SpaceAfterComma` and other cops. ([@jonas054][])
14
+ * [#954](https://github.com/bbatsov/rubocop/pull/954): Fix auto-correction bug in `NilComparison`. ([@bbatsov][])
15
+ * [#953](https://github.com/bbatsov/rubocop/pull/953): Fix auto-correction bug in `NonNilCheck`. ([@bbatsov][])
16
+ * [#952](https://github.com/bbatsov/rubocop/pull/952): Handle implicit receiver in `StringConversionInInterpolation`. ([@bbatsov][])
17
+ * [#956](https://github.com/bbatsov/rubocop/pull/956): Apply `ClassMethods` check only on `class`/`module` bodies. ([@bbatsov][])
18
+ * [#945](https://github.com/bbatsov/rubocop/issues/945): Fix SpaceBeforeFirstArg cop for multiline argument and exclude assignments. ([@cschramm][])
19
+ * [#948](https://github.com/bbatsov/rubocop/issues/948): `Blocks` cop avoids auto-correction if it would introduce a semantic change. ([@jonas054][])
20
+ * [#946](https://github.com/bbatsov/rubocop/issues/946): Allow non-nil checks that are the final expressions of predicate method definitions in `NonNilCheck`. ([@bbatsov][])
21
+ * [#957](https://github.com/bbatsov/rubocop/issues/957): Allow space + comment inside parentheses, braces, and square brackets. ([@jonas054][])
22
+
5
23
  ## 0.20.0 (02/04/2014)
6
24
 
7
25
  ### New features
@@ -56,7 +74,6 @@
56
74
  * [#927](https://github.com/bbatsov/rubocop/issues/927): Let `--auto-gen-config` overwrite an existing `rubocop-todo.yml` file instead of asking the user to remove it. ([@jonas054][])
57
75
  * [#936](https://github.com/bbatsov/rubocop/issues/936): Allow `_other` as well as `other` in `OpMethod`. ([@bbatsov][])
58
76
 
59
-
60
77
  ## 0.19.1 (17/03/2014)
61
78
 
62
79
  ### Bugs fixed
@@ -831,3 +848,4 @@
831
848
  [@hiroponz]: https://github.com/hiroponz
832
849
  [@tamird]: https://github.com/tamird
833
850
  [@fshowalter]: https://github.com/fshowalter
851
+ [@cschramm]: https://github.com/cschramm
@@ -47,6 +47,7 @@ require 'rubocop/cop/variable_inspector/variable_table'
47
47
  require 'rubocop/cop/mixin/annotation_comment'
48
48
  require 'rubocop/cop/mixin/array_syntax'
49
49
  require 'rubocop/cop/mixin/autocorrect_alignment'
50
+ require 'rubocop/cop/mixin/autocorrect_unless_changing_ast'
50
51
  require 'rubocop/cop/mixin/check_assignment'
51
52
  require 'rubocop/cop/mixin/check_methods'
52
53
  require 'rubocop/cop/mixin/configurable_max'
@@ -20,6 +20,7 @@ module Rubocop
20
20
  _receiver, method_name, *args = *node
21
21
  return if args.empty?
22
22
  return if operator?(method_name)
23
+ return if method_name.to_s.end_with?('=')
23
24
 
24
25
  # Setter calls with parentheses are parsed this way. The parentheses
25
26
  # belong to the argument, not the send node.
@@ -28,7 +29,7 @@ module Rubocop
28
29
  arg1 = args.first.loc.expression
29
30
  arg1_with_space = range_with_surrounding_space(arg1, :left)
30
31
 
31
- add_offense(nil, arg1) if arg1_with_space.source =~ /^\S/
32
+ add_offense(nil, arg1) if arg1_with_space.source =~ /\A\S/
32
33
  end
33
34
  end
34
35
  end
@@ -10,17 +10,22 @@ module Rubocop
10
10
  #
11
11
  # "result is #{something.to_s}"
12
12
  class StringConversionInInterpolation < Cop
13
- MSG = 'Redundant use of `Object#to_s` in interpolation.'
13
+ MSG_DEFAULT = 'Redundant use of `Object#to_s` in interpolation.'
14
+ MSG_SELF = 'Use `self` instead of `Object#to_s` in interpolation.'
14
15
 
15
16
  def on_dstr(node)
16
17
  node.children.select { |n| n.type == :begin }.each do |begin_node|
17
18
  final_node = begin_node.children.last
18
19
  next unless final_node && final_node.type == :send
19
20
 
20
- _receiver, method_name, *args = *final_node
21
+ receiver, method_name, *args = *final_node
21
22
 
22
23
  if method_name == :to_s && args.empty?
23
- add_offense(final_node, :selector)
24
+ add_offense(
25
+ final_node,
26
+ :selector,
27
+ receiver ? MSG_DEFAULT : MSG_SELF
28
+ )
24
29
  end
25
30
  end
26
31
  end
@@ -32,7 +37,11 @@ module Rubocop
32
37
  receiver, _method_name, *_args = *node
33
38
  corrector.replace(
34
39
  node.loc.expression,
35
- receiver.loc.expression.source
40
+ if receiver
41
+ receiver.loc.expression.source
42
+ else
43
+ 'self'
44
+ end
36
45
  )
37
46
  end
38
47
  end
@@ -21,7 +21,7 @@ module Rubocop
21
21
  body_nodes = body.type == :begin ? body.children : [body]
22
22
 
23
23
  body_nodes.each do |child_node|
24
- check_for_access_modifier(child_node)
24
+ check_for_access_modifier(child_node) ||
25
25
  check_for_instance_method(child_node)
26
26
  end
27
27
 
@@ -39,7 +39,8 @@ module Rubocop
39
39
  end
40
40
 
41
41
  def check_for_instance_method(node)
42
- return unless node.type == :def
42
+ return unless node.type == :def ||
43
+ node.type == :send
43
44
 
44
45
  @access_modifier_node = nil
45
46
  end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Cop
5
+ # This module does auto-correction of nodes that could become grammatically
6
+ # different after the correction. If the code change would alter the
7
+ # abstract syntax tree, it is not done.
8
+ module AutocorrectUnlessChangingAST
9
+ def autocorrect(node)
10
+ c = correction(node)
11
+ new_source = rewrite_node(node, c)
12
+
13
+ # Make the correction only if it doesn't change the AST.
14
+ @corrections << c if node == SourceParser.parse(new_source).ast
15
+ end
16
+
17
+ def rewrite_node(node, correction)
18
+ processed_source = SourceParser.parse(node.loc.expression.source)
19
+ c = correction(processed_source.ast)
20
+ Corrector.new(processed_source.buffer, [c]).rewrite
21
+ end
22
+ end
23
+ end
24
+ end
@@ -15,7 +15,7 @@ module Rubocop
15
15
  if condition.type == :send
16
16
  _object, method = *condition
17
17
  if method == :! && !(node.loc.respond_to?(:else) && node.loc.else)
18
- add_offense(node, :expression, error_message)
18
+ add_offense(node, :expression)
19
19
  end
20
20
  end
21
21
  end
@@ -25,7 +25,7 @@ module Rubocop
25
25
 
26
26
  def autocorrect(token)
27
27
  @corrections << lambda do |corrector|
28
- corrector.insert_after(token.pos, ' ')
28
+ corrector.replace(token.pos, token.pos.source + ' ')
29
29
  end
30
30
  end
31
31
  end
@@ -13,6 +13,10 @@ module Rubocop
13
13
  left, right, kind = specifics
14
14
  processed_source.tokens.each_cons(2) do |t1, t2|
15
15
  if t1.type == left || t2.type == right
16
+ # If the second token is a comment, that means that a line break
17
+ # follows, and that the rules for space inside don't apply.
18
+ next if t2.type == :tCOMMENT
19
+
16
20
  if t2.pos.line == t1.pos.line && space_between?(t1, t2)
17
21
  range = Parser::Source::Range.new(processed_source.buffer,
18
22
  t1.pos.end_pos,
@@ -5,6 +5,8 @@ module Rubocop
5
5
  module Style
6
6
  # This cop checks for uses of *and* and *or*.
7
7
  class AndOr < Cop
8
+ include AutocorrectUnlessChangingAST
9
+
8
10
  MSG = 'Use `%s` instead of `%s`.'
9
11
 
10
12
  OPS = { 'and' => '&&', 'or' => '||' }
@@ -30,20 +32,6 @@ module Rubocop
30
32
  end
31
33
  end
32
34
 
33
- def autocorrect(node)
34
- c = correction(node)
35
- new_source = rewrite_node(node, c)
36
-
37
- # Make the correction only if it doesn't change the AST.
38
- @corrections << c if node == SourceParser.parse(new_source).ast
39
- end
40
-
41
- def rewrite_node(node, correction)
42
- processed_source = SourceParser.parse(node.loc.expression.source)
43
- c = correction(processed_source.ast)
44
- Corrector.new(processed_source.buffer, [c]).rewrite
45
- end
46
-
47
35
  def correction(node)
48
36
  lambda do |corrector|
49
37
  replacement = (node.type == :and ? '&&' : '||')
@@ -6,6 +6,8 @@ module Rubocop
6
6
  # Check for uses of braces or do/end around single line or
7
7
  # multi-line blocks.
8
8
  class Blocks < Cop
9
+ include AutocorrectUnlessChangingAST
10
+
9
11
  MULTI_LINE_MSG = 'Avoid using {...} for multi-line blocks.'
10
12
  SINGLE_LINE_MSG = 'Prefer {...} over do...end for single-line blocks.'
11
13
 
@@ -35,8 +37,10 @@ module Rubocop
35
37
  end
36
38
  end
37
39
 
38
- def autocorrect(node)
39
- @corrections << lambda do |corrector|
40
+ private
41
+
42
+ def correction(node)
43
+ lambda do |corrector|
40
44
  b, e = node.loc.begin, node.loc.end
41
45
  if b.is?('{')
42
46
  # If the left brace is immediately preceded by a word character,
@@ -53,8 +57,6 @@ module Rubocop
53
57
  end
54
58
  end
55
59
 
56
- private
57
-
58
60
  def get_block(node)
59
61
  case node.type
60
62
  when :block
@@ -8,8 +8,30 @@ module Rubocop
8
8
  class ClassMethods < Cop
9
9
  MSG = 'Use `self.%s` instead of `%s.%s`.'
10
10
 
11
- # TODO: Check if we're in a class/module
12
- def on_defs(node)
11
+ def on_class(node)
12
+ _name, _superclass, body = *node
13
+ check(body)
14
+ end
15
+
16
+ def on_module(node)
17
+ _name, body = *node
18
+ check(body)
19
+ end
20
+
21
+ private
22
+
23
+ def check(node)
24
+ return unless node
25
+
26
+ if node.type == :defs
27
+ check_defs(node)
28
+ elsif node.type == :begin
29
+ defs_nodes = node.children.compact.select { |n| n.type == :defs }
30
+ defs_nodes.each { |n| check_defs(n) }
31
+ end
32
+ end
33
+
34
+ def check_defs(node)
13
35
  definee, method_name, _args, _body = *node
14
36
 
15
37
  if definee.type == :const
@@ -19,8 +41,6 @@ module Rubocop
19
41
  end
20
42
  end
21
43
 
22
- private
23
-
24
44
  def message(class_name, method_name)
25
45
  format(MSG, method_name, class_name, method_name)
26
46
  end
@@ -8,6 +8,8 @@ module Rubocop
8
8
  class NegatedIf < Cop
9
9
  include NegativeConditional
10
10
 
11
+ MSG = 'Favor `%s` over `%s` for negative conditions.'
12
+
11
13
  def on_if(node)
12
14
  return unless node.loc.respond_to?(:keyword)
13
15
  return if node.loc.keyword.is?('elsif')
@@ -15,8 +17,12 @@ module Rubocop
15
17
  check(node)
16
18
  end
17
19
 
18
- def error_message
19
- 'Favor `unless` over `if` for negative conditions.'
20
+ def message(node)
21
+ if node.loc.keyword.is?('if')
22
+ format(MSG, 'unless', 'if')
23
+ else
24
+ format(MSG, 'if', 'unless')
25
+ end
20
26
  end
21
27
 
22
28
  private
@@ -26,7 +32,10 @@ module Rubocop
26
32
  condition, _body, _rest = *node
27
33
  # unwrap the negated portion of the condition (a send node)
28
34
  pos_condition, _method, = *condition
29
- corrector.replace(node.loc.keyword, 'unless')
35
+ corrector.replace(
36
+ node.loc.keyword,
37
+ node.loc.keyword.is?('if') ? 'unless' : 'if'
38
+ )
30
39
  corrector.replace(condition.loc.expression,
31
40
  pos_condition.loc.expression.source)
32
41
  end
@@ -7,12 +7,22 @@ module Rubocop
7
7
  class NegatedWhile < Cop
8
8
  include NegativeConditional
9
9
 
10
+ MSG = 'Favor `%s` over `%s` for negative conditions.'
11
+
10
12
  def on_while(node)
11
13
  check(node)
12
14
  end
13
15
 
14
- def error_message
15
- 'Favor `until` over `while` for negative conditions.'
16
+ def on_until(node)
17
+ check(node)
18
+ end
19
+
20
+ def message(node)
21
+ if node.type == :while
22
+ format(MSG, 'until', 'while')
23
+ else
24
+ format(MSG, 'while', 'until')
25
+ end
16
26
  end
17
27
 
18
28
  private
@@ -22,7 +32,9 @@ module Rubocop
22
32
  condition, _body, _rest = *node
23
33
  # unwrap the negated portion of the condition (a send node)
24
34
  pos_condition, _method, = *condition
25
- corrector.replace(node.loc.keyword, 'until')
35
+ corrector.replace(
36
+ node.loc.keyword,
37
+ node.type == :while ? 'until' : 'while')
26
38
  corrector.replace(condition.loc.expression,
27
39
  pos_condition.loc.expression.source)
28
40
  end
@@ -32,7 +32,7 @@ module Rubocop
32
32
  def autocorrect(node)
33
33
  @corrections << lambda do |corrector|
34
34
  expr = node.loc.expression
35
- new_code = expr.source.sub(/\s*==\s*nil/, '.nil?')
35
+ new_code = expr.source.sub(/\s*={2,3}\s*nil/, '.nil?')
36
36
  corrector.replace(expr, new_code)
37
37
  end
38
38
  end
@@ -13,12 +13,30 @@ module Rubocop
13
13
  #
14
14
  # # good
15
15
  # if x
16
+ #
17
+ # Non-nil checks are allowed if they are the final nodes of predicate.
18
+ #
19
+ # # good
20
+ # def signed_in?
21
+ # !current_user.nil?
22
+ # end
16
23
  class NonNilCheck < Cop
17
24
  MSG = 'Explicit non-nil checks are usually redundant.'
18
25
 
19
26
  NIL_NODE = s(:nil)
20
27
 
28
+ def on_def(node)
29
+ method_name, _args, body = *node
30
+ process_method(method_name, body)
31
+ end
32
+
33
+ def on_defs(node)
34
+ _scope, method_name, _args, body = *node
35
+ process_method(method_name, body)
36
+ end
37
+
21
38
  def on_send(node)
39
+ return if ignored_node?(node)
22
40
  receiver, method, args = *node
23
41
 
24
42
  return unless [:!=, :!].include?(method)
@@ -32,6 +50,18 @@ module Rubocop
32
50
 
33
51
  private
34
52
 
53
+ def process_method(name, body)
54
+ # only predicate methods are handled differently
55
+ return unless name.to_s.end_with?('?')
56
+ return unless body
57
+
58
+ if body.type != :begin
59
+ ignore_node(body)
60
+ elsif body.type == :begin
61
+ ignore_node(body.children.last)
62
+ end
63
+ end
64
+
35
65
  def nil_check?(node)
36
66
  return false unless node && node.type == :send
37
67
 
@@ -60,8 +90,12 @@ module Rubocop
60
90
  def autocorrect_non_nil(node, inner_node)
61
91
  @corrections << lambda do |corrector|
62
92
  receiver, _method, _args = *inner_node
63
- corrector.replace(node.loc.expression,
64
- receiver.loc.expression.source)
93
+ if receiver
94
+ corrector.replace(node.loc.expression,
95
+ receiver.loc.expression.source)
96
+ else
97
+ corrector.replace(node.loc.expression, 'self')
98
+ end
65
99
  end
66
100
  end
67
101
  end
@@ -5,6 +5,8 @@ module Rubocop
5
5
  module Style
6
6
  # This cop checks for uses if the keyword *not* instead of !.
7
7
  class Not < Cop
8
+ include AutocorrectUnlessChangingAST
9
+
8
10
  MSG = 'Use `!` instead of `not`.'
9
11
 
10
12
  def on_send(node)
@@ -19,20 +21,6 @@ module Rubocop
19
21
 
20
22
  private
21
23
 
22
- def autocorrect(node)
23
- c = correction(node)
24
- new_source = rewrite_node(node, c)
25
-
26
- # Make the correction only if it doesn't change the AST.
27
- @corrections << c if node == SourceParser.parse(new_source).ast
28
- end
29
-
30
- def rewrite_node(node, correction)
31
- processed_source = SourceParser.parse(node.loc.expression.source)
32
- c = correction(processed_source.ast)
33
- Corrector.new(processed_source.buffer, [c]).rewrite
34
- end
35
-
36
24
  def correction(node)
37
25
  lambda do |corrector|
38
26
  old_source = node.loc.expression.source
@@ -30,6 +30,7 @@ module Rubocop
30
30
  def check(t1, t2)
31
31
  # No offense if line break inside.
32
32
  return if t1.pos.line < t2.pos.line
33
+ return if t2.type == :tCOMMENT # Also indicates there's a line break.
33
34
 
34
35
  is_empty_braces = t1.text == '{' && t2.text == '}'
35
36
  expect_space = if is_empty_braces
@@ -29,6 +29,10 @@ module Rubocop
29
29
 
30
30
  def finished(inspected_files)
31
31
  output.puts HEADING
32
+
33
+ # Syntax isn't a real cop and it can't be disabled.
34
+ @cops_with_offenses.delete('Syntax')
35
+
32
36
  @cops_with_offenses.sort.each do |cop_name, offense_count|
33
37
  output.puts
34
38
  cfg = self.class.config_to_allow_offenses[cop_name]
@@ -3,7 +3,7 @@
3
3
  module Rubocop
4
4
  # This module holds the RuboCop version information.
5
5
  module Version
6
- STRING = '0.20.0'
6
+ STRING = '0.20.1'
7
7
 
8
8
  MSG = '%s (using Parser %s, running on %s %s %s)'
9
9
 
@@ -0,0 +1,24 @@
1
+ RuboCop 0.20.1 is a bugfix-only release. Below is a list of the bugs we've fixed since 0.20.0:
2
+
3
+ ## 0.20.1 (05/04/2014)
4
+
5
+ ### Bugs fixed
6
+
7
+ * [#940](https://github.com/bbatsov/rubocop/issues/940): Fixed `UselessAccessModifier` not handling `attr_*` correctly. ([@fshowalter][])
8
+ * `NegatedIf` properly handles negated `unless` condition. ([@bbatsov][])
9
+ * `NegatedWhile` properly handles negated `until` condition. ([@bbatsov][])
10
+ * [#925](https://github.com/bbatsov/rubocop/issues/925): Do not disable the `Syntax` cop in output from `--auto-gen-config`. ([@jonas054][])
11
+ * [#943](https://github.com/bbatsov/rubocop/issues/943): Fix auto-correction interference problem between `SpaceAfterComma` and other cops. ([@jonas054][])
12
+ * [#954](https://github.com/bbatsov/rubocop/pull/954): Fix auto-correction bug in `NilComparison`. ([@bbatsov][])
13
+ * [#953](https://github.com/bbatsov/rubocop/pull/953): Fix auto-correction bug in `NonNilCheck`. ([@bbatsov][])
14
+ * [#952](https://github.com/bbatsov/rubocop/pull/952): Handle implicit receiver in `StringConversionInInterpolation`. ([@bbatsov][])
15
+ * [#956](https://github.com/bbatsov/rubocop/pull/956): Apply `ClassMethods` check only on `class`/`module` bodies. ([@bbatsov][])
16
+ * [#945](https://github.com/bbatsov/rubocop/issues/945): Fix SpaceBeforeFirstArg cop for multiline argument and exclude assignments. ([@cschramm][])
17
+ * [#948](https://github.com/bbatsov/rubocop/issues/948): `Blocks` cop avoids auto-correction if it would introduce a semantic change. ([@jonas054][])
18
+ * [#946](https://github.com/bbatsov/rubocop/issues/946): Allow non-nil checks that are the final expressions of predicate method definitions in `NonNilCheck`. ([@bbatsov][])
19
+ * [#957](https://github.com/bbatsov/rubocop/issues/957): Allow space + comment inside parentheses, braces, and square brackets. ([@jonas054][])
20
+
21
+ [@bbatsov]: https://github.com/bbatsov
22
+ [@jonas054]: https://github.com/jonas054
23
+ [@fshowalter]: https://github.com/fshowalter
24
+ [@cschramm]: https://github.com/cschramm
@@ -271,6 +271,44 @@ describe Rubocop::CLI, :isolated_environment do
271
271
  ''].join("\n"))
272
272
  end
273
273
 
274
+ it 'can correct WordArray and SpaceAfterComma offenses' do
275
+ create_file('example.rb',
276
+ ['# encoding: utf-8',
277
+ "f(type: ['offline','offline_payment'],",
278
+ " bar_colors: ['958c12','953579','ff5800','0085cc'])"])
279
+ expect(cli.run(%w(-D --auto-correct --format o))).to eq(1)
280
+ expect($stdout.string)
281
+ .to eq(['',
282
+ '4 SpaceAfterComma',
283
+ '2 WordArray',
284
+ '--',
285
+ '6 Total',
286
+ '',
287
+ ''].join("\n"))
288
+ expect(IO.read('example.rb'))
289
+ .to eq(['# encoding: utf-8',
290
+ 'f(type: %w(offline offline_payment),',
291
+ ' bar_colors: %w(958c12 953579 ff5800 0085cc))',
292
+ ''].join("\n"))
293
+ end
294
+
295
+ it 'can correct SpaceAfterComma and HashSyntax offenses' do
296
+ create_file('example.rb',
297
+ ['# encoding: utf-8',
298
+ "I18n.t('description',:property_name => property.name)"])
299
+ expect(cli.run(%w(-D --auto-correct --format emacs))).to eq(1)
300
+ expect($stdout.string)
301
+ .to eq(["#{abs('example.rb')}:2:21: C: [Corrected] " \
302
+ "SpaceAfterComma: Space missing after comma.",
303
+ "#{abs('example.rb')}:2:22: C: [Corrected] " \
304
+ "HashSyntax: Use the new Ruby 1.9 hash syntax.",
305
+ ''].join("\n"))
306
+ expect(IO.read('example.rb'))
307
+ .to eq(['# encoding: utf-8',
308
+ "I18n.t('description', property_name: property.name)",
309
+ ''].join("\n"))
310
+ end
311
+
274
312
  it 'can correct HashSyntax and SpaceAroundOperators offenses' do
275
313
  create_file('example.rb',
276
314
  ['# encoding: utf-8',
@@ -499,6 +537,43 @@ describe Rubocop::CLI, :isolated_environment do
499
537
  end
500
538
  end
501
539
 
540
+ it 'does not generate configuration for the Syntax cop' do
541
+ create_file('example1.rb', ['# encoding: utf-8',
542
+ 'x = < ', # Syntax error
543
+ 'puts x'])
544
+ create_file('example2.rb', ['# encoding: utf-8',
545
+ "\tx = 0",
546
+ 'puts x'])
547
+ expect(cli.run(['--auto-gen-config'])).to eq(1)
548
+ expect($stderr.string).to eq('')
549
+ expected =
550
+ ['# This configuration was generated by `rubocop --auto-gen-config`',
551
+ /# on .* using RuboCop version .*/,
552
+ '# The point is for the user to remove these configuration records',
553
+ '# one by one as the offenses are removed from the code base.',
554
+ '# Note that changes in the inspected code, or installation of new',
555
+ '# versions of RuboCop, may require this file to be generated ' \
556
+ 'again.',
557
+ '',
558
+ '# Offense count: 1',
559
+ '# Cop supports --auto-correct.',
560
+ 'IndentationConsistency:',
561
+ ' Enabled: false',
562
+ '',
563
+ '# Offense count: 1',
564
+ 'Tab:',
565
+ ' Enabled: false']
566
+ actual = IO.read('rubocop-todo.yml').split($RS)
567
+ expect(actual.length).to eq(expected.length)
568
+ expected.each_with_index do |line, ix|
569
+ if line.is_a?(String)
570
+ expect(actual[ix]).to eq(line)
571
+ else
572
+ expect(actual[ix]).to match(line)
573
+ end
574
+ end
575
+ end
576
+
502
577
  it 'generates a todo list that removes the reports' do
503
578
  create_file('example.rb', ['# encoding: utf-8',
504
579
  'y.gsub!(%r{abc/xyz}, "#{x}")'])
@@ -26,6 +26,16 @@ describe Rubocop::Cop::Lint::SpaceBeforeFirstArg do
26
26
  inspect_source(cop, ['something[:x]'])
27
27
  expect(cop.offenses).to be_empty
28
28
  end
29
+
30
+ it 'accepts a method call with space before a multiline arg' do
31
+ inspect_source(cop, "something [\n 'foo',\n 'bar'\n]")
32
+ expect(cop.offenses).to be_empty
33
+ end
34
+
35
+ it 'accepts an assignment without space before first arg' do
36
+ inspect_source(cop, ['a.something=c', 'a.something,b=c,d'])
37
+ expect(cop.offenses).to be_empty
38
+ end
29
39
  end
30
40
 
31
41
  context 'for method calls with parentheses' do
@@ -8,6 +8,8 @@ describe Rubocop::Cop::Lint::StringConversionInInterpolation do
8
8
  it 'registers an offense for #to_s in interpolation' do
9
9
  inspect_source(cop, '"this is the #{result.to_s}"')
10
10
  expect(cop.offenses.size).to eq(1)
11
+ expect(cop.messages)
12
+ .to eq(['Redundant use of `Object#to_s` in interpolation.'])
11
13
  end
12
14
 
13
15
  it 'detects #to_s in an interpolation with several expressions' do
@@ -25,6 +27,13 @@ describe Rubocop::Cop::Lint::StringConversionInInterpolation do
25
27
  expect(cop.offenses).to be_empty
26
28
  end
27
29
 
30
+ it 'does not explode on implicit receiver' do
31
+ inspect_source(cop, '"#{to_s}"')
32
+ expect(cop.offenses.size).to eq(1)
33
+ expect(cop.messages)
34
+ .to eq(['Use `self` instead of `Object#to_s` in interpolation.'])
35
+ end
36
+
28
37
  it 'does not explode on empty interpolation' do
29
38
  inspect_source(cop, '"this is #{} silly"')
30
39
  expect(cop.offenses).to be_empty
@@ -34,4 +43,9 @@ describe Rubocop::Cop::Lint::StringConversionInInterpolation do
34
43
  corrected = autocorrect_source(cop, ['"some #{something.to_s}"'])
35
44
  expect(corrected).to eq '"some #{something}"'
36
45
  end
46
+
47
+ it 'autocorrects implicit receiver by replacing to_s with self' do
48
+ corrected = autocorrect_source(cop, ['"some #{to_s}"'])
49
+ expect(corrected).to eq '"some #{self}"'
50
+ end
37
51
  end
@@ -49,6 +49,44 @@ describe Rubocop::Cop::Lint::UselessAccessModifier do
49
49
  end
50
50
  end
51
51
 
52
+ context 'when an access modifier is followed by attr_*' do
53
+ let(:source) do
54
+ [
55
+ 'class SomeClass',
56
+ ' protected',
57
+ ' attr_accessor :some_property',
58
+ 'end'
59
+ ]
60
+ end
61
+
62
+ it 'does not register an offense' do
63
+ inspect_source(cop, source)
64
+ expect(cop.offenses.size).to eq(0)
65
+ end
66
+ end
67
+
68
+ context 'when an access modifier is followed by a ' \
69
+ 'class method defined on constant' do
70
+ let(:source) do
71
+ [
72
+ 'class SomeClass',
73
+ ' protected',
74
+ ' def SomeClass.some_method',
75
+ ' end',
76
+ 'end'
77
+ ]
78
+ end
79
+
80
+ it 'registers an offense' do
81
+ inspect_source(cop, source)
82
+ expect(cop.offenses.size).to eq(1)
83
+ expect(cop.offenses.first.message)
84
+ .to eq('Useless `protected` access modifier.')
85
+ expect(cop.offenses.first.line).to eq(2)
86
+ expect(cop.highlights).to eq(['protected'])
87
+ end
88
+ end
89
+
52
90
  context 'when consecutive access modifiers' do
53
91
  let(:source) do
54
92
  [
@@ -27,6 +27,12 @@ describe Rubocop::Cop::Style::Blocks do
27
27
  expect(new_source).to eq('block { |x| }')
28
28
  end
29
29
 
30
+ it 'does not auto-correct do-end if {} would change the meaning' do
31
+ src = "s.subspec 'Subspec' do |sp| end"
32
+ new_source = autocorrect_source(cop, src)
33
+ expect(new_source).to eq(src)
34
+ end
35
+
30
36
  context 'when there are braces around a multi-line block' do
31
37
  it 'registers an offense in the simple case' do
32
38
  inspect_source(cop, ['each { |x|',
@@ -43,7 +43,7 @@ describe Rubocop::Cop::Style::ClassMethods do
43
43
 
44
44
  it 'does not register an offense outside class/module bodies' do
45
45
  inspect_source(cop,
46
- ['def self.some_method',
46
+ ['def Test.some_method',
47
47
  ' do_something',
48
48
  'end'])
49
49
  expect(cop.offenses).to be_empty
@@ -17,6 +17,17 @@ describe Rubocop::Cop::Style::NegatedIf do
17
17
  'conditions.'] * 2)
18
18
  end
19
19
 
20
+ it 'registers an offense for unless with exclamation point condition' do
21
+ inspect_source(cop,
22
+ ['unless !a_condition',
23
+ ' some_method',
24
+ 'end',
25
+ 'some_method unless !a_condition'
26
+ ])
27
+ expect(cop.messages).to eq(['Favor `if` over `unless` for negative ' \
28
+ 'conditions.'] * 2)
29
+ end
30
+
20
31
  it 'registers an offense for if with "not" condition' do
21
32
  inspect_source(cop,
22
33
  ['if not a_condition',
@@ -78,4 +89,10 @@ describe Rubocop::Cop::Style::NegatedIf do
78
89
  corrected = autocorrect_source(cop, 'something if !x.even?')
79
90
  expect(corrected).to eq 'something unless x.even?'
80
91
  end
92
+
93
+ it 'autocorrects by replacing unless not with if' do
94
+ corrected = autocorrect_source(cop, 'something unless !x.even?')
95
+ expect(corrected).to eq 'something if x.even?'
96
+ end
97
+
81
98
  end
@@ -16,6 +16,17 @@ describe Rubocop::Cop::Style::NegatedWhile do
16
16
  ['Favor `until` over `while` for negative conditions.'] * 2)
17
17
  end
18
18
 
19
+ it 'registers an offense for until with exclamation point condition' do
20
+ inspect_source(cop,
21
+ ['until !a_condition',
22
+ ' some_method',
23
+ 'end',
24
+ 'some_method until !a_condition'
25
+ ])
26
+ expect(cop.messages)
27
+ .to eq(['Favor `while` over `until` for negative conditions.'] * 2)
28
+ end
29
+
19
30
  it 'registers an offense for while with "not" condition' do
20
31
  inspect_source(cop,
21
32
  ['while (not a_condition)',
@@ -43,4 +54,9 @@ describe Rubocop::Cop::Style::NegatedWhile do
43
54
  corrected = autocorrect_source(cop, 'something while !x.even?')
44
55
  expect(corrected).to eq 'something until x.even?'
45
56
  end
57
+
58
+ it 'autocorrects by replacing until not with while' do
59
+ corrected = autocorrect_source(cop, 'something until !x.even?')
60
+ expect(corrected).to eq 'something while x.even?'
61
+ end
46
62
  end
@@ -21,4 +21,9 @@ describe Rubocop::Cop::Style::NilComparison do
21
21
  corrected = autocorrect_source(cop, 'x == nil')
22
22
  expect(corrected).to eq 'x.nil?'
23
23
  end
24
+
25
+ it 'autocorrects by replacing === nil with .nil?' do
26
+ corrected = autocorrect_source(cop, 'x === nil')
27
+ expect(corrected).to eq 'x.nil?'
28
+ end
24
29
  end
@@ -23,6 +23,36 @@ describe Rubocop::Cop::Style::NonNilCheck do
23
23
  expect(cop.highlights).to eq(['not x.nil?'])
24
24
  end
25
25
 
26
+ it 'does not register an offense if only expression in predicate' do
27
+ inspect_source(cop, ['def signed_in?',
28
+ ' !current_user.nil?',
29
+ 'end'])
30
+ expect(cop.offenses).to be_empty
31
+ end
32
+
33
+ it 'does not register an offense if only expression in class predicate' do
34
+ inspect_source(cop, ['def Test.signed_in?',
35
+ ' !current_user.nil?',
36
+ 'end'])
37
+ expect(cop.offenses).to be_empty
38
+ end
39
+
40
+ it 'does not register an offense if last expression in predicate' do
41
+ inspect_source(cop, ['def signed_in?',
42
+ ' something',
43
+ ' !current_user.nil?',
44
+ 'end'])
45
+ expect(cop.offenses).to be_empty
46
+ end
47
+
48
+ it 'does not register an offense if last expression in class predicate' do
49
+ inspect_source(cop, ['def Test.signed_in?',
50
+ ' something',
51
+ ' !current_user.nil?',
52
+ 'end'])
53
+ expect(cop.offenses).to be_empty
54
+ end
55
+
26
56
  it 'autocorrects by removing != nil' do
27
57
  corrected = autocorrect_source(cop, 'x != nil')
28
58
  expect(corrected).to eq 'x'
@@ -32,4 +62,9 @@ describe Rubocop::Cop::Style::NonNilCheck do
32
62
  corrected = autocorrect_source(cop, '!x.nil?')
33
63
  expect(corrected).to eq 'x'
34
64
  end
65
+
66
+ it 'does not blow up when autocorrecting implicit receiver' do
67
+ corrected = autocorrect_source(cop, '!nil?')
68
+ expect(corrected).to eq 'self'
69
+ end
35
70
  end
@@ -34,6 +34,12 @@ describe Rubocop::Cop::Style::SpaceInsideBlockBraces do
34
34
  expect(cop.messages).to be_empty
35
35
  end
36
36
 
37
+ it 'accepts empty braces with comment and line break inside' do
38
+ inspect_source(cop, [' each { # Comment',
39
+ ' }'])
40
+ expect(cop.messages).to be_empty
41
+ end
42
+
37
43
  it 'registers an offense for empty braces with space inside' do
38
44
  inspect_source(cop, ['each { }'])
39
45
  expect(cop.messages).to eq(['Space inside empty braces detected.'])
@@ -26,6 +26,13 @@ describe Rubocop::Cop::Style::SpaceInsideBrackets do
26
26
  expect(cop.messages).to be_empty
27
27
  end
28
28
 
29
+ it 'accepts space inside square brackets if with comment' do
30
+ inspect_source(cop, ['a = [ # Comment',
31
+ ' 1, 2',
32
+ ' ]'])
33
+ expect(cop.messages).to be_empty
34
+ end
35
+
29
36
  it 'accepts square brackets as method name' do
30
37
  inspect_source(cop, ['def Vector.[](*array)',
31
38
  'end'])
@@ -107,7 +107,7 @@ describe Rubocop::Cop::Style::SpaceInsideHashLiteralBraces, :config do
107
107
  expect(cop.offenses).to be_empty
108
108
  end
109
109
 
110
- it 'accepts multiline hashes for no space' do
110
+ it 'accepts multiline hash' do
111
111
  inspect_source(cop,
112
112
  ['h = {',
113
113
  ' a: 1,',
@@ -115,6 +115,15 @@ describe Rubocop::Cop::Style::SpaceInsideHashLiteralBraces, :config do
115
115
  '}'])
116
116
  expect(cop.offenses).to be_empty
117
117
  end
118
+
119
+ it 'accepts multiline hash with comment' do
120
+ inspect_source(cop,
121
+ ['h = { # Comment',
122
+ ' a: 1,',
123
+ ' b: 2,',
124
+ '}'])
125
+ expect(cop.offenses).to be_empty
126
+ end
118
127
  end
119
128
 
120
129
  it 'accepts hashes with spaces by default' do
@@ -25,6 +25,18 @@ describe Rubocop::Cop::Style::SpaceInsideParens do
25
25
  expect(cop.messages).to be_empty
26
26
  end
27
27
 
28
+ it 'accepts parentheses with line break' do
29
+ inspect_source(cop, ['f(',
30
+ ' 1)'])
31
+ expect(cop.messages).to be_empty
32
+ end
33
+
34
+ it 'accepts parentheses with comment and line break' do
35
+ inspect_source(cop, ['f( # Comment',
36
+ ' 1)'])
37
+ expect(cop.messages).to be_empty
38
+ end
39
+
28
40
  it 'auto-corrects unwanted space' do
29
41
  new_source = autocorrect_source(cop, ['f( 3)',
30
42
  'g(3 )'])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.20.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bozhidar Batsov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-02 00:00:00.000000000 Z
11
+ date: 2014-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -234,6 +234,7 @@ files:
234
234
  - lib/rubocop/cop/mixin/annotation_comment.rb
235
235
  - lib/rubocop/cop/mixin/array_syntax.rb
236
236
  - lib/rubocop/cop/mixin/autocorrect_alignment.rb
237
+ - lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb
237
238
  - lib/rubocop/cop/mixin/check_assignment.rb
238
239
  - lib/rubocop/cop/mixin/check_methods.rb
239
240
  - lib/rubocop/cop/mixin/code_length.rb
@@ -421,6 +422,7 @@ files:
421
422
  - relnotes/v0.19.0.md
422
423
  - relnotes/v0.19.1.md
423
424
  - relnotes/v0.20.0.md
425
+ - relnotes/v0.20.1.md
424
426
  - rubocop-todo.yml
425
427
  - rubocop.gemspec
426
428
  - spec/.rubocop.yml