reek 1.2.7.3 → 1.2.8
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 +17 -0
- data/README.md +32 -48
- data/config/defaults.reek +7 -1
- data/features/api.feature +20 -0
- data/features/masking_smells.feature +41 -0
- data/features/options.feature +4 -0
- data/features/rake_task.feature +14 -0
- data/features/yaml.feature +8 -8
- data/lib/reek.rb +1 -1
- data/lib/reek/cli/command_line.rb +9 -2
- data/lib/reek/cli/reek_command.rb +5 -4
- data/lib/reek/cli/yaml_command.rb +2 -2
- data/lib/reek/core/code_context.rb +10 -1
- data/lib/reek/core/method_context.rb +2 -2
- data/lib/reek/core/sniffer.rb +3 -1
- data/lib/reek/core/stop_context.rb +4 -0
- data/lib/reek/examiner.rb +2 -2
- data/lib/reek/rake/task.rb +16 -0
- data/lib/reek/smell_warning.rb +3 -2
- data/lib/reek/smells/attribute.rb +13 -9
- data/lib/reek/smells/boolean_parameter.rb +14 -9
- data/lib/reek/smells/class_variable.rb +16 -5
- data/lib/reek/smells/control_couple.rb +11 -6
- data/lib/reek/smells/data_clump.rb +33 -30
- data/lib/reek/smells/duplication.rb +39 -8
- data/lib/reek/smells/feature_envy.rb +7 -8
- data/lib/reek/smells/irresponsible_module.rb +12 -3
- data/lib/reek/smells/large_class.rb +31 -15
- data/lib/reek/smells/long_method.rb +15 -5
- data/lib/reek/smells/long_parameter_list.rb +14 -7
- data/lib/reek/smells/long_yield_list.rb +12 -9
- data/lib/reek/smells/nested_iterators.rb +46 -11
- data/lib/reek/smells/simulated_polymorphism.rb +16 -8
- data/lib/reek/smells/smell_detector.rb +13 -13
- data/lib/reek/smells/uncommunicative_method_name.rb +12 -20
- data/lib/reek/smells/uncommunicative_module_name.rb +17 -19
- data/lib/reek/smells/uncommunicative_parameter_name.rb +22 -15
- data/lib/reek/smells/uncommunicative_variable_name.rb +24 -18
- data/lib/reek/smells/utility_function.rb +6 -6
- data/lib/reek/source/code_comment.rb +19 -1
- data/lib/reek/source/tree_dresser.rb +40 -22
- data/reek.gemspec +6 -4
- data/spec/matchers/smell_of_matcher.rb +58 -0
- data/spec/reek/core/code_context_spec.rb +4 -2
- data/spec/reek/core/code_parser_spec.rb +2 -1
- data/spec/reek/core/method_context_spec.rb +5 -5
- data/spec/reek/smells/attribute_spec.rb +2 -4
- data/spec/reek/smells/boolean_parameter_spec.rb +32 -42
- data/spec/reek/smells/class_variable_spec.rb +22 -6
- data/spec/reek/smells/control_couple_spec.rb +15 -14
- data/spec/reek/smells/data_clump_spec.rb +29 -111
- data/spec/reek/smells/duplication_spec.rb +79 -49
- data/spec/reek/smells/feature_envy_spec.rb +1 -2
- data/spec/reek/smells/irresponsible_module_spec.rb +43 -22
- data/spec/reek/smells/large_class_spec.rb +34 -59
- data/spec/reek/smells/long_method_spec.rb +15 -10
- data/spec/reek/smells/long_parameter_list_spec.rb +24 -24
- data/spec/reek/smells/long_yield_list_spec.rb +13 -14
- data/spec/reek/smells/nested_iterators_spec.rb +93 -76
- data/spec/reek/smells/smell_detector_shared.rb +4 -2
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +10 -27
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +22 -23
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +36 -26
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +45 -48
- data/spec/reek/smells/utility_function_spec.rb +14 -13
- data/spec/reek/source/code_comment_spec.rb +61 -3
- data/spec/reek/source/tree_dresser_spec.rb +96 -1
- data/spec/samples/config/allow_duplication.reek +3 -0
- data/spec/samples/config/deeper_nested_iterators.reek +3 -0
- data/spec/samples/demo/demo.rb +8 -0
- data/spec/samples/inline_config/dirty.rb +16 -0
- data/spec/samples/inline_config/masked.reek +7 -0
- data/spec/samples/mask_some/dirty.rb +8 -0
- data/spec/samples/mask_some/some.reek +8 -0
- data/spec/spec_helper.rb +2 -0
- metadata +15 -5
@@ -8,29 +8,63 @@ include Reek
|
|
8
8
|
include Reek::Smells
|
9
9
|
|
10
10
|
describe Duplication do
|
11
|
+
|
12
|
+
context 'when a smell is reported' do
|
13
|
+
before :each do
|
14
|
+
@source_name = 'copy-cat'
|
15
|
+
@detector = Duplication.new(@source_name)
|
16
|
+
src = <<EOS
|
17
|
+
def double_thing(other)
|
18
|
+
other[@thing]
|
19
|
+
not_the_sam(at = all)
|
20
|
+
other[@thing]
|
21
|
+
end
|
22
|
+
EOS
|
23
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
24
|
+
smells = @detector.examine_context(ctx)
|
25
|
+
smells.length.should == 1
|
26
|
+
@warning = smells[0]
|
27
|
+
end
|
28
|
+
|
29
|
+
it_should_behave_like 'SmellDetector'
|
30
|
+
it_should_behave_like 'common fields set correctly'
|
31
|
+
|
32
|
+
it 'reports the call' do
|
33
|
+
@warning.smell[Duplication::CALL_KEY].should == 'other[@thing]'
|
34
|
+
end
|
35
|
+
it 'reports the correct lines' do
|
36
|
+
@warning.lines.should == [2,4]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
11
40
|
context "with repeated method calls" do
|
12
41
|
it 'reports repeated call' do
|
13
|
-
'def double_thing() @other.thing + @other.thing end'
|
42
|
+
src = 'def double_thing() @other.thing + @other.thing end'
|
43
|
+
src.should smell_of(Duplication, Duplication::CALL_KEY => '@other.thing')
|
14
44
|
end
|
15
45
|
it 'reports repeated call to lvar' do
|
16
|
-
'def double_thing(other) other[@thing] + other[@thing] end'
|
46
|
+
src = 'def double_thing(other) other[@thing] + other[@thing] end'
|
47
|
+
src.should smell_of(Duplication, Duplication::CALL_KEY => 'other[@thing]')
|
17
48
|
end
|
18
49
|
it 'reports call parameters' do
|
19
|
-
'def double_thing() @other.thing(2,3) + @other.thing(2,3) end'
|
50
|
+
src = 'def double_thing() @other.thing(2,3) + @other.thing(2,3) end'
|
51
|
+
src.should smell_of(Duplication, Duplication::CALL_KEY => '@other.thing(2, 3)')
|
20
52
|
end
|
21
53
|
it 'should report nested calls' do
|
22
|
-
|
23
|
-
|
24
|
-
|
54
|
+
src = 'def double_thing() @other.thing.foo + @other.thing.foo end'
|
55
|
+
src.should smell_of(Duplication, {Duplication::CALL_KEY => '@other.thing'},
|
56
|
+
{Duplication::CALL_KEY => '@other.thing.foo'})
|
25
57
|
end
|
26
58
|
it 'should ignore calls to new' do
|
27
|
-
'def double_thing() @other.new + @other.new end'
|
59
|
+
src = 'def double_thing() @other.new + @other.new end'
|
60
|
+
src.should_not smell_of(Duplication)
|
28
61
|
end
|
29
62
|
end
|
30
63
|
|
31
64
|
context 'with repeated attribute assignment' do
|
32
65
|
it 'reports repeated assignment' do
|
33
|
-
'def double_thing(thing) @other[thing] = true; @other[thing] = true; end'
|
66
|
+
src = 'def double_thing(thing) @other[thing] = true; @other[thing] = true; end'
|
67
|
+
src.should smell_of(Duplication, Duplication::CALL_KEY => '@other[thing] = true')
|
34
68
|
end
|
35
69
|
it 'does not report multi-assignments' do
|
36
70
|
src = <<EOS
|
@@ -39,58 +73,54 @@ def _parse ctxt
|
|
39
73
|
error, ctxt.index = @err, @err_ind
|
40
74
|
end
|
41
75
|
EOS
|
42
|
-
src.should_not
|
76
|
+
src.should_not smell_of(Duplication)
|
43
77
|
end
|
44
78
|
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe Duplication, "non-repeated method calls" do
|
48
|
-
it 'should not report similar calls' do
|
49
|
-
'def equals(other) other.thing == self.thing end'.should_not reek
|
50
|
-
end
|
51
79
|
|
52
|
-
|
53
|
-
'
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
80
|
+
context "non-repeated method calls" do
|
81
|
+
it 'should not report similar calls' do
|
82
|
+
src = 'def equals(other) other.thing == self.thing end'
|
83
|
+
src.should_not smell_of(Duplication)
|
84
|
+
end
|
85
|
+
it 'should respect call parameters' do
|
86
|
+
src = 'def double_thing() @other.thing(3) + @other.thing(2) end'
|
87
|
+
src.should_not smell_of(Duplication)
|
88
|
+
end
|
61
89
|
end
|
62
90
|
|
63
|
-
|
64
|
-
|
65
|
-
context 'when a smell is reported' do
|
91
|
+
context "allowing up to 3 calls" do
|
66
92
|
before :each do
|
67
|
-
|
68
|
-
def double_thing(other)
|
69
|
-
other[@thing]
|
70
|
-
not_the_sam(at = all)
|
71
|
-
other[@thing]
|
72
|
-
end
|
73
|
-
EOS
|
74
|
-
source = src.to_reek_source
|
75
|
-
sniffer = Core::Sniffer.new(source)
|
76
|
-
@mctx = Core::CodeParser.new(sniffer).process_defn(source.syntax_tree)
|
77
|
-
@detector.examine(@mctx)
|
78
|
-
@warning = @detector.smells_found.to_a[0] # SMELL: too cumbersome!
|
93
|
+
@config = {Duplication::MAX_ALLOWED_CALLS_KEY => 3}
|
79
94
|
end
|
80
|
-
it '
|
81
|
-
@
|
95
|
+
it 'does not report double calls' do
|
96
|
+
src = 'def double_thing() @other.thing + @other.thing end'
|
97
|
+
src.should_not smell_of(Duplication).with_config(@config)
|
82
98
|
end
|
83
|
-
it '
|
84
|
-
@
|
99
|
+
it 'does not report triple calls' do
|
100
|
+
src = 'def double_thing() @other.thing + @other.thing + @other.thing end'
|
101
|
+
src.should_not smell_of(Duplication).with_config(@config)
|
85
102
|
end
|
86
|
-
it 'reports
|
87
|
-
@
|
103
|
+
it 'reports quadruple calls' do
|
104
|
+
src = 'def double_thing() @other.thing + @other.thing + @other.thing + @other.thing end'
|
105
|
+
src.should smell_of(Duplication, {Duplication::CALL_KEY => '@other.thing', Duplication::OCCURRENCES_KEY => 4}).with_config(@config)
|
88
106
|
end
|
89
|
-
|
90
|
-
|
107
|
+
end
|
108
|
+
|
109
|
+
context "allowing calls to some methods" do
|
110
|
+
before :each do
|
111
|
+
@config = {Duplication::ALLOW_CALLS_KEY => ['@some.thing',/puts/]}
|
91
112
|
end
|
92
|
-
it '
|
93
|
-
@
|
113
|
+
it 'does not report calls to some methods' do
|
114
|
+
src = 'def double_some_thing() @some.thing + @some.thing end'
|
115
|
+
src.should_not smell_of(Duplication).with_config(@config)
|
116
|
+
end
|
117
|
+
it 'reports calls to other methods' do
|
118
|
+
src = 'def double_other_thing() @other.thing + @other.thing end'
|
119
|
+
src.should smell_of(Duplication, {Duplication::CALL_KEY => '@other.thing'}).with_config(@config)
|
120
|
+
end
|
121
|
+
it 'does not report calls to methods specifed with a regular expression' do
|
122
|
+
src = 'def double_puts() puts @other.thing; puts @other.thing end'
|
123
|
+
src.should smell_of(Duplication, {Duplication::CALL_KEY => '@other.thing'}).with_config(@config)
|
94
124
|
end
|
95
125
|
end
|
96
126
|
end
|
@@ -190,8 +190,7 @@ EOS
|
|
190
190
|
source = src.to_reek_source
|
191
191
|
sniffer = Sniffer.new(source)
|
192
192
|
@mctx = CodeParser.new(sniffer).process_defn(source.syntax_tree)
|
193
|
-
@detector.examine_context(@mctx)
|
194
|
-
@smells = @detector.smells_found.to_a
|
193
|
+
@smells = @detector.examine_context(@mctx)
|
195
194
|
end
|
196
195
|
it 'reports only that smell' do
|
197
196
|
@smells.length.should == 1
|
@@ -5,33 +5,54 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'smell_detector_shar
|
|
5
5
|
include Reek::Smells
|
6
6
|
|
7
7
|
describe IrresponsibleModule do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
before(:each) do
|
9
|
+
@bad_module_name = 'WrongUn'
|
10
|
+
@detector = IrresponsibleModule.new('yoof')
|
11
|
+
end
|
12
|
+
|
13
|
+
it_should_behave_like 'SmellDetector'
|
14
|
+
|
15
|
+
it "does not report a class having a comment" do
|
16
|
+
src = <<EOS
|
17
|
+
# test class
|
18
|
+
class Responsible; end
|
13
19
|
EOS
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
|
20
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
21
|
+
@detector.examine_context(ctx).should be_empty
|
22
|
+
end
|
23
|
+
it "reports a class without a comment" do
|
24
|
+
src = "class #{@bad_module_name}; end"
|
25
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
26
|
+
smells = @detector.examine_context(ctx)
|
27
|
+
smells.length.should == 1
|
28
|
+
smells[0].smell_class.should == IrresponsibleModule::SMELL_CLASS
|
29
|
+
smells[0].subclass.should == IrresponsibleModule::SMELL_SUBCLASS
|
30
|
+
smells[0].lines.should == [1]
|
31
|
+
smells[0].smell[IrresponsibleModule::MODULE_NAME_KEY].should == @bad_module_name
|
32
|
+
end
|
33
|
+
it "reports a class with an empty comment" do
|
34
|
+
src = <<EOS
|
21
35
|
#
|
22
36
|
#
|
23
37
|
#
|
24
|
-
#{
|
38
|
+
class #{@bad_module_name}; end
|
25
39
|
EOS
|
26
|
-
|
27
|
-
|
40
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
41
|
+
smells = @detector.examine_context(ctx)
|
42
|
+
smells.length.should == 1
|
43
|
+
smells[0].smell_class.should == IrresponsibleModule::SMELL_CLASS
|
44
|
+
smells[0].subclass.should == IrresponsibleModule::SMELL_SUBCLASS
|
45
|
+
smells[0].lines.should == [4]
|
46
|
+
smells[0].smell[IrresponsibleModule::MODULE_NAME_KEY].should == @bad_module_name
|
28
47
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
48
|
+
it 'reports a fq module name correctly' do
|
49
|
+
src = 'class Foo::Bar; end'
|
50
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
51
|
+
smells = @detector.examine_context(ctx)
|
52
|
+
smells.length.should == 1
|
53
|
+
smells[0].smell_class.should == IrresponsibleModule::SMELL_CLASS
|
54
|
+
smells[0].subclass.should == IrresponsibleModule::SMELL_SUBCLASS
|
55
|
+
smells[0].smell[IrresponsibleModule::MODULE_NAME_KEY].should == 'Foo::Bar'
|
56
|
+
smells[0].context.should match(/#{smells[0].smell[IrresponsibleModule::MODULE_NAME_KEY]}/)
|
34
57
|
end
|
35
|
-
|
36
|
-
it_should_behave_like 'SmellDetector'
|
37
58
|
end
|
@@ -7,7 +7,13 @@ require File.join(File.dirname(File.expand_path(__FILE__)), 'smell_detector_shar
|
|
7
7
|
include Reek
|
8
8
|
include Reek::Smells
|
9
9
|
|
10
|
-
describe LargeClass
|
10
|
+
describe LargeClass do
|
11
|
+
before(:each) do
|
12
|
+
@source_name = 'elephant'
|
13
|
+
@detector = LargeClass.new(@source_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
it_should_behave_like 'SmellDetector'
|
11
17
|
|
12
18
|
context 'counting instance variables' do
|
13
19
|
it 'should not report 9 ivars' do
|
@@ -49,7 +55,8 @@ class Full
|
|
49
55
|
def me41x()3 end;def me42x()3 end;def me43x()3 end;def me44x()3 end;def me45x()3 end
|
50
56
|
end
|
51
57
|
EOS
|
52
|
-
src.
|
58
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
59
|
+
@detector.examine_context(ctx).should be_empty
|
53
60
|
end
|
54
61
|
|
55
62
|
it 'should report 26 methods' do
|
@@ -63,7 +70,11 @@ class Full
|
|
63
70
|
def me51x()3 end
|
64
71
|
end
|
65
72
|
EOS
|
66
|
-
src.
|
73
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
74
|
+
smells = @detector.examine_context(ctx)
|
75
|
+
smells.length.should == 1
|
76
|
+
smells[0].subclass.should == LargeClass::SUBCLASS_TOO_MANY_METHODS
|
77
|
+
smells[0].smell[LargeClass::METHOD_COUNT_KEY].should == 26
|
67
78
|
end
|
68
79
|
end
|
69
80
|
|
@@ -79,22 +90,13 @@ class Full
|
|
79
90
|
def me51x()3 end
|
80
91
|
end
|
81
92
|
EOS
|
82
|
-
src.
|
93
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
94
|
+
@detector.examine_context(ctx).should be_empty
|
83
95
|
end
|
84
96
|
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe LargeClass, 'looking at the YAML' do
|
88
|
-
before(:each) do
|
89
|
-
@source_name = 'elephant'
|
90
|
-
@detector = LargeClass.new(@source_name)
|
91
|
-
end
|
92
|
-
|
93
|
-
it_should_behave_like 'SmellDetector'
|
94
97
|
|
95
|
-
|
96
|
-
|
97
|
-
src = <<EOS
|
98
|
+
it 'reports correctly when the class has many methods' do
|
99
|
+
src = <<EOS
|
98
100
|
class Full
|
99
101
|
def me01x()3 end;def me02x()3 end;def me03x()3 end;def me04x()3 end;def me05x()3 end
|
100
102
|
def me11x()3 end;def me12x()3 end;def me13x()3 end;def me14x()3 end;def me15x()3 end
|
@@ -104,29 +106,17 @@ class Full
|
|
104
106
|
def me51x()3 end
|
105
107
|
end
|
106
108
|
EOS
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
end
|
115
|
-
it 'reports the correct subclass' do
|
116
|
-
@yaml.should match(/\ssubclass:\s*#{LargeClass::SUBCLASS_TOO_MANY_METHODS}/)
|
117
|
-
end
|
118
|
-
it 'reports the number of methods' do
|
119
|
-
@yaml.should match(/method_count:[\s]*26/)
|
120
|
-
# SMELL: many tests duplicate the names of the YAML fields
|
121
|
-
end
|
122
|
-
it 'reports the line number of the declaration' do
|
123
|
-
@yaml.should match(/lines:\s*- 1/)
|
124
|
-
end
|
109
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
110
|
+
@warning = @detector.examine_context(ctx)[0]
|
111
|
+
@warning.source.should == @source_name
|
112
|
+
@warning.smell_class.should == 'LargeClass'
|
113
|
+
@warning.subclass.should == LargeClass::SUBCLASS_TOO_MANY_METHODS
|
114
|
+
@warning.smell[LargeClass::METHOD_COUNT_KEY].should == 26
|
115
|
+
@warning.lines.should == [1]
|
125
116
|
end
|
126
117
|
|
127
|
-
|
128
|
-
|
129
|
-
src = <<EOS
|
118
|
+
it 'reports correctly when the class has 30 instance variables' do
|
119
|
+
src = <<EOS
|
130
120
|
# smelly class for testing purposes
|
131
121
|
class Empty
|
132
122
|
def ivars
|
@@ -134,27 +124,12 @@ class Empty
|
|
134
124
|
end
|
135
125
|
end
|
136
126
|
EOS
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
@yaml.should match(/source:\s*#{@source_name}/)
|
145
|
-
end
|
146
|
-
it 'reports the correct class' do
|
147
|
-
@yaml.should match(/\sclass:\s*LargeClass/)
|
148
|
-
end
|
149
|
-
it 'reports the correct subclass' do
|
150
|
-
@yaml.should match(/\ssubclass:\s*#{LargeClass::SUBCLASS_TOO_MANY_IVARS}/)
|
151
|
-
end
|
152
|
-
it 'reports the number of methods' do
|
153
|
-
@yaml.should match(/ivar_count:\s*10/)
|
154
|
-
# SMELL: many tests duplicate the names of the YAML fields
|
155
|
-
end
|
156
|
-
it 'reports the line number of the declaration' do
|
157
|
-
@yaml.should match(/lines:\s*- 2/)
|
158
|
-
end
|
127
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
128
|
+
@warning = @detector.examine_context(ctx)[0]
|
129
|
+
@warning.source.should == @source_name
|
130
|
+
@warning.smell_class.should == 'LargeClass'
|
131
|
+
@warning.subclass.should == LargeClass::SUBCLASS_TOO_MANY_IVARS
|
132
|
+
@warning.smell[LargeClass::IVAR_COUNT_KEY].should == 10
|
133
|
+
@warning.lines.should == [2]
|
159
134
|
end
|
160
135
|
end
|
@@ -15,15 +15,18 @@ end
|
|
15
15
|
|
16
16
|
describe LongMethod do
|
17
17
|
it 'should not report short methods' do
|
18
|
-
'def short(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;end'
|
18
|
+
src = 'def short(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;end'
|
19
|
+
src.should_not smell_of(LongMethod)
|
19
20
|
end
|
20
21
|
|
21
22
|
it 'should report long methods' do
|
22
|
-
'def long(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'
|
23
|
+
src = 'def long(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'
|
24
|
+
src.should reek_only_of(:LongMethod, /6 statements/)
|
23
25
|
end
|
24
26
|
|
25
27
|
it 'should not report initialize' do
|
26
|
-
'def initialize(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'
|
28
|
+
src = 'def initialize(arga) alf = f(1);@bet = 2;@cut = 3;@dit = 4; @emp = 5;@fry = 6;end'
|
29
|
+
src.should_not smell_of(LongMethod)
|
27
30
|
end
|
28
31
|
|
29
32
|
it 'should only report a long method once' do
|
@@ -205,17 +208,19 @@ describe LongMethod do
|
|
205
208
|
context 'when the method has 30 statements' do
|
206
209
|
before :each do
|
207
210
|
@num_statements = 30
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
@
|
211
|
+
ctx = mock('method_context', :null_object => true)
|
212
|
+
ctx.should_receive(:num_statements).and_return(@num_statements)
|
213
|
+
ctx.should_receive(:config).and_return({})
|
214
|
+
@smells = @detector.examine_context(ctx)
|
215
|
+
end
|
216
|
+
it 'reports only 1 smell' do
|
217
|
+
@smells.length.should == 1
|
212
218
|
end
|
213
219
|
it 'reports the number of statements' do
|
214
|
-
@
|
215
|
-
# SMELL: many tests duplicate the names of the YAML fields
|
220
|
+
@smells[0].smell[LongMethod::STATEMENT_COUNT_KEY].should == @num_statements
|
216
221
|
end
|
217
222
|
it 'reports the correct subclass' do
|
218
|
-
@
|
223
|
+
@smells[0].subclass.should == LongMethod::SUBCLASS_TOO_MANY_STATEMENTS
|
219
224
|
end
|
220
225
|
end
|
221
226
|
end
|
@@ -6,51 +6,56 @@ include Reek
|
|
6
6
|
include Reek::Smells
|
7
7
|
|
8
8
|
describe LongParameterList do
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
context 'for methods with few parameters' do
|
11
11
|
it 'should report nothing for no parameters' do
|
12
|
-
'def simple; f(3);true; end'.should_not
|
12
|
+
'def simple; f(3);true; end'.should_not smell_of(LongParameterList)
|
13
13
|
end
|
14
14
|
it 'should report nothing for 1 parameter' do
|
15
|
-
'def simple(yep) f(3);true end'.should_not
|
15
|
+
'def simple(yep) f(3);true end'.should_not smell_of(LongParameterList)
|
16
16
|
end
|
17
17
|
it 'should report nothing for 2 parameters' do
|
18
|
-
'def simple(yep,zero) f(3);true end'.should_not
|
18
|
+
'def simple(yep,zero) f(3);true end'.should_not smell_of(LongParameterList)
|
19
19
|
end
|
20
20
|
it 'should not count an optional block' do
|
21
|
-
'def simple(alpha, yep, zero, &opt) f(3);true end'.should_not
|
21
|
+
'def simple(alpha, yep, zero, &opt) f(3);true end'.should_not smell_of(LongParameterList)
|
22
22
|
end
|
23
23
|
it 'should not report inner block with too many parameters' do
|
24
|
-
'def simple(yep,zero); m[3]; rand(34); f.each { |arga, argb, argc, argd| true}; end'
|
24
|
+
src = 'def simple(yep,zero); m[3]; rand(34); f.each { |arga, argb, argc, argd| true}; end'
|
25
|
+
src.should_not smell_of(LongParameterList)
|
25
26
|
end
|
26
27
|
|
27
28
|
describe 'and default values' do
|
28
29
|
it 'should report nothing for 1 parameter' do
|
29
|
-
'def simple(zero=nil) f(3);false end'.should_not
|
30
|
+
'def simple(zero=nil) f(3);false end'.should_not smell_of(LongParameterList)
|
30
31
|
end
|
31
32
|
it 'should report nothing for 2 parameters with 1 default' do
|
32
|
-
'def simple(yep, zero=nil) f(3);false end'.should_not
|
33
|
+
'def simple(yep, zero=nil) f(3);false end'.should_not smell_of(LongParameterList)
|
33
34
|
end
|
34
35
|
it 'should report nothing for 2 defaulted parameters' do
|
35
|
-
'def simple(yep=4, zero=nil) f(3);false end'.should_not
|
36
|
+
'def simple(yep=4, zero=nil) f(3);false end'.should_not smell_of(LongParameterList)
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
41
|
describe 'for methods with too many parameters' do
|
41
42
|
it 'should report 4 parameters' do
|
42
|
-
'def simple(arga, argb, argc, argd) f(3);true end'
|
43
|
+
src = 'def simple(arga, argb, argc, argd) f(3);true end'
|
44
|
+
src.should smell_of(LongParameterList, LongParameterList::PARAMETER_COUNT_KEY => 4)
|
43
45
|
end
|
44
46
|
it 'should report 8 parameters' do
|
45
|
-
'def simple(arga, argb, argc, argd,arge, argf, argg, argh) f(3);true end'
|
47
|
+
src = 'def simple(arga, argb, argc, argd,arge, argf, argg, argh) f(3);true end'
|
48
|
+
src.should smell_of(LongParameterList, LongParameterList::PARAMETER_COUNT_KEY => 8)
|
46
49
|
end
|
47
50
|
|
48
51
|
describe 'and default values' do
|
49
52
|
it 'should report 3 with 1 defaulted' do
|
50
|
-
'def simple(polly, queue, yep, zero=nil) f(3);false end'
|
53
|
+
src = 'def simple(polly, queue, yep, zero=nil) f(3);false end'
|
54
|
+
src.should smell_of(LongParameterList, LongParameterList::PARAMETER_COUNT_KEY => 4)
|
51
55
|
end
|
52
56
|
it 'should report with 3 defaulted' do
|
53
|
-
'def simple(aarg, polly=2, yep=:truth, zero=nil) f(3);false end'
|
57
|
+
src = 'def simple(aarg, polly=2, yep=:truth, zero=nil) f(3);false end'
|
58
|
+
src.should smell_of(LongParameterList, LongParameterList::PARAMETER_COUNT_KEY => 4)
|
54
59
|
end
|
55
60
|
end
|
56
61
|
end
|
@@ -59,9 +64,7 @@ end
|
|
59
64
|
describe LongParameterList do
|
60
65
|
before(:each) do
|
61
66
|
@source_name = 'smokin'
|
62
|
-
@detector = LongParameterList.new(@source_name
|
63
|
-
# SMELL: can't use the default config, because that contains an override,
|
64
|
-
# which causes the mocked matches?() method to be called twice!!
|
67
|
+
@detector = LongParameterList.new(@source_name)
|
65
68
|
end
|
66
69
|
|
67
70
|
it_should_behave_like 'SmellDetector'
|
@@ -74,18 +77,15 @@ def badguy(arga, argb, argc, argd)
|
|
74
77
|
true
|
75
78
|
end
|
76
79
|
EOS
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
@detector.examine_context(mctx)
|
81
|
-
@warning = @detector.smells_found.to_a[0] # SMELL: too cumbersome!
|
80
|
+
ctx = CodeContext.new(nil, src.to_reek_source.syntax_tree)
|
81
|
+
@smells = @detector.examine_context(ctx)
|
82
|
+
@warning = @smells[0]
|
82
83
|
end
|
83
84
|
|
84
85
|
it_should_behave_like 'common fields set correctly'
|
85
86
|
|
86
87
|
it 'reports the number of parameters' do
|
87
|
-
@warning.smell[
|
88
|
-
# SMELL: many tests duplicate the names of the YAML fields
|
88
|
+
@warning.smell[LongParameterList::PARAMETER_COUNT_KEY].should == 4
|
89
89
|
end
|
90
90
|
it 'reports the line number of the method' do
|
91
91
|
@warning.lines.should == [1]
|