reek 1.2.1 → 1.2.3
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/History.txt +10 -0
- data/Rakefile +0 -1
- data/config/defaults.reek +8 -6
- data/features/masking_smells.feature +9 -9
- data/features/options.feature +2 -2
- data/features/profile.feature +34 -0
- data/features/rake_task.feature +74 -0
- data/features/reports.feature +1 -1
- data/features/samples.feature +4 -4
- data/features/stdin.feature +1 -1
- data/features/step_definitions/reek_steps.rb +11 -7
- data/features/support/env.rb +26 -18
- data/lib/reek/adapters/application.rb +9 -2
- data/lib/reek/adapters/command_line.rb +2 -2
- data/lib/reek/adapters/core_extras.rb +0 -8
- data/lib/reek/adapters/source.rb +4 -1
- data/lib/reek/adapters/spec.rb +1 -4
- data/lib/reek/block_context.rb +14 -8
- data/lib/reek/class_context.rb +6 -55
- data/lib/reek/code_context.rb +10 -0
- data/lib/reek/code_parser.rb +26 -53
- data/lib/reek/configuration.rb +12 -6
- data/lib/reek/if_context.rb +2 -3
- data/lib/reek/method_context.rb +8 -12
- data/lib/reek/module_context.rb +35 -16
- data/lib/reek/name.rb +2 -0
- data/lib/reek/object_refs.rb +0 -3
- data/lib/reek/sexp_formatter.rb +0 -2
- data/lib/reek/smells/attribute.rb +48 -0
- data/lib/reek/smells/class_variable.rb +17 -4
- data/lib/reek/smells/control_couple.rb +3 -10
- data/lib/reek/smells/data_clump.rb +10 -10
- data/lib/reek/smells/feature_envy.rb +1 -8
- data/lib/reek/smells/large_class.rb +3 -3
- data/lib/reek/smells/simulated_polymorphism.rb +17 -3
- data/lib/reek/smells/smell_detector.rb +11 -2
- data/lib/reek/smells/utility_function.rb +1 -1
- data/lib/reek/sniffer.rb +2 -8
- data/lib/reek/stop_context.rb +1 -1
- data/lib/reek/tree_dresser.rb +74 -0
- data/lib/reek.rb +1 -1
- data/reek.gemspec +3 -3
- data/spec/reek/adapters/should_reek_of_spec.rb +7 -1
- data/spec/reek/block_context_spec.rb +6 -6
- data/spec/reek/class_context_spec.rb +2 -23
- data/spec/reek/code_context_spec.rb +149 -67
- data/spec/reek/code_parser_spec.rb +35 -51
- data/spec/reek/method_context_spec.rb +4 -4
- data/spec/reek/singleton_method_context_spec.rb +1 -1
- data/spec/reek/smells/attribute_spec.rb +26 -0
- data/spec/reek/smells/behaves_like_variable_detector.rb +39 -0
- data/spec/reek/smells/class_variable_spec.rb +77 -43
- data/spec/reek/smells/control_couple_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +31 -13
- data/spec/reek/smells/feature_envy_spec.rb +1 -1
- data/spec/reek/smells/large_class_spec.rb +32 -69
- data/spec/reek/smells/long_parameter_list_spec.rb +0 -12
- data/spec/reek/smells/simulated_polymorphism_spec.rb +66 -18
- data/spec/reek/smells/utility_function_spec.rb +0 -21
- data/spec/reek/sniffer_spec.rb +1 -0
- data/spec/samples/not_quite_masked/dirty.rb +2 -0
- data/spec/spec_helper.rb +1 -1
- data/tasks/reek.rake +1 -1
- data/tasks/test.rake +3 -4
- metadata +8 -5
- data/lib/reek/adapters/object_source.rb +0 -52
- data/lib/reek/exceptions.reek +0 -20
- data/spec/quality/reek_source_spec.rb +0 -15
@@ -10,7 +10,7 @@ describe SingletonMethodContext, 'outer_name' do
|
|
10
10
|
|
11
11
|
it "should report full context" do
|
12
12
|
element = StopContext.new
|
13
|
-
element = ModuleContext.new(element, Name.new(:mod))
|
13
|
+
element = ModuleContext.new(element, Name.new(:mod), s(:module, :mod, nil))
|
14
14
|
element = SingletonMethodContext.new(element, s(:defs, s(:call, nil, :a, s(:arglist)), :b, s(:args)))
|
15
15
|
element.outer_name.should match(/mod::a\.b/)
|
16
16
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
|
+
|
3
|
+
require 'reek/smells/attribute'
|
4
|
+
require 'reek/class_context'
|
5
|
+
|
6
|
+
require 'spec/reek/smells/behaves_like_variable_detector'
|
7
|
+
|
8
|
+
include Reek
|
9
|
+
include Reek::Smells
|
10
|
+
|
11
|
+
describe Attribute do
|
12
|
+
before :each do
|
13
|
+
@detector = Attribute.new
|
14
|
+
@record_variable = :record_attribute
|
15
|
+
end
|
16
|
+
|
17
|
+
[ClassContext, ModuleContext].each do |klass|
|
18
|
+
context "in a #{klass}" do
|
19
|
+
before :each do
|
20
|
+
@ctx = klass.create(StopContext.new, s(:null, :Fred))
|
21
|
+
end
|
22
|
+
|
23
|
+
it_should_behave_like 'a variable detector'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
shared_examples_for 'a variable detector' do
|
2
|
+
context 'with no variables' do
|
3
|
+
it "doesn't record a smell" do
|
4
|
+
@detector.examine_context(@ctx)
|
5
|
+
@detector.num_smells.should == 0
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
context 'with one variable encountered twice' do
|
10
|
+
before :each do
|
11
|
+
@ctx.send(@record_variable, :something)
|
12
|
+
@ctx.send(@record_variable, :something)
|
13
|
+
@detector.examine_context(@ctx)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'records only one smell' do
|
17
|
+
@detector.num_smells.should == 1
|
18
|
+
end
|
19
|
+
it 'mentions the variable name in the report' do
|
20
|
+
@detector.should have_smell([/something/])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with two variables' do
|
25
|
+
before :each do
|
26
|
+
@ctx.send(@record_variable, :something)
|
27
|
+
@ctx.send(@record_variable, :something_else)
|
28
|
+
@detector.examine_context(@ctx)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'records both smells' do
|
32
|
+
@detector.num_smells.should == 2
|
33
|
+
end
|
34
|
+
it 'mentions both variable names in the report' do
|
35
|
+
@detector.should have_smell([/something/])
|
36
|
+
@detector.should have_smell([/something_else/])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -7,75 +7,109 @@ include Reek
|
|
7
7
|
include Reek::Smells
|
8
8
|
|
9
9
|
describe ClassVariable do
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
before :each do
|
11
|
+
@detector = ClassVariable.new
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'with no class variables' do
|
15
|
+
it 'records nothing in the class' do
|
16
|
+
ctx = ClassContext.from_s('class Fred; end')
|
17
|
+
@detector.class_variables_in(ctx).should be_empty
|
18
|
+
end
|
19
|
+
it 'records nothing in the module' do
|
20
|
+
ctx = ModuleContext.from_s('module Fred; end')
|
21
|
+
@detector.class_variables_in(ctx).should be_empty
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with one class variable' do
|
26
|
+
shared_examples_for 'one variable found' do
|
27
|
+
it 'records the class variable' do
|
28
|
+
@detector.class_variables_in(@ctx).should include(:@@tools)
|
29
|
+
end
|
30
|
+
it 'records only that class variable' do
|
31
|
+
@detector.class_variables_in(@ctx).length.should == 1
|
15
32
|
end
|
16
33
|
end
|
17
34
|
|
18
|
-
context '
|
35
|
+
context 'declared in a class' do
|
19
36
|
before :each do
|
20
|
-
@ctx.
|
21
|
-
@detector.examine_context(@ctx)
|
37
|
+
@ctx = ClassContext.from_s('class Fred; @@tools = {}; end')
|
22
38
|
end
|
23
39
|
|
24
|
-
|
25
|
-
@detector.num_smells.should == 1
|
26
|
-
end
|
27
|
-
it 'mentions the variable name in the report' do
|
28
|
-
@detector.should have_smell([/@@cvar/])
|
29
|
-
end
|
40
|
+
it_should_behave_like 'one variable found'
|
30
41
|
end
|
31
42
|
|
32
|
-
context '
|
43
|
+
context 'used in a class' do
|
33
44
|
before :each do
|
34
|
-
@ctx.
|
35
|
-
@ctx.record_class_variable(:@@cvar)
|
36
|
-
@detector.examine_context(@ctx)
|
45
|
+
@ctx = ClassContext.from_s('class Fred; def jim() @@tools = {}; end; end')
|
37
46
|
end
|
38
47
|
|
39
|
-
|
40
|
-
|
48
|
+
it_should_behave_like 'one variable found'
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'indexed in a class' do
|
52
|
+
before :each do
|
53
|
+
@ctx = ClassContext.from_s('class Fred; def jim() @@tools[mash] = {}; end; end')
|
41
54
|
end
|
42
|
-
|
43
|
-
|
55
|
+
|
56
|
+
it_should_behave_like 'one variable found'
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'declared and used in a class' do
|
60
|
+
before :each do
|
61
|
+
@ctx = ClassContext.from_s('class Fred; @@tools = {}; def jim() @@tools = {}; end; end')
|
44
62
|
end
|
63
|
+
|
64
|
+
it_should_behave_like 'one variable found'
|
45
65
|
end
|
46
66
|
|
47
|
-
context '
|
67
|
+
context 'used twice in a class' do
|
48
68
|
before :each do
|
49
|
-
@ctx.
|
50
|
-
@ctx.record_class_variable(:@@another)
|
51
|
-
@detector.examine_context(@ctx)
|
69
|
+
@ctx = ClassContext.from_s('class Fred; def jeff() @@tools = {}; end; def jim() @@tools = {}; end; end')
|
52
70
|
end
|
53
71
|
|
54
|
-
|
55
|
-
|
72
|
+
it_should_behave_like 'one variable found'
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'declared in a module' do
|
76
|
+
before :each do
|
77
|
+
@ctx = ClassContext.from_s('module Fred; @@tools = {}; end')
|
56
78
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
79
|
+
|
80
|
+
it_should_behave_like 'one variable found'
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'used in a module' do
|
84
|
+
before :each do
|
85
|
+
@ctx = ClassContext.from_s('module Fred; def jim() @@tools = {}; end; end')
|
60
86
|
end
|
87
|
+
|
88
|
+
it_should_behave_like 'one variable found'
|
61
89
|
end
|
62
|
-
end
|
63
90
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
91
|
+
context 'indexed in a module' do
|
92
|
+
before :each do
|
93
|
+
@ctx = ClassContext.from_s('module Fred; def jim() @@tools[mash] = {}; end; end')
|
94
|
+
end
|
95
|
+
|
96
|
+
it_should_behave_like 'one variable found'
|
68
97
|
end
|
69
98
|
|
70
|
-
|
71
|
-
|
99
|
+
context 'declared and used in a module' do
|
100
|
+
before :each do
|
101
|
+
@ctx = ClassContext.from_s('module Fred; @@tools = {}; def jim() @@tools = {}; end; end')
|
102
|
+
end
|
72
103
|
|
73
|
-
|
74
|
-
before :each do
|
75
|
-
@ctx = ModuleContext.create(StopContext.new, "Fred")
|
76
|
-
@detector = ClassVariable.new
|
104
|
+
it_should_behave_like 'one variable found'
|
77
105
|
end
|
78
106
|
|
79
|
-
|
107
|
+
context 'used twice in a module' do
|
108
|
+
before :each do
|
109
|
+
@ctx = ClassContext.from_s('module Fred; def jeff() @@tools = {}; end; def jim() @@tools = {}; end; end')
|
110
|
+
end
|
111
|
+
|
112
|
+
it_should_behave_like 'one variable found'
|
113
|
+
end
|
80
114
|
end
|
81
115
|
end
|
@@ -6,7 +6,7 @@ include Reek::Smells
|
|
6
6
|
|
7
7
|
describe ControlCouple do
|
8
8
|
it 'should report a ternary check on a parameter' do
|
9
|
-
'def simple(arga) arga ? @ivar : 3 end'.should
|
9
|
+
'def simple(arga) arga ? @ivar : 3 end'.should reek_only_of(:ControlCouple, /arga/)
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'should not report a ternary check on an ivar' do
|
@@ -4,10 +4,10 @@ require 'reek/smells/data_clump'
|
|
4
4
|
|
5
5
|
include Reek::Smells
|
6
6
|
|
7
|
-
|
8
|
-
it '
|
7
|
+
shared_examples_for 'a data clump detector' do
|
8
|
+
it 'does not report small parameter sets' do
|
9
9
|
src = <<EOS
|
10
|
-
|
10
|
+
#{@context} Scrunch
|
11
11
|
def first(pa) @field == :sym ? 0 : 3; end
|
12
12
|
def second(pa) @field == :sym; end
|
13
13
|
def third(pa) pa - pb + @fred; end
|
@@ -17,9 +17,9 @@ EOS
|
|
17
17
|
src.should_not reek
|
18
18
|
end
|
19
19
|
|
20
|
-
it '
|
20
|
+
it 'reports 3 identical pairs in a class' do
|
21
21
|
src = <<EOS
|
22
|
-
|
22
|
+
#{@context} Scrunch
|
23
23
|
def first(pa, pb) @field == :sym ? 0 : 3; end
|
24
24
|
def second(pa, pb) @field == :sym; end
|
25
25
|
def third(pa, pb) pa - pb + @fred; end
|
@@ -29,9 +29,9 @@ EOS
|
|
29
29
|
src.should reek_of(:DataClump, /\[pa, pb\]/, /3 methods/)
|
30
30
|
end
|
31
31
|
|
32
|
-
it '
|
32
|
+
it 'reports 3 swapped pairs in a class' do
|
33
33
|
src = <<EOS
|
34
|
-
|
34
|
+
#{@context} Scrunch
|
35
35
|
def one(pa, pb) @field == :sym ? 0 : 3; end
|
36
36
|
def two(pb, pa) @field == :sym; end
|
37
37
|
def tri(pa, pb) pa - pb + @fred; end
|
@@ -41,9 +41,9 @@ EOS
|
|
41
41
|
src.should reek_of(:DataClump, /\[pa, pb\]/, /3 methods/)
|
42
42
|
end
|
43
43
|
|
44
|
-
it '
|
44
|
+
it 'reports 3 identical parameter sets in a class' do
|
45
45
|
src = <<EOS
|
46
|
-
|
46
|
+
#{@context} Scrunch
|
47
47
|
def first(pa, pb, pc) @field == :sym ? 0 : 3; end
|
48
48
|
def second(pa, pb, pc) @field == :sym; end
|
49
49
|
def third(pa, pb, pc) pa - pb + @fred; end
|
@@ -56,9 +56,9 @@ EOS
|
|
56
56
|
src.should_not reek_of(:DataClump, /\[pb, pc\]/, /3 methods/)
|
57
57
|
end
|
58
58
|
|
59
|
-
it '
|
59
|
+
it 'recognises re-ordered identical parameter sets' do
|
60
60
|
src = <<EOS
|
61
|
-
|
61
|
+
#{@context} Scrunch
|
62
62
|
def first(pb, pa, pc) @field == :sym ? 0 : 3; end
|
63
63
|
def second(pc, pb, pa) @field == :sym; end
|
64
64
|
def third(pa, pb, pc) pa - pb + @fred; end
|
@@ -71,9 +71,9 @@ EOS
|
|
71
71
|
src.should_not reek_of(:DataClump, /\[pb, pc\]/, /3 methods/)
|
72
72
|
end
|
73
73
|
|
74
|
-
it '
|
74
|
+
it 'counts only identical parameter sets' do
|
75
75
|
src = <<EOS
|
76
|
-
|
76
|
+
#{@context} RedCloth
|
77
77
|
def fa(p1, p2, p3, conten) end
|
78
78
|
def fb(p1, p2, p3, conten) end
|
79
79
|
def fc(name, windowW, windowH) end
|
@@ -82,6 +82,24 @@ EOS
|
|
82
82
|
|
83
83
|
src.should_not reek_of(:DataClump)
|
84
84
|
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe DataClump do
|
88
|
+
context 'in a class' do
|
89
|
+
before :each do
|
90
|
+
@context = 'class'
|
91
|
+
end
|
92
|
+
|
93
|
+
it_should_behave_like 'a data clump detector'
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'in a module' do
|
97
|
+
before :each do
|
98
|
+
@context = 'module'
|
99
|
+
end
|
100
|
+
|
101
|
+
it_should_behave_like 'a data clump detector'
|
102
|
+
end
|
85
103
|
|
86
104
|
# TODO: include singleton methods in the calcs
|
87
105
|
end
|
@@ -8,73 +8,31 @@ require 'reek/smells/large_class'
|
|
8
8
|
include Reek
|
9
9
|
include Reek::Smells
|
10
10
|
|
11
|
-
describe LargeClass, 'checking Class objects' do
|
12
|
-
|
13
|
-
it 'should not report class with 26 methods' do
|
14
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
15
|
-
class BigOne
|
16
|
-
26.times do |i|
|
17
|
-
define_method "method#{i}x".to_sym do
|
18
|
-
@melting
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
BigOne.should_not reek
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should not report short class' do
|
26
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
27
|
-
class ShortClass
|
28
|
-
def method_a() @var_a; end
|
29
|
-
def method_b() @var_b; end
|
30
|
-
def method_c() @var_c; end
|
31
|
-
def method_d() @var_d; end
|
32
|
-
def method_e() @var_e; end
|
33
|
-
def method_f() @var_f; end
|
34
|
-
end
|
35
|
-
ShortClass.should_not reek
|
36
|
-
end
|
37
|
-
|
38
|
-
describe LargeClass, 'counting instance variables' do
|
39
|
-
it 'should not report class with 10 ivars' do
|
40
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
41
|
-
class ManyIvars
|
42
|
-
def meth
|
43
|
-
@vara = @varb = @varc = @vard = @vare
|
44
|
-
@varf = @varg = @varh = @vari = @varj
|
45
|
-
end
|
46
|
-
end
|
47
|
-
ManyIvars.should_not reek
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'ignores class with only a couple of ivars' do
|
51
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
52
|
-
LargeClass.should_not reek_of(:LargeClass)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'ignores fq class with only a couple of ivars' do
|
56
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
57
|
-
Reek::Smells::LargeClass.should_not reek_of(:LargeClass)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
11
|
describe LargeClass, 'when exceptions are listed' do
|
63
|
-
|
64
12
|
before(:each) do
|
65
|
-
@
|
66
|
-
|
13
|
+
@class_name = 'Humungous'
|
14
|
+
src = <<EOS
|
15
|
+
class #{@class_name}
|
16
|
+
def me01x()3 end;def me02x()3 end;def me03x()3 end;def me04x()3 end;def me05x()3 end
|
17
|
+
def me11x()3 end;def me12x()3 end;def me13x()3 end;def me14x()3 end;def me15x()3 end
|
18
|
+
def me21x()3 end;def me22x()3 end;def me23x()3 end;def me24x()3 end;def me25x()3 end
|
19
|
+
def me31x()3 end;def me32x()3 end;def me33x()3 end;def me34x()3 end;def me35x()3 end
|
20
|
+
def me41x()3 end;def me42x()3 end;def me43x()3 end;def me44x()3 end;def me45x()3 end
|
21
|
+
def me51x()3 end
|
22
|
+
end
|
23
|
+
EOS
|
24
|
+
@ctx = ClassContext.from_s(src)
|
67
25
|
@config = LargeClass.default_config
|
68
26
|
end
|
69
27
|
|
70
28
|
it 'should ignore first excepted name' do
|
71
|
-
@config[LargeClass::EXCLUDE_KEY] = [
|
29
|
+
@config[LargeClass::EXCLUDE_KEY] = [@class_name]
|
72
30
|
lc = LargeClass.new(@config)
|
73
31
|
lc.examine(@ctx).should == false
|
74
32
|
end
|
75
33
|
|
76
34
|
it 'should ignore second excepted name' do
|
77
|
-
@config[LargeClass::EXCLUDE_KEY] = ['Oversized',
|
35
|
+
@config[LargeClass::EXCLUDE_KEY] = ['Oversized', @class_name]
|
78
36
|
lc = LargeClass.new(@config)
|
79
37
|
lc.examine(@ctx).should == false
|
80
38
|
end
|
@@ -88,7 +46,7 @@ end
|
|
88
46
|
|
89
47
|
describe LargeClass, 'checking source code' do
|
90
48
|
|
91
|
-
|
49
|
+
context 'counting instance variables' do
|
92
50
|
it 'should not report empty class' do
|
93
51
|
ClassContext.from_s('class Empty;end').should have(0).variable_names
|
94
52
|
end
|
@@ -119,18 +77,7 @@ EOS
|
|
119
77
|
end
|
120
78
|
end
|
121
79
|
|
122
|
-
|
123
|
-
it 'should not report empty class' do
|
124
|
-
ClassContext.from_s('class Empty;end').num_methods.should == 0
|
125
|
-
end
|
126
|
-
|
127
|
-
it 'should count 1 method' do
|
128
|
-
ClassContext.from_s('class Empty;def ivars() @aa=@ab; end;end').num_methods.should == 1
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'should count 2 methods' do
|
132
|
-
ClassContext.from_s('class Empty;def meth1() @aa=@ab;end;def meth2() @aa=@ab;end;end').num_methods.should == 2
|
133
|
-
end
|
80
|
+
context 'counting methods' do
|
134
81
|
|
135
82
|
it 'should not report 25 methods' do
|
136
83
|
src = <<EOS
|
@@ -159,4 +106,20 @@ EOS
|
|
159
106
|
src.should reek_of(:LargeClass)
|
160
107
|
end
|
161
108
|
end
|
109
|
+
|
110
|
+
context 'with a nested module' do
|
111
|
+
it 'stops at a nested module' do
|
112
|
+
src = <<EOS
|
113
|
+
class Full
|
114
|
+
def me01x()3 end;def me02x()3 end;def me03x()3 end;def me04x()3 end;def me05x()3 end
|
115
|
+
def me11x()3 end;def me12x()3 end;def me13x()3 end;def me14x()3 end;def me15x()3 end
|
116
|
+
def me21x()3 end;def me22x()3 end;def me23x()3 end;def me24x()3 end;def me25x()3 end
|
117
|
+
def me31x()3 end;def me32x()3 end;def me33x()3 end;def me34x()3 end;def me35x()3 end
|
118
|
+
module Hidden; def me41x()3 end;def me42x()3 end;def me43x()3 end;def me44x()3 end;def me45x()3 end; end
|
119
|
+
def me51x()3 end
|
120
|
+
end
|
121
|
+
EOS
|
122
|
+
src.should_not reek_of(:LargeClass)
|
123
|
+
end
|
124
|
+
end
|
162
125
|
end
|
@@ -53,18 +53,6 @@ describe LongParameterList do
|
|
53
53
|
'def simple(aarg, polly=2, yep=true, zero=nil) f(3);false end'.should reek_only_of(:LongParameterList, /4 parameters/)
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
|
-
describe 'in a class' do
|
58
|
-
class InnerTest
|
59
|
-
def xyzero(arga,argb) f(3);true end
|
60
|
-
def abc(argx,yep,zero,argm) f(3);false end
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'should only report long param list' do
|
64
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
65
|
-
InnerTest.should reek_only_of(:LongParameterList, /abc/)
|
66
|
-
end
|
67
|
-
end
|
68
56
|
end
|
69
57
|
|
70
58
|
describe 'yield' do
|
@@ -1,49 +1,97 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper.rb'
|
2
2
|
|
3
3
|
require 'reek/smells/simulated_polymorphism'
|
4
|
+
require 'reek/code_context'
|
4
5
|
|
6
|
+
include Reek
|
5
7
|
include Reek::Smells
|
6
8
|
|
7
9
|
describe SimulatedPolymorphism do
|
8
|
-
|
9
|
-
|
10
|
+
before :each do
|
11
|
+
@detector = SimulatedPolymorphism.new
|
12
|
+
end
|
13
|
+
context 'with no conditionals' do
|
14
|
+
it 'gathers an empty hash' do
|
15
|
+
ast = 'module Stable; end'.to_reek_source.syntax_tree
|
16
|
+
ctx = CodeContext.new(nil, ast)
|
17
|
+
@detector.conditional_counts(ctx).length.should == 0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'with a test of block_given?' do
|
22
|
+
it 'does not record the condition' do
|
23
|
+
ast = 'def fred() yield(3) if block_given?; end'.to_reek_source.syntax_tree
|
24
|
+
ctx = CodeContext.new(nil, ast)
|
25
|
+
@detector.conditional_counts(ctx).length.should == 0
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with three identical conditionals' do
|
30
|
+
before :each do
|
31
|
+
cond = '@field == :sym'
|
32
|
+
@cond_expr = cond.to_reek_source.syntax_tree
|
33
|
+
src = <<EOS
|
10
34
|
class Scrunch
|
11
35
|
def first
|
12
|
-
return
|
36
|
+
return #{cond} ? 0 : 3;
|
13
37
|
end
|
14
38
|
def second
|
15
|
-
if
|
39
|
+
if #{cond}
|
16
40
|
@other += " quarts"
|
17
41
|
end
|
18
42
|
end
|
19
43
|
def third
|
20
|
-
raise 'flu!' unless
|
44
|
+
raise 'flu!' unless #{cond}
|
21
45
|
end
|
22
46
|
end
|
23
47
|
EOS
|
24
48
|
|
25
|
-
|
49
|
+
ast = src.to_reek_source.syntax_tree
|
50
|
+
ctx = CodeContext.new(nil, ast)
|
51
|
+
@conds = @detector.conditional_counts(ctx)
|
52
|
+
end
|
53
|
+
it 'finds one matching conditional' do
|
54
|
+
@conds.length.should == 1
|
55
|
+
end
|
56
|
+
it 'returns the condition expr' do
|
57
|
+
@conds.keys[0].should == @cond_expr
|
58
|
+
end
|
59
|
+
it 'knows there are three copies' do
|
60
|
+
@conds[@cond_expr].should == 3
|
61
|
+
end
|
26
62
|
end
|
27
63
|
|
28
|
-
|
29
|
-
|
64
|
+
context 'with a matching if and case' do
|
65
|
+
before :each do
|
66
|
+
cond = '@field == :sym'
|
67
|
+
@cond_expr = cond.to_reek_source.syntax_tree
|
68
|
+
src = <<EOS
|
30
69
|
class Scrunch
|
31
|
-
def
|
32
|
-
return
|
70
|
+
def alpha
|
71
|
+
return #{cond} ? 0 : 2;
|
33
72
|
end
|
34
|
-
def
|
35
|
-
case
|
36
|
-
when :
|
37
|
-
@
|
73
|
+
def beta
|
74
|
+
case #{cond}
|
75
|
+
when :symbol
|
76
|
+
@tother += " pints"
|
38
77
|
end
|
39
78
|
end
|
40
|
-
def third
|
41
|
-
raise 'flu!' unless @field
|
42
|
-
end
|
43
79
|
end
|
44
80
|
EOS
|
45
81
|
|
46
|
-
|
82
|
+
ast = src.to_reek_source.syntax_tree
|
83
|
+
ctx = CodeContext.new(nil, ast)
|
84
|
+
@conds = @detector.conditional_counts(ctx)
|
85
|
+
end
|
86
|
+
it 'finds exactly one conditional' do
|
87
|
+
@conds.length.should == 1
|
88
|
+
end
|
89
|
+
it 'returns the condition expr' do
|
90
|
+
@conds.keys[0].should == @cond_expr
|
91
|
+
end
|
92
|
+
it 'knows there are three copies' do
|
93
|
+
@conds[@cond_expr].should == 2
|
94
|
+
end
|
47
95
|
end
|
48
96
|
|
49
97
|
# And count code in superclasses, if we have it
|
@@ -79,24 +79,3 @@ EOS
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
83
|
-
describe UtilityFunction do
|
84
|
-
it 'should not report attrset' do
|
85
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
86
|
-
class Fred
|
87
|
-
attr_writer :xyz
|
88
|
-
end
|
89
|
-
Fred.should_not reek
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'should not report overriding methods' do
|
93
|
-
pending('test requires ParseTree') unless ObjectSource.can_parse_objects?
|
94
|
-
class Father
|
95
|
-
def thing(ff); @kids = 0; end
|
96
|
-
end
|
97
|
-
class Son < Father
|
98
|
-
def thing(ff); ff; end
|
99
|
-
end
|
100
|
-
Son.should_not reek
|
101
|
-
end
|
102
|
-
end
|
data/spec/reek/sniffer_spec.rb
CHANGED
data/spec/spec_helper.rb
CHANGED