rubocop 0.16.0 → 0.17.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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -1
  4. data/CHANGELOG.md +44 -0
  5. data/CONTRIBUTING.md +40 -8
  6. data/Gemfile +6 -0
  7. data/README.md +65 -20
  8. data/Rakefile +0 -1
  9. data/config/default.yml +15 -3
  10. data/config/enabled.yml +143 -109
  11. data/lib/rubocop.rb +45 -26
  12. data/lib/rubocop/cli.rb +26 -27
  13. data/lib/rubocop/config.rb +0 -1
  14. data/lib/rubocop/config_loader.rb +16 -23
  15. data/lib/rubocop/cop/commissioner.rb +2 -7
  16. data/lib/rubocop/cop/cop.rb +24 -51
  17. data/lib/rubocop/cop/ignored_node.rb +31 -0
  18. data/lib/rubocop/cop/lint/ambiguous_operator.rb +50 -0
  19. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +36 -0
  20. data/lib/rubocop/cop/lint/assignment_in_condition.rb +3 -11
  21. data/lib/rubocop/cop/lint/block_alignment.rb +6 -20
  22. data/lib/rubocop/cop/lint/condition_position.rb +52 -0
  23. data/lib/rubocop/cop/lint/else_layout.rb +57 -0
  24. data/lib/rubocop/cop/lint/end_alignment.rb +33 -8
  25. data/lib/rubocop/cop/lint/invalid_character_literal.rb +37 -0
  26. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -4
  27. data/lib/rubocop/cop/lint/syntax.rb +6 -12
  28. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +25 -0
  29. data/lib/rubocop/cop/mixin/array_syntax.rb +20 -0
  30. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +76 -0
  31. data/lib/rubocop/cop/mixin/check_assignment.rb +26 -0
  32. data/lib/rubocop/cop/{check_methods.rb → mixin/check_methods.rb} +0 -0
  33. data/lib/rubocop/cop/mixin/code_length.rb +33 -0
  34. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +53 -0
  35. data/lib/rubocop/cop/mixin/configurable_max.rb +19 -0
  36. data/lib/rubocop/cop/mixin/configurable_naming.rb +45 -0
  37. data/lib/rubocop/cop/{style → mixin}/if_node.rb +0 -0
  38. data/lib/rubocop/cop/mixin/if_then_else.rb +23 -0
  39. data/lib/rubocop/cop/mixin/negative_conditional.rb +24 -0
  40. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +34 -0
  41. data/lib/rubocop/cop/mixin/safe_assignment.rb +19 -0
  42. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +32 -0
  43. data/lib/rubocop/cop/mixin/space_inside.rb +31 -0
  44. data/lib/rubocop/cop/mixin/statement_modifier.rb +59 -0
  45. data/lib/rubocop/cop/mixin/string_help.rb +32 -0
  46. data/lib/rubocop/cop/mixin/surrounding_space.rb +42 -0
  47. data/lib/rubocop/cop/rails/default_scope.rb +3 -1
  48. data/lib/rubocop/cop/style/accessor_method_name.rb +4 -12
  49. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +16 -1
  50. data/lib/rubocop/cop/style/case_indentation.rb +33 -16
  51. data/lib/rubocop/cop/style/character_literal.rb +10 -0
  52. data/lib/rubocop/cop/style/dot_position.rb +23 -6
  53. data/lib/rubocop/cop/style/empty_lines_around_body.rb +5 -5
  54. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +1 -32
  55. data/lib/rubocop/cop/style/favor_until_over_negated_while.rb +20 -0
  56. data/lib/rubocop/cop/style/hash_syntax.rb +5 -1
  57. data/lib/rubocop/cop/style/if_unless_modifier.rb +34 -0
  58. data/lib/rubocop/cop/style/if_with_semicolon.rb +1 -1
  59. data/lib/rubocop/cop/style/indentation_consistency.rb +51 -0
  60. data/lib/rubocop/cop/style/indentation_width.rb +0 -26
  61. data/lib/rubocop/cop/style/lambda_call.rb +12 -5
  62. data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -11
  63. data/lib/rubocop/cop/style/multiline_if_then.rb +4 -9
  64. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +22 -0
  65. data/lib/rubocop/cop/style/{ternary_operator.rb → nested_ternary_operator.rb} +0 -15
  66. data/lib/rubocop/cop/style/numeric_literals.rb +30 -2
  67. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -1
  68. data/lib/rubocop/cop/style/parameter_lists.rb +7 -3
  69. data/lib/rubocop/cop/style/parentheses_around_condition.rb +9 -11
  70. data/lib/rubocop/cop/style/predicate_name.rb +4 -12
  71. data/lib/rubocop/cop/style/raise_args.rb +19 -11
  72. data/lib/rubocop/cop/style/regexp_literal.rb +19 -6
  73. data/lib/rubocop/cop/style/space_after_colon.rb +36 -0
  74. data/lib/rubocop/cop/style/space_after_comma.rb +16 -0
  75. data/lib/rubocop/cop/style/space_after_semicolon.rb +16 -0
  76. data/lib/rubocop/cop/style/space_around_block_braces.rb +38 -38
  77. data/lib/rubocop/cop/style/space_around_operators.rb +1 -2
  78. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +6 -2
  79. data/lib/rubocop/cop/style/string_literals.rb +5 -5
  80. data/lib/rubocop/cop/style/trailing_comma.rb +94 -0
  81. data/lib/rubocop/cop/style/unless_else.rb +2 -2
  82. data/lib/rubocop/cop/style/while_until_modifier.rb +32 -0
  83. data/lib/rubocop/cop/style/word_array.rb +9 -1
  84. data/lib/rubocop/cop/util.rb +14 -0
  85. data/lib/rubocop/cop/variable_inspector.rb +11 -6
  86. data/lib/rubocop/cop/variable_inspector/scope.rb +4 -3
  87. data/lib/rubocop/file_inspector.rb +22 -6
  88. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  89. data/lib/rubocop/formatter/colorizable.rb +37 -0
  90. data/lib/rubocop/formatter/disabled_config_formatter.rb +27 -6
  91. data/lib/rubocop/formatter/progress_formatter.rb +1 -1
  92. data/lib/rubocop/formatter/simple_text_formatter.rb +9 -5
  93. data/lib/rubocop/options.rb +19 -4
  94. data/lib/rubocop/target_finder.rb +4 -0
  95. data/lib/rubocop/version.rb +1 -1
  96. data/rubocop-todo.yml +10 -2
  97. data/rubocop.gemspec +3 -2
  98. data/spec/project_spec.rb +12 -7
  99. data/spec/rubocop/cli_spec.rb +262 -99
  100. data/spec/rubocop/config_loader_spec.rb +5 -5
  101. data/spec/rubocop/config_spec.rb +3 -3
  102. data/spec/rubocop/config_store_spec.rb +12 -11
  103. data/spec/rubocop/cop/commissioner_spec.rb +21 -5
  104. data/spec/rubocop/cop/cop_spec.rb +1 -1
  105. data/spec/rubocop/cop/lint/ambiguous_operator_spec.rb +113 -0
  106. data/spec/rubocop/cop/lint/ambiguous_regexp_literal_spec.rb +35 -0
  107. data/spec/rubocop/cop/lint/block_alignment_spec.rb +2 -2
  108. data/spec/rubocop/cop/lint/condition_position_spec.rb +49 -0
  109. data/spec/rubocop/cop/lint/else_layout_spec.rb +65 -0
  110. data/spec/rubocop/cop/lint/end_alignment_spec.rb +41 -1
  111. data/spec/rubocop/cop/lint/invalid_character_literal_spec.rb +33 -0
  112. data/spec/rubocop/cop/lint/parentheses_as_grouped_expression_spec.rb +3 -3
  113. data/spec/rubocop/cop/lint/shadowing_outer_local_variable_spec.rb +12 -12
  114. data/spec/rubocop/cop/lint/syntax_spec.rb +2 -2
  115. data/spec/rubocop/cop/lint/useless_assignment_spec.rb +72 -54
  116. data/spec/rubocop/cop/lint/useless_else_without_rescue_spec.rb +48 -0
  117. data/spec/rubocop/cop/offence_spec.rb +1 -1
  118. data/spec/rubocop/cop/rails/default_scope_spec.rb +6 -0
  119. data/spec/rubocop/cop/rails/output_spec.rb +2 -1
  120. data/spec/rubocop/cop/style/align_hash_spec.rb +9 -9
  121. data/spec/rubocop/cop/style/align_parameters_spec.rb +1 -1
  122. data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +5 -0
  123. data/spec/rubocop/cop/style/case_indentation_spec.rb +53 -2
  124. data/spec/rubocop/cop/style/class_and_module_camel_case_spec.rb +3 -3
  125. data/spec/rubocop/cop/style/documentation_spec.rb +0 -1
  126. data/spec/rubocop/cop/style/dot_position_spec.rb +18 -3
  127. data/spec/rubocop/cop/style/empty_line_between_defs_spec.rb +4 -4
  128. data/spec/rubocop/cop/style/empty_lines_around_body_spec.rb +13 -0
  129. data/spec/rubocop/cop/style/favor_unless_over_negated_if_spec.rb +1 -1
  130. data/spec/rubocop/cop/style/favor_until_over_negated_while_spec.rb +1 -1
  131. data/spec/rubocop/cop/style/hash_syntax_spec.rb +5 -0
  132. data/spec/rubocop/cop/style/{favor_modifier_spec.rb → if_unless_modifier_spec.rb} +4 -111
  133. data/spec/rubocop/cop/style/indentation_consistency_spec.rb +490 -0
  134. data/spec/rubocop/cop/style/indentation_width_spec.rb +19 -91
  135. data/spec/rubocop/cop/style/lambda_call_spec.rb +18 -0
  136. data/spec/rubocop/cop/style/method_called_on_do_end_block_spec.rb +2 -2
  137. data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +35 -1
  138. data/spec/rubocop/cop/style/method_length_spec.rb +1 -0
  139. data/spec/rubocop/cop/style/method_name_spec.rb +27 -5
  140. data/spec/rubocop/cop/style/multiline_block_chain_spec.rb +4 -4
  141. data/spec/rubocop/cop/style/multiline_if_then_spec.rb +2 -2
  142. data/spec/rubocop/cop/style/multiline_ternary_operator_spec.rb +18 -0
  143. data/spec/rubocop/cop/style/{ternary_operator_spec.rb → nested_ternary_operator_spec.rb} +0 -15
  144. data/spec/rubocop/cop/style/numeric_literals_spec.rb +18 -1
  145. data/spec/rubocop/cop/style/one_line_conditional_spec.rb +2 -1
  146. data/spec/rubocop/cop/style/parameter_lists_spec.rb +1 -0
  147. data/spec/rubocop/cop/style/parentheses_around_condition_spec.rb +13 -4
  148. data/spec/rubocop/cop/style/raise_args_spec.rb +22 -0
  149. data/spec/rubocop/cop/style/redundant_self_spec.rb +4 -4
  150. data/spec/rubocop/cop/style/regexp_literal_spec.rb +4 -0
  151. data/spec/rubocop/cop/style/space_after_colon_spec.rb +12 -4
  152. data/spec/rubocop/cop/style/space_after_method_name_spec.rb +2 -2
  153. data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +30 -1
  154. data/spec/rubocop/cop/style/{space_around_equals_in_default_parameter_spec.rb → space_around_equals_in_parameter_default_spec.rb} +0 -0
  155. data/spec/rubocop/cop/style/space_around_operators_spec.rb +2 -1
  156. data/spec/rubocop/cop/style/space_inside_hash_literal_braces_spec.rb +20 -3
  157. data/spec/rubocop/cop/style/string_literals_spec.rb +33 -0
  158. data/spec/rubocop/cop/style/trailing_comma_spec.rb +200 -0
  159. data/spec/rubocop/cop/style/variable_name_spec.rb +27 -3
  160. data/spec/rubocop/cop/style/while_until_modifier_spec.rb +75 -0
  161. data/spec/rubocop/cop/style/word_array_spec.rb +1 -0
  162. data/spec/rubocop/cop/team_spec.rb +1 -1
  163. data/spec/rubocop/cop/variable_inspector/scope_spec.rb +3 -4
  164. data/spec/rubocop/file_inspector_spec.rb +1 -1
  165. data/spec/rubocop/formatter/base_formatter_spec.rb +12 -11
  166. data/spec/rubocop/formatter/colorizable_spec.rb +107 -0
  167. data/spec/rubocop/formatter/disabled_config_formatter_spec.rb +2 -0
  168. data/spec/rubocop/formatter/formatter_set_spec.rb +1 -1
  169. data/spec/rubocop/formatter/json_formatter_spec.rb +4 -3
  170. data/spec/rubocop/formatter/progress_formatter_spec.rb +2 -2
  171. data/spec/rubocop/options_spec.rb +3 -1
  172. data/spec/rubocop/target_finder_spec.rb +13 -11
  173. data/spec/spec_helper.rb +5 -1
  174. data/spec/support/shared_examples.rb +2 -2
  175. data/spec/support/statement_modifier_helper.rb +41 -0
  176. metadata +88 -30
  177. data/lib/rubocop/cop/check_assignment.rb +0 -43
  178. data/lib/rubocop/cop/style/array_syntax.rb +0 -22
  179. data/lib/rubocop/cop/style/autocorrect_alignment.rb +0 -78
  180. data/lib/rubocop/cop/style/code_length.rb +0 -35
  181. data/lib/rubocop/cop/style/configurable_enforced_style.rb +0 -51
  182. data/lib/rubocop/cop/style/configurable_max.rb +0 -17
  183. data/lib/rubocop/cop/style/configurable_naming.rb +0 -41
  184. data/lib/rubocop/cop/style/favor_modifier.rb +0 -118
  185. data/lib/rubocop/cop/style/if_then_else.rb +0 -27
  186. data/lib/rubocop/cop/style/space_after_comma_etc.rb +0 -73
  187. data/lib/rubocop/cop/style/space_inside.rb +0 -33
  188. data/lib/rubocop/cop/style/string_help.rb +0 -30
  189. data/lib/rubocop/cop/style/surrounding_space.rb +0 -44
