rubocop 0.13.0 → 0.13.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +18 -0
- data/config/default.yml +4 -0
- data/config/enabled.yml +13 -9
- data/lib/rubocop.rb +5 -1
- data/lib/rubocop/backports/bsearch.rb +39 -0
- data/lib/rubocop/cop/lint/useless_comparison.rb +2 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +88 -13
- data/lib/rubocop/cop/style/align_array.rb +2 -20
- data/lib/rubocop/cop/style/align_parameters.rb +2 -20
- data/lib/rubocop/cop/style/ascii_comments.rb +1 -1
- data/lib/rubocop/cop/style/ascii_identifiers.rb +1 -1
- data/lib/rubocop/cop/style/autocorrect_alignment.rb +32 -0
- data/lib/rubocop/cop/style/character_literal.rb +5 -13
- data/lib/rubocop/cop/style/final_newline.rb +2 -2
- data/lib/rubocop/cop/style/hash_syntax.rb +10 -3
- data/lib/rubocop/cop/style/lambda_call.rb +39 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/redundant_self.rb +48 -2
- data/lib/rubocop/cop/style/string_help.rb +27 -0
- data/lib/rubocop/cop/style/string_literals.rb +5 -13
- data/lib/rubocop/cop/style/surrounding_space.rb +17 -5
- data/lib/rubocop/version.rb +1 -1
- data/rubocop.gemspec +0 -1
- data/spec/rubocop/cli_spec.rb +909 -914
- data/spec/rubocop/cop/lint/useless_comparison_spec.rb +5 -0
- data/spec/rubocop/cop/lint/useless_setter_call_spec.rb +41 -0
- data/spec/rubocop/cop/style/final_newline_spec.rb +6 -0
- data/spec/rubocop/cop/style/hash_syntax_spec.rb +26 -21
- data/spec/rubocop/cop/style/lambda_call_spec.rb +29 -0
- data/spec/rubocop/cop/style/nil_comparison_spec.rb +5 -0
- data/spec/rubocop/cop/style/redundant_self_spec.rb +18 -0
- data/spec/rubocop/cop/style/space_around_block_braces_spec.rb +68 -0
- metadata +20 -50
- data/spec/rubocop/cop/style/space_around_braces_spec.rb +0 -50
@@ -5,24 +5,16 @@ module Rubocop
|
|
5
5
|
module Style
|
6
6
|
# Checks for uses of the character literal ?x.
|
7
7
|
class CharacterLiteral < Cop
|
8
|
-
|
8
|
+
include StringHelp
|
9
9
|
|
10
|
-
|
11
|
-
# Constants like __FILE__ are handled as strings,
|
12
|
-
# but don't respond to begin.
|
13
|
-
return unless node.loc.respond_to?(:begin) && node.loc.begin
|
14
|
-
return if part_of_ignored_node?(node)
|
10
|
+
MSG = 'Do not use the character literal - use string literal instead.'
|
15
11
|
|
12
|
+
def offence?(node)
|
16
13
|
# we don't register an offence for things like ?\C-\M-d
|
17
|
-
|
18
|
-
|
19
|
-
convention(node, :expression)
|
20
|
-
end
|
14
|
+
node.loc.begin.is?('?') &&
|
15
|
+
node.loc.expression.source.size.between?(2, 3)
|
21
16
|
end
|
22
17
|
|
23
|
-
alias_method :on_dstr, :ignore_node
|
24
|
-
alias_method :on_regexp, :ignore_node
|
25
|
-
|
26
18
|
def autocorrect_action(node)
|
27
19
|
@corrections << lambda do |corrector|
|
28
20
|
string = node.loc.expression.source[1..-1]
|
@@ -5,12 +5,12 @@ module Rubocop
|
|
5
5
|
module Style
|
6
6
|
# This cop enforces the presence of a final newline in each source file.
|
7
7
|
class FinalNewline < Cop
|
8
|
-
MSG = 'Source files should end with a newline(\n).'
|
8
|
+
MSG = 'Source files should end with a newline (\n).'
|
9
9
|
|
10
10
|
def investigate(processed_source)
|
11
11
|
final_line = processed_source.raw_lines.to_a.last
|
12
12
|
|
13
|
-
unless final_line.end_with?("\n")
|
13
|
+
unless final_line.nil? || final_line.end_with?("\n")
|
14
14
|
convention(nil,
|
15
15
|
source_range(processed_source.buffer,
|
16
16
|
processed_source[0...-1],
|
@@ -18,14 +18,21 @@ module Rubocop
|
|
18
18
|
if sym_indices
|
19
19
|
pairs.each do |pair|
|
20
20
|
if pair.loc.operator && pair.loc.operator.is?('=>')
|
21
|
-
convention(
|
22
|
-
pair.loc.expression.begin.join(pair.loc.operator)
|
23
|
-
MSG)
|
21
|
+
convention(pair,
|
22
|
+
pair.loc.expression.begin.join(pair.loc.operator))
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
28
|
+
def autocorrect_action(node)
|
29
|
+
@corrections << lambda do |corrector|
|
30
|
+
replacement = node.loc.expression.source[1..-1]
|
31
|
+
.sub(/\s*=>\s*/, ': ')
|
32
|
+
corrector.replace(node.loc.expression, replacement)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
29
36
|
private
|
30
37
|
|
31
38
|
def word_symbol_pair?(pair)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for use of the lambda.(args) syntax.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
# lambda.(x, y)
|
12
|
+
#
|
13
|
+
# # good
|
14
|
+
# lambda.call(x, y)
|
15
|
+
class LambdaCall < Cop
|
16
|
+
MSG = 'Prefer the use of `lambda.call(...)` over `lambda.(...)`.'
|
17
|
+
|
18
|
+
def on_send(node)
|
19
|
+
_receiver, selector, = *node
|
20
|
+
|
21
|
+
# lambda.() does not have a selector
|
22
|
+
return unless selector == :call && node.loc.selector.nil?
|
23
|
+
|
24
|
+
convention(node, :expression)
|
25
|
+
end
|
26
|
+
|
27
|
+
def autocorrect_action(node)
|
28
|
+
@corrections << lambda do |corrector|
|
29
|
+
receiver_node, = *node
|
30
|
+
expr = node.loc.expression
|
31
|
+
receiver = receiver_node.loc.expression.source
|
32
|
+
replacement = expr.source.sub("#{receiver}.", "#{receiver}.call")
|
33
|
+
corrector.replace(expr, replacement)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -3,8 +3,40 @@
|
|
3
3
|
module Rubocop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop checks for redundant uses of `self`.
|
7
|
-
#
|
6
|
+
# This cop checks for redundant uses of `self`.
|
7
|
+
#
|
8
|
+
# `self` is only needed when:
|
9
|
+
#
|
10
|
+
# * Sending a message to same object with zero arguments in
|
11
|
+
# presence of a method name clash with an argument or a local
|
12
|
+
# variable.
|
13
|
+
#
|
14
|
+
# Note, with using explicit self you can only send messages
|
15
|
+
# with public or protected scope, you cannot send private
|
16
|
+
# messages this way.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
#
|
20
|
+
# def bar
|
21
|
+
# :baz
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def foo(bar)
|
25
|
+
# self.bar # resolves name clash with argument
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# def foo2
|
29
|
+
# bar = 1
|
30
|
+
# self.bar # resolves name class with local variable
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# * Calling an attribute writer to prevent an local variable assignment
|
34
|
+
#
|
35
|
+
# attr_writer :bar
|
36
|
+
#
|
37
|
+
# def foo
|
38
|
+
# self.bar= 1 # Make sure above attr writer is called
|
39
|
+
# end
|
8
40
|
#
|
9
41
|
# Special cases:
|
10
42
|
#
|
@@ -43,6 +75,14 @@ module Rubocop
|
|
43
75
|
@local_variables = []
|
44
76
|
end
|
45
77
|
|
78
|
+
def on_arg(node)
|
79
|
+
on_argument(node)
|
80
|
+
end
|
81
|
+
|
82
|
+
def on_blockarg(node)
|
83
|
+
on_argument(node)
|
84
|
+
end
|
85
|
+
|
46
86
|
def on_lvasgn(node)
|
47
87
|
lhs, _rhs = *node
|
48
88
|
@local_variables << lhs
|
@@ -70,6 +110,11 @@ module Rubocop
|
|
70
110
|
|
71
111
|
private
|
72
112
|
|
113
|
+
def on_argument(node)
|
114
|
+
name, _ = *node
|
115
|
+
@local_variables << name
|
116
|
+
end
|
117
|
+
|
73
118
|
def operator?(method_name)
|
74
119
|
method_name.to_s =~ /\W/
|
75
120
|
end
|
@@ -88,6 +133,7 @@ module Rubocop
|
|
88
133
|
@allowed_send_nodes << node if receiver && receiver.type == :self
|
89
134
|
end
|
90
135
|
end
|
136
|
+
|
91
137
|
end
|
92
138
|
end
|
93
139
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Rubocop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for uses of double quotes where single quotes would do.
|
7
|
+
module StringHelp
|
8
|
+
def on_str(node)
|
9
|
+
# Constants like __FILE__ are handled as strings,
|
10
|
+
# but don't respond to begin.
|
11
|
+
return unless node.loc.respond_to?(:begin) && node.loc.begin
|
12
|
+
return if part_of_ignored_node?(node)
|
13
|
+
|
14
|
+
convention(node, :expression) if offence?(node)
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_dstr(node)
|
18
|
+
ignore_node(node)
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_regexp(node)
|
22
|
+
ignore_node(node)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -5,27 +5,19 @@ module Rubocop
|
|
5
5
|
module Style
|
6
6
|
# Checks for uses of double quotes where single quotes would do.
|
7
7
|
class StringLiterals < Cop
|
8
|
+
include StringHelp
|
9
|
+
|
8
10
|
MSG = "Prefer single-quoted strings when you don't need " +
|
9
11
|
'string interpolation or special symbols.'
|
10
12
|
|
11
|
-
def
|
12
|
-
# Constants like __FILE__ are handled as strings,
|
13
|
-
# but don't respond to begin.
|
14
|
-
return unless node.loc.respond_to?(:begin)
|
15
|
-
return if part_of_ignored_node?(node)
|
16
|
-
|
13
|
+
def offence?(node)
|
17
14
|
# regex matches IF there is a ' or there is a \\ in the string that
|
18
15
|
# is not preceeded/followed by another \\ (e.g. "\\x34") but not
|
19
16
|
# "\\\\"
|
20
|
-
|
21
|
-
|
22
|
-
convention(node, :expression)
|
23
|
-
end
|
17
|
+
node.loc.expression.source !~ /' | (?<! \\) \\{2}* \\ (?! \\)/x &&
|
18
|
+
node.loc.begin && node.loc.begin.is?('"')
|
24
19
|
end
|
25
20
|
|
26
|
-
alias_method :on_dstr, :ignore_node
|
27
|
-
alias_method :on_regexp, :ignore_node
|
28
|
-
|
29
21
|
def autocorrect_action(node)
|
30
22
|
@corrections << lambda do |corrector|
|
31
23
|
corrector.replace(node.loc.begin, "'")
|
@@ -174,11 +174,14 @@ module Rubocop
|
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
|
-
# Checks that block braces have surrounding space.
|
178
|
-
|
177
|
+
# Checks that block braces have surrounding space. For blocks taking
|
178
|
+
# parameters, it check that the left brace has or doesn't have trailing
|
179
|
+
# space depending on configuration.
|
180
|
+
class SpaceAroundBlockBraces < Cop
|
179
181
|
include SurroundingSpace
|
180
182
|
MSG_LEFT = "Surrounding space missing for '{'."
|
181
183
|
MSG_RIGHT = "Space missing to the left of '}'."
|
184
|
+
MSG_PIPE = 'Space between { and | detected.'
|
182
185
|
|
183
186
|
def investigate(processed_source)
|
184
187
|
return unless processed_source.ast
|
@@ -188,9 +191,14 @@ module Rubocop
|
|
188
191
|
next if ([t1.pos, t2.pos] - positions_not_to_check).size < 2
|
189
192
|
|
190
193
|
type1, type2 = t1.type, t2.type
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
+
check(t1, t2, MSG_LEFT) if type2 == :tLCURLY
|
195
|
+
if type1 == :tLCURLY
|
196
|
+
if type2 == :tPIPE && cop_config['NoSpaceBeforeBlockParameters']
|
197
|
+
check_pipe(t1, t2, MSG_PIPE)
|
198
|
+
else
|
199
|
+
check(t1, t2, MSG_LEFT)
|
200
|
+
end
|
201
|
+
end
|
194
202
|
check(t1, t2, MSG_RIGHT) if type2 == :tRCURLY
|
195
203
|
end
|
196
204
|
end
|
@@ -227,6 +235,10 @@ module Rubocop
|
|
227
235
|
convention(nil, brace_token.pos, msg)
|
228
236
|
end
|
229
237
|
end
|
238
|
+
|
239
|
+
def check_pipe(t1, t2, msg)
|
240
|
+
convention(nil, t1.pos, msg) if space_between?(t1, t2)
|
241
|
+
end
|
230
242
|
end
|
231
243
|
|
232
244
|
# Common functionality for checking for spaces inside various
|
data/lib/rubocop/version.rb
CHANGED
data/rubocop.gemspec
CHANGED
@@ -28,7 +28,6 @@ Gem::Specification.new do |s|
|
|
28
28
|
|
29
29
|
s.add_runtime_dependency('rainbow', '>= 1.1.4')
|
30
30
|
s.add_runtime_dependency('parser', '~> 2.0.0.pre6')
|
31
|
-
s.add_runtime_dependency('backports', '~> 3.3.3')
|
32
31
|
s.add_runtime_dependency('powerpack', '~> 0.0.6')
|
33
32
|
s.add_development_dependency('rake', '~> 10.1')
|
34
33
|
s.add_development_dependency('rspec', '~> 2.14')
|
data/spec/rubocop/cli_spec.rb
CHANGED
@@ -25,19 +25,20 @@ module Rubocop
|
|
25
25
|
File.expand_path(path)
|
26
26
|
end
|
27
27
|
|
28
|
-
describe '
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
it 'shows help text' do
|
35
|
-
begin
|
36
|
-
cli.run(['--help'])
|
37
|
-
rescue SystemExit # rubocop:disable HandleExceptions
|
28
|
+
describe 'option' do
|
29
|
+
describe '-h/--help' do
|
30
|
+
it 'exits cleanly' do
|
31
|
+
expect { cli.run ['-h'] }.to exit_with_code(0)
|
32
|
+
expect { cli.run ['--help'] }.to exit_with_code(0)
|
38
33
|
end
|
39
34
|
|
40
|
-
|
35
|
+
it 'shows help text' do
|
36
|
+
begin
|
37
|
+
cli.run(['--help'])
|
38
|
+
rescue SystemExit # rubocop:disable HandleExceptions
|
39
|
+
end
|
40
|
+
|
41
|
+
expected_help = <<-END
|
41
42
|
Usage: rubocop [options] [file1, file2, ...]
|
42
43
|
-d, --debug Display debug info.
|
43
44
|
-c, --config FILE Specify configuration file.
|
@@ -70,44 +71,514 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
70
71
|
-V, --verbose-version Display verbose version.
|
71
72
|
END
|
72
73
|
|
73
|
-
|
74
|
+
expect($stdout.string).to eq(expected_help)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'lists all builtin formatters' do
|
78
|
+
begin
|
79
|
+
cli.run(['--help'])
|
80
|
+
rescue SystemExit # rubocop:disable HandleExceptions
|
81
|
+
end
|
82
|
+
|
83
|
+
option_sections = $stdout.string.lines.slice_before(/^\s*-/)
|
84
|
+
|
85
|
+
format_section = option_sections.find do |lines|
|
86
|
+
lines.first =~ /^\s*-f/
|
87
|
+
end
|
88
|
+
|
89
|
+
formatter_keys = format_section.reduce([]) do |keys, line|
|
90
|
+
match = line.match(/^[ ]{39}(\[[a-z\]]+)/)
|
91
|
+
next keys unless match
|
92
|
+
keys << match.captures.first.gsub(/\[|\]/, '')
|
93
|
+
end.sort
|
94
|
+
|
95
|
+
expected_formatter_keys =
|
96
|
+
Formatter::FormatterSet::BUILTIN_FORMATTERS_FOR_KEYS.keys.sort
|
97
|
+
|
98
|
+
expect(formatter_keys).to eq(expected_formatter_keys)
|
99
|
+
end
|
74
100
|
end
|
75
101
|
|
76
|
-
|
77
|
-
|
78
|
-
cli.run
|
79
|
-
|
102
|
+
describe '--version' do
|
103
|
+
it 'exits cleanly' do
|
104
|
+
expect { cli.run ['-v'] }.to exit_with_code(0)
|
105
|
+
expect { cli.run ['--version'] }.to exit_with_code(0)
|
106
|
+
expect($stdout.string).to eq((Rubocop::Version::STRING + "\n") * 2)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '--auto-gen-config' do
|
111
|
+
it 'exits with error if asked to re-generate a todo list that is in ' +
|
112
|
+
'use' do
|
113
|
+
create_file('example1.rb', ['# encoding: utf-8',
|
114
|
+
'x= 0 ',
|
115
|
+
'#' * 85,
|
116
|
+
'y ',
|
117
|
+
'puts x'])
|
118
|
+
todo_contents = ['# This configuration was generated with `rubocop' +
|
119
|
+
' --auto-gen-config`',
|
120
|
+
'',
|
121
|
+
'LineLength:',
|
122
|
+
' Enabled: false']
|
123
|
+
create_file('rubocop-todo.yml', todo_contents)
|
124
|
+
expect(IO.read('rubocop-todo.yml'))
|
125
|
+
.to eq(todo_contents.join("\n") + "\n")
|
126
|
+
create_file('.rubocop.yml', ['inherit_from: rubocop-todo.yml'])
|
127
|
+
expect(cli.run(['--auto-gen-config'])).to eq(1)
|
128
|
+
expect($stderr.string).to eq('Remove rubocop-todo.yml from the ' +
|
129
|
+
'current configuration before ' +
|
130
|
+
"generating it again.\n")
|
80
131
|
end
|
81
132
|
|
82
|
-
|
133
|
+
it 'exits with error if file arguments are given' do
|
134
|
+
create_file('example1.rb', ['# encoding: utf-8',
|
135
|
+
'x= 0 ',
|
136
|
+
'#' * 85,
|
137
|
+
'y ',
|
138
|
+
'puts x'])
|
139
|
+
expect(cli.run(['--auto-gen-config', 'example1.rb'])).to eq(1)
|
140
|
+
expect($stderr.string)
|
141
|
+
.to eq('--auto-gen-config can not be combined with any other ' +
|
142
|
+
"arguments.\n")
|
143
|
+
expect($stdout.string).to eq('')
|
144
|
+
end
|
83
145
|
|
84
|
-
|
85
|
-
|
146
|
+
it 'can generate a todo list' do
|
147
|
+
create_file('example1.rb', ['# encoding: utf-8',
|
148
|
+
'x= 0 ',
|
149
|
+
'#' * 85,
|
150
|
+
'y ',
|
151
|
+
'puts x'])
|
152
|
+
create_file('example2.rb', ['# encoding: utf-8',
|
153
|
+
"\tx = 0",
|
154
|
+
'puts x'])
|
155
|
+
expect(cli.run(['--auto-gen-config'])).to eq(1)
|
156
|
+
expect($stderr.string).to eq('')
|
157
|
+
expect($stdout.string)
|
158
|
+
.to include([
|
159
|
+
'Created rubocop-todo.yml.',
|
160
|
+
'Run rubocop with --config rubocop-todo.yml, or',
|
161
|
+
'add inherit_from: rubocop-todo.yml in a ' +
|
162
|
+
'.rubocop.yml file.',
|
163
|
+
''].join("\n"))
|
164
|
+
expect(IO.read('rubocop-todo.yml'))
|
165
|
+
.to eq(['# This configuration was generated by `rubocop' +
|
166
|
+
' --auto-gen-config`.',
|
167
|
+
'# The point is for the user to remove these' +
|
168
|
+
' configuration records',
|
169
|
+
'# one by one as the offences are removed from the code ' +
|
170
|
+
'base.',
|
171
|
+
'',
|
172
|
+
'LineLength:',
|
173
|
+
' Enabled: false',
|
174
|
+
'',
|
175
|
+
'SpaceAroundOperators:',
|
176
|
+
' Enabled: false',
|
177
|
+
'',
|
178
|
+
'Tab:',
|
179
|
+
' Enabled: false',
|
180
|
+
'',
|
181
|
+
'TrailingWhitespace:',
|
182
|
+
' Enabled: false',
|
183
|
+
''].join("\n"))
|
86
184
|
end
|
185
|
+
end
|
87
186
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
187
|
+
describe '--only' do
|
188
|
+
it 'runs just one cop' do
|
189
|
+
create_file('example.rb', ['if x== 0 ',
|
190
|
+
"\ty",
|
191
|
+
'end'])
|
192
|
+
# IfUnlessModifier depends on the configuration of LineLength.
|
193
|
+
|
194
|
+
expect(cli.run(['--format', 'simple',
|
195
|
+
'--only', 'IfUnlessModifier',
|
196
|
+
'example.rb'])).to eq(1)
|
197
|
+
expect($stdout.string)
|
198
|
+
.to eq(['== example.rb ==',
|
199
|
+
'C: 1: 1: Favor modifier if/unless usage when you ' +
|
200
|
+
'have a single-line body. Another good alternative is ' +
|
201
|
+
'the usage of control flow &&/||.',
|
202
|
+
'',
|
203
|
+
'1 file inspected, 1 offence detected',
|
204
|
+
''].join("\n"))
|
205
|
+
end
|
93
206
|
|
94
|
-
|
95
|
-
|
207
|
+
it 'exits with error if an incorrect cop name is passed' do
|
208
|
+
expect(cli.run(%w(--only 123))).to eq(1)
|
209
|
+
expect($stderr.string).to eq("Unrecognized cop name: 123.\n")
|
210
|
+
end
|
211
|
+
end
|
96
212
|
|
97
|
-
|
213
|
+
describe '--lint' do
|
214
|
+
it 'runs only lint cops' do
|
215
|
+
create_file('example.rb', ['if 0 ',
|
216
|
+
"\ty",
|
217
|
+
'end'])
|
218
|
+
# IfUnlessModifier depends on the configuration of LineLength.
|
219
|
+
|
220
|
+
expect(cli.run(['--format', 'simple', '--lint',
|
221
|
+
'example.rb'])).to eq(1)
|
222
|
+
expect($stdout.string)
|
223
|
+
.to eq(['== example.rb ==',
|
224
|
+
'W: 1: 4: Literal 0 appeared in a condition.',
|
225
|
+
'',
|
226
|
+
'1 file inspected, 1 offence detected',
|
227
|
+
''].join("\n"))
|
228
|
+
end
|
98
229
|
end
|
99
|
-
end
|
100
230
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
231
|
+
describe '--show-cops' do
|
232
|
+
let(:cops) { Cop::Cop.all }
|
233
|
+
|
234
|
+
let(:global_conf) do
|
235
|
+
config_path = Rubocop::Config.configuration_file_for(Dir.pwd.to_s)
|
236
|
+
Rubocop::Config.configuration_from_file(config_path)
|
237
|
+
end
|
238
|
+
|
239
|
+
let(:stdout) { $stdout.string }
|
240
|
+
|
241
|
+
before do
|
242
|
+
expect { cli.run ['--show-cops'] }.to exit_with_code(0)
|
243
|
+
end
|
244
|
+
|
245
|
+
# Extracts the first line out of the description
|
246
|
+
def short_description_of_cop(cop)
|
247
|
+
desc = full_description_of_cop(cop)
|
248
|
+
desc ? desc.lines.first.strip : ''
|
249
|
+
end
|
250
|
+
|
251
|
+
# Gets the full description of the cop or nil if no description is set.
|
252
|
+
def full_description_of_cop(cop)
|
253
|
+
cop_config = global_conf.for_cop(cop)
|
254
|
+
cop_config['Description']
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'prints all available cops and their description' do
|
258
|
+
cops.each do |cop|
|
259
|
+
expect(stdout).to include cop.cop_name
|
260
|
+
expect(stdout).to include short_description_of_cop(cop)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
it 'prints all types' do
|
265
|
+
cops
|
266
|
+
.types
|
267
|
+
.map(&:to_s)
|
268
|
+
.map(&:capitalize)
|
269
|
+
.each { |type| expect(stdout).to include(type) }
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'prints all cops in their right type listing' do
|
273
|
+
lines = stdout.lines
|
274
|
+
lines.slice_before(/Type /).each do |slice|
|
275
|
+
types = cops.types.map(&:to_s).map(&:capitalize)
|
276
|
+
current = types.delete(slice.shift[/Type '(?<c>[^'']+)'/, 'c'])
|
277
|
+
# all cops in their type listing
|
278
|
+
cops.with_type(current).each do |cop|
|
279
|
+
expect(slice.any? { |l| l.include? cop.cop_name }).to be_true
|
280
|
+
end
|
281
|
+
|
282
|
+
# no cop in wrong type listing
|
283
|
+
types.each do |type|
|
284
|
+
cops.with_type(type).each do |cop|
|
285
|
+
expect(slice.any? { |l| l.include? cop.cop_name }).to be_false
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'prints the current configuration' do
|
292
|
+
out = stdout.lines.to_a
|
293
|
+
cops.each do |cop|
|
294
|
+
conf = global_conf[cop.cop_name].dup
|
295
|
+
confstrt =
|
296
|
+
out.find_index { |i| i.include?("- #{cop.cop_name}") } + 1
|
297
|
+
c = out[confstrt, conf.keys.size].to_s
|
298
|
+
conf.delete('Description')
|
299
|
+
expect(c).to include(short_description_of_cop(cop))
|
300
|
+
conf.each do |k, v|
|
301
|
+
# ugly hack to get hash/array content tested
|
302
|
+
if v.kind_of?(Hash) || v.kind_of?(Array)
|
303
|
+
expect(c).to include "#{k}: #{v.to_s.dump[2, -2]}"
|
304
|
+
else
|
305
|
+
expect(c).to include "#{k}: #{v}"
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
describe '-d/--debug' do
|
313
|
+
it 'shows config files', ruby: 2.0 do
|
314
|
+
create_file('example1.rb', "\tputs 0")
|
315
|
+
expect(cli.run(['--debug', 'example1.rb'])).to eq(1)
|
316
|
+
home = File.dirname(File.dirname(File.dirname(__FILE__)))
|
317
|
+
expect($stdout.string.lines[2, 7].map(&:chomp).join("\n"))
|
318
|
+
.to eq(["For #{abs('')}:" +
|
319
|
+
" configuration from #{home}/config/default.yml",
|
320
|
+
"Inheriting configuration from #{home}/config/enabled.yml",
|
321
|
+
"Inheriting configuration from #{home}/config/" +
|
322
|
+
'disabled.yml',
|
323
|
+
"AllCops/Excludes configuration from #{home}/.rubocop.yml",
|
324
|
+
"Inheriting configuration from #{home}/config/default.yml",
|
325
|
+
"Inheriting configuration from #{home}/config/enabled.yml",
|
326
|
+
"Inheriting configuration from #{home}/config/disabled.yml"
|
327
|
+
].join("\n"))
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'shows cop names', ruby: 2.0 do
|
331
|
+
create_file('example1.rb', "\tputs 0")
|
332
|
+
expect(cli.run(['--format',
|
333
|
+
'emacs',
|
334
|
+
'--debug',
|
335
|
+
'example1.rb'])).to eq(1)
|
336
|
+
expect($stdout.string.lines[-1])
|
337
|
+
.to eq(["#{abs('example1.rb')}:1:1: C: Tab: Tab detected.",
|
338
|
+
''].join("\n"))
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
describe '--require' do
|
343
|
+
let(:required_file_path) { './path/to/required_file.rb' }
|
344
|
+
|
345
|
+
before do
|
346
|
+
create_file('example.rb', '# encoding: utf-8')
|
347
|
+
|
348
|
+
create_file(required_file_path, [
|
349
|
+
'# encoding: utf-8',
|
350
|
+
"puts 'Hello from required file!'"
|
351
|
+
])
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'requires the passed path' do
|
355
|
+
cli.run(['--require', required_file_path, 'example.rb'])
|
356
|
+
expect($stdout.string).to start_with('Hello from required file!')
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
describe '-f/--format' do
|
361
|
+
let(:target_file) { 'example.rb' }
|
362
|
+
|
363
|
+
before do
|
364
|
+
create_file(target_file, [
|
365
|
+
'# encoding: utf-8',
|
366
|
+
'#' * 90
|
367
|
+
])
|
368
|
+
end
|
369
|
+
|
370
|
+
describe 'builtin formatters' do
|
371
|
+
context 'when simple format is specified' do
|
372
|
+
it 'outputs with simple format' do
|
373
|
+
cli.run(['--format', 'simple', 'example.rb'])
|
374
|
+
expect($stdout.string)
|
375
|
+
.to include([
|
376
|
+
"== #{target_file} ==",
|
377
|
+
'C: 2: 80: Line is too long. [90/79]'
|
378
|
+
].join("\n"))
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
context 'when clang format is specified' do
|
383
|
+
it 'outputs with clang format' do
|
384
|
+
create_file('example1.rb', ['# encoding: utf-8',
|
385
|
+
'x= 0 ',
|
386
|
+
'#' * 85,
|
387
|
+
'y ',
|
388
|
+
'puts x'])
|
389
|
+
create_file('example2.rb', ['# encoding: utf-8',
|
390
|
+
"\tx",
|
391
|
+
'def a',
|
392
|
+
' puts',
|
393
|
+
'end'])
|
394
|
+
create_file('example3.rb', ['# encoding: utf-8',
|
395
|
+
'def badName',
|
396
|
+
' if something',
|
397
|
+
' test',
|
398
|
+
' end',
|
399
|
+
'end'])
|
400
|
+
expect(cli.run(['--format', 'clang', 'example1.rb',
|
401
|
+
'example2.rb', 'example3.rb']))
|
402
|
+
.to eq(1)
|
403
|
+
expect($stdout.string)
|
404
|
+
.to eq(['example1.rb:2:2: C: Surrounding space missing for ' +
|
405
|
+
"operator '='.",
|
406
|
+
'x= 0 ',
|
407
|
+
' ^',
|
408
|
+
'example1.rb:2:5: C: Trailing whitespace detected.',
|
409
|
+
'x= 0 ',
|
410
|
+
' ^',
|
411
|
+
'example1.rb:3:80: C: Line is too long. [85/79]',
|
412
|
+
'###################################################' +
|
413
|
+
'##################################',
|
414
|
+
' ' +
|
415
|
+
' ^^^^^^',
|
416
|
+
'example1.rb:4:2: C: Trailing whitespace detected.',
|
417
|
+
'y ',
|
418
|
+
' ^',
|
419
|
+
'example2.rb:2:1: C: Tab detected.',
|
420
|
+
"\tx",
|
421
|
+
'^^^^^',
|
422
|
+
'example2.rb:4:1: C: Use 2 (not 3) spaces for ' +
|
423
|
+
'indentation.',
|
424
|
+
' puts',
|
425
|
+
'^^^',
|
426
|
+
'example3.rb:2:5: C: Use snake_case for methods and ' +
|
427
|
+
'variables.',
|
428
|
+
'def badName',
|
429
|
+
' ^^^^^^^',
|
430
|
+
'example3.rb:3:3: C: Favor modifier if/unless usage ' +
|
431
|
+
'when you have a single-line body. Another good ' +
|
432
|
+
'alternative is the usage of control flow &&/||.',
|
433
|
+
' if something',
|
434
|
+
' ^^',
|
435
|
+
'example3.rb:5:5: W: end at 5, 4 is not aligned ' +
|
436
|
+
'with if at 3, 2',
|
437
|
+
' end',
|
438
|
+
' ^^^',
|
439
|
+
'',
|
440
|
+
'3 files inspected, 9 offences detected',
|
441
|
+
''].join("\n"))
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
context 'when emacs format is specified' do
|
446
|
+
it 'outputs with emacs format' do
|
447
|
+
create_file('example1.rb', ['# encoding: utf-8',
|
448
|
+
'x= 0 ',
|
449
|
+
'y ',
|
450
|
+
'puts x'])
|
451
|
+
create_file('example2.rb', ['# encoding: utf-8',
|
452
|
+
"\tx = 0",
|
453
|
+
'puts x'])
|
454
|
+
expect(cli.run(['--format', 'emacs', 'example1.rb',
|
455
|
+
'example2.rb'])).to eq(1)
|
456
|
+
expected_output =
|
457
|
+
["#{abs('example1.rb')}:2:2: C: Surrounding space missing" +
|
458
|
+
" for operator '='.",
|
459
|
+
"#{abs('example1.rb')}:2:5: C: Trailing whitespace detected.",
|
460
|
+
"#{abs('example1.rb')}:3:2: C: Trailing whitespace detected.",
|
461
|
+
"#{abs('example2.rb')}:2:1: C: Tab detected.",
|
462
|
+
''].join("\n")
|
463
|
+
expect($stdout.string).to eq(expected_output)
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
context 'when unknown format name is specified' do
|
468
|
+
it 'aborts with error message' do
|
469
|
+
expect { cli.run(['--format', 'unknown', 'example.rb']) }
|
470
|
+
.to exit_with_code(1)
|
471
|
+
expect($stderr.string)
|
472
|
+
.to include('No formatter for "unknown"')
|
473
|
+
end
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
describe 'custom formatter' do
|
478
|
+
let(:target_file) { abs('example.rb') }
|
479
|
+
|
480
|
+
context 'when a class name is specified' do
|
481
|
+
it 'uses the class as a formatter' do
|
482
|
+
module ::MyTool
|
483
|
+
class RubocopFormatter < Rubocop::Formatter::BaseFormatter
|
484
|
+
def started(all_files)
|
485
|
+
output.puts "started: #{all_files.join(',')}"
|
486
|
+
end
|
487
|
+
|
488
|
+
def file_started(file, options)
|
489
|
+
output.puts "file_started: #{file}"
|
490
|
+
end
|
491
|
+
|
492
|
+
def file_finished(file, offences)
|
493
|
+
output.puts "file_finished: #{file}"
|
494
|
+
end
|
495
|
+
|
496
|
+
def finished(processed_files)
|
497
|
+
output.puts "finished: #{processed_files.join(',')}"
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
cli.run(['--format', 'MyTool::RubocopFormatter', 'example.rb'])
|
503
|
+
expect($stdout.string).to eq([
|
504
|
+
"started: #{target_file}",
|
505
|
+
"file_started: #{target_file}",
|
506
|
+
"file_finished: #{target_file}",
|
507
|
+
"finished: #{target_file}",
|
508
|
+
''
|
509
|
+
].join("\n"))
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
context 'when unknown class name is specified' do
|
514
|
+
it 'aborts with error message' do
|
515
|
+
args = '--format UnknownFormatter example.rb'
|
516
|
+
expect { cli.run(args.split) }.to exit_with_code(1)
|
517
|
+
expect($stderr.string).to include('UnknownFormatter')
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
it 'can be used multiple times' do
|
523
|
+
cli.run(['--format', 'simple', '--format', 'emacs', 'example.rb'])
|
524
|
+
expect($stdout.string)
|
525
|
+
.to include([
|
526
|
+
"== #{target_file} ==",
|
527
|
+
'C: 2: 80: Line is too long. [90/79]',
|
528
|
+
"#{abs(target_file)}:2:80: C: Line is too long. " +
|
529
|
+
'[90/79]'
|
530
|
+
].join("\n"))
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
describe '-o/--out option' do
|
535
|
+
let(:target_file) { 'example.rb' }
|
536
|
+
|
537
|
+
before do
|
538
|
+
create_file(target_file, [
|
539
|
+
'# encoding: utf-8',
|
540
|
+
'#' * 90
|
541
|
+
])
|
542
|
+
end
|
543
|
+
|
544
|
+
it 'redirects output to the specified file' do
|
545
|
+
cli.run(['--out', 'output.txt', target_file])
|
546
|
+
expect(File.read('output.txt')).to include('Line is too long.')
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'is applied to the previously specified formatter' do
|
550
|
+
cli.run([
|
551
|
+
'--format', 'simple',
|
552
|
+
'--format', 'emacs', '--out', 'emacs_output.txt',
|
553
|
+
target_file
|
554
|
+
])
|
555
|
+
|
556
|
+
expect($stdout.string).to eq([
|
557
|
+
"== #{target_file} ==",
|
558
|
+
'C: 2: 80: Line is too long. [90/79]',
|
559
|
+
'',
|
560
|
+
'1 file inspected, 1 offence detected',
|
561
|
+
''
|
562
|
+
].join("\n"))
|
563
|
+
|
564
|
+
expect(File.read('emacs_output.txt'))
|
565
|
+
.to eq("#{abs(target_file)}:2:80: C: Line is too long. [90/79]\n")
|
566
|
+
end
|
567
|
+
end
|
105
568
|
end
|
106
569
|
|
107
570
|
describe '#wants_to_quit?' do
|
108
571
|
it 'is initially false' do
|
109
572
|
expect(cli.wants_to_quit?).to be_false
|
110
573
|
end
|
574
|
+
|
575
|
+
context 'when true' do
|
576
|
+
it 'returns 1' do
|
577
|
+
create_file('example.rb', '# encoding: utf-8')
|
578
|
+
cli.wants_to_quit = true
|
579
|
+
expect(cli.run(['example.rb'])).to eq(1)
|
580
|
+
end
|
581
|
+
end
|
111
582
|
end
|
112
583
|
|
113
584
|
describe '#trap_interrupt' do
|
@@ -154,20 +625,12 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
154
625
|
end
|
155
626
|
end
|
156
627
|
|
157
|
-
context 'when #wants_to_quit? is true' do
|
158
|
-
it 'returns 1' do
|
159
|
-
create_file('example.rb', '# encoding: utf-8')
|
160
|
-
cli.wants_to_quit = true
|
161
|
-
expect(cli.run(['example.rb'])).to eq(1)
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
628
|
it 'checks a given correct file and returns 0' do
|
166
629
|
create_file('example.rb', [
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
630
|
+
'# encoding: utf-8',
|
631
|
+
'x = 0',
|
632
|
+
'puts x'
|
633
|
+
])
|
171
634
|
expect(cli.run(['--format', 'simple', 'example.rb'])).to eq(0)
|
172
635
|
expect($stdout.string)
|
173
636
|
.to eq("\n1 file inspected, no offences detected\n")
|
@@ -175,10 +638,10 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
175
638
|
|
176
639
|
it 'checks a given file with faults and returns 1' do
|
177
640
|
create_file('example.rb', [
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
641
|
+
'# encoding: utf-8',
|
642
|
+
'x = 0 ',
|
643
|
+
'puts x'
|
644
|
+
])
|
182
645
|
expect(cli.run(['--format', 'simple', 'example.rb'])).to eq(1)
|
183
646
|
expect($stdout.string)
|
184
647
|
.to eq ['== example.rb ==',
|
@@ -188,598 +651,12 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
188
651
|
''].join("\n")
|
189
652
|
end
|
190
653
|
|
191
|
-
it 'can report in emacs style', ruby: 1.9 do
|
192
|
-
create_file('example1.rb', [
|
193
|
-
'x= 0 ',
|
194
|
-
'y ',
|
195
|
-
'puts x'
|
196
|
-
])
|
197
|
-
create_file('example2.rb', [
|
198
|
-
"\tx = 0",
|
199
|
-
'puts x'
|
200
|
-
])
|
201
|
-
expect(cli.run(['--format', 'emacs', 'example1.rb', 'example2.rb']))
|
202
|
-
.to eq(1)
|
203
|
-
expect($stdout.string)
|
204
|
-
.to eq(
|
205
|
-
["#{abs('example1.rb')}:1:1: C: Missing utf-8 encoding comment.",
|
206
|
-
"#{abs('example1.rb')}:1:2: C: Surrounding space missing" +
|
207
|
-
" for operator '='.",
|
208
|
-
"#{abs('example1.rb')}:1:5: C: Trailing whitespace detected.",
|
209
|
-
"#{abs('example1.rb')}:2:2: C: Trailing whitespace detected.",
|
210
|
-
"#{abs('example2.rb')}:1:1: C: Missing utf-8 encoding comment.",
|
211
|
-
"#{abs('example2.rb')}:1:1: C: Tab detected.",
|
212
|
-
''].join("\n"))
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'can report in emacs style', ruby: 2.0 do
|
216
|
-
create_file('example1.rb', [
|
217
|
-
'x= 0 ',
|
218
|
-
'y ',
|
219
|
-
'puts x'
|
220
|
-
])
|
221
|
-
create_file('example2.rb', [
|
222
|
-
"\tx = 0",
|
223
|
-
'puts x'
|
224
|
-
])
|
225
|
-
expect(cli.run(['--format', 'emacs', 'example1.rb', 'example2.rb']))
|
226
|
-
.to eq(1)
|
227
|
-
expect($stdout.string)
|
228
|
-
.to eq(
|
229
|
-
["#{abs('example1.rb')}:1:2: C: Surrounding space missing" +
|
230
|
-
" for operator '='.",
|
231
|
-
"#{abs('example1.rb')}:1:5: C: Trailing whitespace detected.",
|
232
|
-
"#{abs('example1.rb')}:2:2: C: Trailing whitespace detected.",
|
233
|
-
"#{abs('example2.rb')}:1:1: C: Tab detected.",
|
234
|
-
''].join("\n"))
|
235
|
-
end
|
236
|
-
|
237
|
-
it 'can report in clang style' do
|
238
|
-
create_file('example1.rb', ['# encoding: utf-8',
|
239
|
-
'x= 0 ',
|
240
|
-
'#' * 85,
|
241
|
-
'y ',
|
242
|
-
'puts x'])
|
243
|
-
create_file('example2.rb', ['# encoding: utf-8',
|
244
|
-
"\tx",
|
245
|
-
'def a',
|
246
|
-
' puts',
|
247
|
-
'end'])
|
248
|
-
create_file('example3.rb', ['# encoding: utf-8',
|
249
|
-
'def badName',
|
250
|
-
' if something',
|
251
|
-
' test',
|
252
|
-
' end',
|
253
|
-
'end'])
|
254
|
-
expect(cli.run(['--format', 'clang', 'example1.rb', 'example2.rb',
|
255
|
-
'example3.rb']))
|
256
|
-
.to eq(1)
|
257
|
-
expect($stdout.string)
|
258
|
-
.to eq(['example1.rb:2:2: C: Surrounding space missing for operator ' +
|
259
|
-
"'='.",
|
260
|
-
'x= 0 ',
|
261
|
-
' ^',
|
262
|
-
'example1.rb:2:5: C: Trailing whitespace detected.',
|
263
|
-
'x= 0 ',
|
264
|
-
' ^',
|
265
|
-
'example1.rb:3:80: C: Line is too long. [85/79]',
|
266
|
-
'###########################################################' +
|
267
|
-
'##########################',
|
268
|
-
' ' +
|
269
|
-
' ^^^^^^',
|
270
|
-
'example1.rb:4:2: C: Trailing whitespace detected.',
|
271
|
-
'y ',
|
272
|
-
' ^',
|
273
|
-
'example2.rb:2:1: C: Tab detected.',
|
274
|
-
"\tx",
|
275
|
-
'^^^^^',
|
276
|
-
'example2.rb:4:1: C: Use 2 (not 3) spaces for indentation.',
|
277
|
-
' puts',
|
278
|
-
'^^^',
|
279
|
-
'example3.rb:2:5: C: Use snake_case for methods and ' +
|
280
|
-
'variables.',
|
281
|
-
'def badName',
|
282
|
-
' ^^^^^^^',
|
283
|
-
'example3.rb:3:3: C: Favor modifier if/unless usage when ' +
|
284
|
-
'you have a single-line body. Another good alternative is ' +
|
285
|
-
'the usage of control flow &&/||.',
|
286
|
-
' if something',
|
287
|
-
' ^^',
|
288
|
-
'example3.rb:5:5: W: end at 5, 4 is not aligned with if at ' +
|
289
|
-
'3, 2',
|
290
|
-
' end',
|
291
|
-
' ^^^',
|
292
|
-
'',
|
293
|
-
'3 files inspected, 9 offences detected',
|
294
|
-
''].join("\n"))
|
295
|
-
end
|
296
|
-
|
297
|
-
it 'exits with error if asked to re-generate a todo list that is in use' do
|
298
|
-
create_file('example1.rb', ['# encoding: utf-8',
|
299
|
-
'x= 0 ',
|
300
|
-
'#' * 85,
|
301
|
-
'y ',
|
302
|
-
'puts x'])
|
303
|
-
todo_contents = ['# This configuration was generated with `rubocop' +
|
304
|
-
' --auto-gen-config`',
|
305
|
-
'',
|
306
|
-
'LineLength:',
|
307
|
-
' Enabled: false']
|
308
|
-
create_file('rubocop-todo.yml', todo_contents)
|
309
|
-
expect(IO.read('rubocop-todo.yml'))
|
310
|
-
.to eq(todo_contents.join("\n") + "\n")
|
311
|
-
create_file('.rubocop.yml', ['inherit_from: rubocop-todo.yml'])
|
312
|
-
expect(cli.run(['--auto-gen-config'])).to eq(1)
|
313
|
-
expect($stderr.string).to eq('Remove rubocop-todo.yml from the current' +
|
314
|
-
' configuration before generating it' +
|
315
|
-
" again.\n")
|
316
|
-
end
|
317
|
-
|
318
|
-
it 'exits with error if file arguments are given with --auto-gen-config' do
|
319
|
-
create_file('example1.rb', ['# encoding: utf-8',
|
320
|
-
'x= 0 ',
|
321
|
-
'#' * 85,
|
322
|
-
'y ',
|
323
|
-
'puts x'])
|
324
|
-
expect(cli.run(['--auto-gen-config', 'example1.rb'])).to eq(1)
|
325
|
-
expect($stderr.string).to eq('--auto-gen-config can not be combined ' +
|
326
|
-
"with any other arguments.\n")
|
327
|
-
expect($stdout.string).to eq('')
|
328
|
-
end
|
329
|
-
|
330
|
-
it 'can generate a todo list' do
|
331
|
-
create_file('example1.rb', ['# encoding: utf-8',
|
332
|
-
'x= 0 ',
|
333
|
-
'#' * 85,
|
334
|
-
'y ',
|
335
|
-
'puts x'])
|
336
|
-
create_file('example2.rb', ['# encoding: utf-8',
|
337
|
-
"\tx = 0",
|
338
|
-
'puts x'])
|
339
|
-
expect(cli.run(['--auto-gen-config'])).to eq(1)
|
340
|
-
expect($stderr.string).to eq('')
|
341
|
-
expect($stdout.string).to include([
|
342
|
-
'Created rubocop-todo.yml.',
|
343
|
-
'Run rubocop with --config rubocop-todo.yml, or',
|
344
|
-
'add inherit_from: rubocop-todo.yml in a .rubocop.yml file.',
|
345
|
-
''].join("\n"))
|
346
|
-
expect(IO.read('rubocop-todo.yml'))
|
347
|
-
.to eq(['# This configuration was generated by `rubocop' +
|
348
|
-
' --auto-gen-config`.',
|
349
|
-
'# The point is for the user to remove these configuration' +
|
350
|
-
' records',
|
351
|
-
'# one by one as the offences are removed from the code base.',
|
352
|
-
'',
|
353
|
-
'LineLength:',
|
354
|
-
' Enabled: false',
|
355
|
-
'',
|
356
|
-
'SpaceAroundOperators:',
|
357
|
-
' Enabled: false',
|
358
|
-
'',
|
359
|
-
'Tab:',
|
360
|
-
' Enabled: false',
|
361
|
-
'',
|
362
|
-
'TrailingWhitespace:',
|
363
|
-
' Enabled: false',
|
364
|
-
''].join("\n"))
|
365
|
-
end
|
366
|
-
|
367
|
-
it 'runs just one cop if --only is passed' do
|
368
|
-
create_file('example.rb', ['if x== 0 ',
|
369
|
-
"\ty",
|
370
|
-
'end'])
|
371
|
-
# IfUnlessModifier depends on the configuration of LineLength.
|
372
|
-
|
373
|
-
expect(cli.run(['--format', 'simple',
|
374
|
-
'--only', 'IfUnlessModifier', 'example.rb'])).to eq(1)
|
375
|
-
expect($stdout.string)
|
376
|
-
.to eq(['== example.rb ==',
|
377
|
-
'C: 1: 1: Favor modifier if/unless usage when you have a ' +
|
378
|
-
'single-line body. Another good alternative is the usage of ' +
|
379
|
-
'control flow &&/||.',
|
380
|
-
'',
|
381
|
-
'1 file inspected, 1 offence detected',
|
382
|
-
''].join("\n"))
|
383
|
-
end
|
384
|
-
|
385
|
-
it 'runs only lint cops if --lint is passed' do
|
386
|
-
create_file('example.rb', ['if 0 ',
|
387
|
-
"\ty",
|
388
|
-
'end'])
|
389
|
-
# IfUnlessModifier depends on the configuration of LineLength.
|
390
|
-
|
391
|
-
expect(cli.run(['--format', 'simple', '--lint', 'example.rb'])).to eq(1)
|
392
|
-
expect($stdout.string)
|
393
|
-
.to eq(['== example.rb ==',
|
394
|
-
'W: 1: 4: Literal 0 appeared in a condition.',
|
395
|
-
'',
|
396
|
-
'1 file inspected, 1 offence detected',
|
397
|
-
''].join("\n"))
|
398
|
-
|
399
|
-
end
|
400
|
-
|
401
|
-
it 'exits with error if an incorrect cop name is passed to --only' do
|
402
|
-
expect(cli.run(%w(--only 123))).to eq(1)
|
403
|
-
|
404
|
-
expect($stderr.string).to eq("Unrecognized cop name: 123.\n")
|
405
|
-
end
|
406
|
-
|
407
|
-
describe '--show-cops option' do
|
408
|
-
let(:cops) { Cop::Cop.all }
|
409
|
-
|
410
|
-
let(:global_conf) do
|
411
|
-
config_path = Rubocop::Config.configuration_file_for(Dir.pwd.to_s)
|
412
|
-
Rubocop::Config.configuration_from_file(config_path)
|
413
|
-
end
|
414
|
-
|
415
|
-
let(:stdout) { $stdout.string }
|
416
|
-
|
417
|
-
before do
|
418
|
-
expect { cli.run ['--show-cops'] }.to exit_with_code(0)
|
419
|
-
end
|
420
|
-
|
421
|
-
# Extracts the first line out of the description
|
422
|
-
def short_description_of_cop(cop)
|
423
|
-
desc = full_description_of_cop(cop)
|
424
|
-
desc ? desc.lines.first.strip : ''
|
425
|
-
end
|
426
|
-
|
427
|
-
# Gets the full description of the cop or nil if no description is set.
|
428
|
-
def full_description_of_cop(cop)
|
429
|
-
cop_config = global_conf.for_cop(cop)
|
430
|
-
cop_config['Description']
|
431
|
-
end
|
432
|
-
|
433
|
-
it 'prints all available cops and their description' do
|
434
|
-
cops.each do |cop|
|
435
|
-
expect(stdout).to include cop.cop_name
|
436
|
-
expect(stdout).to include short_description_of_cop(cop)
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
it 'prints all types' do
|
441
|
-
cops
|
442
|
-
.types
|
443
|
-
.map(&:to_s)
|
444
|
-
.map(&:capitalize)
|
445
|
-
.each { |type| expect(stdout).to include(type) }
|
446
|
-
end
|
447
|
-
|
448
|
-
it 'prints all cops in their right type listing' do
|
449
|
-
lines = stdout.lines
|
450
|
-
lines.slice_before(/Type /).each do |slice|
|
451
|
-
types = cops.types.map(&:to_s).map(&:capitalize)
|
452
|
-
current = types.delete(slice.shift[/Type '(?<c>[^'']+)'/, 'c'])
|
453
|
-
# all cops in their type listing
|
454
|
-
cops.with_type(current).each do |cop|
|
455
|
-
expect(slice.any? { |l| l.include? cop.cop_name }).to be_true
|
456
|
-
end
|
457
|
-
|
458
|
-
# no cop in wrong type listing
|
459
|
-
types.each do |type|
|
460
|
-
cops.with_type(type).each do |cop|
|
461
|
-
expect(slice.any? { |l| l.include? cop.cop_name }).to be_false
|
462
|
-
end
|
463
|
-
end
|
464
|
-
end
|
465
|
-
end
|
466
|
-
|
467
|
-
it 'prints the current configuration' do
|
468
|
-
out = stdout.lines.to_a
|
469
|
-
cops.each do |cop|
|
470
|
-
conf = global_conf[cop.cop_name].dup
|
471
|
-
confstrt = out.find_index { |i| i.include?("- #{cop.cop_name}") } + 1
|
472
|
-
c = out[confstrt, conf.keys.size].to_s
|
473
|
-
conf.delete('Description')
|
474
|
-
expect(c).to include(short_description_of_cop(cop))
|
475
|
-
conf.each do |k, v|
|
476
|
-
# ugly hack to get hash/array content tested
|
477
|
-
if v.kind_of?(Hash) || v.kind_of?(Array)
|
478
|
-
expect(c).to include "#{k}: #{v.to_s.dump[2, -2]}"
|
479
|
-
else
|
480
|
-
expect(c).to include "#{k}: #{v}"
|
481
|
-
end
|
482
|
-
end
|
483
|
-
end
|
484
|
-
end
|
485
|
-
end
|
486
|
-
|
487
|
-
it 'shows config files when --debug is passed', ruby: 2.0 do
|
488
|
-
create_file('example1.rb', "\tputs 0")
|
489
|
-
expect(cli.run(['--debug', 'example1.rb'])).to eq(1)
|
490
|
-
home = File.dirname(File.dirname(File.dirname(__FILE__)))
|
491
|
-
expect($stdout.string.lines[2, 7].map(&:chomp).join("\n"))
|
492
|
-
.to eq(["For #{abs('')}:" +
|
493
|
-
" configuration from #{home}/config/default.yml",
|
494
|
-
"Inheriting configuration from #{home}/config/enabled.yml",
|
495
|
-
"Inheriting configuration from #{home}/config/disabled.yml",
|
496
|
-
"AllCops/Excludes configuration from #{home}/.rubocop.yml",
|
497
|
-
"Inheriting configuration from #{home}/config/default.yml",
|
498
|
-
"Inheriting configuration from #{home}/config/enabled.yml",
|
499
|
-
"Inheriting configuration from #{home}/config/disabled.yml"
|
500
|
-
].join("\n"))
|
501
|
-
end
|
502
|
-
|
503
|
-
it 'shows cop names when --debug is passed', ruby: 2.0 do
|
504
|
-
create_file('example1.rb', "\tputs 0")
|
505
|
-
expect(cli.run(['--format',
|
506
|
-
'emacs',
|
507
|
-
'--debug',
|
508
|
-
'example1.rb'])).to eq(1)
|
509
|
-
expect($stdout.string.lines[-1]).to eq(
|
510
|
-
["#{abs('example1.rb')}:1:1: C: Tab: Tab detected.",
|
511
|
-
''].join("\n"))
|
512
|
-
end
|
513
|
-
|
514
|
-
it 'can be configured with option to disable a certain error' do
|
515
|
-
create_file('example1.rb', 'puts 0 ')
|
516
|
-
create_file('rubocop.yml', [
|
517
|
-
'Encoding:',
|
518
|
-
' Enabled: false',
|
519
|
-
'',
|
520
|
-
'CaseIndentation:',
|
521
|
-
' Enabled: false'
|
522
|
-
])
|
523
|
-
expect(cli.run(['--format', 'simple',
|
524
|
-
'-c', 'rubocop.yml', 'example1.rb'])).to eq(1)
|
525
|
-
expect($stdout.string).to eq(
|
526
|
-
['== example1.rb ==',
|
527
|
-
'C: 1: 7: Trailing whitespace detected.',
|
528
|
-
'',
|
529
|
-
'1 file inspected, 1 offence detected',
|
530
|
-
''].join("\n"))
|
531
|
-
end
|
532
|
-
|
533
|
-
it 'can be configured to override a parameter that is a hash' do
|
534
|
-
create_file('example1.rb',
|
535
|
-
['# encoding: utf-8',
|
536
|
-
'arr.find_all { |e| e > 0 }.collect { |e| -e }'])
|
537
|
-
# We only care about select over find_all. All other preferred methods
|
538
|
-
# appearing in the default config are gone when we override
|
539
|
-
# PreferredMethods. We get no report about collect.
|
540
|
-
create_file('rubocop.yml',
|
541
|
-
['CollectionMethods:',
|
542
|
-
' PreferredMethods:',
|
543
|
-
' find_all: select'])
|
544
|
-
cli.run(['--format', 'simple', '-c', 'rubocop.yml', 'example1.rb'])
|
545
|
-
expect($stdout.string).to eq(
|
546
|
-
['== example1.rb ==',
|
547
|
-
'C: 2: 5: Prefer select over find_all.',
|
548
|
-
'',
|
549
|
-
'1 file inspected, 1 offence detected',
|
550
|
-
''].join("\n"))
|
551
|
-
end
|
552
|
-
|
553
|
-
it 'works when a cop that others depend on is disabled' do
|
554
|
-
create_file('example1.rb', ['if a',
|
555
|
-
' b',
|
556
|
-
'end'])
|
557
|
-
create_file('rubocop.yml', [
|
558
|
-
'Encoding:',
|
559
|
-
' Enabled: false',
|
560
|
-
'',
|
561
|
-
'LineLength:',
|
562
|
-
' Enabled: false'
|
563
|
-
])
|
564
|
-
result = cli.run(['--format', 'simple',
|
565
|
-
'-c', 'rubocop.yml', 'example1.rb'])
|
566
|
-
expect($stdout.string).to eq(
|
567
|
-
['== example1.rb ==',
|
568
|
-
'C: 1: 1: Favor modifier if/unless usage when you have a ' +
|
569
|
-
'single-line body. Another good alternative is the usage of ' +
|
570
|
-
'control flow &&/||.',
|
571
|
-
'',
|
572
|
-
'1 file inspected, 1 offence detected',
|
573
|
-
''].join("\n"))
|
574
|
-
expect(result).to eq(1)
|
575
|
-
end
|
576
|
-
|
577
|
-
it 'can be configured with project config to disable a certain error' do
|
578
|
-
create_file('example_src/example1.rb', 'puts 0 ')
|
579
|
-
create_file('example_src/.rubocop.yml', [
|
580
|
-
'Encoding:',
|
581
|
-
' Enabled: false',
|
582
|
-
'',
|
583
|
-
'CaseIndentation:',
|
584
|
-
' Enabled: false'
|
585
|
-
])
|
586
|
-
expect(cli.run(['--format', 'simple',
|
587
|
-
'example_src/example1.rb'])).to eq(1)
|
588
|
-
expect($stdout.string).to eq(
|
589
|
-
['== example_src/example1.rb ==',
|
590
|
-
'C: 1: 7: Trailing whitespace detected.',
|
591
|
-
'',
|
592
|
-
'1 file inspected, 1 offence detected',
|
593
|
-
''].join("\n"))
|
594
|
-
end
|
595
|
-
|
596
|
-
it 'can use an alternative max line length from a config file' do
|
597
|
-
create_file('example_src/example1.rb', [
|
598
|
-
'# encoding: utf-8',
|
599
|
-
'#' * 90
|
600
|
-
])
|
601
|
-
create_file('example_src/.rubocop.yml', [
|
602
|
-
'LineLength:',
|
603
|
-
' Enabled: true',
|
604
|
-
' Max: 100'
|
605
|
-
])
|
606
|
-
expect(cli.run(['--format', 'simple',
|
607
|
-
'example_src/example1.rb'])).to eq(0)
|
608
|
-
expect($stdout.string).to eq(
|
609
|
-
['', '1 file inspected, no offences detected',
|
610
|
-
''].join("\n"))
|
611
|
-
end
|
612
|
-
|
613
|
-
it 'can have different config files in different directories' do
|
614
|
-
%w(src lib).each do |dir|
|
615
|
-
create_file("example/#{dir}/example1.rb", [
|
616
|
-
'# encoding: utf-8',
|
617
|
-
'#' * 90
|
618
|
-
])
|
619
|
-
end
|
620
|
-
create_file('example/src/.rubocop.yml', [
|
621
|
-
'LineLength:',
|
622
|
-
' Enabled: true',
|
623
|
-
' Max: 100'
|
624
|
-
])
|
625
|
-
expect(cli.run(%w(--format simple example))).to eq(1)
|
626
|
-
expect($stdout.string).to eq(
|
627
|
-
['== example/lib/example1.rb ==',
|
628
|
-
'C: 2: 80: Line is too long. [90/79]',
|
629
|
-
'',
|
630
|
-
'2 files inspected, 1 offence detected',
|
631
|
-
''].join("\n"))
|
632
|
-
end
|
633
|
-
|
634
|
-
it 'prefers a config file in ancestor directory to another in home' do
|
635
|
-
create_file('example_src/example1.rb', [
|
636
|
-
'# encoding: utf-8',
|
637
|
-
'#' * 90
|
638
|
-
])
|
639
|
-
create_file('example_src/.rubocop.yml', [
|
640
|
-
'LineLength:',
|
641
|
-
' Enabled: true',
|
642
|
-
' Max: 100'
|
643
|
-
])
|
644
|
-
create_file("#{Dir.home}/.rubocop.yml", [
|
645
|
-
'LineLength:',
|
646
|
-
' Enabled: true',
|
647
|
-
' Max: 80'
|
648
|
-
])
|
649
|
-
expect(cli.run(['--format', 'simple',
|
650
|
-
'example_src/example1.rb'])).to eq(0)
|
651
|
-
expect($stdout.string).to eq(
|
652
|
-
['', '1 file inspected, no offences detected',
|
653
|
-
''].join("\n"))
|
654
|
-
end
|
655
|
-
|
656
|
-
it 'can exclude directories relative to .rubocop.yml' do
|
657
|
-
%w(src etc/test etc/spec tmp/test tmp/spec).each do |dir|
|
658
|
-
create_file("example/#{dir}/example1.rb", [
|
659
|
-
'# encoding: utf-8',
|
660
|
-
'#' * 90
|
661
|
-
])
|
662
|
-
end
|
663
|
-
|
664
|
-
create_file('example/.rubocop.yml', [
|
665
|
-
'AllCops:',
|
666
|
-
' Excludes:',
|
667
|
-
' - src/**',
|
668
|
-
' - etc/**',
|
669
|
-
' - tmp/spec/**'
|
670
|
-
])
|
671
|
-
|
672
|
-
expect(cli.run(%w(--format simple example))).to eq(1)
|
673
|
-
expect($stdout.string).to eq(
|
674
|
-
['== example/tmp/test/example1.rb ==',
|
675
|
-
'C: 2: 80: Line is too long. [90/79]',
|
676
|
-
'',
|
677
|
-
'1 file inspected, 1 offence detected',
|
678
|
-
''].join("\n"))
|
679
|
-
end
|
680
|
-
|
681
|
-
it 'can exclude a typical vendor directory' do
|
682
|
-
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
|
683
|
-
['AllCops:',
|
684
|
-
' Excludes:',
|
685
|
-
' - lib/parser/lexer.rb'])
|
686
|
-
|
687
|
-
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
|
688
|
-
['# encoding: utf-8',
|
689
|
-
'#' * 90])
|
690
|
-
|
691
|
-
create_file('.rubocop.yml',
|
692
|
-
['AllCops:',
|
693
|
-
' Excludes:',
|
694
|
-
' - vendor/**'])
|
695
|
-
|
696
|
-
cli.run(%w(--format simple))
|
697
|
-
expect($stdout.string).to eq(
|
698
|
-
['',
|
699
|
-
'0 files inspected, no offences detected',
|
700
|
-
''].join("\n"))
|
701
|
-
end
|
702
|
-
|
703
|
-
# Relative exclude paths in .rubocop.yml files are relative to that file,
|
704
|
-
# but in configuration files with other names they will be relative to
|
705
|
-
# whatever file inherits from them.
|
706
|
-
it 'can exclude a vendor directory indirectly' do
|
707
|
-
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
|
708
|
-
['AllCops:',
|
709
|
-
' Excludes:',
|
710
|
-
' - lib/parser/lexer.rb'])
|
711
|
-
|
712
|
-
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
|
713
|
-
['# encoding: utf-8',
|
714
|
-
'#' * 90])
|
715
|
-
|
716
|
-
create_file('.rubocop.yml',
|
717
|
-
['inherit_from: config/default.yml'])
|
718
|
-
|
719
|
-
create_file('config/default.yml',
|
720
|
-
['AllCops:',
|
721
|
-
' Excludes:',
|
722
|
-
' - vendor/**'])
|
723
|
-
|
724
|
-
cli.run(%w(--format simple))
|
725
|
-
expect($stdout.string).to eq(
|
726
|
-
['',
|
727
|
-
'0 files inspected, no offences detected',
|
728
|
-
''].join("\n"))
|
729
|
-
end
|
730
|
-
|
731
|
-
it 'prints a warning for an unrecognized cop name in .rubocop.yml' do
|
732
|
-
create_file('example/example1.rb', [
|
733
|
-
'# encoding: utf-8',
|
734
|
-
'#' * 90
|
735
|
-
])
|
736
|
-
|
737
|
-
create_file('example/.rubocop.yml', [
|
738
|
-
'LyneLenth:',
|
739
|
-
' Enabled: true',
|
740
|
-
' Max: 100'
|
741
|
-
])
|
742
|
-
|
743
|
-
expect(cli.run(%w(--format simple example))).to eq(1)
|
744
|
-
expect($stdout.string).to eq(
|
745
|
-
['Warning: unrecognized cop LyneLenth found in ' +
|
746
|
-
File.expand_path('example/.rubocop.yml'),
|
747
|
-
'== example/example1.rb ==',
|
748
|
-
'C: 2: 80: Line is too long. [90/79]',
|
749
|
-
'',
|
750
|
-
'1 file inspected, 1 offence detected',
|
751
|
-
''].join("\n"))
|
752
|
-
end
|
753
|
-
|
754
|
-
it 'prints a warning for an unrecognized configuration parameter' do
|
755
|
-
create_file('example/example1.rb', [
|
756
|
-
'# encoding: utf-8',
|
757
|
-
'#' * 90
|
758
|
-
])
|
759
|
-
|
760
|
-
create_file('example/.rubocop.yml', [
|
761
|
-
'LineLength:',
|
762
|
-
' Enabled: true',
|
763
|
-
' Min: 10'
|
764
|
-
])
|
765
|
-
|
766
|
-
expect(cli.run(%w(--format simple example))).to eq(1)
|
767
|
-
expect($stdout.string).to eq(
|
768
|
-
['Warning: unrecognized parameter LineLength:Min found in ' +
|
769
|
-
File.expand_path('example/.rubocop.yml'),
|
770
|
-
'== example/example1.rb ==',
|
771
|
-
'C: 2: 80: Line is too long. [90/79]',
|
772
|
-
'',
|
773
|
-
'1 file inspected, 1 offence detected',
|
774
|
-
''].join("\n"))
|
775
|
-
end
|
776
|
-
|
777
654
|
it 'registers an offence for a syntax error' do
|
778
655
|
create_file('example.rb', [
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
656
|
+
'# encoding: utf-8',
|
657
|
+
'class Test',
|
658
|
+
'en'
|
659
|
+
])
|
783
660
|
expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
|
784
661
|
expect($stdout.string)
|
785
662
|
.to eq(["#{abs('example.rb')}:3:3: E: unexpected " +
|
@@ -805,280 +682,435 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
805
682
|
|
806
683
|
it 'can process a file with an invalid UTF-8 byte sequence' do
|
807
684
|
create_file('example.rb', [
|
808
|
-
|
809
|
-
|
810
|
-
|
685
|
+
'# encoding: utf-8',
|
686
|
+
"# #{'f9'.hex.chr}#{'29'.hex.chr}"
|
687
|
+
])
|
811
688
|
expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(0)
|
812
689
|
end
|
813
690
|
|
814
|
-
|
815
|
-
|
816
|
-
'
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
691
|
+
describe 'rubocop:disable comment' do
|
692
|
+
it 'can disable all cops in a code section' do
|
693
|
+
create_file('example.rb',
|
694
|
+
['# encoding: utf-8',
|
695
|
+
'# rubocop:disable all',
|
696
|
+
'#' * 90,
|
697
|
+
'x(123456)',
|
698
|
+
'y("123")',
|
699
|
+
'def func',
|
700
|
+
' # rubocop: enable LineLength, StringLiterals',
|
701
|
+
' ' + '#' * 93,
|
702
|
+
' x(123456)',
|
703
|
+
' y("123")',
|
704
|
+
'end'])
|
705
|
+
expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
|
706
|
+
# all cops were disabled, then 2 were enabled again, so we
|
707
|
+
# should get 2 offences reported.
|
708
|
+
expect($stdout.string)
|
709
|
+
.to eq(["#{abs('example.rb')}:8:80: C: Line is too long. [95/79]",
|
710
|
+
"#{abs('example.rb')}:10:5: C: Prefer single-quoted " +
|
711
|
+
"strings when you don't need string interpolation or " +
|
712
|
+
'special symbols.',
|
713
|
+
''].join("\n"))
|
714
|
+
end
|
837
715
|
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
716
|
+
it 'can disable selected cops in a code section' do
|
717
|
+
create_file('example.rb',
|
718
|
+
['# encoding: utf-8',
|
719
|
+
'# rubocop:disable LineLength,NumericLiterals,' +
|
720
|
+
'StringLiterals',
|
721
|
+
'#' * 90,
|
722
|
+
'x(123456)',
|
723
|
+
'y("123")',
|
724
|
+
'def func',
|
725
|
+
' # rubocop: enable LineLength, StringLiterals',
|
726
|
+
' ' + '#' * 93,
|
727
|
+
' x(123456)',
|
728
|
+
' y("123")',
|
729
|
+
'end'])
|
730
|
+
expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
|
731
|
+
# 3 cops were disabled, then 2 were enabled again, so we
|
732
|
+
# should get 2 offences reported.
|
733
|
+
expect($stdout.string)
|
734
|
+
.to eq(["#{abs('example.rb')}:8:80: C: Line is too long. [95/79]",
|
735
|
+
"#{abs('example.rb')}:10:5: C: Prefer single-quoted " +
|
736
|
+
"strings when you don't need string interpolation or " +
|
737
|
+
'special symbols.',
|
738
|
+
''].join("\n"))
|
739
|
+
end
|
861
740
|
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
741
|
+
it 'can disable all cops on a single line' do
|
742
|
+
create_file('example.rb', [
|
743
|
+
'# encoding: utf-8',
|
744
|
+
'y("123", 123456) # rubocop:disable all'
|
745
|
+
])
|
746
|
+
expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(0)
|
747
|
+
expect($stdout.string).to be_empty
|
748
|
+
end
|
870
749
|
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
750
|
+
it 'can disable selected cops on a single line' do
|
751
|
+
create_file('example.rb',
|
752
|
+
[
|
753
|
+
'# encoding: utf-8',
|
754
|
+
'#' * 90 + ' # rubocop:disable LineLength',
|
755
|
+
'#' * 95,
|
756
|
+
'y("123") # rubocop:disable LineLength,StringLiterals'
|
757
|
+
])
|
758
|
+
expect(cli.run(['--format', 'emacs', 'example.rb'])).to eq(1)
|
759
|
+
expect($stdout.string)
|
760
|
+
.to eq(
|
761
|
+
["#{abs('example.rb')}:3:80: C: Line is too long. [95/79]",
|
762
|
+
''].join("\n"))
|
763
|
+
end
|
882
764
|
end
|
883
|
-
|
765
|
+
|
884
766
|
it 'finds a file with no .rb extension but has a shebang line' do
|
885
767
|
create_file('example', [
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
768
|
+
'#!/usr/bin/env ruby',
|
769
|
+
'# encoding: utf-8',
|
770
|
+
'x = 0',
|
771
|
+
'puts x'
|
772
|
+
])
|
891
773
|
expect(cli.run(%w(--format simple))).to eq(0)
|
892
|
-
expect($stdout.string)
|
893
|
-
['', '1 file inspected, no offences detected',
|
894
|
-
''].join("\n"))
|
895
|
-
end
|
896
|
-
|
897
|
-
it 'finds included files' do
|
898
|
-
create_file('example', [
|
899
|
-
'# encoding: utf-8',
|
900
|
-
'x = 0',
|
901
|
-
'puts x'
|
902
|
-
])
|
903
|
-
create_file('regexp', [
|
904
|
-
'# encoding: utf-8',
|
905
|
-
'x = 0',
|
906
|
-
'puts x'
|
907
|
-
])
|
908
|
-
create_file('.rubocop.yml', [
|
909
|
-
'AllCops:',
|
910
|
-
' Includes:',
|
911
|
-
' - example',
|
912
|
-
' - !ruby/regexp /regexp$/'
|
913
|
-
])
|
914
|
-
expect(cli.run(%w(--format simple))).to eq(0)
|
915
|
-
expect($stdout.string).to eq(
|
916
|
-
['', '2 files inspected, no offences detected',
|
917
|
-
''].join("\n"))
|
918
|
-
end
|
919
|
-
|
920
|
-
it 'ignores excluded files' do
|
921
|
-
create_file('example.rb', [
|
922
|
-
'# encoding: utf-8',
|
923
|
-
'x = 0',
|
924
|
-
'puts x'
|
925
|
-
])
|
926
|
-
create_file('regexp.rb', [
|
927
|
-
'# encoding: utf-8',
|
928
|
-
'x = 0',
|
929
|
-
'puts x'
|
930
|
-
])
|
931
|
-
create_file('exclude_glob.rb', [
|
932
|
-
'#!/usr/bin/env ruby',
|
933
|
-
'# encoding: utf-8',
|
934
|
-
'x = 0',
|
935
|
-
'puts x'
|
936
|
-
])
|
937
|
-
create_file('.rubocop.yml', [
|
938
|
-
'AllCops:',
|
939
|
-
' Excludes:',
|
940
|
-
' - example.rb',
|
941
|
-
' - !ruby/regexp /regexp.rb$/',
|
942
|
-
' - "exclude_*"'
|
943
|
-
])
|
944
|
-
expect(cli.run(%w(--format simple))).to eq(0)
|
945
|
-
expect($stdout.string).to eq(
|
946
|
-
['', '0 files inspected, no offences detected',
|
947
|
-
''].join("\n"))
|
774
|
+
expect($stdout.string)
|
775
|
+
.to eq(['', '1 file inspected, no offences detected', ''].join("\n"))
|
948
776
|
end
|
949
777
|
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
778
|
+
describe 'configuration from file' do
|
779
|
+
it 'finds included files' do
|
780
|
+
create_file('example', [
|
781
|
+
'# encoding: utf-8',
|
782
|
+
'x = 0',
|
783
|
+
'puts x'
|
784
|
+
])
|
785
|
+
create_file('regexp', [
|
786
|
+
'# encoding: utf-8',
|
787
|
+
'x = 0',
|
788
|
+
'puts x'
|
789
|
+
])
|
790
|
+
create_file('.rubocop.yml', [
|
791
|
+
'AllCops:',
|
792
|
+
' Includes:',
|
793
|
+
' - example',
|
794
|
+
' - !ruby/regexp /regexp$/'
|
795
|
+
])
|
796
|
+
expect(cli.run(%w(--format simple))).to eq(0)
|
797
|
+
expect($stdout.string)
|
798
|
+
.to eq(['', '2 files inspected, no offences detected',
|
799
|
+
''].join("\n"))
|
958
800
|
end
|
959
801
|
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
802
|
+
it 'ignores excluded files' do
|
803
|
+
create_file('example.rb', [
|
804
|
+
'# encoding: utf-8',
|
805
|
+
'x = 0',
|
806
|
+
'puts x'
|
807
|
+
])
|
808
|
+
create_file('regexp.rb', [
|
809
|
+
'# encoding: utf-8',
|
810
|
+
'x = 0',
|
811
|
+
'puts x'
|
812
|
+
])
|
813
|
+
create_file('exclude_glob.rb', [
|
814
|
+
'#!/usr/bin/env ruby',
|
815
|
+
'# encoding: utf-8',
|
816
|
+
'x = 0',
|
817
|
+
'puts x'
|
818
|
+
])
|
819
|
+
create_file('.rubocop.yml', [
|
820
|
+
'AllCops:',
|
821
|
+
' Excludes:',
|
822
|
+
' - example.rb',
|
823
|
+
' - !ruby/regexp /regexp.rb$/',
|
824
|
+
' - "exclude_*"'
|
825
|
+
])
|
826
|
+
expect(cli.run(%w(--format simple))).to eq(0)
|
827
|
+
expect($stdout.string)
|
828
|
+
.to eq(['', '0 files inspected, no offences detected',
|
829
|
+
''].join("\n"))
|
830
|
+
end
|
975
831
|
|
976
|
-
|
977
|
-
|
832
|
+
# With rubinius 2.0.0.rc1 + rspec 2.13.1,
|
833
|
+
# File.stub(:open).and_call_original causes SystemStackError.
|
834
|
+
it 'does not read files in excluded list', broken: :rbx do
|
835
|
+
%w(rb.rb non-rb.ext without-ext).each do |filename|
|
836
|
+
create_file("example/ignored/#{filename}", [
|
837
|
+
'# encoding: utf-8',
|
838
|
+
'#' * 90
|
839
|
+
])
|
840
|
+
end
|
978
841
|
|
979
|
-
create_file(
|
980
|
-
|
981
|
-
|
982
|
-
|
842
|
+
create_file('example/.rubocop.yml', [
|
843
|
+
'AllCops:',
|
844
|
+
' Excludes:',
|
845
|
+
' - ignored/**',
|
846
|
+
])
|
847
|
+
File.should_not_receive(:open).with(%r(/ignored/))
|
848
|
+
File.stub(:open).and_call_original
|
849
|
+
expect(cli.run(%w(--format simple example))).to eq(0)
|
850
|
+
expect($stdout.string)
|
851
|
+
.to eq(['', '0 files inspected, no offences detected',
|
852
|
+
''].join("\n"))
|
983
853
|
end
|
984
854
|
|
985
|
-
it '
|
986
|
-
|
987
|
-
|
855
|
+
it 'can be configured with option to disable a certain error' do
|
856
|
+
create_file('example1.rb', 'puts 0 ')
|
857
|
+
create_file('rubocop.yml', [
|
858
|
+
'Encoding:',
|
859
|
+
' Enabled: false',
|
860
|
+
'',
|
861
|
+
'CaseIndentation:',
|
862
|
+
' Enabled: false'
|
863
|
+
])
|
864
|
+
expect(cli.run(['--format', 'simple',
|
865
|
+
'-c', 'rubocop.yml', 'example1.rb'])).to eq(1)
|
866
|
+
expect($stdout.string)
|
867
|
+
.to eq(['== example1.rb ==',
|
868
|
+
'C: 1: 7: Trailing whitespace detected.',
|
869
|
+
'',
|
870
|
+
'1 file inspected, 1 offence detected',
|
871
|
+
''].join("\n"))
|
988
872
|
end
|
989
|
-
end
|
990
873
|
|
991
|
-
|
992
|
-
|
874
|
+
it 'can be configured to override a parameter that is a hash' do
|
875
|
+
create_file('example1.rb',
|
876
|
+
['# encoding: utf-8',
|
877
|
+
'arr.find_all { |e| e > 0 }.collect { |e| -e }'])
|
878
|
+
# We only care about select over find_all. All other preferred methods
|
879
|
+
# appearing in the default config are gone when we override
|
880
|
+
# PreferredMethods. We get no report about collect.
|
881
|
+
create_file('rubocop.yml',
|
882
|
+
['CollectionMethods:',
|
883
|
+
' PreferredMethods:',
|
884
|
+
' find_all: select'])
|
885
|
+
cli.run(['--format', 'simple', '-c', 'rubocop.yml', 'example1.rb'])
|
886
|
+
expect($stdout.string)
|
887
|
+
.to eq(['== example1.rb ==',
|
888
|
+
'C: 2: 5: Prefer select over find_all.',
|
889
|
+
'',
|
890
|
+
'1 file inspected, 1 offence detected',
|
891
|
+
''].join("\n"))
|
892
|
+
end
|
993
893
|
|
994
|
-
|
995
|
-
create_file(
|
996
|
-
|
997
|
-
|
998
|
-
|
894
|
+
it 'works when a cop that others depend on is disabled' do
|
895
|
+
create_file('example1.rb', ['if a',
|
896
|
+
' b',
|
897
|
+
'end'])
|
898
|
+
create_file('rubocop.yml', [
|
899
|
+
'Encoding:',
|
900
|
+
' Enabled: false',
|
901
|
+
'',
|
902
|
+
'LineLength:',
|
903
|
+
' Enabled: false'
|
904
|
+
])
|
905
|
+
result = cli.run(['--format', 'simple',
|
906
|
+
'-c', 'rubocop.yml', 'example1.rb'])
|
907
|
+
expect($stdout.string)
|
908
|
+
.to eq(['== example1.rb ==',
|
909
|
+
'C: 1: 1: Favor modifier if/unless usage when you have ' +
|
910
|
+
'a single-line body. Another good alternative is the ' +
|
911
|
+
'usage of control flow &&/||.',
|
912
|
+
'',
|
913
|
+
'1 file inspected, 1 offence detected',
|
914
|
+
''].join("\n"))
|
915
|
+
expect(result).to eq(1)
|
999
916
|
end
|
1000
917
|
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
918
|
+
it 'can be configured with project config to disable a certain error' do
|
919
|
+
create_file('example_src/example1.rb', 'puts 0 ')
|
920
|
+
create_file('example_src/.rubocop.yml', [
|
921
|
+
'Encoding:',
|
922
|
+
' Enabled: false',
|
923
|
+
'',
|
924
|
+
'CaseIndentation:',
|
925
|
+
' Enabled: false'
|
926
|
+
])
|
927
|
+
expect(cli.run(['--format', 'simple',
|
928
|
+
'example_src/example1.rb'])).to eq(1)
|
929
|
+
expect($stdout.string)
|
930
|
+
.to eq(['== example_src/example1.rb ==',
|
931
|
+
'C: 1: 7: Trailing whitespace detected.',
|
932
|
+
'',
|
933
|
+
'1 file inspected, 1 offence detected',
|
934
|
+
''].join("\n"))
|
935
|
+
end
|
1011
936
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
937
|
+
it 'can use an alternative max line length from a config file' do
|
938
|
+
create_file('example_src/example1.rb', [
|
939
|
+
'# encoding: utf-8',
|
940
|
+
'#' * 90
|
941
|
+
])
|
942
|
+
create_file('example_src/.rubocop.yml', [
|
943
|
+
'LineLength:',
|
944
|
+
' Enabled: true',
|
945
|
+
' Max: 100'
|
946
|
+
])
|
947
|
+
expect(cli.run(['--format', 'simple',
|
948
|
+
'example_src/example1.rb'])).to eq(0)
|
949
|
+
expect($stdout.string)
|
950
|
+
.to eq(['', '1 file inspected, no offences detected', ''].join("\n"))
|
951
|
+
end
|
1019
952
|
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
end
|
953
|
+
it 'can have different config files in different directories' do
|
954
|
+
%w(src lib).each do |dir|
|
955
|
+
create_file("example/#{dir}/example1.rb", [
|
956
|
+
'# encoding: utf-8',
|
957
|
+
'#' * 90
|
958
|
+
])
|
1027
959
|
end
|
960
|
+
create_file('example/src/.rubocop.yml', [
|
961
|
+
'LineLength:',
|
962
|
+
' Enabled: true',
|
963
|
+
' Max: 100'
|
964
|
+
])
|
965
|
+
expect(cli.run(%w(--format simple example))).to eq(1)
|
966
|
+
expect($stdout.string).to eq(
|
967
|
+
['== example/lib/example1.rb ==',
|
968
|
+
'C: 2: 80: Line is too long. [90/79]',
|
969
|
+
'',
|
970
|
+
'2 files inspected, 1 offence detected',
|
971
|
+
''].join("\n"))
|
1028
972
|
end
|
1029
973
|
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
974
|
+
it 'prefers a config file in ancestor directory to another in home' do
|
975
|
+
create_file('example_src/example1.rb', [
|
976
|
+
'# encoding: utf-8',
|
977
|
+
'#' * 90
|
978
|
+
])
|
979
|
+
create_file('example_src/.rubocop.yml', [
|
980
|
+
'LineLength:',
|
981
|
+
' Enabled: true',
|
982
|
+
' Max: 100'
|
983
|
+
])
|
984
|
+
create_file("#{Dir.home}/.rubocop.yml", [
|
985
|
+
'LineLength:',
|
986
|
+
' Enabled: true',
|
987
|
+
' Max: 80'
|
988
|
+
])
|
989
|
+
expect(cli.run(['--format', 'simple',
|
990
|
+
'example_src/example1.rb'])).to eq(0)
|
991
|
+
expect($stdout.string)
|
992
|
+
.to eq(['', '1 file inspected, no offences detected', ''].join("\n"))
|
993
|
+
end
|
1040
994
|
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
995
|
+
it 'can exclude directories relative to .rubocop.yml' do
|
996
|
+
%w(src etc/test etc/spec tmp/test tmp/spec).each do |dir|
|
997
|
+
create_file("example/#{dir}/example1.rb", [
|
998
|
+
'# encoding: utf-8',
|
999
|
+
'#' * 90
|
1000
|
+
])
|
1001
|
+
end
|
1044
1002
|
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1003
|
+
create_file('example/.rubocop.yml', [
|
1004
|
+
'AllCops:',
|
1005
|
+
' Excludes:',
|
1006
|
+
' - src/**',
|
1007
|
+
' - etc/**',
|
1008
|
+
' - tmp/spec/**'
|
1009
|
+
])
|
1010
|
+
|
1011
|
+
expect(cli.run(%w(--format simple example))).to eq(1)
|
1012
|
+
expect($stdout.string).to eq(
|
1013
|
+
['== example/tmp/test/example1.rb ==',
|
1014
|
+
'C: 2: 80: Line is too long. [90/79]',
|
1015
|
+
'',
|
1016
|
+
'1 file inspected, 1 offence detected',
|
1017
|
+
''].join("\n"))
|
1018
|
+
end
|
1048
1019
|
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1020
|
+
it 'can exclude a typical vendor directory' do
|
1021
|
+
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
|
1022
|
+
['AllCops:',
|
1023
|
+
' Excludes:',
|
1024
|
+
' - lib/parser/lexer.rb'])
|
1025
|
+
|
1026
|
+
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
|
1027
|
+
['# encoding: utf-8',
|
1028
|
+
'#' * 90])
|
1029
|
+
|
1030
|
+
create_file('.rubocop.yml',
|
1031
|
+
['AllCops:',
|
1032
|
+
' Excludes:',
|
1033
|
+
' - vendor/**'])
|
1034
|
+
|
1035
|
+
cli.run(%w(--format simple))
|
1036
|
+
expect($stdout.string)
|
1037
|
+
.to eq(['', '0 files inspected, no offences detected',
|
1038
|
+
''].join("\n"))
|
1039
|
+
end
|
1054
1040
|
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1041
|
+
# Relative exclude paths in .rubocop.yml files are relative to that file,
|
1042
|
+
# but in configuration files with other names they will be relative to
|
1043
|
+
# whatever file inherits from them.
|
1044
|
+
it 'can exclude a vendor directory indirectly' do
|
1045
|
+
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/.rubocop.yml',
|
1046
|
+
['AllCops:',
|
1047
|
+
' Excludes:',
|
1048
|
+
' - lib/parser/lexer.rb'])
|
1049
|
+
|
1050
|
+
create_file('vendor/bundle/ruby/1.9.1/gems/parser-2.0.0/lib/ex.rb',
|
1051
|
+
['# encoding: utf-8',
|
1052
|
+
'#' * 90])
|
1053
|
+
|
1054
|
+
create_file('.rubocop.yml',
|
1055
|
+
['inherit_from: config/default.yml'])
|
1056
|
+
|
1057
|
+
create_file('config/default.yml',
|
1058
|
+
['AllCops:',
|
1059
|
+
' Excludes:',
|
1060
|
+
' - vendor/**'])
|
1061
|
+
|
1062
|
+
cli.run(%w(--format simple))
|
1063
|
+
expect($stdout.string)
|
1064
|
+
.to eq(['', '0 files inspected, no offences detected',
|
1065
|
+
''].join("\n"))
|
1066
|
+
end
|
1065
1067
|
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1068
|
+
it 'prints a warning for an unrecognized cop name in .rubocop.yml' do
|
1069
|
+
create_file('example/example1.rb', [
|
1070
|
+
'# encoding: utf-8',
|
1071
|
+
'#' * 90
|
1072
|
+
])
|
1073
|
+
|
1074
|
+
create_file('example/.rubocop.yml', [
|
1075
|
+
'LyneLenth:',
|
1076
|
+
' Enabled: true',
|
1077
|
+
' Max: 100'
|
1078
|
+
])
|
1079
|
+
|
1080
|
+
expect(cli.run(%w(--format simple example))).to eq(1)
|
1081
|
+
expect($stdout.string)
|
1082
|
+
.to eq(
|
1083
|
+
['Warning: unrecognized cop LyneLenth found in ' +
|
1084
|
+
File.expand_path('example/.rubocop.yml'),
|
1085
|
+
'== example/example1.rb ==',
|
1086
|
+
'C: 2: 80: Line is too long. [90/79]',
|
1087
|
+
'',
|
1088
|
+
'1 file inspected, 1 offence detected',
|
1089
|
+
''].join("\n"))
|
1073
1090
|
end
|
1074
1091
|
|
1075
|
-
it '
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1092
|
+
it 'prints a warning for an unrecognized configuration parameter' do
|
1093
|
+
create_file('example/example1.rb', [
|
1094
|
+
'# encoding: utf-8',
|
1095
|
+
'#' * 90
|
1096
|
+
])
|
1097
|
+
|
1098
|
+
create_file('example/.rubocop.yml', [
|
1099
|
+
'LineLength:',
|
1100
|
+
' Enabled: true',
|
1101
|
+
' Min: 10'
|
1102
|
+
])
|
1103
|
+
|
1104
|
+
expect(cli.run(%w(--format simple example))).to eq(1)
|
1105
|
+
expect($stdout.string)
|
1106
|
+
.to eq(
|
1107
|
+
['Warning: unrecognized parameter LineLength:Min found in ' +
|
1108
|
+
File.expand_path('example/.rubocop.yml'),
|
1109
|
+
'== example/example1.rb ==',
|
1110
|
+
'C: 2: 80: Line is too long. [90/79]',
|
1111
|
+
'',
|
1112
|
+
'1 file inspected, 1 offence detected',
|
1113
|
+
''].join("\n"))
|
1082
1114
|
end
|
1083
1115
|
end
|
1084
1116
|
|
@@ -1101,43 +1133,6 @@ Usage: rubocop [options] [file1, file2, ...]
|
|
1101
1133
|
end
|
1102
1134
|
end
|
1103
1135
|
|
1104
|
-
describe '-o/--out option' do
|
1105
|
-
let(:target_file) { 'example.rb' }
|
1106
|
-
|
1107
|
-
before do
|
1108
|
-
create_file(target_file, [
|
1109
|
-
'# encoding: utf-8',
|
1110
|
-
'#' * 90
|
1111
|
-
])
|
1112
|
-
end
|
1113
|
-
|
1114
|
-
it 'redirects output to the specified file' do
|
1115
|
-
cli.run(['--out', 'output.txt', target_file])
|
1116
|
-
expect(File.read('output.txt')).to include('Line is too long.')
|
1117
|
-
end
|
1118
|
-
|
1119
|
-
it 'is applied to the previously specified formatter' do
|
1120
|
-
cli.run([
|
1121
|
-
'--format', 'simple',
|
1122
|
-
'--format', 'emacs', '--out', 'emacs_output.txt',
|
1123
|
-
target_file
|
1124
|
-
])
|
1125
|
-
|
1126
|
-
expect($stdout.string).to eq([
|
1127
|
-
"== #{target_file} ==",
|
1128
|
-
'C: 2: 80: Line is too long. [90/79]',
|
1129
|
-
'',
|
1130
|
-
'1 file inspected, 1 offence detected',
|
1131
|
-
''
|
1132
|
-
].join("\n"))
|
1133
|
-
|
1134
|
-
expect(File.read('emacs_output.txt')).to eq([
|
1135
|
-
"#{abs(target_file)}:2:80: C: Line is too long. [90/79]",
|
1136
|
-
''
|
1137
|
-
].join("\n"))
|
1138
|
-
end
|
1139
|
-
end
|
1140
|
-
|
1141
1136
|
describe '#display_error_summary' do
|
1142
1137
|
it 'displays an error message to stderr when errors are present' do
|
1143
1138
|
msg = 'An error occurred while Encoding cop was inspecting file.rb.'
|