sabat-rubocop 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +50 -0
- data/.rspec +1 -0
- data/.rubocop.yml +7 -0
- data/.travis.yml +7 -0
- data/.yardopts +2 -0
- data/CHANGELOG.md +268 -0
- data/CONTRIBUTING.md +16 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +20 -0
- data/README.md +324 -0
- data/Rakefile +29 -0
- data/bin/rubocop +22 -0
- data/config/default.yml +58 -0
- data/config/disabled.yml +5 -0
- data/config/enabled.yml +403 -0
- data/lib/rubocop.rb +116 -0
- data/lib/rubocop/cli.rb +407 -0
- data/lib/rubocop/config.rb +250 -0
- data/lib/rubocop/config_store.rb +39 -0
- data/lib/rubocop/cop/cop.rb +138 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +54 -0
- data/lib/rubocop/cop/lint/end_alignment.rb +189 -0
- data/lib/rubocop/cop/lint/end_in_method.rb +30 -0
- data/lib/rubocop/cop/lint/ensure_return.rb +22 -0
- data/lib/rubocop/cop/lint/eval.rb +22 -0
- data/lib/rubocop/cop/lint/handle_exceptions.rb +20 -0
- data/lib/rubocop/cop/lint/literal_in_condition.rb +81 -0
- data/lib/rubocop/cop/lint/loop.rb +29 -0
- data/lib/rubocop/cop/lint/rescue_exception.rb +29 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +34 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +35 -0
- data/lib/rubocop/cop/lint/unused_local_variable.rb +32 -0
- data/lib/rubocop/cop/lint/void.rb +58 -0
- data/lib/rubocop/cop/offence.rb +136 -0
- data/lib/rubocop/cop/rails/validation.rb +30 -0
- data/lib/rubocop/cop/style/access_control.rb +58 -0
- data/lib/rubocop/cop/style/alias.rb +28 -0
- data/lib/rubocop/cop/style/align_parameters.rb +39 -0
- data/lib/rubocop/cop/style/and_or.rb +45 -0
- data/lib/rubocop/cop/style/ascii_comments.rb +21 -0
- data/lib/rubocop/cop/style/ascii_identifiers.rb +22 -0
- data/lib/rubocop/cop/style/attr.rb +20 -0
- data/lib/rubocop/cop/style/avoid_class_vars.rb +20 -0
- data/lib/rubocop/cop/style/avoid_for.rb +18 -0
- data/lib/rubocop/cop/style/avoid_global_vars.rb +65 -0
- data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +21 -0
- data/lib/rubocop/cop/style/avoid_perlisms.rb +50 -0
- data/lib/rubocop/cop/style/begin_block.rb +18 -0
- data/lib/rubocop/cop/style/block_comments.rb +20 -0
- data/lib/rubocop/cop/style/block_nesting.rb +47 -0
- data/lib/rubocop/cop/style/blocks.rb +27 -0
- data/lib/rubocop/cop/style/case_equality.rb +22 -0
- data/lib/rubocop/cop/style/case_indentation.rb +28 -0
- data/lib/rubocop/cop/style/character_literal.rb +37 -0
- data/lib/rubocop/cop/style/class_and_module_camel_case.rb +33 -0
- data/lib/rubocop/cop/style/class_methods.rb +22 -0
- data/lib/rubocop/cop/style/collection_methods.rb +56 -0
- data/lib/rubocop/cop/style/colon_method_call.rb +29 -0
- data/lib/rubocop/cop/style/constant_name.rb +31 -0
- data/lib/rubocop/cop/style/def_parentheses.rb +70 -0
- data/lib/rubocop/cop/style/documentation.rb +58 -0
- data/lib/rubocop/cop/style/dot_position.rb +25 -0
- data/lib/rubocop/cop/style/empty_line_between_defs.rb +26 -0
- data/lib/rubocop/cop/style/empty_lines.rb +40 -0
- data/lib/rubocop/cop/style/empty_literal.rb +53 -0
- data/lib/rubocop/cop/style/encoding.rb +29 -0
- data/lib/rubocop/cop/style/end_block.rb +18 -0
- data/lib/rubocop/cop/style/end_of_line.rb +23 -0
- data/lib/rubocop/cop/style/favor_join.rb +29 -0
- data/lib/rubocop/cop/style/favor_modifier.rb +118 -0
- data/lib/rubocop/cop/style/favor_sprintf.rb +28 -0
- data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +54 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +47 -0
- data/lib/rubocop/cop/style/if_then_else.rb +29 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +20 -0
- data/lib/rubocop/cop/style/lambda.rb +47 -0
- data/lib/rubocop/cop/style/leading_comment_space.rb +25 -0
- data/lib/rubocop/cop/style/line_continuation.rb +26 -0
- data/lib/rubocop/cop/style/line_length.rb +30 -0
- data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +61 -0
- data/lib/rubocop/cop/style/method_call_parentheses.rb +22 -0
- data/lib/rubocop/cop/style/method_length.rb +57 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +47 -0
- data/lib/rubocop/cop/style/not.rb +24 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +25 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +20 -0
- data/lib/rubocop/cop/style/op_method.rb +29 -0
- data/lib/rubocop/cop/style/parameter_lists.rb +42 -0
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +42 -0
- data/lib/rubocop/cop/style/proc.rb +30 -0
- data/lib/rubocop/cop/style/reduce_arguments.rb +34 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +39 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +55 -0
- data/lib/rubocop/cop/style/semicolon.rb +51 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +48 -0
- data/lib/rubocop/cop/style/space_after_comma_etc.rb +69 -0
- data/lib/rubocop/cop/style/space_after_control_keyword.rb +32 -0
- data/lib/rubocop/cop/style/string_literals.rb +36 -0
- data/lib/rubocop/cop/style/surrounding_space.rb +314 -0
- data/lib/rubocop/cop/style/symbol_array.rb +31 -0
- data/lib/rubocop/cop/style/symbol_name.rb +27 -0
- data/lib/rubocop/cop/style/tab.rb +25 -0
- data/lib/rubocop/cop/style/ternary_operator.rb +49 -0
- data/lib/rubocop/cop/style/trailing_whitespace.rb +24 -0
- data/lib/rubocop/cop/style/trivial_accessors.rb +32 -0
- data/lib/rubocop/cop/style/unless_else.rb +26 -0
- data/lib/rubocop/cop/style/variable_interpolation.rb +32 -0
- data/lib/rubocop/cop/style/when_then.rb +25 -0
- data/lib/rubocop/cop/style/while_until_do.rb +45 -0
- data/lib/rubocop/cop/style/word_array.rb +44 -0
- data/lib/rubocop/cop/util.rb +27 -0
- data/lib/rubocop/cop/variable_inspector.rb +280 -0
- data/lib/rubocop/formatter/base_formatter.rb +119 -0
- data/lib/rubocop/formatter/clang_style_formatter.rb +21 -0
- data/lib/rubocop/formatter/emacs_style_formatter.rb +17 -0
- data/lib/rubocop/formatter/formatter_set.rb +77 -0
- data/lib/rubocop/formatter/json_formatter.rb +76 -0
- data/lib/rubocop/formatter/progress_formatter.rb +63 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +62 -0
- data/lib/rubocop/version.rb +21 -0
- data/rubocop.gemspec +36 -0
- data/spec/.rubocop.yml +5 -0
- data/spec/project_spec.rb +24 -0
- data/spec/rubocop/cli_spec.rb +906 -0
- data/spec/rubocop/config_spec.rb +470 -0
- data/spec/rubocop/config_store_spec.rb +66 -0
- data/spec/rubocop/cops/cop_spec.rb +38 -0
- data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +111 -0
- data/spec/rubocop/cops/lint/end_alignment_spec.rb +333 -0
- data/spec/rubocop/cops/lint/end_in_method_spec.rb +35 -0
- data/spec/rubocop/cops/lint/ensure_return_spec.rb +37 -0
- data/spec/rubocop/cops/lint/eval_spec.rb +41 -0
- data/spec/rubocop/cops/lint/handle_exceptions_spec.rb +36 -0
- data/spec/rubocop/cops/lint/literal_in_condition_spec.rb +42 -0
- data/spec/rubocop/cops/lint/loop_spec.rb +33 -0
- data/spec/rubocop/cops/lint/rescue_exception_spec.rb +127 -0
- data/spec/rubocop/cops/lint/shadowing_outer_local_variable_spec.rb +243 -0
- data/spec/rubocop/cops/lint/unreachable_code_spec.rb +69 -0
- data/spec/rubocop/cops/lint/unused_local_variable_spec.rb +497 -0
- data/spec/rubocop/cops/lint/void_spec.rb +63 -0
- data/spec/rubocop/cops/offence_spec.rb +133 -0
- data/spec/rubocop/cops/rails/validation_spec.rb +27 -0
- data/spec/rubocop/cops/style/access_control_spec.rb +142 -0
- data/spec/rubocop/cops/style/alias_spec.rb +47 -0
- data/spec/rubocop/cops/style/align_parameters_spec.rb +199 -0
- data/spec/rubocop/cops/style/and_or_spec.rb +39 -0
- data/spec/rubocop/cops/style/ascii_comments_spec.rb +28 -0
- data/spec/rubocop/cops/style/ascii_identifiers_spec.rb +28 -0
- data/spec/rubocop/cops/style/attr_spec.rb +20 -0
- data/spec/rubocop/cops/style/avoid_class_vars_spec.rb +27 -0
- data/spec/rubocop/cops/style/avoid_for_spec.rb +37 -0
- data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +34 -0
- data/spec/rubocop/cops/style/avoid_perl_backrefs_spec.rb +20 -0
- data/spec/rubocop/cops/style/avoid_perlisms_spec.rb +47 -0
- data/spec/rubocop/cops/style/begin_block_spec.rb +19 -0
- data/spec/rubocop/cops/style/block_comments_spec.rb +27 -0
- data/spec/rubocop/cops/style/block_nesting_spec.rb +159 -0
- data/spec/rubocop/cops/style/blocks_spec.rb +35 -0
- data/spec/rubocop/cops/style/case_equality_spec.rb +18 -0
- data/spec/rubocop/cops/style/case_indentation_spec.rb +88 -0
- data/spec/rubocop/cops/style/character_literal_spec.rb +28 -0
- data/spec/rubocop/cops/style/class_and_module_camel_case_spec.rb +46 -0
- data/spec/rubocop/cops/style/class_methods_spec.rb +51 -0
- data/spec/rubocop/cops/style/collection_methods_spec.rb +41 -0
- data/spec/rubocop/cops/style/colon_method_call_spec.rb +55 -0
- data/spec/rubocop/cops/style/constant_name_spec.rb +56 -0
- data/spec/rubocop/cops/style/def_with_parentheses_spec.rb +40 -0
- data/spec/rubocop/cops/style/def_without_parentheses_spec.rb +34 -0
- data/spec/rubocop/cops/style/documentation_spec.rb +79 -0
- data/spec/rubocop/cops/style/dot_position_spec.rb +30 -0
- data/spec/rubocop/cops/style/empty_line_between_defs_spec.rb +85 -0
- data/spec/rubocop/cops/style/empty_lines_spec.rb +40 -0
- data/spec/rubocop/cops/style/empty_literal_spec.rb +91 -0
- data/spec/rubocop/cops/style/encoding_spec.rb +49 -0
- data/spec/rubocop/cops/style/end_block_spec.rb +19 -0
- data/spec/rubocop/cops/style/end_of_line_spec.rb +25 -0
- data/spec/rubocop/cops/style/favor_join_spec.rb +37 -0
- data/spec/rubocop/cops/style/favor_modifier_spec.rb +160 -0
- data/spec/rubocop/cops/style/favor_sprintf_spec.rb +53 -0
- data/spec/rubocop/cops/style/favor_unless_over_negated_if_spec.rb +64 -0
- data/spec/rubocop/cops/style/favor_until_over_negated_while_spec.rb +47 -0
- data/spec/rubocop/cops/style/hash_syntax_spec.rb +51 -0
- data/spec/rubocop/cops/style/if_with_semicolon_spec.rb +25 -0
- data/spec/rubocop/cops/style/lambda_spec.rb +45 -0
- data/spec/rubocop/cops/style/leading_comment_space_spec.rb +65 -0
- data/spec/rubocop/cops/style/line_continuation_spec.rb +26 -0
- data/spec/rubocop/cops/style/line_length_spec.rb +25 -0
- data/spec/rubocop/cops/style/method_and_variable_snake_case_spec.rb +95 -0
- data/spec/rubocop/cops/style/method_call_parentheses_spec.rb +25 -0
- data/spec/rubocop/cops/style/method_length_spec.rb +151 -0
- data/spec/rubocop/cops/style/multiline_if_then_spec.rb +97 -0
- data/spec/rubocop/cops/style/not_spec.rb +28 -0
- data/spec/rubocop/cops/style/numeric_literals_spec.rb +51 -0
- data/spec/rubocop/cops/style/one_line_conditional_spec.rb +18 -0
- data/spec/rubocop/cops/style/op_method_spec.rb +80 -0
- data/spec/rubocop/cops/style/parameter_lists_spec.rb +49 -0
- data/spec/rubocop/cops/style/parentheses_around_condition_spec.rb +59 -0
- data/spec/rubocop/cops/style/proc_spec.rb +28 -0
- data/spec/rubocop/cops/style/reduce_arguments_spec.rb +59 -0
- data/spec/rubocop/cops/style/regexp_literal_spec.rb +83 -0
- data/spec/rubocop/cops/style/rescue_modifier_spec.rb +122 -0
- data/spec/rubocop/cops/style/semicolon_spec.rb +95 -0
- data/spec/rubocop/cops/style/single_line_methods_spec.rb +54 -0
- data/spec/rubocop/cops/style/space_after_colon_spec.rb +29 -0
- data/spec/rubocop/cops/style/space_after_comma_spec.rb +31 -0
- data/spec/rubocop/cops/style/space_after_control_keyword_spec.rb +69 -0
- data/spec/rubocop/cops/style/space_after_semicolon_spec.rb +24 -0
- data/spec/rubocop/cops/style/space_around_braces_spec.rb +49 -0
- data/spec/rubocop/cops/style/space_around_equals_in_default_parameter_spec.rb +34 -0
- data/spec/rubocop/cops/style/space_around_operators_spec.rb +216 -0
- data/spec/rubocop/cops/style/space_inside_brackets_spec.rb +51 -0
- data/spec/rubocop/cops/style/space_inside_hash_literal_braces_spec.rb +99 -0
- data/spec/rubocop/cops/style/space_inside_parens_spec.rb +33 -0
- data/spec/rubocop/cops/style/string_literals_spec.rb +62 -0
- data/spec/rubocop/cops/style/symbol_array_spec.rb +45 -0
- data/spec/rubocop/cops/style/symbol_name_spec.rb +122 -0
- data/spec/rubocop/cops/style/tab_spec.rb +23 -0
- data/spec/rubocop/cops/style/ternary_operator_spec.rb +42 -0
- data/spec/rubocop/cops/style/trailing_whitespace_spec.rb +29 -0
- data/spec/rubocop/cops/style/trivial_accessors_spec.rb +338 -0
- data/spec/rubocop/cops/style/unless_else_spec.rb +31 -0
- data/spec/rubocop/cops/style/variable_interpolation_spec.rb +53 -0
- data/spec/rubocop/cops/style/when_then_spec.rb +40 -0
- data/spec/rubocop/cops/style/while_until_do_spec.rb +47 -0
- data/spec/rubocop/cops/style/word_array_spec.rb +61 -0
- data/spec/rubocop/cops/variable_inspector_spec.rb +374 -0
- data/spec/rubocop/formatter/base_formatter_spec.rb +190 -0
- data/spec/rubocop/formatter/clang_style_formatter_spec.rb +70 -0
- data/spec/rubocop/formatter/emacs_style_formatter_spec.rb +32 -0
- data/spec/rubocop/formatter/formatter_set_spec.rb +132 -0
- data/spec/rubocop/formatter/json_formatter_spec.rb +142 -0
- data/spec/rubocop/formatter/progress_formatter_spec.rb +196 -0
- data/spec/rubocop/formatter/simple_text_formatter_spec.rb +74 -0
- data/spec/spec_helper.rb +92 -0
- data/spec/support/file_helper.rb +21 -0
- data/spec/support/isolated_environment.rb +27 -0
- data/spec/support/mri_syntax_checker.rb +69 -0
- data/spec/support/shared_examples.rb +33 -0
- metadata +517 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
describe UnlessElse do
|
9
|
+
let(:ue) { UnlessElse.new }
|
10
|
+
|
11
|
+
it 'registers an offence for an unless with else' do
|
12
|
+
inspect_source(ue, ['unless x',
|
13
|
+
' a = 1',
|
14
|
+
'else',
|
15
|
+
' a = 0',
|
16
|
+
'end'])
|
17
|
+
expect(ue.offences.map(&:message)).to eq(
|
18
|
+
['Never use unless with else. Rewrite these with the ' +
|
19
|
+
'positive case first.'])
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'accepts an unless without else' do
|
23
|
+
inspect_source(ue, ['unless x',
|
24
|
+
' a = 1',
|
25
|
+
'end'])
|
26
|
+
expect(ue.offences.map(&:message)).to be_empty
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
describe VariableInterpolation do
|
9
|
+
let(:vi) { VariableInterpolation.new }
|
10
|
+
|
11
|
+
it 'registers an offence for interpolated global variables' do
|
12
|
+
inspect_source(vi,
|
13
|
+
['puts "this is a #$test"'])
|
14
|
+
expect(vi.offences.size).to eq(1)
|
15
|
+
expect(vi.offences.map(&:message))
|
16
|
+
.to eq(['Replace interpolated var $test' +
|
17
|
+
' with expression #{$test}.'])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'registers an offence for interpolated regexp back references' do
|
21
|
+
inspect_source(vi,
|
22
|
+
['puts "this is a #$1"'])
|
23
|
+
expect(vi.offences.size).to eq(1)
|
24
|
+
expect(vi.offences.map(&:message))
|
25
|
+
.to eq(['Replace interpolated var $1 with expression #{$1}.'])
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'registers an offence for interpolated instance variables' do
|
29
|
+
inspect_source(vi,
|
30
|
+
['puts "this is a #@test"'])
|
31
|
+
expect(vi.offences.size).to eq(1)
|
32
|
+
expect(vi.offences.map(&:message))
|
33
|
+
.to eq(['Replace interpolated var @test' +
|
34
|
+
' with expression #{@test}.'])
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'registers an offence for interpolated class variables' do
|
38
|
+
inspect_source(vi,
|
39
|
+
['puts "this is a #@@t"'])
|
40
|
+
expect(vi.offences.size).to eq(1)
|
41
|
+
expect(vi.offences.map(&:message))
|
42
|
+
.to eq(['Replace interpolated var @@t with expression #{@@t}.'])
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'does not register an offence for variables in expressions' do
|
46
|
+
inspect_source(vi,
|
47
|
+
['puts "this is a #{@test} #{@@t} #{$t} #{$1}"'])
|
48
|
+
expect(vi.offences).to be_empty
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
describe WhenThen do
|
9
|
+
let(:wt) { WhenThen.new }
|
10
|
+
|
11
|
+
it 'registers an offence for when x;' do
|
12
|
+
inspect_source(wt, ['case a',
|
13
|
+
'when b; c',
|
14
|
+
'end'])
|
15
|
+
expect(wt.offences.map(&:message)).to eq(
|
16
|
+
['Never use "when x;". Use "when x then" instead.'])
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'accepts when x then' do
|
20
|
+
inspect_source(wt, ['case a',
|
21
|
+
'when b then c',
|
22
|
+
'end'])
|
23
|
+
expect(wt.offences.map(&:message)).to be_empty
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'accepts ; separating statements in the body of when' do
|
27
|
+
inspect_source(wt, ['case a',
|
28
|
+
'when b then c; d',
|
29
|
+
'end',
|
30
|
+
'',
|
31
|
+
'case e',
|
32
|
+
'when f',
|
33
|
+
' g; h',
|
34
|
+
'end'])
|
35
|
+
expect(wt.offences.map(&:message)).to be_empty
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
describe WhileUntilDo do
|
9
|
+
let(:cop) { WhileUntilDo.new }
|
10
|
+
|
11
|
+
it 'registers an offence for do in multiline while' do
|
12
|
+
inspect_source(cop, ['while cond do',
|
13
|
+
'end'])
|
14
|
+
expect(cop.offences.size).to eq(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'registers an offence for do in multiline until' do
|
18
|
+
inspect_source(cop, ['until cond do',
|
19
|
+
'end'])
|
20
|
+
expect(cop.offences.size).to eq(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'accepts do in single-line while' do
|
24
|
+
inspect_source(cop, ['while cond do something end'])
|
25
|
+
expect(cop.offences).to be_empty
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'accepts do in single-line until' do
|
29
|
+
inspect_source(cop, ['until cond do something end'])
|
30
|
+
expect(cop.offences).to be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'it accepts multi-line while without do' do
|
34
|
+
inspect_source(cop, ['while cond',
|
35
|
+
'end'])
|
36
|
+
expect(cop.offences).to be_empty
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'it accepts multi-line until without do' do
|
40
|
+
inspect_source(cop, ['until cond',
|
41
|
+
'end'])
|
42
|
+
expect(cop.offences).to be_empty
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module Style
|
8
|
+
describe WordArray do
|
9
|
+
let(:wa) { WordArray.new }
|
10
|
+
|
11
|
+
it 'registers an offence for arrays of single quoted strings' do
|
12
|
+
inspect_source(wa,
|
13
|
+
["['one', 'two', 'three']"])
|
14
|
+
expect(wa.offences.size).to eq(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'registers an offence for arrays of double quoted strings' do
|
18
|
+
inspect_source(wa,
|
19
|
+
['["one", "two", "three"]'])
|
20
|
+
expect(wa.offences.size).to eq(1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'registers an offence for arrays with character constants' do
|
24
|
+
inspect_source(wa,
|
25
|
+
['["one", ?\n]'])
|
26
|
+
expect(wa.offences.size).to eq(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'does not register an offence for array of non-words' do
|
30
|
+
inspect_source(wa,
|
31
|
+
['["one space", "two", "three"]'])
|
32
|
+
expect(wa.offences).to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'does not register an offence for array containing non-string' do
|
36
|
+
inspect_source(wa,
|
37
|
+
['["one", "two", 3]'])
|
38
|
+
expect(wa.offences).to be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'does not register an offence for array starting with %w' do
|
42
|
+
inspect_source(wa,
|
43
|
+
['%w(one two three)'])
|
44
|
+
expect(wa.offences).to be_empty
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'does not register an offence for array with one element' do
|
48
|
+
inspect_source(wa,
|
49
|
+
['["three"]'])
|
50
|
+
expect(wa.offences).to be_empty
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'does not register an offence for array with empty strings' do
|
54
|
+
inspect_source(wa,
|
55
|
+
['["", "two", "three"]'])
|
56
|
+
expect(wa.offences).to be_empty
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,374 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
module Rubocop
|
6
|
+
module Cop
|
7
|
+
module VariableInspector
|
8
|
+
describe VariableEntry do
|
9
|
+
include AST::Sexp
|
10
|
+
|
11
|
+
describe '.new' do
|
12
|
+
context 'when non variable declaration node is passed' do
|
13
|
+
it 'raises error' do
|
14
|
+
node = s(:def)
|
15
|
+
expect { VariableEntry.new(node) }.to raise_error(ArgumentError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Scope do
|
22
|
+
include AST::Sexp
|
23
|
+
|
24
|
+
describe '.new' do
|
25
|
+
context 'when non scope node is passed' do
|
26
|
+
it 'raises error' do
|
27
|
+
node = s(:lvasgn)
|
28
|
+
expect { Scope.new(node) }.to raise_error(ArgumentError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'when begin node is passed' do
|
33
|
+
it 'accepts that as pseudo scope for top level scope' do
|
34
|
+
node = s(:begin)
|
35
|
+
expect { Scope.new(node) }.not_to raise_error(ArgumentError)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe VariableTable do
|
42
|
+
include AST::Sexp
|
43
|
+
|
44
|
+
subject(:variable_table) { VariableTable.new }
|
45
|
+
|
46
|
+
describe '#push_scope' do
|
47
|
+
it 'returns pushed scope object' do
|
48
|
+
node = s(:def)
|
49
|
+
scope = variable_table.push_scope(node)
|
50
|
+
expect(scope).to equal(variable_table.current_scope)
|
51
|
+
expect(scope.node).to equal(node)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#pop_scope' do
|
56
|
+
before do
|
57
|
+
node = s(:def)
|
58
|
+
variable_table.push_scope(node)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'returns popped scope object' do
|
62
|
+
last_scope = variable_table.current_scope
|
63
|
+
popped_scope = variable_table.pop_scope
|
64
|
+
expect(popped_scope).to equal(last_scope)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe '#current_scope_level' do
|
69
|
+
before do
|
70
|
+
variable_table.push_scope(s(:def))
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'increases by pushing scope' do
|
74
|
+
last_scope_level = variable_table.current_scope_level
|
75
|
+
variable_table.push_scope(s(:def))
|
76
|
+
expect(variable_table.current_scope_level)
|
77
|
+
.to eq(last_scope_level + 1)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'decreases by popping scope' do
|
81
|
+
last_scope_level = variable_table.current_scope_level
|
82
|
+
variable_table.pop_scope
|
83
|
+
expect(variable_table.current_scope_level)
|
84
|
+
.to eq(last_scope_level - 1)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#add_variable_entry' do
|
89
|
+
before do
|
90
|
+
2.times do
|
91
|
+
node = s(:def)
|
92
|
+
variable_table.push_scope(node)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'adds variable entry to current scope with its name as key' do
|
97
|
+
node = s(:lvasgn, :foo)
|
98
|
+
variable_table.add_variable_entry(node)
|
99
|
+
expect(variable_table.current_scope.variable_entries)
|
100
|
+
.to have_key(:foo)
|
101
|
+
expect(variable_table.scope_stack[-2].variable_entries)
|
102
|
+
.to be_empty
|
103
|
+
entry = variable_table.current_scope.variable_entries[:foo]
|
104
|
+
expect(entry.node).to equal(node)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'returns the added variable entry' do
|
108
|
+
node = s(:lvasgn, :foo)
|
109
|
+
entry = variable_table.add_variable_entry(node)
|
110
|
+
expect(entry.node).to equal(node)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#find_variable_entry' do
|
115
|
+
before do
|
116
|
+
variable_table.push_scope(s(:class))
|
117
|
+
variable_table.add_variable_entry(s(:lvasgn, :baz))
|
118
|
+
|
119
|
+
variable_table.push_scope(s(:def))
|
120
|
+
variable_table.add_variable_entry(s(:lvasgn, :bar))
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'when current scope is block' do
|
124
|
+
before do
|
125
|
+
variable_table.push_scope(s(:block))
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when a variable with the target name exists ' +
|
129
|
+
'in current scope' do
|
130
|
+
before do
|
131
|
+
variable_table.add_variable_entry(s(:lvasgn, :foo))
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'and does not exist in outer scope' do
|
135
|
+
it 'returns the current scope variable entry' do
|
136
|
+
found_entry = variable_table.find_variable_entry(:foo)
|
137
|
+
expect(found_entry.name).to eq(:foo)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'and also exists in outer scope' do
|
142
|
+
before do
|
143
|
+
variable_table.add_variable_entry(s(:lvasgn, :bar))
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'returns the current scope variable entry' do
|
147
|
+
found_entry = variable_table.find_variable_entry(:bar)
|
148
|
+
expect(found_entry.name).to equal(:bar)
|
149
|
+
expect(variable_table.current_scope.variable_entries)
|
150
|
+
.to have_value(found_entry)
|
151
|
+
expect(variable_table.scope_stack[-2].variable_entries)
|
152
|
+
.not_to have_value(found_entry)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when a variable with the target name does not exist ' +
|
158
|
+
'in current scope' do
|
159
|
+
context 'but exists in the direct outer scope' do
|
160
|
+
it 'returns the direct outer scope variable entry' do
|
161
|
+
found_entry = variable_table.find_variable_entry(:bar)
|
162
|
+
expect(found_entry.name).to equal(:bar)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'but exists in a indirect outer scope' do
|
167
|
+
context 'when the direct outer scope is block' do
|
168
|
+
before do
|
169
|
+
variable_table.pop_scope
|
170
|
+
variable_table.pop_scope
|
171
|
+
|
172
|
+
variable_table.push_scope(s(:block))
|
173
|
+
variable_table.push_scope(s(:block))
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'returns the indirect outer scope variable entry' do
|
177
|
+
found_entry = variable_table.find_variable_entry(:baz)
|
178
|
+
expect(found_entry.name).to equal(:baz)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'when the direct outer scope is not block' do
|
183
|
+
it 'returns nil' do
|
184
|
+
found_entry = variable_table.find_variable_entry(:baz)
|
185
|
+
expect(found_entry).to be_nil
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'and does not exist in all outer scopes' do
|
191
|
+
it 'returns nil' do
|
192
|
+
found_entry = variable_table.find_variable_entry(:non)
|
193
|
+
expect(found_entry).to be_nil
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when current scope is not block' do
|
200
|
+
before do
|
201
|
+
variable_table.push_scope(s(:def))
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when a variable with the target name exists ' +
|
205
|
+
'in current scope' do
|
206
|
+
before do
|
207
|
+
variable_table.add_variable_entry(s(:lvasgn, :foo))
|
208
|
+
end
|
209
|
+
|
210
|
+
context 'and does not exist in outer scope' do
|
211
|
+
it 'returns the current scope variable entry' do
|
212
|
+
found_entry = variable_table.find_variable_entry(:foo)
|
213
|
+
expect(found_entry.name).to eq(:foo)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context 'and also exists in outer scope' do
|
218
|
+
it 'returns the current scope variable entry' do
|
219
|
+
found_entry = variable_table.find_variable_entry(:foo)
|
220
|
+
expect(found_entry.name).to equal(:foo)
|
221
|
+
expect(variable_table.current_scope.variable_entries)
|
222
|
+
.to have_value(found_entry)
|
223
|
+
expect(variable_table.scope_stack[-2].variable_entries)
|
224
|
+
.not_to have_value(found_entry)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'when a variable with the target name does not exist ' +
|
230
|
+
'in current scope' do
|
231
|
+
context 'but exists in the direct outer scope' do
|
232
|
+
it 'returns nil' do
|
233
|
+
found_entry = variable_table.find_variable_entry(:bar)
|
234
|
+
expect(found_entry).to be_nil
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'and does not exist in all outer scopes' do
|
239
|
+
it 'returns nil' do
|
240
|
+
found_entry = variable_table.find_variable_entry(:non)
|
241
|
+
expect(found_entry).to be_nil
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe NodeScanner do
|
250
|
+
let(:source) do
|
251
|
+
<<-END
|
252
|
+
class SomeClass
|
253
|
+
foo = 1.to_s
|
254
|
+
bar = 2.to_s
|
255
|
+
def some_method
|
256
|
+
baz = 3.to_s
|
257
|
+
end
|
258
|
+
end
|
259
|
+
END
|
260
|
+
end
|
261
|
+
|
262
|
+
let(:ast) do
|
263
|
+
ast, *_ = Rubocop::CLI.parse('(string)') do |sb|
|
264
|
+
sb.source = source
|
265
|
+
end
|
266
|
+
ast
|
267
|
+
end
|
268
|
+
|
269
|
+
# (class
|
270
|
+
# (const nil :SomeClass) nil
|
271
|
+
# (begin
|
272
|
+
# (lvasgn :foo
|
273
|
+
# (send
|
274
|
+
# (int 1) :to_s))
|
275
|
+
# (lvasgn :bar
|
276
|
+
# (send
|
277
|
+
# (int 2) :to_s))
|
278
|
+
# (def :some_method
|
279
|
+
# (args)
|
280
|
+
# (lvasgn :baz
|
281
|
+
# (send
|
282
|
+
# (int 3) :to_s)))))
|
283
|
+
|
284
|
+
describe '.scan_nodes_in_scope' do
|
285
|
+
it 'does not scan children of inner scope node' do
|
286
|
+
scanned_node_count = 0
|
287
|
+
|
288
|
+
NodeScanner.scan_nodes_in_scope(ast) do |node|
|
289
|
+
scanned_node_count += 1
|
290
|
+
fail if node.type == :lvasgn && node.children.first == :baz
|
291
|
+
end
|
292
|
+
|
293
|
+
expect(scanned_node_count).to eq(9)
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'scans nodes with depth first order' do
|
297
|
+
index = 0
|
298
|
+
|
299
|
+
NodeScanner.scan_nodes_in_scope(ast) do |node|
|
300
|
+
case index
|
301
|
+
when 0
|
302
|
+
expect(node.type).to eq(:const)
|
303
|
+
when 1
|
304
|
+
expect(node.type).to eq(:begin)
|
305
|
+
when 2
|
306
|
+
expect(node.type).to eq(:lvasgn)
|
307
|
+
when 3
|
308
|
+
expect(node.type).to eq(:send)
|
309
|
+
when 4
|
310
|
+
expect(node.type).to eq(:int)
|
311
|
+
when 5
|
312
|
+
expect(node.type).to eq(:lvasgn)
|
313
|
+
end
|
314
|
+
|
315
|
+
index += 1
|
316
|
+
end
|
317
|
+
|
318
|
+
expect(index).not_to eq(0)
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'passes node index in the scope as second block argument' do
|
322
|
+
last_index = -1
|
323
|
+
|
324
|
+
NodeScanner.scan_nodes_in_scope(ast) do |node, index|
|
325
|
+
expect(index).to eq(last_index + 1)
|
326
|
+
last_index = index
|
327
|
+
end
|
328
|
+
|
329
|
+
expect(last_index).not_to eq(-1)
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
describe VariableInspector do
|
335
|
+
include AST::Sexp
|
336
|
+
|
337
|
+
class ExampleInspector
|
338
|
+
include VariableInspector
|
339
|
+
end
|
340
|
+
|
341
|
+
subject(:inspector) { ExampleInspector.new }
|
342
|
+
|
343
|
+
describe '#process_node' do
|
344
|
+
before do
|
345
|
+
inspector.variable_table.push_scope(s(:def))
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'when processing lvar node' do
|
349
|
+
let(:node) { s(:lvar, :foo) }
|
350
|
+
|
351
|
+
context 'when the variable is already declared' do
|
352
|
+
before do
|
353
|
+
inspector.variable_table.add_variable_entry(s(:lvasgn, :foo))
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'marks the variable as used' do
|
357
|
+
entry = inspector.variable_table.find_variable_entry(:foo)
|
358
|
+
expect(entry).not_to be_used
|
359
|
+
inspector.process_node(node)
|
360
|
+
expect(entry).to be_used
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
context 'when the variable is not yet declared' do
|
365
|
+
it 'raises error' do
|
366
|
+
expect { inspector.process_node(node) }.to raise_error
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|