@@ -26,9 +26,10 @@ Gem::Specification.new do |s|
26
26
  s.rubygems_version = '1.8.23'
27
27
  s.summary = 'Automatic Ruby code style checking tool.'
28
28
 
29
- s.add_runtime_dependency('rainbow', '>= 1.1.4')
30
- s.add_runtime_dependency('parser', '~> 2.1')
29
+ s.add_runtime_dependency('rainbow', '~> 1.99.1')
30
+ s.add_runtime_dependency('parser', '~> 2.1.3')
31
31
  s.add_runtime_dependency('powerpack', '~> 0.0.6')
32
+ s.add_runtime_dependency('json', '~> 1.8')
32
33
  s.add_development_dependency('rake', '~> 10.1')
33
34
  s.add_development_dependency('rspec', '~> 2.14')
34
35
  s.add_development_dependency('yard', '~> 0.8')
@@ -4,16 +4,21 @@ require 'spec_helper'
4
4
 
5
5
  describe 'RuboCop Project' do
6
6
  describe 'default configuration file' do
7
+ let(:cop_names) { Rubocop::Cop::Cop.all.map(&:cop_name) }
8
+
9
+ subject(:default_config) do
10
+ Rubocop::ConfigLoader.load_file('config/default.yml')
11
+ end
12
+
7
13
  it 'has configuration for all cops' do
