reek 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/History.txt +11 -1
  2. data/README.txt +1 -0
  3. data/lib/reek.rb +8 -9
  4. data/lib/reek/checker.rb +10 -2
  5. data/lib/reek/class_checker.rb +4 -7
  6. data/lib/reek/file_checker.rb +0 -6
  7. data/lib/reek/method_checker.rb +56 -30
  8. data/lib/reek/object_refs.rb +5 -2
  9. data/lib/reek/printer.rb +45 -7
  10. data/lib/reek/rake_task.rb +5 -3
  11. data/lib/reek/smells/control_couple.rb +53 -0
  12. data/lib/reek/smells/duplication.rb +54 -0
  13. data/lib/reek/smells/feature_envy.rb +65 -0
  14. data/lib/reek/smells/large_class.rb +35 -0
  15. data/lib/reek/smells/long_method.rb +35 -0
  16. data/lib/reek/smells/long_parameter_list.rb +36 -0
  17. data/lib/reek/smells/long_yield_list.rb +20 -0
  18. data/lib/reek/smells/nested_iterators.rb +24 -0
  19. data/lib/reek/smells/smell.rb +56 -0
  20. data/lib/reek/smells/smells.rb +24 -0
  21. data/lib/reek/smells/uncommunicative_name.rb +72 -0
  22. data/lib/reek/smells/utility_function.rb +34 -0
  23. data/lib/reek/version.rb +1 -1
  24. data/spec/integration_spec.rb +6 -6
  25. data/spec/reek/printer_spec.rb +21 -21
  26. data/spec/reek/report_spec.rb +5 -5
  27. data/spec/reek/{control_couple_spec.rb → smells/control_couple_spec.rb} +1 -1
  28. data/spec/reek/smells/duplication_spec.rb +60 -0
  29. data/spec/reek/smells/feature_envy_spec.rb +91 -0
  30. data/spec/reek/{large_class_spec.rb → smells/large_class_spec.rb} +8 -8
  31. data/spec/reek/{long_method_spec.rb → smells/long_method_spec.rb} +1 -1
  32. data/spec/reek/{long_parameter_list_spec.rb → smells/long_parameter_list_spec.rb} +1 -1
  33. data/spec/reek/smells/nested_iterators_spec.rb +43 -0
  34. data/spec/reek/{smell_spec.rb → smells/smell_spec.rb} +2 -2
  35. data/spec/reek/smells/uncommunicative_name_spec.rb +83 -0
  36. data/spec/reek/{utility_function_spec.rb → smells/utility_function_spec.rb} +1 -1
  37. data/spec/samples/inline.reek +13 -5
  38. data/spec/samples/optparse.reek +32 -10
  39. data/spec/samples/redcloth.reek +24 -6
  40. data/spec/script_spec.rb +1 -1
  41. data/tasks/reek.rake +9 -0
  42. data/website/index.html +3 -2
  43. data/website/index.txt +3 -1
  44. metadata +24 -12
  45. data/lib/reek/smells.rb +0 -192
  46. data/spec/reek/feature_envy_spec.rb +0 -222
  47. data/spec/reek/nested_iterators_spec.rb +0 -42
  48. data/spec/reek/uncommunicative_name_spec.rb +0 -106
