reek 0.3.0 → 0.3.1

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.
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