8
- cop_names = Rubocop::Cop::Cop.all.map(&:cop_name)
9
- expect(Rubocop::ConfigLoader.load_file('config/default.yml').keys.sort)
10
- .to eq((['AllCops'] + cop_names).sort)
14
+ expect(default_config.keys.sort).to eq((['AllCops'] + cop_names).sort)
11
15
  end
12
- it 'has a description for all cops' do
13
- cop_names = Rubocop::Cop::Cop.all.map(&:cop_name)
14
- conf = Rubocop::ConfigLoader.load_file('config/default.yml')
16
+
17
+ it 'has a nicely formatted description for all cops' do
15
18
  cop_names.each do |name|
16
- expect(conf[name]['Description']).not_to be_nil
19
+ description = default_config[name]['Description']
20
+ expect(description).not_to be_nil
21
+ expect(description).not_to include("\n")
17
22
  end
18
23
  end
19
24
  end
@@ -47,6 +47,76 @@ describe Rubocop::CLI, :isolated_environment do
47
47
  ' puts i',
48
48
  'end'].join("\n") + "\n")
49
49
  end
50
+
51
+ # In this example, the auto-correction (changing "raise" to "fail")
52
+ # creates a new problem (alignment of parameters), which is also
53
+ # corrected automatically.
54
+ it 'can correct a problems and the problem it creates' do
55
+ create_file('example.rb',
56
+ ['# encoding: utf-8',
57
+ 'raise NotImplementedError,',
58
+ " 'Method should be overridden in child classes'"])
59
+ expect(cli.run(['--auto-correct'])).to eq(1)
60
+ expect(IO.read('example.rb'))
61
+ .to eq(['# encoding: utf-8',
62
+ 'fail NotImplementedError,',
63
+ " 'Method should be overridden in child classes'"]
64
+ .join("\n") + "\n")
65
+ expect($stdout.string)
66
+ .to eq(['Inspecting 1 file',
67
+ 'C',
68
+ '',
69
+ 'Offences:',
70
+ '',
71
+ 'example.rb:2:1: C: [Corrected] Use `fail` instead of ' +
72
+ '`raise` to signal exceptions.',
73
+ 'raise NotImplementedError,',
74
+ '^^^^^',
75
+ 'example.rb:3:7: C: [Corrected] Align the parameters of a ' +
76
+ 'method call if they span more than one line.',
77
+ " 'Method should be overridden in child classes'",
78
+ ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',
79
+ '',
80
+ '1 file inspected, 2 offences detected, 2 offences ' +
81
+ 'corrected',
82
+ ''].join("\n"))
83
+ end
84
+
85
+ # Thanks to repeated auto-correction, we can get rid of the trailing
86
+ # spaces, and then the extra empty line.
87
+ it 'can correct two problems in the same place' do
88
+ create_file('example.rb',
89
+ ['# encoding: utf-8',
90
+ '# Example class.',
91
+ 'class Klass',
92
+ ' ',
93
+ ' def f',
94
+ ' end',
95
+ 'end'])
96
+ expect(cli.run(['--auto-correct'])).to eq(1)
97
+ expect(IO.read('example.rb'))
98
+ .to eq(['# encoding: utf-8',
99
+ '# Example class.',
100
+ 'class Klass',
101
+ ' def f',
102
+ ' end',
103
+ 'end'].join("\n") + "\n")
104
+ expect($stderr.string).to eq('')
105
+ expect($stdout.string)
106
+ .to eq(['Inspecting 1 file',
107
+ 'C',
108
+ '',
109
+ 'Offences:',
110
+ '',
111
+ 'example.rb:4:1: C: [Corrected] Trailing whitespace ' +
112
+ 'detected.',
113
+ 'example.rb:4:1: C: [Corrected] Extra empty line detected ' +
114
+ 'at body beginning.',
115
+ '',
116
+ '1 file inspected, 2 offences detected, 2 offences ' +
117
+ 'corrected',
118
+ ''].join("\n"))
119
+ end
50
120
  end