@@ -1,222 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
2
-
3
- require 'reek/method_checker'
4
- require 'reek/smells'
5
- require 'reek/report'
6
-
7
- include Reek
8
-
9
- describe FeatureEnvy, 'with only messages to self' do
10
- before(:each) do
11
- @rpt = Report.new
12
- @cchk = MethodChecker.new(@rpt, 'Thing')
13
- end
14
-
15
- it 'should not report use of self' do
16
- @cchk.check_source('def simple() self.to_s + self.to_i end')
17
- @rpt.should be_empty
18
- end
19
-
20
- it 'should not report vcall with no argument' do
21
- @cchk.check_source('def simple() func + grunc end')
22
- @rpt.should be_empty
23
- end
24
-
25
- it 'should not report vcall with argument' do
26
- @cchk.check_source('def simple(arga) func(17) + grunc(arga) end')
27
- @rpt.should be_empty
28
- end
29
- end
30
-
31
- describe FeatureEnvy, 'when the receiver is a parameter' do
32
- before(:each) do
33
- @rpt = Report.new
34
- @cchk = MethodChecker.new(@rpt, 'Thing')
35
- end
36
-
37
- it 'should not report single use' do
38
- @cchk.check_source('def no_envy(arga) arga.barg(@item) end')
39
- @rpt.length.should == 0
40
- end
41
-
42
- it 'should not report return value' do
43
- @cchk.check_source('def no_envy(arga) arga.barg(@item); arga end')
44
- @rpt.length.should == 0
45
- end
46
-
47
- it 'should report many calls to parameter' do
48
- @cchk.check_source('def envy(arga) arga.b(arga) + arga.c(@fred) end')
49
- @rpt.length.should == 1
50
- FeatureEnvy.should === @rpt[0]
51
- @rpt[0].to_s.should match(/arga/)
52
- end
53
- end
54
-
55
- describe FeatureEnvy, 'when there are many possible receivers' do
56
- before(:each) do
57
- @rpt = Report.new
58
- @cchk = MethodChecker.new(@rpt, 'Thing')
59
- end
60
-
61
- it 'should report highest affinity' do
62
- @cchk.check_source('def total_envy() @total += @item.price; @total += @item.tax; @total *= 1.15 end')
63
- @rpt.length.should == 1
64
- FeatureEnvy.should === @rpt[0]
65
- @rpt[0].to_s.should match(/@total/)
66
- end
67
-
68
- it 'should report multiple affinities' do
69
- @cchk.check_source('def total_envy() @total += @item.price; @total += @item.tax end')
70
- @rpt.length.should == 1
71
- @rpt[0].to_s.should match(/@total/)
72
- @rpt[0].to_s.should match(/@item/)
73
- end
74
- end
75
-
76
- describe FeatureEnvy, 'when the receiver is external' do
77
- before(:each) do
78
- @rpt = Report.new
79
- @cchk = MethodChecker.new(@rpt, 'Thing')
80
- end
81
-
82
- it 'should ignore global variables' do
83
- @cchk.check_source('def no_envy() $s2.to_a; $s2[@item] end')
84
- @rpt.should be_empty
85
- end
86
-
87
- it 'should not report class methods' do
88
- @cchk.check_source('def simple() self.class.new.flatten_merge(self) end')
89
- @rpt.should be_empty
90
- end
91
- end
92
-
93
- describe FeatureEnvy, 'when the receiver is an ivar' do
94
- before(:each) do
95
- @rpt = Report.new
96
- @cchk = MethodChecker.new(@rpt, 'Thing')
97
- end
98
-
99
- it 'should not report single use of an ivar' do
100
- @cchk.check_source('def no_envy() @item.to_a end')
101
- @rpt.length.should == 0
102
- end
103
-
104
- it 'should not report returning an ivar' do
105
- @cchk.check_source('def no_envy() @item.to_a; @item end')
106
- @rpt.length.should == 0
107
- end
108
-
109
- it 'should report many calls to ivar' do
110
- @cchk.check_source('def envy; @item.price + @item.tax end')
111
- @rpt.length.should == 1
112
- FeatureEnvy.should === @rpt[0]
113
- @rpt[0].to_s.should match(/@item/)
114
- end
115
-
116
- it 'should not report ivar usage in a parameter' do
117
- @cchk.check_source('def no_envy; @item.price + tax(@item) - savings(@item) end')
118
- @rpt.should be_empty
119
- end
120
- end
121
-
122
- describe FeatureEnvy, 'when the receiver is an lvar' do
123
- before(:each) do
124
- @rpt = Report.new
125
- @cchk = MethodChecker.new(@rpt, 'Thing')
126
- end
127
-
128
- it 'should not report single use of an lvar' do
129
- @cchk.check_source('def no_envy() lv = @item; lv.to_a end')
130
- @rpt.length.should == 0
131
- end
132
-
133
- it 'should not report returning an lvar' do
134
- @cchk.check_source('def no_envy() lv = @item; lv.to_a; lv end')
135
- @rpt.length.should == 0
136
- end
137
-
138
- it 'should report many calls to lvar' do
139
- @cchk.check_source('def envy; lv = @item; lv.price + lv.tax end')
140
- @rpt.length.should == 1
141
- FeatureEnvy.should === @rpt[0]
142
- @rpt[0].to_s.should match(/lv/)
143
- end
144
-
145
- it 'should not report lvar usage in a parameter' do
146
- @cchk.check_source('def no_envy; lv = @item; lv.price + tax(lv) - savings(lv) end')
147
- @rpt.should be_empty
148
- end
149
- end
150
-
151
- describe FeatureEnvy, 'when the receiver is a returned value' do
152
- before(:each) do
153
- @rpt = Report.new
154
- @cchk = MethodChecker.new(@rpt, 'Thing')
155
- end
156
-
157
- it 'should not report single use of a return value' do
158
- @cchk.check_source('def no_envy() f.g.price end')
159
- @rpt.length.should == 0
160
- end
161
-
162
- it 'should not report return value' do
163
- @cchk.check_source('def no_envy() f.g.wibble; f.g end')
164
- @rpt.length.should == 1
165
- FeatureEnvy.should === @rpt[0]
166
- @rpt[0].to_s.should match(/f/)
167
- @rpt[0].to_s.should_not match(/f.g/)
168
- end
169
-
170
- it 'should report many calls to a returned value' do
171
- @cchk.check_source('def envy; f.g.price + f.g.tax end')
172
- @rpt.length.should == 1
173
- FeatureEnvy.should === @rpt[0]
174
- @rpt[0].to_s.should match(/f.g/)
175
- end
176
-
177
- it 'should not report value usage in a parameter' do
178
- @cchk.check_source('def no_envy; f.g.price + tax(f.g) - savings(f.g) end')
179
- @rpt.should be_empty
180
- end
181
- end
182
-
183
- describe FeatureEnvy, 'when the receiver is a dvar' do
184
- before(:each) do
185
- @rpt = Report.new
186
- @cchk = MethodChecker.new(@rpt, 'Thing')
187
- end
188
-
189
- it "should count each scope separately" do
190
- pending('bug')
191
- source =<<EOS
192
- def bad(fred)
193
- @fred.each {|item| item.each }
194
- @jim.each {|item| item.each }
195
- end
196
- EOS
197
- @chk.check_source(source)
198
- @rpt.should be_empty
199
- end
200
- end
201
-
202
- describe FeatureEnvy, 'when the receiver is a message chain keyed on self' do
203
- before(:each) do
204
- @rpt = Report.new
205
- @cchk = MethodChecker.new(@rpt, 'Thing')
206
- end
207
-
208
- it "count the references correctly" do
209
- pending('bug')
210
- source =<<EOS
211
- class Parcel
212
- def addressee
213
- "#{self.person.first_name} #{self.person.last_name}"
214
- end
215
- end
216
- EOS
217
- @chk.check_source(source)
218
- @rpt.length.should == 1
219
- FeatureEnvy.should === @rpt[0]
220
- @rpt[0].to_s.should match(/self.person/)
221
- end
222
- end
@@ -1,42 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
2
-
3
- require 'reek/method_checker'
4
- require 'reek/report'
5
-
6
- include Reek
7
-
8
- describe MethodChecker, " nested iterators" do
9
-
10
- before(:each) do
11
- @rpt = Report.new
12
- @chk = MethodChecker.new(@rpt, 'Thing')
13
- end
14
-
15
- it "should report nested iterators in a method" do
16
- @chk.check_source('def bad(fred) @fred.each {|item| item.each {|ting| ting.ting} } end')
17
- @rpt.length.should == 1
18
- end
19
-
20
- it "should not report method with successive iterators" do
21
- source =<<EOS
22
- def bad(fred)
23
- @fred.each {|item| item.each }
24
- @jim.each {|ting| ting.each }
25
- end
26
- EOS
27
- @chk.check_source(source)
28
- @rpt.should be_empty
29
- end
30
-
31
- it "should report nested iterators only once per method" do
32
- source =<<EOS
33
- def bad(fred)
34
- @fred.each {|item| item.each {|part| @joe.send} }
35
- @jim.each {|ting| ting.each {|piece| @hal.send} }
36
- end
37
- EOS
38
- @chk.check_source(source)
39
- @rpt.length.should == 1
40
- end
41
- end
42
-
@@ -1,106 +0,0 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
2
-
3
- require 'reek/method_checker'
4
- require 'reek/report'
5
-
6
- include Reek
7
-
8
- describe MethodChecker, "uncommunicative method name" do
9
-
10
- before(:each) do
11
- @rpt = Report.new
12
- @cchk = MethodChecker.new(@rpt, 'Thing')
13
- end
14
-
15
- it 'should not report one-word method name' do
16
- @cchk.check_source('def help(fred) basics(17) end')
17
- @rpt.should be_empty
18
- end
19
-
20
- it 'should report one-letter method name' do
21
- @cchk.check_source('def x(fred) basics(17) end')
22
- @rpt.length.should == 1
23
- @rpt[0].detailed_report.should match(/x/)
24
- @rpt[0].detailed_report.should match(/method name/)
25
- end
26
- end
27
-
28
- describe MethodChecker, "uncommunicative field name" do
29
-
30
- before(:each) do
31
- @rpt = Report.new
32
- @cchk = MethodChecker.new(@rpt, 'Thing')
33
- end
34
-
35
- it 'should not report one-word field name' do
36
- @cchk.check_source('def help(fred) @simple end')
37
- @rpt.should be_empty
38
- end
39
-
40
- it 'should report one-letter fieldname' do
41
- @cchk.check_source('def simple(fred) @x end')
42
- @rpt.length.should == 1
43
- @rpt[0].detailed_report.should match(/@x/)
44
- @rpt[0].detailed_report.should match(/field name/)
45
- end
46
- end
47
-
48
- describe MethodChecker, "uncommunicative local variable name" do
49
-
50
- before(:each) do
51
- @rpt = Report.new
52
- @cchk = MethodChecker.new(@rpt, 'Thing')
53
- end
54
-
55
- it 'should not report one-word variable name' do
56
- @cchk.check_source('def help(fred) simple = jim(45) end')
57
- @rpt.should be_empty
58
- end
59
-
60
- it 'should report one-letter variable name' do
61
- @cchk.check_source('def simple(fred) x = jim(45) end')
62
- @rpt.length.should == 1
63
- @rpt[0].detailed_report.should match(/x/)
64
- @rpt[0].detailed_report.should match(/local variable name/)
65
- end
66
-
67
- it 'should report variable name only once' do
68
- @cchk.check_source('def simple(fred) x = jim(45); x = y end')
69
- @rpt.length.should == 1
70
- end
71
- end
72
-
73
- describe MethodChecker, "uncommunicative parameter name" do
74
-
75
- before(:each) do
76
- @rpt = Report.new
77
- @cchk = MethodChecker.new(@rpt, 'Thing')
78
- end
79
-
80
- it 'should recognise short parameter name' do
81
- @cchk.check_source('def help(x) basics(17) end')
82
- @rpt.length.should == 1
83
- @rpt[0].name.should == 'Uncommunicative Name'
84
- end
85
-
86
- it 'should not recognise *' do
87
- @cchk.check_source('def help(xray, *) basics(17) end')
88
- @rpt.length.should == 0
89
- end
90
-
91
- it "should report parameter's name" do
92
- @cchk.check_source('def help(x) basics(17) end')
93
- @rpt[0].detailed_report.should match(/x/)
94
- @rpt[0].detailed_report.should match(/parameter name/)
95
- end
96
- end
97
-
98
- describe UncommunicativeName, '#report' do
99
- it 'should report the bad symbol name' do
100
- mchk = MethodChecker.new([], 'Class')
101
- smell = UncommunicativeName.new(mchk, 'thing')
102
- smell.recognise?(:x).should == true
103
- smell.report.should match(/x/)
104
- smell.report.should_not match(/:x/)
105
- end
106
- end