rubocop 0.25.0 → 0.26.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +37 -0
- data/README.md +2 -2
- data/assets/output.html.erb +190 -0
- data/config/default.yml +14 -2
- data/config/disabled.yml +7 -0
- data/config/enabled.yml +132 -5
- data/lib/rubocop.rb +5 -0
- data/lib/rubocop/cop/commissioner.rb +4 -10
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -1
- data/lib/rubocop/cop/lint/end_in_method.rb +3 -8
- data/lib/rubocop/cop/lint/ensure_return.rb +2 -2
- data/lib/rubocop/cop/lint/space_before_first_arg.rb +8 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +35 -0
- data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -3
- data/lib/rubocop/cop/metrics/block_nesting.rb +3 -3
- data/lib/rubocop/cop/metrics/class_length.rb +1 -2
- data/lib/rubocop/cop/mixin/access_modifier_node.rb +5 -1
- data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -3
- data/lib/rubocop/cop/rails/delegate.rb +1 -1
- data/lib/rubocop/cop/rails/validation.rb +25 -2
- data/lib/rubocop/cop/style/alias.rb +1 -1
- data/lib/rubocop/cop/style/and_or.rb +12 -2
- data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -12
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/dot_position.rb +20 -0
- data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +5 -1
- data/lib/rubocop/cop/style/encoding.rb +4 -4
- data/lib/rubocop/cop/style/format_string.rb +12 -2
- data/lib/rubocop/cop/style/if_unless_modifier.rb +8 -11
- data/lib/rubocop/cop/style/infinite_loop.rb +57 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +15 -16
- data/lib/rubocop/cop/style/multiline_if_then.rb +10 -0
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -3
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -1
- data/lib/rubocop/cop/style/predicate_name.rb +23 -5
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +4 -8
- data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +9 -11
- data/lib/rubocop/cop/style/space_inside_range_literal.rb +58 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/symbol_proc.rb +71 -0
- data/lib/rubocop/cop/style/tab.rb +11 -3
- data/lib/rubocop/cop/style/unneeded_capital_w.rb +6 -2
- data/lib/rubocop/cop/style/variable_name.rb +4 -14
- data/lib/rubocop/cop/style/while_until_modifier.rb +12 -8
- data/lib/rubocop/cop/variable_force.rb +17 -30
- data/lib/rubocop/cop/variable_force/assignment.rb +15 -23
- data/lib/rubocop/cop/variable_force/locatable.rb +29 -8
- data/lib/rubocop/cop/variable_force/scope.rb +34 -23
- data/lib/rubocop/cop/variable_force/variable.rb +7 -10
- data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -0
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +90 -0
- data/lib/rubocop/formatter/progress_formatter.rb +1 -1
- data/lib/rubocop/options.rb +1 -0
- data/lib/rubocop/processed_source.rb +10 -1
- data/lib/rubocop/string_util.rb +153 -0
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/relnotes/v0.26.0.md +89 -0
- data/rubocop.gemspec +1 -0
- data/spec/rubocop/cli_spec.rb +60 -34
- data/spec/rubocop/config_loader_spec.rb +19 -15
- data/spec/rubocop/cop/commissioner_spec.rb +2 -2
- data/spec/rubocop/cop/lint/block_alignment_spec.rb +74 -58
- data/spec/rubocop/cop/lint/space_before_first_arg_spec.rb +7 -0
- data/spec/rubocop/cop/lint/useless_assignment_spec.rb +173 -0
- data/spec/rubocop/cop/rails/validation_spec.rb +9 -2
- data/spec/rubocop/cop/style/access_modifier_indentation_spec.rb +26 -0
- data/spec/rubocop/cop/style/and_or_spec.rb +52 -61
- data/spec/rubocop/cop/style/braces_around_hash_parameters_spec.rb +26 -8
- data/spec/rubocop/cop/style/case_indentation_spec.rb +8 -8
- data/spec/rubocop/cop/style/def_with_parentheses_spec.rb +6 -2
- data/spec/rubocop/cop/style/dot_position_spec.rb +39 -0
- data/spec/rubocop/cop/style/empty_lines_around_access_modifier_spec.rb +12 -2
- data/spec/rubocop/cop/style/encoding_spec.rb +16 -28
- data/spec/rubocop/cop/style/format_string_spec.rb +12 -0
- data/spec/rubocop/cop/style/infinite_loop_spec.rb +48 -0
- data/spec/rubocop/cop/style/method_def_parentheses_spec.rb +3 -1
- data/spec/rubocop/cop/style/multiline_if_then_spec.rb +9 -0
- data/spec/rubocop/cop/style/percent_literal_delimiters_spec.rb +21 -1
- data/spec/rubocop/cop/style/predicate_name_spec.rb +44 -13
- data/spec/rubocop/cop/style/redundant_begin_spec.rb +32 -0
- data/spec/rubocop/cop/style/space_inside_range_literal_spec.rb +52 -0
- data/spec/rubocop/cop/style/symbol_proc_spec.rb +76 -0
- data/spec/rubocop/cop/style/tab_spec.rb +30 -0
- data/spec/rubocop/cop/style/trailing_whitespace_spec.rb +2 -1
- data/spec/rubocop/cop/style/unneeded_capital_w_spec.rb +18 -5
- data/spec/rubocop/cop/style/variable_name_spec.rb +5 -5
- data/spec/rubocop/cop/style/when_then_spec.rb +3 -1
- data/spec/rubocop/cop/style/while_until_do_spec.rb +4 -2
- data/spec/rubocop/cop/util_spec.rb +1 -9
- data/spec/rubocop/cop/variable_force/assignment_spec.rb +2 -15
- data/spec/rubocop/cop/variable_force/locatable_spec.rb +2 -37
- data/spec/rubocop/cop/variable_force/scope_spec.rb +156 -49
- data/spec/rubocop/cop/variable_force/variable_spec.rb +2 -1
- data/spec/rubocop/cop/variable_force_spec.rb +2 -1
- data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +2 -1
- data/spec/rubocop/formatter/html_formatter_spec.rb +145 -0
- data/spec/rubocop/formatter/simple_text_formatter_spec.rb +18 -6
- data/spec/rubocop/options_spec.rb +1 -0
- data/spec/rubocop/path_util_spec.rb +6 -4
- data/spec/rubocop/processed_source_spec.rb +17 -1
- data/spec/rubocop/string_util_spec.rb +46 -0
- metadata +33 -4
- data/spec/support/ast_helper.rb +0 -15
@@ -51,10 +51,10 @@ describe RuboCop::Cop::Style::VariableName, :config do
|
|
51
51
|
expect(cop.highlights).to eq(['@myAttribute'])
|
52
52
|
end
|
53
53
|
|
54
|
-
it 'registers an offense for camel case in
|
55
|
-
inspect_source(cop, '
|
54
|
+
it 'registers an offense for camel case in class variable name' do
|
55
|
+
inspect_source(cop, '@@myAttr = 2')
|
56
56
|
expect(cop.offenses.size).to eq(1)
|
57
|
-
expect(cop.highlights).to eq(['
|
57
|
+
expect(cop.highlights).to eq(['@@myAttr'])
|
58
58
|
end
|
59
59
|
|
60
60
|
include_examples 'always accepted'
|
@@ -88,8 +88,8 @@ describe RuboCop::Cop::Style::VariableName, :config do
|
|
88
88
|
expect(cop.offenses).to be_empty
|
89
89
|
end
|
90
90
|
|
91
|
-
it 'accepts camel case in
|
92
|
-
inspect_source(cop, '
|
91
|
+
it 'accepts camel case in class variable name' do
|
92
|
+
inspect_source(cop, '@@myAttr = 2')
|
93
93
|
expect(cop.offenses).to be_empty
|
94
94
|
end
|
95
95
|
|
@@ -35,6 +35,8 @@ describe RuboCop::Cop::Style::WhenThen do
|
|
35
35
|
new_source = autocorrect_source(cop, ['case a',
|
36
36
|
'when b; c',
|
37
37
|
'end'])
|
38
|
-
expect(new_source).to eq(
|
38
|
+
expect(new_source).to eq(['case a',
|
39
|
+
'when b then c',
|
40
|
+
'end'].join("\n"))
|
39
41
|
end
|
40
42
|
end
|
@@ -42,12 +42,14 @@ describe RuboCop::Cop::Style::WhileUntilDo do
|
|
42
42
|
it 'auto-corrects the usage of "do" in multiline while' do
|
43
43
|
new_source = autocorrect_source(cop, ['while cond do',
|
44
44
|
'end'])
|
45
|
-
expect(new_source).to eq(
|
45
|
+
expect(new_source).to eq(['while cond',
|
46
|
+
'end'].join("\n"))
|
46
47
|
end
|
47
48
|
|
48
49
|
it 'auto-corrects the usage of "do" in multiline until' do
|
49
50
|
new_source = autocorrect_source(cop, ['until cond do',
|
50
51
|
'end'])
|
51
|
-
expect(new_source).to eq(
|
52
|
+
expect(new_source).to eq(['until cond',
|
53
|
+
'end'].join("\n"))
|
52
54
|
end
|
53
55
|
end
|
@@ -4,8 +4,6 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe RuboCop::Cop::Util do
|
6
6
|
describe '#line_range' do
|
7
|
-
include ASTHelper
|
8
|
-
|
9
7
|
let(:source) do
|
10
8
|
<<-END
|
11
9
|
foo = 1
|
@@ -24,13 +22,7 @@ describe RuboCop::Cop::Util do
|
|
24
22
|
processed_source.ast
|
25
23
|
end
|
26
24
|
|
27
|
-
let(:node)
|
28
|
-
target_node = scan_node(ast) do |node|
|
29
|
-
break node if node.type == :class
|
30
|
-
end
|
31
|
-
fail 'No target node found!' unless target_node
|
32
|
-
target_node
|
33
|
-
end
|
25
|
+
let(:node) { ast.each_node.find(&:class_type?) }
|
34
26
|
|
35
27
|
context 'when Source::Range object is passed' do
|
36
28
|
it 'returns line range of that' do
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe RuboCop::Cop::VariableForce::Assignment do
|
6
|
-
include ASTHelper
|
7
6
|
include AST::Sexp
|
8
7
|
|
9
8
|
let(:ast) do
|
@@ -25,21 +24,9 @@ describe RuboCop::Cop::VariableForce::Assignment do
|
|
25
24
|
END
|
26
25
|
end
|
27
26
|
|
28
|
-
let(:def_node)
|
29
|
-
found_node = scan_node(ast, include_origin_node: true) do |node|
|
30
|
-
break node if node.type == :def
|
31
|
-
end
|
32
|
-
fail 'No def node found!' unless found_node
|
33
|
-
found_node
|
34
|
-
end
|
27
|
+
let(:def_node) { ast.each_node.find(&:def_type?) }
|
35
28
|
|
36
|
-
let(:lvasgn_node)
|
37
|
-
found_node = scan_node(ast) do |node|
|
38
|
-
break node if node.type == :lvasgn
|
39
|
-
end
|
40
|
-
fail 'No lvasgn node found!' unless found_node
|
41
|
-
found_node
|
42
|
-
end
|
29
|
+
let(:lvasgn_node) { ast.each_node.find(&:lvasgn_type?) }
|
43
30
|
|
44
31
|
let(:name) { lvasgn_node.children.first }
|
45
32
|
let(:scope) { RuboCop::Cop::VariableForce::Scope.new(def_node) }
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe RuboCop::Cop::VariableForce::Locatable do
|
6
|
-
include ASTHelper
|
7
6
|
include AST::Sexp
|
8
7
|
|
9
8
|
class LocatableObject
|
@@ -22,46 +21,12 @@ describe RuboCop::Cop::VariableForce::Locatable do
|
|
22
21
|
processed_source.ast
|
23
22
|
end
|
24
23
|
|
25
|
-
let(:def_node)
|
26
|
-
|
27
|
-
break node if node.type == :def
|
28
|
-
end
|
29
|
-
fail 'No def node found!' unless found_node
|
30
|
-
found_node
|
31
|
-
end
|
32
|
-
|
33
|
-
let(:lvasgn_node) do
|
34
|
-
found_node = scan_node(ast) do |node|
|
35
|
-
break node if node.type == :lvasgn
|
36
|
-
end
|
37
|
-
fail 'No lvasgn node found!' unless found_node
|
38
|
-
found_node
|
39
|
-
end
|
24
|
+
let(:def_node) { ast.each_node.find(&:def_type?) }
|
25
|
+
let(:lvasgn_node) { ast.each_node.find(&:lvasgn_type?) }
|
40
26
|
|
41
27
|
let(:scope) { RuboCop::Cop::VariableForce::Scope.new(def_node) }
|
42
28
|
let(:assignment) { LocatableObject.new(lvasgn_node, scope) }
|
43
29
|
|
44
|
-
describe '#ancestor_nodes_in_scope' do
|
45
|
-
let(:source) do
|
46
|
-
<<-END
|
47
|
-
class SomeClass
|
48
|
-
def some_method(flag)
|
49
|
-
puts 'Hello World!'
|
50
|
-
|
51
|
-
if flag > 0
|
52
|
-
foo = 1
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
END
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'returns its ancestor nodes in the scope excluding scope node' do
|
60
|
-
ancestor_types = assignment.ancestor_nodes_in_scope.map(&:type)
|
61
|
-
expect(ancestor_types).to eq([:begin, :if])
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
30
|
describe '#branch_point_node' do
|
66
31
|
context 'when it is not in branch' do
|
67
32
|
let(:source) do
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe RuboCop::Cop::VariableForce::Scope do
|
6
|
-
include ASTHelper
|
7
6
|
include AST::Sexp
|
8
7
|
|
9
8
|
describe '.new' do
|
@@ -24,18 +23,12 @@ describe RuboCop::Cop::VariableForce::Scope do
|
|
24
23
|
|
25
24
|
let(:ast) do
|
26
25
|
ast = RuboCop::ProcessedSource.new(source).ast
|
27
|
-
RuboCop::Cop::VariableForce.
|
26
|
+
RuboCop::Cop::VariableForce.wrap_with_top_level_scope_node(ast)
|
28
27
|
end
|
29
28
|
|
30
29
|
let(:scope_node_type) { :def }
|
31
30
|
|
32
|
-
let(:scope_node)
|
33
|
-
found_node = scan_node(ast, include_origin_node: true) do |node|
|
34
|
-
break node if node.type == scope_node_type
|
35
|
-
end
|
36
|
-
fail 'No scope node found!' unless found_node
|
37
|
-
found_node
|
38
|
-
end
|
31
|
+
let(:scope_node) { ast.each_node(scope_node_type).first }
|
39
32
|
|
40
33
|
subject(:scope) { described_class.new(scope_node) }
|
41
34
|
|
@@ -67,45 +60,6 @@ describe RuboCop::Cop::VariableForce::Scope do
|
|
67
60
|
end
|
68
61
|
end
|
69
62
|
|
70
|
-
describe '#ancestors_of_node' do
|
71
|
-
let(:source) do
|
72
|
-
<<-END
|
73
|
-
puts 1
|
74
|
-
|
75
|
-
class SomeClass
|
76
|
-
def some_method
|
77
|
-
foo = 1
|
78
|
-
|
79
|
-
if foo > 0
|
80
|
-
while foo < 10
|
81
|
-
this_is_target
|
82
|
-
foo += 1
|
83
|
-
end
|
84
|
-
else
|
85
|
-
do_something
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
END
|
90
|
-
end
|
91
|
-
|
92
|
-
let(:target_node) do
|
93
|
-
found_node = scan_node(ast) do |node|
|
94
|
-
next unless node.type == :send
|
95
|
-
_receiver_node, method_name = *node
|
96
|
-
break node if method_name == :this_is_target
|
97
|
-
end
|
98
|
-
fail 'No target node found!' unless found_node
|
99
|
-
found_node
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'returns nodes in between the scope node and the passed node' do
|
103
|
-
ancestor_nodes = scope.ancestors_of_node(target_node)
|
104
|
-
ancestor_types = ancestor_nodes.map(&:type)
|
105
|
-
expect(ancestor_types).to eq([:begin, :if, :while, :begin])
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
63
|
describe '#body_node' do
|
110
64
|
shared_examples 'returns the body node' do
|
111
65
|
it 'returns the body node' do
|
@@ -204,9 +158,162 @@ describe RuboCop::Cop::VariableForce::Scope do
|
|
204
158
|
END
|
205
159
|
end
|
206
160
|
|
207
|
-
let(:scope_node_type) { :
|
161
|
+
let(:scope_node_type) { :begin }
|
208
162
|
|
209
163
|
include_examples 'returns the body node'
|
210
164
|
end
|
211
165
|
end
|
166
|
+
|
167
|
+
describe '#each_node' do
|
168
|
+
shared_examples 'yields' do |description|
|
169
|
+
it "yields #{description}" do
|
170
|
+
yielded_types = []
|
171
|
+
|
172
|
+
scope.each_node do |node|
|
173
|
+
yielded_types << node.type
|
174
|
+
end
|
175
|
+
|
176
|
+
expect(yielded_types).to eq(expected_types.map(&:to_sym))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
describe 'outer scope boundary handling' do
|
181
|
+
context 'when the scope is instance method' do
|
182
|
+
let(:source) { <<-END }
|
183
|
+
def some_method(arg1, arg2)
|
184
|
+
:body
|
185
|
+
end
|
186
|
+
END
|
187
|
+
|
188
|
+
let(:scope_node_type) { :def }
|
189
|
+
let(:expected_types) { %w(args arg arg sym) }
|
190
|
+
include_examples 'yields', 'the argument and the body nodes'
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when the scope is singleton method' do
|
194
|
+
let(:source) { <<-END }
|
195
|
+
def self.some_method(arg1, arg2)
|
196
|
+
:body
|
197
|
+
end
|
198
|
+
END
|
199
|
+
|
200
|
+
let(:scope_node_type) { :defs }
|
201
|
+
let(:expected_types) { %w(args arg arg sym) }
|
202
|
+
include_examples 'yields', 'the argument and the body nodes'
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'when the scope is module' do
|
206
|
+
let(:source) { <<-END }
|
207
|
+
module SomeModule
|
208
|
+
:body
|
209
|
+
end
|
210
|
+
END
|
211
|
+
|
212
|
+
let(:scope_node_type) { :module }
|
213
|
+
let(:expected_types) { %w(sym) }
|
214
|
+
include_examples 'yields', 'the body nodes'
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'when the scope is class' do
|
218
|
+
let(:source) { <<-END }
|
219
|
+
some_super_class = Class.new
|
220
|
+
|
221
|
+
class SomeClass < some_super_class
|
222
|
+
:body
|
223
|
+
end
|
224
|
+
END
|
225
|
+
|
226
|
+
let(:scope_node_type) { :class }
|
227
|
+
let(:expected_types) { %w(sym) }
|
228
|
+
include_examples 'yields', 'the body nodes'
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'when the scope is singleton class' do
|
232
|
+
let(:source) { <<-END }
|
233
|
+
some_object = Object.new
|
234
|
+
|
235
|
+
class << some_object
|
236
|
+
:body
|
237
|
+
end
|
238
|
+
END
|
239
|
+
|
240
|
+
let(:scope_node_type) { :sclass }
|
241
|
+
let(:expected_types) { %w(sym) }
|
242
|
+
include_examples 'yields', 'the body nodes'
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'when the scope is block' do
|
246
|
+
let(:source) { <<-END }
|
247
|
+
1.times do |arg1, arg2|
|
248
|
+
:body
|
249
|
+
end
|
250
|
+
END
|
251
|
+
|
252
|
+
let(:scope_node_type) { :block }
|
253
|
+
let(:expected_types) { %w(args arg arg sym) }
|
254
|
+
include_examples 'yields', 'the argument and the body nodes'
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'when the scope is top level' do
|
258
|
+
let(:source) { <<-END }
|
259
|
+
:body
|
260
|
+
END
|
261
|
+
|
262
|
+
let(:scope_node_type) { :begin }
|
263
|
+
let(:expected_types) { %w(sym) }
|
264
|
+
include_examples 'yields', 'the body nodes'
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe 'inner scope boundary handling' do
|
269
|
+
context "when there's a method invocation with block" do
|
270
|
+
let(:source) { <<-END }
|
271
|
+
foo = 1
|
272
|
+
|
273
|
+
do_something(1, 2) do |arg|
|
274
|
+
:body
|
275
|
+
end
|
276
|
+
|
277
|
+
foo
|
278
|
+
END
|
279
|
+
|
280
|
+
let(:scope_node_type) { :begin }
|
281
|
+
let(:expected_types) { %w(lvasgn int block send int int lvar) }
|
282
|
+
include_examples 'yields', 'only the block node and the child send node'
|
283
|
+
end
|
284
|
+
|
285
|
+
context "when there's a singleton method definition" do
|
286
|
+
let(:source) { <<-END }
|
287
|
+
foo = 1
|
288
|
+
|
289
|
+
def self.some_method(arg1, arg2)
|
290
|
+
:body
|
291
|
+
end
|
292
|
+
|
293
|
+
foo
|
294
|
+
END
|
295
|
+
|
296
|
+
let(:scope_node_type) { :begin }
|
297
|
+
let(:expected_types) { %w(lvasgn int defs self lvar) }
|
298
|
+
include_examples 'yields', 'only the defs node and the method host node'
|
299
|
+
end
|
300
|
+
|
301
|
+
context 'when there are grouped nodes with a begin node' do
|
302
|
+
let(:source) { <<-END }
|
303
|
+
foo = 1
|
304
|
+
|
305
|
+
if true
|
306
|
+
do_something
|
307
|
+
do_anything
|
308
|
+
end
|
309
|
+
|
310
|
+
foo
|
311
|
+
END
|
312
|
+
|
313
|
+
let(:scope_node_type) { :begin }
|
314
|
+
let(:expected_types) { %w(lvasgn int if true begin send send lvar) }
|
315
|
+
include_examples 'yields', 'them without confused with top level scope'
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
212
319
|
end
|
@@ -24,7 +24,8 @@ module RuboCop
|
|
24
24
|
|
25
25
|
formatter.file_finished('test', cop.offenses)
|
26
26
|
expect(output.string).to eq ['test:1:1: C: message 1',
|
27
|
-
|
27
|
+
'test:3:6: C: message 2',
|
28
|
+
''].join("\n")
|
28
29
|
end
|
29
30
|
|
30
31
|
context 'when the offense is automatically corrected' do
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
describe Formatter::HTMLFormatter do
|
8
|
+
subject(:formatter) { described_class.new(output) }
|
9
|
+
let(:output) { StringIO.new }
|
10
|
+
let(:files) { %w(/path/to/file1 /path/to/file2) }
|
11
|
+
let(:location) do
|
12
|
+
source_buffer = Parser::Source::Buffer.new('test', 1)
|
13
|
+
source_buffer.source = %w(a b cdefghi).join("\n")
|
14
|
+
Parser::Source::Range.new(source_buffer, 9, 10)
|
15
|
+
end
|
16
|
+
let(:offense) do
|
17
|
+
Cop::Offense.new(:convention, location,
|
18
|
+
'This is message', 'CopName', true)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#started' do
|
22
|
+
let(:summary) { formatter.output_hash[:summary] }
|
23
|
+
|
24
|
+
it 'sets target file count in summary' do
|
25
|
+
expect(summary[:target_file_count]).to be_nil
|
26
|
+
formatter.started(%w(/path/to/file1 /path/to/file2))
|
27
|
+
expect(summary[:target_file_count]).to eq(2)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#file_finished' do
|
32
|
+
before do
|
33
|
+
count = 0
|
34
|
+
allow(formatter).to receive(:hash_for_file) do
|
35
|
+
count += 1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:summary) { formatter.output_hash[:summary] }
|
40
|
+
|
41
|
+
it 'adds detected offense count in summary' do
|
42
|
+
expect(summary[:offense_count]).to eq(0)
|
43
|
+
|
44
|
+
formatter.file_started(files[0], {})
|
45
|
+
expect(summary[:offense_count]).to eq(0)
|
46
|
+
formatter.file_finished(files[0], [
|
47
|
+
double('offense1'), double('offense2')
|
48
|
+
])
|
49
|
+
expect(summary[:offense_count]).to eq(2)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'adds value of #hash_for_file to #output_hash[:files]' do
|
53
|
+
expect(formatter.output_hash[:files]).to be_empty
|
54
|
+
|
55
|
+
formatter.file_started(files[0], {})
|
56
|
+
expect(formatter.output_hash[:files]).to be_empty
|
57
|
+
formatter.file_finished(files[0], [])
|
58
|
+
expect(formatter.output_hash[:files]).to eq([1])
|
59
|
+
|
60
|
+
formatter.file_started(files[1], {})
|
61
|
+
expect(formatter.output_hash[:files]).to eq([1])
|
62
|
+
formatter.file_finished(files[1], [])
|
63
|
+
expect(formatter.output_hash[:files]).to eq([1, 2])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#finished' do
|
68
|
+
let(:summary) { formatter.output_hash[:summary] }
|
69
|
+
|
70
|
+
it 'sets inspected file count in summary' do
|
71
|
+
expect(summary[:inspected_file_count]).to be_nil
|
72
|
+
formatter.finished(%w(/path/to/file1 /path/to/file2))
|
73
|
+
expect(summary[:inspected_file_count]).to eq(2)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#hash_for_file' do
|
78
|
+
subject(:hash) { formatter.hash_for_file(file, offenses) }
|
79
|
+
let(:file) { File.expand_path('spec/spec_helper.rb') }
|
80
|
+
let(:offenses) { [double('offense1'), double('offense2')] }
|
81
|
+
|
82
|
+
it 'sets relative file path for :path key' do
|
83
|
+
expect(hash[:path]).to eq('spec/spec_helper.rb')
|
84
|
+
end
|
85
|
+
|
86
|
+
before do
|
87
|
+
count = 0
|
88
|
+
allow(formatter).to receive(:hash_for_offense) do
|
89
|
+
count += 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'sets an array of #hash_for_offense values for :offenses key' do
|
94
|
+
expect(hash[:offenses]).to eq([1, 2])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#hash_for_offense' do
|
99
|
+
subject(:hash) { formatter.hash_for_offense(offense) }
|
100
|
+
|
101
|
+
it 'sets Offense#severity value for :severity key' do
|
102
|
+
expect(hash[:severity]).to eq(:convention)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'sets Offense#message value for :message key' do
|
106
|
+
expect(hash[:message]).to eq('This is message')
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'sets Offense#cop_name value for :cop_name key' do
|
110
|
+
expect(hash[:cop_name]).to eq('CopName')
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'sets Offense#corrected? value for :corrected key' do
|
114
|
+
expect(hash[:corrected]).to be_truthy
|
115
|
+
end
|
116
|
+
|
117
|
+
before do
|
118
|
+
allow(formatter)
|
119
|
+
.to receive(:hash_for_location).and_return(location_hash)
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:location_hash) { { line: 1, column: 2 } }
|
123
|
+
|
124
|
+
it 'sets value of #hash_for_location for :location key' do
|
125
|
+
expect(hash[:location]).to eq(location_hash)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#hash_for_location' do
|
130
|
+
subject(:hash) { formatter.hash_for_location(offense) }
|
131
|
+
|
132
|
+
it 'sets line value for :line key' do
|
133
|
+
expect(hash[:line]).to eq(3)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'sets column value for :column key' do
|
137
|
+
expect(hash[:column]).to eq(6)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'sets length value for :length key' do
|
141
|
+
expect(hash[:length]).to eq(1)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|