51
121
 
52
122
  describe '--auto-gen-config' do
@@ -87,7 +157,7 @@ describe Rubocop::CLI, :isolated_environment do
87
157
 
88
158
  it 'can generate a todo list' do
89
159
  create_file('example1.rb', ['# encoding: utf-8',
90
- 'x= 0 ',
160
+ '$x= 0 ',
91
161
  '#' * 90,
92
162
  '#' * 85,
93
163
  'y ',
@@ -104,29 +174,49 @@ describe Rubocop::CLI, :isolated_environment do
104
174
  'add inherit_from: rubocop-todo.yml in a ' +
105
175
  '.rubocop.yml file.',
106
176
  ''].join("\n"))
107
- expect(IO.read('rubocop-todo.yml'))
108
- .to eq(['# This configuration was generated by `rubocop' +
109
- ' --auto-gen-config`.',
110
- '# The point is for the user to remove these' +
111
- ' configuration records',
112
- '# one by one as the offences are removed from the code ' +
113
- 'base.',
114
- '',
115
- 'IndentationWidth:',
116
- ' Enabled: false',
117
- '',
118
- 'LineLength:',
119
- ' Max: 90',
120
- '',
121
- 'SpaceAroundOperators:',
122
- ' Enabled: false',
123
- '',
124
- 'Tab:',
125
- ' Enabled: false',
126
- '',
127
- 'TrailingWhitespace:',
128
- ' Enabled: false',
129
- ''].join("\n"))
177
+ expected =
178
+ ['# This configuration was generated by `rubocop --auto-gen-config`',
179
+ /# on .* using RuboCop version .*/,
180
+ '# The point is for the user to remove these configuration records',
181
+ '# one by one as the offences are removed from the code base.',
182
+ '# Note that changes in the inspected code, or installation of new',
183
+ '# versions of RuboCop, may require this file to be generated ' +
184
+ 'again.',
185
+ '',
186
+ '# Offence count: 1',
187
+ '# Configuration parameters: AllowedVariables.',
188
+ 'GlobalVars:',
189
+ ' Enabled: false',
190
+ '',
191
+ '# Offence count: 1',
192
+ 'IndentationConsistency:',
193
+ ' Enabled: false',
194
+ '',
195
+ '# Offence count: 2',
196
+ 'LineLength:',
197
+ ' Max: 90',
198
+ '',
199
+ '# Offence count: 1',
200
+ '# Cop supports --auto-correct.',
201
+ 'SpaceAroundOperators:',
202
+ ' Enabled: false',
203
+ '',
204
+ '# Offence count: 1',
205
+ 'Tab:',
206
+ ' Enabled: false',
207
+ '',
208
+ '# Offence count: 2',
209
+ '# Cop supports --auto-correct.',
210
+ 'TrailingWhitespace:',
211
+ ' Enabled: false']
212
+ actual = IO.read('rubocop-todo.yml').split($RS)
213
+ expected.each_with_index do |line, ix|
214
+ if line.is_a?(String)
215
+ expect(actual[ix]).to eq(line)
216
+ else
217
+ expect(actual[ix]).to match(line)
218
+ end
219
+ end
130
220
  end
