nitpick 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|