nitpick 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README +56 -0
- data/VERSION.yml +4 -0
- data/bin/nitpick +92 -0
- data/lib/nitpick.rb +32 -0
- data/lib/nitpick/argument_nitpicker.rb +21 -0
- data/lib/nitpick/block_nitpicker.rb +21 -0
- data/lib/nitpick/branch_nitpicker.rb +17 -0
- data/lib/nitpick/local_variable_counter.rb +81 -0
- data/lib/nitpick/local_variable_nitpicker.rb +26 -0
- data/lib/nitpick/method_nitpicker.rb +14 -0
- data/lib/nitpick/nitpicker.rb +46 -0
- data/lib/nitpick/rescue_nitpicker.rb +15 -0
- data/lib/nitpick/sexp_extension.rb +7 -0
- data/lib/nitpick/warnings/assignment_as_condition.rb +22 -0
- data/lib/nitpick/warnings/empty_method.rb +19 -0
- data/lib/nitpick/warnings/identical_branch.rb +18 -0
- data/lib/nitpick/warnings/rescue_everything.rb +20 -0
- data/lib/nitpick/warnings/rescue_value.rb +22 -0
- data/lib/nitpick/warnings/shadowed_variable.rb +51 -0
- data/lib/nitpick/warnings/simple_warning.rb +28 -0
- data/lib/nitpick/warnings/unprotected_block.rb +24 -0
- data/lib/nitpick/warnings/unused_argument.rb +19 -0
- data/lib/nitpick/warnings/unused_variable.rb +19 -0
- data/lib/nitpick/warnings/useless_branch.rb +20 -0
- data/spec/argument_nitpicker_spec.rb +79 -0
- data/spec/assignment_as_condition_spec.rb +41 -0
- data/spec/block_nitpicker_spec.rb +31 -0
- data/spec/branch_nitpicker_spec.rb +24 -0
- data/spec/fixtures/block_badness.rb +23 -0
- data/spec/fixtures/branch_badness.rb +27 -0
- data/spec/fixtures/local_variable_badness.rb +113 -0
- data/spec/fixtures/method_badness.rb +10 -0
- data/spec/fixtures/rescue_badness.rb +15 -0
- data/spec/local_variable_nitpicker_spec.rb +90 -0
- data/spec/method_nitpicker_spec.rb +18 -0
- data/spec/nitpicker_spec.rb +20 -0
- data/spec/rescue_nitpicker_spec.rb +25 -0
- data/spec/rescue_value_spec.rb +27 -0
- data/spec/shadowed_variable_spec.rb +60 -0
- data/spec/simple_warning_spec.rb +22 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/useless_branch_spec.rb +11 -0
- metadata +109 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/branch_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::BranchNitpicker do
|
7
|
+
it "should warn for a branch simply returning true and false" do
|
8
|
+
nitpicker = Nitpick::BranchNitpicker.new(BranchBadness, :branch_returning_true_or_false)
|
9
|
+
nitpicker.nitpick!
|
10
|
+
nitpicker.warnings.should == [Nitpick::Warnings::UselessBranch.new]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should warn for identical branches" do
|
14
|
+
nitpicker = Nitpick::BranchNitpicker.new(BranchBadness, :branch_returning_identical_things)
|
15
|
+
nitpicker.nitpick!
|
16
|
+
nitpicker.warnings.should == [Nitpick::Warnings::IdenticalBranch.new]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should warn for assignments as conditions" do
|
20
|
+
nitpicker = Nitpick::BranchNitpicker.new(BranchBadness, :branch_with_assignment_as_condition)
|
21
|
+
nitpicker.nitpick!
|
22
|
+
nitpicker.warnings.should == [Nitpick::Warnings::AssignmentAsCondition.new]
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Fixtures
|
2
|
+
class BlockBadness
|
3
|
+
def no_conditional_for_block_given
|
4
|
+
yield
|
5
|
+
end
|
6
|
+
|
7
|
+
def simple_check_for_block_given
|
8
|
+
yield if block_given?
|
9
|
+
end
|
10
|
+
|
11
|
+
def simple_conditional_without_check
|
12
|
+
if true
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def complex_conditional_with_check(var)
|
18
|
+
if (1 + 2 == var) && block_given?
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Fixtures
|
2
|
+
class BranchBadness
|
3
|
+
def branch_returning_true_or_false
|
4
|
+
if 1 == 2
|
5
|
+
true
|
6
|
+
else
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def branch_returning_identical_things
|
12
|
+
if true
|
13
|
+
1 + 2
|
14
|
+
else
|
15
|
+
1 + 2
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def branch_with_assignment_as_condition
|
20
|
+
if a = 1
|
21
|
+
1
|
22
|
+
else
|
23
|
+
2
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Fixtures
|
2
|
+
class LocalVariableBadness
|
3
|
+
def unused_lasgn
|
4
|
+
bar = 4
|
5
|
+
1 + 2
|
6
|
+
end
|
7
|
+
|
8
|
+
def used_lvar
|
9
|
+
bar = 4
|
10
|
+
bar + 4
|
11
|
+
end
|
12
|
+
|
13
|
+
def unused_lvar
|
14
|
+
bar = 4
|
15
|
+
bar
|
16
|
+
1 + 2
|
17
|
+
end
|
18
|
+
|
19
|
+
def lvar_with_call(foo)
|
20
|
+
foo.bar
|
21
|
+
end
|
22
|
+
|
23
|
+
def simple_unused_arg(other)
|
24
|
+
-1
|
25
|
+
end
|
26
|
+
|
27
|
+
def unused_arg(arg)
|
28
|
+
1 + 2
|
29
|
+
end
|
30
|
+
|
31
|
+
def used_arg(arg)
|
32
|
+
arg + 4
|
33
|
+
end
|
34
|
+
|
35
|
+
def lvar_with_iasgn
|
36
|
+
foo = 1
|
37
|
+
@bar = foo
|
38
|
+
end
|
39
|
+
|
40
|
+
def arg_with_iasgn(arg)
|
41
|
+
@foo = arg
|
42
|
+
end
|
43
|
+
|
44
|
+
def lvar_shadowed
|
45
|
+
x = 1
|
46
|
+
yields_to do |x|
|
47
|
+
something_else_happens_here
|
48
|
+
end
|
49
|
+
x + 1
|
50
|
+
end
|
51
|
+
|
52
|
+
def lvar_shadowed_many_block_vars
|
53
|
+
x = 1
|
54
|
+
yields_to do |p,d,q,x|
|
55
|
+
something_else_happens_here
|
56
|
+
end
|
57
|
+
x + 1
|
58
|
+
end
|
59
|
+
|
60
|
+
def lvar_not_shadowed
|
61
|
+
x = 1
|
62
|
+
yields_to do |y|
|
63
|
+
something_else_happens_here
|
64
|
+
end
|
65
|
+
x + 1
|
66
|
+
end
|
67
|
+
|
68
|
+
def used_splat_arg(*args)
|
69
|
+
args + 4
|
70
|
+
end
|
71
|
+
|
72
|
+
def args_used_with_splats(args)
|
73
|
+
respond(*args)
|
74
|
+
end
|
75
|
+
|
76
|
+
def splat_args_used_with_splat(*args)
|
77
|
+
respond(*args)
|
78
|
+
end
|
79
|
+
|
80
|
+
def default_args(args=false)
|
81
|
+
args
|
82
|
+
end
|
83
|
+
|
84
|
+
def block_arg_unused(&block)
|
85
|
+
1 + 2
|
86
|
+
end
|
87
|
+
|
88
|
+
def block_arg_called(&block)
|
89
|
+
block.call
|
90
|
+
end
|
91
|
+
|
92
|
+
def block_arg_curried(&block)
|
93
|
+
respond(&block)
|
94
|
+
end
|
95
|
+
|
96
|
+
def super_with_implicit_args(arg)
|
97
|
+
super
|
98
|
+
end
|
99
|
+
|
100
|
+
def super_with_explicit_args(arg)
|
101
|
+
super()
|
102
|
+
end
|
103
|
+
|
104
|
+
def rescue_to_variable
|
105
|
+
begin
|
106
|
+
rescue => e
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def anonymous_args(*)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/local_variable_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::LocalVariableNitpicker do
|
7
|
+
it "should increment uses for an lasgn node" do
|
8
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :unused_lasgn)
|
9
|
+
nitpicker.nitpick!
|
10
|
+
nitpicker.uses(:bar).should == 1
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should increment uses for an lvar node" do
|
14
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :used_lvar)
|
15
|
+
nitpicker.nitpick!
|
16
|
+
nitpicker.uses(:bar).should == 2 # lvar + lasgn
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should create warnings for an an assigned but unused local variable" do
|
20
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :unused_lasgn)
|
21
|
+
nitpicker.nitpick!
|
22
|
+
nitpicker.warnings.should == [Nitpick::Warnings::UnusedVariable.new(:bar)]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not create warnings for used local variables" do
|
26
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :used_lvar)
|
27
|
+
nitpicker.nitpick!
|
28
|
+
nitpicker.warnings.should == []
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not create warnings for local variables with calls" do
|
32
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :lvar_with_call)
|
33
|
+
nitpicker.nitpick!
|
34
|
+
nitpicker.warnings.should == []
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should not create warnings for local variables with iasgns" do
|
38
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :lvar_with_iasgn)
|
39
|
+
nitpicker.nitpick!
|
40
|
+
nitpicker.warnings.should == []
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should not create warnings for arguments with iasgns" do
|
44
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :arg_with_iasgn)
|
45
|
+
nitpicker.nitpick!
|
46
|
+
nitpicker.warnings.should == []
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should warn when a block variable shadows a local variable" do
|
50
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :lvar_shadowed)
|
51
|
+
nitpicker.nitpick!
|
52
|
+
nitpicker.warnings.should == [Nitpick::Warnings::ShadowedVariable.new(:x)]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should warn when a block variable (among many) shadows a local variable" do
|
56
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :lvar_shadowed_many_block_vars)
|
57
|
+
nitpicker.nitpick!
|
58
|
+
nitpicker.warnings.should == [Nitpick::Warnings::ShadowedVariable.new]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should not warn when a block variable does not shadow a local variable" do
|
62
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :lvar_not_shadowed)
|
63
|
+
nitpicker.nitpick!
|
64
|
+
nitpicker.warnings.should == []
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should not warn when a block arg is referenced" do
|
68
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :block_arg_curried)
|
69
|
+
nitpicker.nitpick!
|
70
|
+
nitpicker.warnings.should == []
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should not warn when splat args are used with splats" do
|
74
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :splat_args_used_with_splat)
|
75
|
+
nitpicker.nitpick!
|
76
|
+
nitpicker.warnings.should == []
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should not warn about unused args" do
|
80
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :simple_unused_arg)
|
81
|
+
nitpicker.nitpick!
|
82
|
+
nitpicker.warnings.should == []
|
83
|
+
end
|
84
|
+
|
85
|
+
it "shouldn't barf on anonymous splat args" do
|
86
|
+
nitpicker = Nitpick::LocalVariableNitpicker.new(LocalVariableBadness, :anonymous_args)
|
87
|
+
nitpicker.nitpick!
|
88
|
+
nitpicker.warnings.should == []
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/method_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::MethodNitpicker do
|
7
|
+
it "should create a warning for an empty method" do
|
8
|
+
nitpicker = Nitpick::MethodNitpicker.new(MethodBadness, :empty_method)
|
9
|
+
nitpicker.nitpick!
|
10
|
+
nitpicker.warnings.include?(Nitpick::Warnings::EmptyMethod.new(:empty_method)).should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not create a empty method warning for a non empty method" do
|
14
|
+
nitpicker = Nitpick::MethodNitpicker.new(MethodBadness, :non_empty_method)
|
15
|
+
nitpicker.nitpick!
|
16
|
+
nitpicker.warnings.any? {|w| w.is_a? Nitpick::Warnings::EmptyMethod }.should be_false
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/branch_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::Nitpicker do
|
7
|
+
before do
|
8
|
+
@nitpicker = nitpicker = Nitpick::Nitpicker.new(BranchBadness, :branch_returning_true_or_false)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should discover each of the warning classes with the correct options" do
|
12
|
+
warnings = [Nitpick::Warnings::UselessBranch, Nitpick::Warnings::IdenticalBranch]
|
13
|
+
branches = [s(:true), s(:false)]
|
14
|
+
warnings.each do |warning|
|
15
|
+
warning.should_receive(:discover).with(branches)
|
16
|
+
end
|
17
|
+
|
18
|
+
@nitpicker.scan_for warnings, :with => branches
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/rescue_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::RescueNitpicker do
|
7
|
+
it "should create a warning for rescuing to a value" do
|
8
|
+
nitpicker = Nitpick::RescueNitpicker.new(RescueBadness, :rescue_nil)
|
9
|
+
nitpicker.nitpick!
|
10
|
+
nitpicker.warnings.should == [Nitpick::Warnings::RescueValue.new]
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should create a warning for rescuing Exception" do
|
14
|
+
nitpicker = Nitpick::RescueNitpicker.new(RescueBadness, :rescue_exception)
|
15
|
+
nitpicker.nitpick!
|
16
|
+
nitpicker.warnings.should == [Nitpick::Warnings::RescueEverything.new]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should create a warning for rescuing Object" do
|
20
|
+
nitpicker = Nitpick::RescueNitpicker.new(RescueBadness, :rescue_object)
|
21
|
+
nitpicker.nitpick!
|
22
|
+
nitpicker.warnings.should == [Nitpick::Warnings::RescueEverything.new]
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/rescue_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::Warnings::RescueValue do
|
7
|
+
|
8
|
+
it "should match rescuing to a nil" do
|
9
|
+
warning = Nitpick::Warnings::RescueValue.new(nil, [:nil])
|
10
|
+
warning.matches?.should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should match rescuing to a lit" do
|
14
|
+
warning = Nitpick::Warnings::RescueValue.new(nil, [:lit, 4])
|
15
|
+
warning.matches?.should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not match with a rescue body" do
|
19
|
+
exp = [nil,
|
20
|
+
[:block,
|
21
|
+
[:call, [:lit, 4], :+, [:array, [:lit, 5]]],
|
22
|
+
[:call, [:lit, 6], :+, [:array, [:lit, 7]]]]]
|
23
|
+
|
24
|
+
warning = Nitpick::Warnings::RescueValue.new(*exp)
|
25
|
+
warning.matches?.should be_false
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'fixtures/local_variable_badness'
|
3
|
+
|
4
|
+
include Fixtures
|
5
|
+
|
6
|
+
describe Nitpick::Warnings::ShadowedVariable do
|
7
|
+
|
8
|
+
it "should match an lasgn" do
|
9
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(s(:lasgn, :x, nil))
|
10
|
+
warning.matches?.should be_true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not match when there are no assignments" do
|
14
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(nil)
|
15
|
+
warning.matches?.should_not be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not match a block variable assignment" do
|
19
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(s(:dasgn_curr, :y))
|
20
|
+
warning.matches?.should_not be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should store the name of a shadowed variable" do
|
24
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(s(:lasgn, :x, nil))
|
25
|
+
warning.matches?
|
26
|
+
warning.vars.should == Set.new([:x])
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should match and store names in multiple assignment" do
|
30
|
+
exp = s(:masgn, s(:array, s(:dasgn_curr, :p), s(:dasgn_curr, :d),
|
31
|
+
s(:dasgn_curr, :q), s(:lasgn, :x, nil)), nil, nil)
|
32
|
+
|
33
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(exp)
|
34
|
+
warning.matches?.should be_true
|
35
|
+
warning.vars.should == Set.new([:x])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should handle splat args in multiple assignment" do
|
39
|
+
exp = s(:masgn, s(:array, s(:dasgn_curr, :x), s(:dasgn_curr, :y)), s(:lasgn, :a), nil)
|
40
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(exp)
|
41
|
+
warning.matches?.should be_true
|
42
|
+
warning.vars.should == Set.new([:a])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should handle one splat arg" do
|
46
|
+
exp = s(:masgn, nil, s(:lasgn, :a), nil)
|
47
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(exp)
|
48
|
+
warning.matches?.should be_true
|
49
|
+
warning.vars.should == Set.new([:a])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should store the name of all shadowed variables" do
|
53
|
+
exp = s(:masgn, s(:array, s(:dasgn_curr, :p), s(:dasgn_curr, :d),
|
54
|
+
s(:lasgn, :q, nil), s(:lasgn, :x, nil)), nil, nil)
|
55
|
+
warning = Nitpick::Warnings::ShadowedVariable.new(exp)
|
56
|
+
warning.matches?
|
57
|
+
warning.vars.should == Set.new([:q, :x])
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|