131
221
  end
132
222
 
@@ -142,7 +232,7 @@ describe Rubocop::CLI, :isolated_environment do
142
232
  'example.rb'])).to eq(1)
143
233
  expect($stdout.string)
144
234
  .to eq(['== example.rb ==',
145
- 'C: 1: 1: Favor modifier if/unless usage when you ' +
235
+ 'C: 1: 1: Favor modifier if usage when you ' +
146
236
  'have a single-line body. Another good alternative is ' +
147
237
  'the usage of control flow &&/||.',
148
238
  '',
@@ -170,34 +260,58 @@ describe Rubocop::CLI, :isolated_environment do
170
260
  end
171
261
 
172
262
  describe '-d/--debug' do
173
- it 'shows config files', ruby: 2.0 do
263
+ it 'shows config files' do
174
264
  create_file('example1.rb', "\tputs 0")
175
265
  expect(cli.run(['--debug', 'example1.rb'])).to eq(1)
176
266
  home = File.dirname(File.dirname(File.dirname(__FILE__)))
177
- expect($stdout.string.lines[2, 5].map(&:chomp).join("\n"))
267
+ expect($stdout.string.lines.grep(/configuration/).map(&:chomp))
178
268
  .to eq(["For #{abs('')}:" +
179
269
  " configuration from #{home}/config/default.yml",
180
270
  "Inheriting configuration from #{home}/config/enabled.yml",
181
- "Inheriting configuration from #{home}/config/" +
182
- 'disabled.yml',
183
- "AllCops/Excludes configuration from #{home}/.rubocop.yml",
184
- "Inheriting configuration from #{home}/rubocop-todo.yml"
185
- ].join("\n"))
271
+ "Inheriting configuration from #{home}/config/disabled.yml"
272
+ ])
186
273
  end
