rubocop 0.21.0 → 0.22.0

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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/{rubocop-todo.yml → .rubocop_todo.yml} +5 -5
  4. data/CHANGELOG.md +41 -0
  5. data/README.md +21 -11
  6. data/config/default.yml +33 -10
  7. data/config/disabled.yml +0 -4
  8. data/config/enabled.yml +27 -1
  9. data/lib/rubocop.rb +17 -1
  10. data/lib/rubocop/config.rb +32 -27
  11. data/lib/rubocop/config_loader.rb +21 -8
  12. data/lib/rubocop/cop/cop.rb +8 -8
  13. data/lib/rubocop/cop/lint/block_alignment.rb +22 -22
  14. data/lib/rubocop/cop/lint/condition_position.rb +3 -5
  15. data/lib/rubocop/cop/lint/debugger.rb +4 -5
  16. data/lib/rubocop/cop/lint/end_alignment.rb +11 -10
  17. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +10 -11
  18. data/lib/rubocop/cop/lint/require_parentheses.rb +7 -7
  19. data/lib/rubocop/cop/lint/rescue_exception.rb +3 -3
  20. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -7
  21. data/lib/rubocop/cop/lint/unreachable_code.rb +2 -3
  22. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -15
  23. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -14
  24. data/lib/rubocop/cop/lint/useless_comparison.rb +4 -5
  25. data/lib/rubocop/cop/lint/void.rb +6 -8
  26. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +4 -2
  27. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +1 -3
  28. data/lib/rubocop/cop/mixin/code_length.rb +5 -5
  29. data/lib/rubocop/cop/mixin/negative_conditional.rb +6 -6
  30. data/lib/rubocop/cop/mixin/percent_literal.rb +2 -3
  31. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -5
  32. data/lib/rubocop/cop/mixin/space_inside.rb +10 -11
  33. data/lib/rubocop/cop/mixin/unused_argument.rb +35 -0
  34. data/lib/rubocop/cop/offense.rb +1 -1
  35. data/lib/rubocop/cop/rails/action_filter.rb +6 -8
  36. data/lib/rubocop/cop/rails/default_scope.rb +2 -4
  37. data/lib/rubocop/cop/rails/delegate.rb +2 -0
  38. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +2 -3
  39. data/lib/rubocop/cop/rails/output.rb +2 -3
  40. data/lib/rubocop/cop/rails/read_write_attribute.rb +3 -4
  41. data/lib/rubocop/cop/rails/validation.rb +2 -3
  42. data/lib/rubocop/cop/style/alias.rb +3 -3
  43. data/lib/rubocop/cop/style/align_hash.rb +4 -4
  44. data/lib/rubocop/cop/style/align_parameters.rb +13 -1
  45. data/lib/rubocop/cop/style/and_or.rb +2 -5
  46. data/lib/rubocop/cop/style/array_join.rb +3 -4
  47. data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -3
  48. data/lib/rubocop/cop/style/block_comments.rb +2 -3
  49. data/lib/rubocop/cop/style/block_nesting.rb +2 -3
  50. data/lib/rubocop/cop/style/blocks.rb +9 -9
  51. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +5 -5
  52. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  53. data/lib/rubocop/cop/style/class_methods.rb +3 -5
  54. data/lib/rubocop/cop/style/collection_methods.rb +8 -11
  55. data/lib/rubocop/cop/style/comment_annotation.rb +9 -9
  56. data/lib/rubocop/cop/style/comment_indentation.rb +66 -0
  57. data/lib/rubocop/cop/style/constant_name.rb +3 -3
  58. data/lib/rubocop/cop/style/cyclomatic_complexity.rb +5 -5
  59. data/lib/rubocop/cop/style/deprecated_hash_methods.rb +6 -6
  60. data/lib/rubocop/cop/style/each_with_object.rb +38 -0
  61. data/lib/rubocop/cop/style/empty_lines.rb +8 -8
  62. data/lib/rubocop/cop/style/empty_lines_around_body.rb +7 -7
  63. data/lib/rubocop/cop/style/encoding.rb +6 -7
  64. data/lib/rubocop/cop/style/end_of_line.rb +10 -10
  65. data/lib/rubocop/cop/style/file_name.rb +11 -7
  66. data/lib/rubocop/cop/style/guard_clause.rb +32 -22
  67. data/lib/rubocop/cop/style/indentation_width.rb +25 -26
  68. data/lib/rubocop/cop/style/lambda.rb +8 -9
  69. data/lib/rubocop/cop/style/leading_comment_space.rb +4 -5
  70. data/lib/rubocop/cop/style/line_end_concatenation.rb +29 -6
  71. data/lib/rubocop/cop/style/line_length.rb +9 -9
  72. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +7 -6
  73. data/lib/rubocop/cop/style/module_function.rb +3 -4
  74. data/lib/rubocop/cop/style/multiline_if_then.rb +3 -3
  75. data/lib/rubocop/cop/style/negated_if.rb +2 -0
  76. data/lib/rubocop/cop/style/next.rb +80 -0
  77. data/lib/rubocop/cop/style/nil_comparison.rb +2 -3
  78. data/lib/rubocop/cop/style/non_nil_check.rb +15 -3
  79. data/lib/rubocop/cop/style/not.rb +4 -4
  80. data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
  81. data/lib/rubocop/cop/style/op_method.rb +3 -5
  82. data/lib/rubocop/cop/style/parameter_lists.rb +4 -4
  83. data/lib/rubocop/cop/style/parentheses_around_condition.rb +5 -6
  84. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +5 -5
  85. data/lib/rubocop/cop/style/predicate_name.rb +2 -4
  86. data/lib/rubocop/cop/style/redundant_self.rb +11 -12
  87. data/lib/rubocop/cop/style/self_assignment.rb +8 -13
  88. data/lib/rubocop/cop/style/semicolon.rb +16 -19
  89. data/lib/rubocop/cop/style/signal_exception.rb +10 -11
  90. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -3
  91. data/lib/rubocop/cop/style/single_line_methods.rb +3 -4
  92. data/lib/rubocop/cop/style/space_after_colon.rb +9 -9
  93. data/lib/rubocop/cop/style/space_after_control_keyword.rb +3 -3
  94. data/lib/rubocop/cop/style/space_after_method_name.rb +3 -3
  95. data/lib/rubocop/cop/style/space_after_not.rb +3 -4
  96. data/lib/rubocop/cop/style/space_around_operators.rb +5 -4
  97. data/lib/rubocop/cop/style/space_before_comment.rb +29 -0
  98. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +6 -7
  99. data/lib/rubocop/cop/style/symbol_array.rb +2 -3
  100. data/lib/rubocop/cop/style/tab.rb +8 -8
  101. data/lib/rubocop/cop/style/trailing_blank_lines.rb +10 -10
  102. data/lib/rubocop/cop/style/trailing_whitespace.rb +6 -7
  103. data/lib/rubocop/cop/style/trivial_accessors.rb +3 -4
  104. data/lib/rubocop/cop/style/unless_else.rb +2 -3
  105. data/lib/rubocop/cop/style/unneeded_capital_w.rb +3 -3
  106. data/lib/rubocop/cop/style/unneeded_percent_x.rb +26 -0
  107. data/lib/rubocop/cop/style/when_then.rb +3 -3
  108. data/lib/rubocop/cop/style/while_until_do.rb +3 -6
  109. data/lib/rubocop/cop/style/word_array.rb +8 -7
  110. data/lib/rubocop/cop/team.rb +9 -11
  111. data/lib/rubocop/cop/util.rb +2 -3
  112. data/lib/rubocop/cop/variable_force.rb +2 -3
  113. data/lib/rubocop/cop/variable_force/variable_table.rb +1 -2
  114. data/lib/rubocop/file_inspector.rb +5 -0
  115. data/lib/rubocop/formatter/clang_style_formatter.rb +3 -4
  116. data/lib/rubocop/formatter/disabled_config_formatter.rb +6 -6
  117. data/lib/rubocop/options.rb +14 -11
  118. data/lib/rubocop/target_finder.rb +12 -1
  119. data/lib/rubocop/version.rb +1 -1
  120. data/relnotes/v0.21.0.md +11 -0
  121. data/relnotes/v0.22.0.md +77 -0
  122. data/spec/rubocop/cli_spec.rb +86 -40
  123. data/spec/rubocop/comment_config_spec.rb +1 -1
  124. data/spec/rubocop/config_loader_spec.rb +3 -3
  125. data/spec/rubocop/config_spec.rb +14 -3
  126. data/spec/rubocop/cop/force_spec.rb +1 -1
  127. data/spec/rubocop/cop/lint/unused_block_argument_spec.rb +164 -99
  128. data/spec/rubocop/cop/lint/unused_method_argument_spec.rb +195 -85
  129. data/spec/rubocop/cop/lint/void_spec.rb +8 -0
  130. data/spec/rubocop/cop/rails/delegate_spec.rb +17 -0
  131. data/spec/rubocop/cop/rails/output_spec.rb +3 -3
  132. data/spec/rubocop/cop/severity_spec.rb +5 -5
  133. data/spec/rubocop/cop/style/align_parameters_spec.rb +108 -0
  134. data/spec/rubocop/cop/style/block_nesting_spec.rb +3 -3
  135. data/spec/rubocop/cop/style/class_and_module_children_spec.rb +12 -10
  136. data/spec/rubocop/cop/style/comment_indentation_spec.rb +174 -0
  137. data/spec/rubocop/cop/style/each_with_object_spec.rb +44 -0
  138. data/spec/rubocop/cop/style/end_of_line_spec.rb +3 -5
  139. data/spec/rubocop/cop/style/guard_clause_spec.rb +135 -57
  140. data/spec/rubocop/cop/style/if_unless_modifier_spec.rb +7 -7
  141. data/spec/rubocop/cop/style/line_end_concatenation_spec.rb +75 -1
  142. data/spec/rubocop/cop/style/line_length_spec.rb +7 -7
  143. data/spec/rubocop/cop/style/negated_if_spec.rb +5 -1
  144. data/spec/rubocop/cop/style/next_spec.rb +210 -0
  145. data/spec/rubocop/cop/style/non_nil_check_spec.rb +44 -13
  146. data/spec/rubocop/cop/style/self_assignment_spec.rb +1 -1
  147. data/spec/rubocop/cop/style/space_around_operators_spec.rb +1 -0
  148. data/spec/rubocop/cop/style/space_before_comment_spec.rb +34 -0
  149. data/spec/rubocop/cop/style/unneeded_percent_x_spec.rb +34 -0
  150. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +2 -2
  151. data/spec/rubocop/cop/util_spec.rb +2 -2
  152. data/spec/rubocop/cop/variable_force_spec.rb +1 -1
  153. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +4 -4
  154. data/spec/rubocop/formatter/disabled_lines_formatter_spec.rb +2 -2
  155. data/spec/rubocop/formatter/offense_count_formatter_spec.rb +2 -2
  156. data/spec/rubocop/options_spec.rb +3 -0
  157. data/spec/support/shared_context.rb +1 -3
  158. data/spec/support/statement_modifier_helper.rb +2 -2
  159. metadata +20 -3