187
274
 
188
- it 'shows cop names', ruby: 2.0 do
275
+ it 'shows cop names' do
189
276
  create_file('example1.rb', "\tputs 0")
190
277
  expect(cli.run(['--format',
191
278
  'emacs',
192
279
  '--debug',
193
280
  'example1.rb'])).to eq(1)
194
- expect($stdout.string.lines[-1])
281
+ expect($stdout.string.lines.to_a[-1])
282
+ .to eq(["#{abs('example1.rb')}:1:1: C: Tab: Tab detected.",
283
+ ''].join("\n"))
284
+ end
285
+ end
286
+
287
+ describe '-D/--display-cop-names' do
288
+ it 'shows cop names' do
289
+ create_file('example1.rb', "\tputs 0")
290
+ expect(cli.run(['--format',
291
+ 'emacs',
292
+ '--debug',
293
+ 'example1.rb'])).to eq(1)
294
+ expect($stdout.string.lines.to_a[-1])
195
295
  .to eq(["#{abs('example1.rb')}:1:1: C: Tab: Tab detected.",
196
296
  ''].join("\n"))
197
297
  end
198
298
  end
199
299
 
200
300
  describe '--show-cops' do
301
+ shared_examples(:prints_config) do
302
+ it 'prints the current configuration' do
303
+ out = stdout.lines.to_a
304
+ printed_config = YAML.load(out.join)
305
+ cop_names = (cop_list[0] || '').split(',')
306
+ cop_names.each do |cop_name|
307
+ global_conf[cop_name].each do |key, value|
308
+ printed_value = printed_config[cop_name][key]
309
+ expect(printed_value).to eq(value)
310
+ end
311
+ end
312
+ end
313
+ end
314
+
201
315
  let(:cops) { Rubocop::Cop::Cop.all }
202
316
 
203
317
  let(:global_conf) do
@@ -209,72 +323,90 @@ describe Rubocop::CLI, :isolated_environment do
209
323
  let(:stdout) { $stdout.string }
210
324
 
211
325
  before do
212
- expect { cli.run ['--show-cops'] }.to exit_with_code(0)
326
+ expect { cli.run ['--show-cops'] + cop_list }.to exit_with_code(0)
213
327
  end
214
328
 
215
- # Extracts the first line out of the description
216
- def short_description_of_cop(cop)
217
- desc = full_description_of_cop(cop)
218
- desc ? desc.lines.first.strip : ''
219
- end
220
-
221
- # Gets the full description of the cop or nil if no description is set.
222
- def full_description_of_cop(cop)
223
- cop_config = global_conf.for_cop(cop)
224
- cop_config['Description']
225
- end
329
+ context 'with no args' do
330
+ let(:cop_list) { [] }
226
331
 
227
- it 'prints all available cops and their description' do
228
- cops.each do |cop|
229
- expect(stdout).to include cop.cop_name
230
- expect(stdout).to include short_description_of_cop(cop)
332
+ # Extracts the first line out of the description
333
+ def short_description_of_cop(cop)
334
+ desc = full_description_of_cop(cop)
335
+ desc ? desc.lines.first.strip : ''
231
336
  end
232
- end
233
337
 
234
- it 'prints all types' do
235
- cops
236
- .types
237
- .map(&:to_s)
238
- .map(&:capitalize)
239
- .each { |type| expect(stdout).to include(type) }
240
- end
338
+ # Gets the full description of the cop or nil if no description is set.
339
+ def full_description_of_cop(cop)
340
+ cop_config = global_conf.for_cop(cop)
341
+ cop_config['Description']
342
+ end
241
343
 
242
- it 'prints all cops in their right type listing' do
243
- lines = stdout.lines
244
- lines.slice_before(/Type /).each do |slice|
245
- types = cops.types.map(&:to_s).map(&:capitalize)
246
- current = types.delete(slice.shift[/Type '(?<c>[^'']+)'/, 'c'])
247
- # all cops in their type listing
248
- cops.with_type(current).each do |cop|
249
- expect(slice.any? { |l| l.include? cop.cop_name }).to be_true
344
+ it 'prints all available cops and their description' do
345
+ cops.each do |cop|
346
+ expect(stdout).to include cop.cop_name
347
+ # Because of line breaks, we will only find the beginning.
348
+ expect(stdout).to include short_description_of_cop(cop)[0..60]
250
349
  end
350
+ end
351
+
352
+ it 'prints all types' do
353
+ cops
354
+ .types
355
+ .map(&:to_s)
356
+ .map(&:capitalize)
357
+ .each { |type| expect(stdout).to include(type) }
358
+ end
251
359
 
252
- # no cop in wrong type listing
253
- types.each do |type|
254
- cops.with_type(type).each do |cop|
255
- expect(slice.any? { |l| l.include? cop.cop_name }).to be_false
360
+ it 'prints all cops in their right type listing' do
361
+ lines = stdout.lines
362
+ lines.slice_before(/Type /).each do |slice|
363
+ types = cops.types.map(&:to_s).map(&:capitalize)
364
+ current = types.delete(slice.shift[/Type '(?<c>[^'']+)'/, 'c'])
365
+ # all cops in their type listing
366
+ cops.with_type(current).each do |cop|
367
+ expect(slice.any? { |l| l.include? cop.cop_name }).to be_true
368
+ end
369
+
370
+ # no cop in wrong type listing
371
+ types.each do |type|
372
+ cops.with_type(type).each do |cop|
373
+ expect(slice.any? { |l| l.include? cop.cop_name }).to be_false
374
+ end
256
375
  end
257
376
  end
258
377
  end
378
+
379
+ include_examples :prints_config
259
380
  end
260
381
 
261
- it 'prints the current configuration' do
262
- out = stdout.lines.to_a
263
- cops.each do |cop|
264
- conf = global_conf[cop.cop_name].dup
265
- confstrt =
266
- out.find_index { |i| i.include?("- #{cop.cop_name}") } + 1
267
- c = out[confstrt, conf.keys.size].to_s
268
- conf.delete('Description')
269
- expect(c).to include(short_description_of_cop(cop))
270
- conf.each do |k, v|
271
- # ugly hack to get hash/array content tested
272
- if v.kind_of?(Hash) || v.kind_of?(Array)
273
- expect(c).to include "#{k}: #{v.to_s.dump[2, -2]}"
274
- else
275
- expect(c).to include "#{k}: #{v}"
276
- end
277
- end
382
+ context 'with one cop given' do
383
+ let(:cop_list) { ['Tab'] }
384
+
385
+ it 'prints that cop and nothing else' do
386
+ expect(stdout).to eq(['Tab:',
387
+ ' Description: No hard tabs.',
388
+ ' Enabled: true',
389
+ '',
390
+ ''].join("\n"))
391
+ end
392
+
393
+ include_examples :prints_config
394
+ end
395
+
396
+ context 'with two cops given' do
397
+ let(:cop_list) { ['Tab,LineLength'] }
398
+ include_examples :prints_config
399
+ end
400
+
401
+ context 'with one of the cops misspelled' do
402
+ let(:cop_list) { ['Tab,X123'] }
403
+
404
+ it 'skips the unknown cop' do
405
+ expect(stdout).to eq(['Tab:',
406
+ ' Description: No hard tabs.',
407
+ ' Enabled: true',
408
+ '',
409
+ ''].join("\n"))
278
410
  end
279
411
  end
280
412
  end
@@ -352,7 +484,7 @@ describe Rubocop::CLI, :isolated_environment do
352
484
  'example3.rb:2:5: C: Use snake_case for methods.',
353
485
  'def badName',
354
486
  ' ^^^^^^^',
355
- 'example3.rb:3:3: C: Favor modifier if/unless usage ' +
487
+ 'example3.rb:3:3: C: Favor modifier if usage ' +
356
488
  'when you have a single-line body. Another good ' +
357
489
  'alternative is the usage of control flow &&/||.',
358
490
  ' if something',
@@ -511,7 +643,7 @@ describe Rubocop::CLI, :isolated_environment do
511
643
  describe '#trap_interrupt' do
512
644
  before do
513
645
  @interrupt_handlers = []
514
- Signal.stub(:trap).with('INT') do |&block|
646
+ allow(Signal).to receive(:trap).with('INT') do |&block|
515
647
  @interrupt_handlers << block
516
648
  end
517
649
  end
@@ -535,8 +667,8 @@ describe Rubocop::CLI, :isolated_environment do
535
667
  end