@@ -7,7 +7,7 @@ describe Rubocop::Cop::Style::IfUnlessModifier do
7
7
 
8
8
  subject(:cop) { described_class.new(config) }
9
9
  let(:config) do
10
- hash = { 'LineLength' => { 'Max' => 79 } }
10
+ hash = { 'LineLength' => { 'Max' => 80 } }
11
11
  Rubocop::Config.new(hash)
12
12
  end
13
13
 
@@ -15,8 +15,8 @@ describe Rubocop::Cop::Style::IfUnlessModifier do
15
15
  # This if statement fits exactly on one line if written as a
16
16
  # modifier.
17
17
  condition = 'a' * 38
18
- body = 'b' * 35
19
- expect(" #{body} if #{condition}".length).to eq(79)
18
+ body = 'b' * 36
19
+ expect(" #{body} if #{condition}".length).to eq(80)
20
20
 
21
21
  inspect_source(cop,
22
22
  [" if #{condition}",
@@ -101,13 +101,13 @@ describe Rubocop::Cop::Style::IfUnlessModifier do
101
101
  ]
102
102
  end
103
103
 
104
- let(:body) { 'b' * 35 }
104
+ let(:body) { 'b' * 36 }
105
105
 
106
106
  context 'when a multiline if fits on one line' do
107
107
  let(:conditional) { "/#{'a' * 36}/" }
108
108
 
109
109
  it 'registers an offense' do
110
- expect(" #{body} if #{conditional}".length).to eq(79)
110
+ expect(" #{body} if #{conditional}".length).to eq(80)
111
111
 
112
112
  inspect_source(cop, source)
113
113
  expect(cop.offenses.size).to eq(1)
@@ -118,7 +118,7 @@ describe Rubocop::Cop::Style::IfUnlessModifier do
118
118
  let(:conditional) { "/#{'a' * 37}/" }
119
119
 
120
120
  it 'accepts' do
121
- expect(" #{body} if #{conditional}".length).to eq(80)
121
+ expect(" #{body} if #{conditional}".length).to eq(81)
122
122
 
123
123
  inspect_source(cop, source)
124
124
  expect(cop.offenses).to be_empty
@@ -129,7 +129,7 @@ describe Rubocop::Cop::Style::IfUnlessModifier do
129
129
  let(:config) do
130
130
  hash = {
131
131
  'LineLength' => { 'Max' => 100 },
132
- 'IfUnlessModifier' => { 'MaxLineLength' => 79 }
132
+ 'IfUnlessModifier' => { 'MaxLineLength' => 80 }
133
133
  }
134
134
  Rubocop::Config.new(hash)
135
135
  end
@@ -33,6 +33,32 @@ describe Rubocop::Cop::Style::LineEndConcatenation do
33
33
  expect(cop.offenses.size).to eq(1)
34
34
  end
35
35
 
36
+ it 'registers multiple offenses when there are chained << methods' do
37
+ inspect_source(cop,
38
+ ['top = "test#{x}" <<',
39
+ '"top" <<',
40
+ '"ubertop"'])
41
+ expect(cop.offenses.size).to eq(2)
42
+ end
43
+
44
+ it 'registers multiple offenses when there are chained concatenations' do
45
+ inspect_source(cop,
46
+ ['top = "test#{x}" +',
47
+ '"top" +',
48
+ '"foo"'])
49
+ expect(cop.offenses.size).to eq(2)
50
+ end
51
+
52
+ it 'registers multiple offenses when there are chained concatenations' \
53
+ 'combined with << calls' do
54
+ inspect_source(cop,
55
+ ['top = "test#{x}" <<',
56
+ '"top" +',
57
+ '"foo" <<',
58
+ '"bar"'])
59
+ expect(cop.offenses.size).to eq(3)
60
+ end
61
+
36
62
  it 'accepts string concat on the same line' do
37
63
  inspect_source(cop,
38
64
  ['top = "test" + "top"'])
@@ -53,10 +79,58 @@ describe Rubocop::Cop::Style::LineEndConcatenation do
53
79
  expect(cop.offenses).to be_empty
54
80
  end
55
81
 
56
- it 'autocorrects by replacing + with \\' do
82
+ it 'accepts string concat at line end for special strings like __FILE__' do
83
+ inspect_source(cop,
84
+ ['top = __FILE__ +',
85
+ '"top"'])
86
+ expect(cop.offenses).to be_empty
87
+ end
88
+
89
+ it 'registers offenses only for the appropriate lines in chained concats' do
90
+ # only the last concatenation is an offense
91
+ inspect_source(cop,
92
+ ['top = "test#{x}" + # comment',
93
+ '"foo" +',
94
+ '%(bar) +',
95
+ '"baz" +',
96
+ '"qux"'])
97
+ expect(cop.offenses.size).to eq(1)
98
+ end
99
+
100
+ it 'autocorrects in the simple case by replacing + with \\' do
57
101
  corrected = autocorrect_source(cop,
58
102
  ['top = "test" +',
59
103
  '"top"'])
60
104
  expect(corrected).to eq ['top = "test" \\', '"top"'].join("\n")
61
105
  end
106
+
107
+ it 'autocorrects for chained concatenations and << calls' do
108
+ corrected = autocorrect_source(cop,
109
+ ['top = "test#{x}" <<',
110
+ '"top" +',
111
+ '"ubertop" <<',
112
+ '"foo"'])
113
+
114
+ expect(corrected).to eq ['top = "test#{x}" \\',
115
+ '"top" \\',
116
+ '"ubertop" \\',
117
+ '"foo"'].join("\n")
118
+ end
119
+
120
+ it 'autocorrects only the lines that should be autocorrected' do
121
+ corrected = autocorrect_source(cop,
122
+ ['top = "test#{x}" <<',
123
+ '"top" + # comment',
124
+ '"foo" +',
125
+ '"bar" +',
126
+ '%(baz) +',
127
+ '"qux"'])
128
+
129
+ expect(corrected).to eq ['top = "test#{x}" \\',
130
+ '"top" + # comment',
131
+ '"foo" \\',
132
+ '"bar" +',
133
+ '%(baz) +',
134
+ '"qux"'].join("\n")
135
+ end
62
136
  end
@@ -4,17 +4,17 @@ require 'spec_helper'
4
4
 
5
5
  describe Rubocop::Cop::Style::LineLength, :config do
6
6
  subject(:cop) { described_class.new(config) }
7
- let(:cop_config) { { 'Max' => 79 } }
7
+ let(:cop_config) { { 'Max' => 80 } }
8
8
 
9
- it "registers an offense for a line that's 80 characters wide" do
10
- inspect_source(cop, ['#' * 80])
9
+ it "registers an offense for a line that's 81 characters wide" do
10
+ inspect_source(cop, ['#' * 81])
11
11
  expect(cop.offenses.size).to eq(1)
12
- expect(cop.offenses.first.message).to eq('Line is too long. [80/79]')
13
- expect(cop.config_to_allow_offenses).to eq('Max' => 80)
12
+ expect(cop.offenses.first.message).to eq('Line is too long. [81/80]')
13
+ expect(cop.config_to_allow_offenses).to eq('Max' => 81)
14
14
  end
15
15
 
16
- it "accepts a line that's 79 characters wide" do
17
- inspect_source(cop, ['#' * 79])
16
+ it "accepts a line that's 80 characters wide" do
17
+ inspect_source(cop, ['#' * 80])
18
18
  expect(cop.offenses).to be_empty
19
19
  end
20
20
  end
@@ -90,9 +90,13 @@ describe Rubocop::Cop::Style::NegatedIf do
90
90
  expect(corrected).to eq 'something unless x.even?'
91
91
  end
92
92
 
93
+ it 'autocorrects by replacing parenthesized if not with unless' do
94
+ corrected = autocorrect_source(cop, 'something if (!x.even?)')
95
+ expect(corrected).to eq 'something unless (x.even?)'
96
+ end
97
+
93
98
  it 'autocorrects by replacing unless not with if' do
94
99
  corrected = autocorrect_source(cop, 'something unless !x.even?')
95
100
  expect(corrected).to eq 'something if x.even?'
96
101
  end
97
-
98
102
  end
@@ -0,0 +1,210 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Rubocop::Cop::Style::Next, :config do
6
+ subject(:cop) { described_class.new(config) }
7
+ let(:cop_config) { {} }
8
+
9
+ it 'finds all kind of loops with condition at the end of the iteration' do
10
+ inspect_source(cop,
11
+ ['3.downto(1) do',
12
+ ' if o == 1',
13
+ ' puts o',
14
+ ' end',
15
+ 'end',
16
+ '',
17
+ '[].each do |o|',
18
+ ' if o == 1',
19
+ ' puts o',
20
+ ' end',
21
+ 'end',
22
+ '',
23
+ '[].each_with_object({}) do |o, a|',
24
+ ' if o == 1',
25
+ ' a[o] = {}',
26
+ ' end',
27
+ 'end',
28
+ '',
29
+ 'for o in 1..3 do',
30
+ ' if o == 1',
31
+ ' puts o',
32
+ ' end',
33
+ 'end',
34
+ '',
35
+ 'loop do',
36
+ ' if o == 1',
37
+ ' puts o',
38
+ ' end',
39
+ 'end',
40
+ '',
41
+ '{}.map do |k, v|',
42
+ ' if v == 1',
43
+ ' puts k',
44
+ ' end',
45
+ 'end',
46
+ '',
47
+ '3.times do |o|',
48
+ ' if o == 1',
49
+ ' puts o',
50
+ ' end',
51
+ 'end',
52
+ '',
53
+ 'until false',
54
+ ' if o == 1',
55
+ ' puts o',
56
+ ' end',
57
+ 'end',
58
+ '',
59
+ 'while true',
60
+ ' if o == 1',
61
+ ' puts o',
62
+ ' end',
63
+ 'end'])
64
+ expect(cop.offenses.size).to eq(9)
65
+ expect(cop.offenses.map(&:line).sort).to eq([1, 7, 13, 19, 25, 31, 37, 43,
66
+ 49])
67
+ expect(cop.messages) .to eq(['Use `next` to skip iteration.'] * 9)
68
+ expect(cop.highlights).to eq(%w(downto each each_with_object for loop map
69
+ times until while))
70
+ end
71
+
72
+ it 'finds loop with condition at the end in different styles' do
73
+ inspect_source(cop,
74
+ ['[].each do |o|',
75
+ ' if o == 1',
76
+ ' puts o',
77
+ ' end',
78
+ 'end',
79
+ '',
80
+ '[].each do |o|',
81
+ ' puts o',
82
+ ' if o == 1',
83
+ ' puts o',
84
+ ' end',
85
+ 'end',
86
+ '',
87
+ '[].each do |o|',
88
+ ' unless o == 1',
89
+ ' puts o',
90
+ ' end',
91
+ 'end'])
92
+
93
+ expect(cop.offenses.size).to eq(3)
94
+ expect(cop.offenses.map(&:line).sort).to eq([1, 7, 14])
95
+ expect(cop.messages)
96
+ .to eq(['Use `next` to skip iteration.'] * 3)
97
+ expect(cop.highlights).to eq(['each'] * 3)
98
+ end
99
+
100
+ it 'ignores empty blocks' do
101
+ inspect_source(cop,
102
+ ['[].each do', 'end',
103
+ '[].each { }'])
104
+ expect(cop.offenses.size).to eq(0)
105
+ end
106
+
107
+ it 'ignores loops with conditional break' do
108
+ inspect_source(cop,
109
+ ['loop do',
110
+ " puts ''",
111
+ ' break if o == 1',
112
+ 'end',
113
+ '',
114
+ 'loop do',
115
+ ' break if o == 1',
116
+ 'end',
117
+ '',
118
+ 'loop do',
119
+ " puts ''",
120
+ ' break unless o == 1',
121
+ 'end',
122
+ '',
123
+ 'loop do',
124
+ ' break unless o == 1',
125
+ 'end'])
126
+ expect(cop.offenses.size).to eq(0)
127
+ end
128
+
129
+ context 'EnforcedStyle: skip_modifier_ifs' do
130
+ let(:cop_config) do
131
+ { 'EnforcedStyle' => 'skip_modifier_ifs' }
132
+ end
133
+
134
+ it 'ignores modifier ifs' do
135
+ inspect_source(cop,
136
+ ['[].each do |o|',
137
+ ' puts o if o == 1',
138
+ 'end',
139
+ '',
140
+ '[].each do |o|',
141
+ ' puts o unless o == 1',
142
+ 'end'])
143
+
144
+ expect(cop.offenses.size).to eq(0)
145
+ end
146
+ end
147
+
148
+ context 'EnforcedStyle: always' do
149
+ let(:cop_config) do
150
+ { 'EnforcedStyle' => 'always' }
151
+ end
152
+
153
+ it 'ignores modifier ifs' do
154
+ inspect_source(cop,
155
+ ['[].each do |o|',
156
+ ' puts o if o == 1',
157
+ 'end',
158
+ '',
159
+ '[].each do |o|',
160
+ ' puts o unless o == 1',
161
+ 'end'])
162
+
163
+ expect(cop.offenses.size).to eq(2)
164
+ expect(cop.offenses.map(&:line).sort).to eq([1, 5])
165
+ expect(cop.messages)
166
+ .to eq(['Use `next` to skip iteration.'] * 2)
167
+ expect(cop.highlights).to eq(['each'] * 2)
168
+ end
169
+ end
170
+
171
+ it 'ignores loops with conditions at the end with else' do
172
+ inspect_source(cop,
173
+ ['[].each do |o|',
174
+ ' if o == 1',
175
+ ' puts o',
176
+ ' else',
177
+ " puts 'no'",
178
+ ' end',
179
+ 'end',
180
+ '',
181
+ '[].each do |o|',
182
+ ' puts o',
183
+ ' if o == 1',
184
+ ' puts o',
185
+ ' else',
186
+ " puts 'no'",
187
+ ' end',
188
+ 'end',
189
+ '',
190
+ '[].each do |o|',
191
+ ' unless o == 1',
192
+ ' puts o',
193
+ ' else',
194
+ " puts 'no'",
195
+ ' end',
196
+ 'end'])
197
+
198
+ expect(cop.offenses.size).to eq(0)
199
+ end
200
+
201
+ it 'ignores loops with conditions at the end with ternary op' do
202
+ inspect_source(cop,
203
+ ['[].each do |o|',
204
+ ' o == x ? y : z',
205
+ 'end'
206
+ ])
207
+
208
+ expect(cop.offenses.size).to eq(0)
209
+ end
210
+ end
@@ -2,8 +2,14 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- describe Rubocop::Cop::Style::NonNilCheck do
6
- subject(:cop) { described_class.new }
5
+ describe Rubocop::Cop::Style::NonNilCheck, :config do
6
+ subject(:cop) { described_class.new(config) }
7
+
8
+ let(:cop_config) do
9
+ {
10
+ 'IncludeSemanticChanges' => false
11
+ }
12
+ end
7
13
 
8
14
  it 'registers an offense for != nil' do
9
15
  inspect_source(cop, 'x != nil')
@@ -11,16 +17,14 @@ describe Rubocop::Cop::Style::NonNilCheck do
11
17
  expect(cop.highlights).to eq(['!='])
12
18
  end
13
19
 
14
- it 'registers an offense for !x.nil?' do
20
+ it 'does not register an offense for !x.nil?' do
15
21
  inspect_source(cop, '!x.nil?')
16
- expect(cop.offenses.size).to eq(1)
17
- expect(cop.highlights).to eq(['!x.nil?'])
22
+ expect(cop.offenses).to be_empty
18
23
  end
19
24
 
20
- it 'registers an offense for not x.nil?' do
25
+ it 'does not register an offense for not x.nil?' do
21
26
  inspect_source(cop, 'not x.nil?')
22
- expect(cop.offenses.size).to eq(1)
23
- expect(cop.highlights).to eq(['not x.nil?'])
27
+ expect(cop.offenses).to be_empty
24
28
  end
25
29
 
26
30
  it 'does not register an offense if only expression in predicate' do
@@ -53,18 +57,45 @@ describe Rubocop::Cop::Style::NonNilCheck do
53
57
  expect(cop.offenses).to be_empty
54
58
  end
55
59
 
56
- it 'autocorrects by removing != nil' do
60
+ it 'autocorrects by changing `!= nil` to `!x.nil?`' do
57
61
  corrected = autocorrect_source(cop, 'x != nil')
58
- expect(corrected).to eq 'x'
62
+ expect(corrected).to eq '!x.nil?'
59
63
  end
60
64
 
61
- it 'autocorrects by removing non-nil (!x.nil?) check' do
65
+ it 'does not autocorrect by removing non-nil (!x.nil?) check' do
62
66
  corrected = autocorrect_source(cop, '!x.nil?')
63
- expect(corrected).to eq 'x'
67
+ expect(corrected).to eq '!x.nil?'
64
68
  end
65
69
 
66
70
  it 'does not blow up when autocorrecting implicit receiver' do
67
71
  corrected = autocorrect_source(cop, '!nil?')
68
- expect(corrected).to eq 'self'
72
+ expect(corrected).to eq '!nil?'
73
+ end
74
+
75
+ context 'when allowing semantic changes' do
76
+ subject(:cop) { described_class.new(config) }
77
+
78
+ let(:cop_config) do
79
+ {
80
+ 'IncludeSemanticChanges' => true
81
+ }
82
+ end
83
+
84
+ it 'registers an offense for `!x.nil?`' do
85
+ inspect_source(cop, '!x.nil?')
86
+ expect(cop.offenses.size).to eq(1)
87
+ expect(cop.highlights).to eq(['!x.nil?'])
88
+ end
89
+
90
+ it 'registers an offense for `not x.nil?`' do
91
+ inspect_source(cop, 'not x.nil?')
92
+ expect(cop.offenses.size).to eq(1)
93
+ expect(cop.highlights).to eq(['not x.nil?'])
94
+ end
95
+
96
+ it 'autocorrects by changing `x != nil` to `x`' do
97
+ corrected = autocorrect_source(cop, 'x != nil')
98
+ expect(corrected).to eq 'x'
99
+ end
69
100
  end
70
101
  end