536
668
 
537
669
  it 'does not exit immediately' do
538
- Object.any_instance.should_not_receive(:exit)
539
- Object.any_instance.should_not_receive(:exit!)
670
+ expect_any_instance_of(Object).not_to receive(:exit)
671
+ expect_any_instance_of(Object).not_to receive(:exit!)
540
672
  cli.trap_interrupt
541
673
  interrupt
542
674
  end
@@ -544,7 +676,7 @@ describe Rubocop::CLI, :isolated_environment do
544
676
 
545
677
  context 'with SIGINT twice' do
546
678
  it 'exits immediately' do
547
- Object.any_instance.should_receive(:exit!).with(1)
679
+ expect_any_instance_of(Object).to receive(:exit!).with(1)
548
680
  cli.trap_interrupt
549
681
  interrupt
550
682
  interrupt
@@ -600,7 +732,9 @@ describe Rubocop::CLI, :isolated_environment do
600
732
  expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
601
733
  expect($stdout.string)
602
734
  .to eq(["#{abs('example.rb')}:2:6: W: " +
603
- "`*' interpreted as argument prefix",
735
+ 'Ambiguous splat operator. Parenthesize the method arguments ' +
736
+ "if it's surely a splat operator, or add a whitespace to the " +
737
+ 'right of the * if it should be a multiplication.',
604
738
  "#{abs('example.rb')}:3:1: C: " +
605
739
  'Favor the ternary operator (?:) over if/then/else/end ' +
606
740
  'constructs.',
@@ -757,6 +891,36 @@ describe Rubocop::CLI, :isolated_environment do
757
891
  end
758
892
  end
759
893
 
894
+ describe 'cops can exclude files based on config' do
895
+ it 'ignores excluded files' do
896
+ create_file('example.rb', [
897
+ '# encoding: utf-8',
898
+ 'x = 0'
899
+ ])
900
+ create_file('regexp.rb', [
901
+ '# encoding: utf-8',
902
+ 'x = 0'
903
+ ])
904
+ create_file('exclude_glob.rb', [
905
+ '#!/usr/bin/env ruby',
906
+ '# encoding: utf-8',
907
+ 'x = 0'
908
+ ])
909
+ create_file('.rubocop.yml', [
910
+ 'UselessAssignment:',
911
+ ' Exclude:',
912
+ ' - example.rb',
913
+ ' - !ruby/regexp /regexp.rb\z/',
914
+ ' - "exclude_*"'
915
+ ])
916
+ expect(cli.run(%w(--format simple))).to eq(0)
917
+ expect($stdout.string)
918
+ .to eq(['', '3 files inspected, no offences detected',
919
+ ''].join("\n"))
920
+ end
921
+
922
+ end
923
+
760
924
  describe 'configuration from file' do
761
925
  it 'finds included files' do
762
926
  create_file('example', [
@@ -826,8 +990,8 @@ describe Rubocop::CLI, :isolated_environment do
826
990
  ' Excludes:',
827
991
  ' - ignored/**',
828
992
  ])
829
- File.should_not_receive(:open).with(%r(/ignored/))
830
- File.stub(:open).and_call_original
993
+ expect(File).not_to receive(:open).with(%r(/ignored/))
994
+ allow(File).to receive(:open).and_call_original
831
995
  expect(cli.run(%w(--format simple example))).to eq(0)
832
996
  expect($stdout.string)
833
997
  .to eq(['', '0 files inspected, no offences detected',
@@ -853,15 +1017,14 @@ describe Rubocop::CLI, :isolated_environment do
853
1017
  ''].join("\n"))
854
1018
  end
855
1019
 
856
- it 'can disable Syntax offences with warning severity' do
857
- pending
1020
+ it 'can disable parser-derived offences with warning severity' do
858
1021
  # `-' interpreted as argument prefix
859
1022
  create_file('example.rb', 'puts -1')
860
1023
  create_file('.rubocop.yml', [
861
1024
  'Encoding:',
862
1025
  ' Enabled: false',
863
1026
  '',
864
- 'Syntax:',
1027
+ 'AmbiguousOperator:',
865
1028
  ' Enabled: false'
866
1029
  ])
867
1030
  expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(0)
@@ -915,7 +1078,7 @@ describe Rubocop::CLI, :isolated_environment do
915
1078
  '-c', 'rubocop.yml', 'example1.rb'])
916
1079
  expect($stdout.string)
917
1080
  .to eq(['== example1.rb ==',
918
- 'C: 1: 1: Favor modifier if/unless usage when you have ' +
1081
+ 'C: 1: 1: Favor modifier if usage when you have ' +
919
1082
  'a single-line body. Another good alternative is the ' +
920
1083
  'usage of control flow &&/||.',
921
1084
  '',