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.
- data/History.txt +11 -1
- data/README.txt +1 -0
- data/lib/reek.rb +8 -9
- data/lib/reek/checker.rb +10 -2
- data/lib/reek/class_checker.rb +4 -7
- data/lib/reek/file_checker.rb +0 -6
- data/lib/reek/method_checker.rb +56 -30
- data/lib/reek/object_refs.rb +5 -2
- data/lib/reek/printer.rb +45 -7
- data/lib/reek/rake_task.rb +5 -3
- data/lib/reek/smells/control_couple.rb +53 -0
- data/lib/reek/smells/duplication.rb +54 -0
- data/lib/reek/smells/feature_envy.rb +65 -0
- data/lib/reek/smells/large_class.rb +35 -0
- data/lib/reek/smells/long_method.rb +35 -0
- data/lib/reek/smells/long_parameter_list.rb +36 -0
- data/lib/reek/smells/long_yield_list.rb +20 -0
- data/lib/reek/smells/nested_iterators.rb +24 -0
- data/lib/reek/smells/smell.rb +56 -0
- data/lib/reek/smells/smells.rb +24 -0
- data/lib/reek/smells/uncommunicative_name.rb +72 -0
- data/lib/reek/smells/utility_function.rb +34 -0
- data/lib/reek/version.rb +1 -1
- data/spec/integration_spec.rb +6 -6
- data/spec/reek/printer_spec.rb +21 -21
- data/spec/reek/report_spec.rb +5 -5
- data/spec/reek/{control_couple_spec.rb → smells/control_couple_spec.rb} +1 -1
- data/spec/reek/smells/duplication_spec.rb +60 -0
- data/spec/reek/smells/feature_envy_spec.rb +91 -0
- data/spec/reek/{large_class_spec.rb → smells/large_class_spec.rb} +8 -8
- data/spec/reek/{long_method_spec.rb → smells/long_method_spec.rb} +1 -1
- data/spec/reek/{long_parameter_list_spec.rb → smells/long_parameter_list_spec.rb} +1 -1
- data/spec/reek/smells/nested_iterators_spec.rb +43 -0
- data/spec/reek/{smell_spec.rb → smells/smell_spec.rb} +2 -2
- data/spec/reek/smells/uncommunicative_name_spec.rb +83 -0
- data/spec/reek/{utility_function_spec.rb → smells/utility_function_spec.rb} +1 -1
- data/spec/samples/inline.reek +13 -5
- data/spec/samples/optparse.reek +32 -10
- data/spec/samples/redcloth.reek +24 -6
- data/spec/script_spec.rb +1 -1
- data/tasks/reek.rake +9 -0
- data/website/index.html +3 -2
- data/website/index.txt +3 -1
- metadata +24 -12
- data/lib/reek/smells.rb +0 -192
- data/spec/reek/feature_envy_spec.rb +0 -222
- data/spec/reek/nested_iterators_spec.rb +0 -42
- data/spec/reek/uncommunicative_name_spec.rb +0 -106
data/spec/samples/inline.reek
CHANGED
@@ -1,19 +1,27 @@
|
|
1
|
+
[Duplication] C#build calls $?.==(0) more than once
|
2
|
+
[Duplication] C#build calls Inline.directory more than once
|
3
|
+
[Duplication] C#build calls io.puts more than once
|
4
|
+
[Duplication] C#build calls io.puts(#endif) more than once
|
5
|
+
[Duplication] C#build calls io.puts(#ifdef __cplusplus) more than once
|
1
6
|
[Long Method] C#build has approx 61 statements
|
2
7
|
[Nested Iterators] C#build has nested iterators
|
3
|
-
[Feature Envy] C#build uses io more than self
|
4
8
|
[Uncommunicative Name] C#build uses the local variable name 't'
|
5
9
|
[Uncommunicative Name] C#c uses the method name 'c'
|
6
|
-
[
|
10
|
+
[Duplication] C#crap_for_windoze calls Config::CONFIG[libdir] more than once
|
11
|
+
[Duplication] C#generate calls result.sub!((?-mix:\A\n), ) more than once
|
12
|
+
[Duplication] C#generate calls signature[args] more than once
|
13
|
+
[Duplication] C#generate calls signature[args].map more than once
|
7
14
|
[Long Method] C#generate has approx 33 statements
|
8
|
-
[
|
15
|
+
[Duplication] C#initialize calls stack.empty? more than once
|
9
16
|
[Long Method] C#load_cache has approx 7 statements
|
10
17
|
[Long Method] C#module_name has approx 6 statements
|
11
|
-
[
|
12
|
-
[Feature Envy] C#module_name uses md5 more than self
|
18
|
+
[Feature Envy] C#module_name refers to md5 more than self
|
13
19
|
[Long Method] C#parse_signature has approx 15 statements
|
14
20
|
[Control Couple] C#parse_signature is controlled by argument raw
|
15
21
|
[Utility Function] C#strip_comments doesn't depend on instance state
|
22
|
+
[Feature Envy] C#strip_comments refers to src more than self
|
16
23
|
[Large Class] Dir has 31 methods
|
17
24
|
[Large Class] Module has 34 methods
|
25
|
+
[Duplication] Module#inline calls Inline.const_get(lang) more than once
|
18
26
|
[Long Method] Module#inline has approx 12 statements
|
19
27
|
[Control Couple] Module#inline is controlled by argument options
|
data/spec/samples/optparse.reek
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
[Long Parameter List] CompletingHash#complete has 4 parameters
|
3
3
|
[Nested Iterators] CompletingHash#complete has nested iterators
|
4
4
|
[Long Method] CompletingHash#getopts has approx 17 statements
|
5
|
+
[Duplication] CompletingHash#make_switch calls default_style.guess(arg=a) more than once
|
6
|
+
[Duplication] CompletingHash#make_switch calls long.<<(o=q.downcase) more than once
|
7
|
+
[Duplication] CompletingHash#make_switch calls pattern.method(convert) more than once
|
8
|
+
[Duplication] CompletingHash#make_switch calls pattern.method(convert).to_proc more than once
|
9
|
+
[Duplication] CompletingHash#make_switch calls pattern.respond_to?(convert) more than once
|
10
|
+
[Duplication] CompletingHash#make_switch calls q.downcase more than once
|
11
|
+
[Duplication] CompletingHash#make_switch calls sdesc.<<("-#{q}") more than once
|
5
12
|
[Long Method] CompletingHash#make_switch has approx 69 statements
|
6
13
|
[Nested Iterators] CompletingHash#make_switch has nested iterators
|
7
14
|
[Uncommunicative Name] CompletingHash#make_switch uses the local variable name 'a'
|
@@ -10,30 +17,37 @@
|
|
10
17
|
[Uncommunicative Name] CompletingHash#make_switch uses the local variable name 'q'
|
11
18
|
[Uncommunicative Name] CompletingHash#make_switch uses the local variable name 's'
|
12
19
|
[Nested Iterators] CompletingHash#match has nested iterators
|
13
|
-
[
|
14
|
-
[Feature Envy] CompletingHash#
|
20
|
+
[Duplication] CompletingHash#order calls argv[0] more than once
|
21
|
+
[Feature Envy] CompletingHash#order refers to argv more than self
|
22
|
+
[Duplication] CompletingHash#parse calls argv[0] more than once
|
23
|
+
[Feature Envy] CompletingHash#parse refers to argv more than self
|
24
|
+
[Duplication] CompletingHash#parse_in_order calls $!.set_option(arg, true) more than once
|
25
|
+
[Duplication] CompletingHash#parse_in_order calls cb.call(val) more than once
|
26
|
+
[Duplication] CompletingHash#parse_in_order calls setter.call(sw.switch_name, val) more than once
|
27
|
+
[Duplication] CompletingHash#parse_in_order calls sw.block more than once
|
28
|
+
[Duplication] CompletingHash#parse_in_order calls sw.switch_name more than once
|
15
29
|
[Long Method] CompletingHash#parse_in_order has approx 30 statements
|
16
30
|
[Nested Iterators] CompletingHash#parse_in_order has nested iterators
|
17
31
|
[Control Couple] CompletingHash#parse_in_order is controlled by argument setter
|
18
|
-
[
|
32
|
+
[Duplication] CompletingHash#permute calls argv[0] more than once
|
33
|
+
[Feature Envy] CompletingHash#permute refers to argv more than self
|
19
34
|
[Long Parameter List] CompletingHash#summarize has 4 parameters
|
20
35
|
[Uncommunicative Name] CompletingHash#ver uses the local variable name 'v'
|
21
36
|
[Control Couple] List#accept is controlled by argument pat
|
22
|
-
[Feature Envy] List#accept
|
37
|
+
[Feature Envy] List#accept refers to pat more than self
|
23
38
|
[Uncommunicative Name] List#accept uses the parameter name 't'
|
24
|
-
[Feature Envy] List#add_banner uses opt more than self
|
25
39
|
[Long Parameter List] List#complete has 4 parameters
|
26
|
-
[Feature Envy] List#initialize uses OptionMap more than self
|
27
40
|
[Uncommunicative Name] List#reject uses the parameter name 't'
|
28
|
-
[Feature Envy] List#summarize uses opt more than self
|
29
41
|
[Long Parameter List] List#update has 5 parameters
|
30
42
|
[Long Method] List#update has approx 6 statements
|
31
43
|
[Control Couple] List#update is controlled by argument lopts
|
32
44
|
[Control Couple] List#update is controlled by argument sopts
|
33
45
|
[Uncommunicative Name] List#update uses the local variable name 'o'
|
34
46
|
[Control Couple] NoArgument#parse is controlled by argument arg
|
47
|
+
[Duplication] OptionParser#complete calls candidates.size more than once
|
48
|
+
[Duplication] OptionParser#complete calls k.id2name more than once
|
35
49
|
[Long Method] OptionParser#complete has approx 23 statements
|
36
|
-
[Feature Envy] OptionParser#complete
|
50
|
+
[Feature Envy] OptionParser#complete refers to candidates more than self
|
37
51
|
[Uncommunicative Name] OptionParser#complete uses the local variable name 'k'
|
38
52
|
[Uncommunicative Name] OptionParser#complete uses the local variable name 'v'
|
39
53
|
[Utility Function] OptionParser#convert doesn't depend on instance state
|
@@ -43,14 +57,22 @@
|
|
43
57
|
[Control Couple] RequiredArgument#parse is controlled by argument arg
|
44
58
|
[Uncommunicative Name] Switch#add_banner uses the local variable name 's'
|
45
59
|
[Long Parameter List] Switch#initialize has 7 parameters
|
60
|
+
[Duplication] Switch#parse_arg calls s.length more than once
|
46
61
|
[Long Method] Switch#parse_arg has approx 12 statements
|
47
|
-
[Feature Envy] Switch#parse_arg
|
62
|
+
[Feature Envy] Switch#parse_arg refers to arg more than self
|
48
63
|
[Uncommunicative Name] Switch#parse_arg uses the local variable name 'm'
|
49
64
|
[Uncommunicative Name] Switch#parse_arg uses the local variable name 's'
|
65
|
+
[Duplication] Switch#summarize calls block.max more than once
|
66
|
+
[Duplication] Switch#summarize calls block.max.to_i more than once
|
67
|
+
[Duplication] Switch#summarize calls indent.+(l) more than once
|
68
|
+
[Duplication] Switch#summarize calls left.collect more than once
|
69
|
+
[Duplication] Switch#summarize calls left.shift more than once
|
70
|
+
[Duplication] Switch#summarize calls left[-1] more than once
|
71
|
+
[Duplication] Switch#summarize calls s.length more than once
|
50
72
|
[Long Parameter List] Switch#summarize has 5 parameters
|
51
73
|
[Long Method] Switch#summarize has approx 27 statements
|
52
74
|
[Nested Iterators] Switch#summarize has nested iterators
|
53
|
-
[Feature Envy] Switch#summarize
|
75
|
+
[Feature Envy] Switch#summarize refers to left more than self
|
54
76
|
[Uncommunicative Name] Switch#summarize uses the local variable name 'l'
|
55
77
|
[Uncommunicative Name] Switch#summarize uses the local variable name 'r'
|
56
78
|
[Uncommunicative Name] Switch#summarize uses the local variable name 's'
|
data/spec/samples/redcloth.reek
CHANGED
@@ -1,24 +1,34 @@
|
|
1
1
|
[Long Method] RedCloth#block_markdown_bq has approx 6 statements
|
2
2
|
[Utility Function] RedCloth#block_markdown_rule doesn't depend on instance state
|
3
|
+
[Duplication] RedCloth#block_textile_lists calls depth.last more than once
|
4
|
+
[Duplication] RedCloth#block_textile_lists calls depth.last.length more than once
|
5
|
+
[Duplication] RedCloth#block_textile_lists calls depth[i] more than once
|
6
|
+
[Duplication] RedCloth#block_textile_lists calls line_id.-(1) more than once
|
7
|
+
[Duplication] RedCloth#block_textile_lists calls lines[line_id.-(1)] more than once
|
8
|
+
[Duplication] RedCloth#block_textile_lists calls tl.length more than once
|
3
9
|
[Long Method] RedCloth#block_textile_lists has approx 21 statements
|
4
10
|
[Nested Iterators] RedCloth#block_textile_lists has nested iterators
|
5
|
-
[Feature Envy] RedCloth#block_textile_lists uses depth more than self
|
6
11
|
[Long Method] RedCloth#block_textile_table has approx 19 statements
|
7
12
|
[Nested Iterators] RedCloth#block_textile_table has nested iterators
|
8
13
|
[Long Method] RedCloth#blocks has approx 17 statements
|
9
14
|
[Nested Iterators] RedCloth#blocks has nested iterators
|
10
15
|
[Control Couple] RedCloth#blocks is controlled by argument deep_code
|
11
16
|
[Control Couple] RedCloth#check_refs is controlled by argument text
|
17
|
+
[Duplication] RedCloth#clean_html calls tags[tag] more than once
|
12
18
|
[Utility Function] RedCloth#clean_html doesn't depend on instance state
|
13
19
|
[Long Method] RedCloth#clean_html has approx 14 statements
|
14
20
|
[Nested Iterators] RedCloth#clean_html has nested iterators
|
21
|
+
[Feature Envy] RedCloth#clean_html refers to tags more than self
|
15
22
|
[Long Method] RedCloth#clean_white_space has approx 7 statements
|
16
|
-
[Feature Envy] RedCloth#clean_white_space
|
23
|
+
[Feature Envy] RedCloth#clean_white_space refers to text more than self
|
17
24
|
[Utility Function] RedCloth#flush_left doesn't depend on instance state
|
25
|
+
[Feature Envy] RedCloth#flush_left refers to indt more than self
|
26
|
+
[Feature Envy] RedCloth#flush_left refers to text more than self
|
18
27
|
[Utility Function] RedCloth#footnote_ref doesn't depend on instance state
|
19
28
|
[Long Method] RedCloth#glyphs_textile has approx 9 statements
|
20
29
|
[Utility Function] RedCloth#h_align doesn't depend on instance state
|
21
30
|
[Utility Function] RedCloth#htmlesc doesn't depend on instance state
|
31
|
+
[Feature Envy] RedCloth#htmlesc refers to str more than self
|
22
32
|
[Utility Function] RedCloth#incoming_entities doesn't depend on instance state
|
23
33
|
[Nested Iterators] RedCloth#inline has nested iterators
|
24
34
|
[Long Method] RedCloth#inline_markdown_link has approx 6 statements
|
@@ -29,13 +39,21 @@
|
|
29
39
|
[Nested Iterators] RedCloth#inline_textile_span has nested iterators
|
30
40
|
[Utility Function] RedCloth#lT doesn't depend on instance state
|
31
41
|
[Utility Function] RedCloth#no_textile doesn't depend on instance state
|
42
|
+
[Feature Envy] RedCloth#no_textile refers to text more than self
|
43
|
+
[Duplication] RedCloth#pba calls $1.length more than once
|
32
44
|
[Long Method] RedCloth#pba has approx 22 statements
|
33
45
|
[Control Couple] RedCloth#pba is controlled by argument text_in
|
34
|
-
[Feature Envy] RedCloth#pba
|
46
|
+
[Feature Envy] RedCloth#pba refers to style more than self
|
47
|
+
[Feature Envy] RedCloth#pba refers to text more than self
|
48
|
+
[Duplication] RedCloth#rip_offtags calls @pre_list.last more than once
|
49
|
+
[Duplication] RedCloth#rip_offtags calls @pre_list.last.<<(line) more than once
|
50
|
+
[Duplication] RedCloth#rip_offtags calls codepre.-(used_offtags.length) more than once
|
51
|
+
[Duplication] RedCloth#rip_offtags calls codepre.-(used_offtags.length).>(0) more than once
|
52
|
+
[Duplication] RedCloth#rip_offtags calls codepre.zero? more than once
|
53
|
+
[Duplication] RedCloth#rip_offtags calls used_offtags.length more than once
|
54
|
+
[Duplication] RedCloth#rip_offtags calls used_offtags[notextile] more than once
|
35
55
|
[Long Method] RedCloth#rip_offtags has approx 22 statements
|
36
|
-
[Feature Envy] RedCloth#rip_offtags
|
37
|
-
[Feature Envy] RedCloth#shelve uses @shelf more than self
|
38
|
-
[Feature Envy] RedCloth#smooth_offtags uses @pre_list more than self
|
56
|
+
[Feature Envy] RedCloth#rip_offtags refers to codepre more than self
|
39
57
|
[Long Parameter List] RedCloth#textile_bq has 4 parameters
|
40
58
|
[Control Couple] RedCloth#textile_bq is controlled by argument atts
|
41
59
|
[Control Couple] RedCloth#textile_bq is controlled by argument cite
|
data/spec/script_spec.rb
CHANGED
@@ -62,7 +62,7 @@ describe 'report format', 'with one source' do
|
|
62
62
|
|
63
63
|
it 'should not adorn the list of warnings' do
|
64
64
|
report = `ruby -Ilib bin/reek "def y() @x = 3; end"`
|
65
|
-
report.split(/\n/).length.should ==
|
65
|
+
report.split(/\n/).length.should == 2
|
66
66
|
report.should_not match(/\n\n/)
|
67
67
|
end
|
68
68
|
end
|
data/tasks/reek.rake
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
require 'reek/rake_task'
|
2
|
+
require 'flay'
|
2
3
|
|
3
4
|
Reek::RakeTask.new do |t|
|
4
5
|
t.fail_on_error = true
|
5
6
|
t.verbose = false
|
6
7
|
# t.sort = 'smell'
|
7
8
|
end
|
9
|
+
|
10
|
+
desc 'Check for code duplication'
|
11
|
+
task 'flay' do
|
12
|
+
files = FileList['lib/**/*.rb']
|
13
|
+
flayer = Flay.new(16)
|
14
|
+
flayer.process(*files)
|
15
|
+
flayer.report
|
16
|
+
end
|
data/website/index.html
CHANGED
@@ -39,7 +39,7 @@
|
|
39
39
|
<h2>Installing</h2>
|
40
40
|
<code>$ gem install reek</code>
|
41
41
|
<h2>The basics</h2>
|
42
|
-
<code>$ reek [options]
|
42
|
+
<code>$ reek [options] sources</code>
|
43
43
|
<p>(See <code>reek --help</code> for details.)</p>
|
44
44
|
<h2>Code Smells</h2>
|
45
45
|
<p>reek currently includes very naive checks for the following code smells:</p>
|
@@ -51,6 +51,7 @@
|
|
51
51
|
<li>Long Parameter List</li>
|
52
52
|
<li>Utility Function</li>
|
53
53
|
<li>Nested Iterators</li>
|
54
|
+
<li>Control Couple</li>
|
54
55
|
</ul>
|
55
56
|
<h2>How to access the source code</h2>
|
56
57
|
<p>The source is hosted on both <a href="http://github.com/kevinrutherford/reek/tree/master">github</a> and <a href="http://rubyforge.org/projects/reek/">rubyforge</a></p>
|
@@ -59,7 +60,7 @@
|
|
59
60
|
<h2>Contact</h2>
|
60
61
|
<p>Comments are welcome. Send an email to <a href="mailto:kevin@rutherford-software.com">Kevin Rutherford</a></p>
|
61
62
|
<p class="coda">
|
62
|
-
<a href="http://www.kevinrutherford.co.uk">Kevin Rutherford</a>,
|
63
|
+
<a href="http://www.kevinrutherford.co.uk">Kevin Rutherford</a>, 2nd November 2008<br>
|
63
64
|
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
64
65
|
</p>
|
65
66
|
</div>
|
data/website/index.txt
CHANGED
@@ -8,7 +8,7 @@ h2. Installing
|
|
8
8
|
|
9
9
|
h2. The basics
|
10
10
|
|
11
|
-
@$ reek [options]
|
11
|
+
@$ reek [options] sources@
|
12
12
|
|
13
13
|
(See @reek --help@ for details.)
|
14
14
|
|
@@ -23,6 +23,8 @@ reek currently includes very naive checks for the following code smells:
|
|
23
23
|
* Long Parameter List
|
24
24
|
* Utility Function
|
25
25
|
* Nested Iterators
|
26
|
+
* Control Couple
|
27
|
+
* Duplication
|
26
28
|
|
27
29
|
h2. How to access the source code
|
28
30
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reek
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Rutherford
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-11-
|
12
|
+
date: 2008-11-17 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -68,25 +68,37 @@ files:
|
|
68
68
|
- lib/reek/printer.rb
|
69
69
|
- lib/reek/rake_task.rb
|
70
70
|
- lib/reek/report.rb
|
71
|
-
- lib/reek/smells.rb
|
71
|
+
- lib/reek/smells/control_couple.rb
|
72
|
+
- lib/reek/smells/duplication.rb
|
73
|
+
- lib/reek/smells/feature_envy.rb
|
74
|
+
- lib/reek/smells/large_class.rb
|
75
|
+
- lib/reek/smells/long_method.rb
|
76
|
+
- lib/reek/smells/long_parameter_list.rb
|
77
|
+
- lib/reek/smells/long_yield_list.rb
|
78
|
+
- lib/reek/smells/nested_iterators.rb
|
79
|
+
- lib/reek/smells/smell.rb
|
80
|
+
- lib/reek/smells/smells.rb
|
81
|
+
- lib/reek/smells/uncommunicative_name.rb
|
82
|
+
- lib/reek/smells/utility_function.rb
|
72
83
|
- lib/reek/version.rb
|
73
84
|
- setup.rb
|
74
85
|
- spec/integration_spec.rb
|
75
86
|
- spec/reek/class_checker_spec.rb
|
76
|
-
- spec/reek/control_couple_spec.rb
|
77
|
-
- spec/reek/feature_envy_spec.rb
|
78
|
-
- spec/reek/large_class_spec.rb
|
79
|
-
- spec/reek/long_method_spec.rb
|
80
|
-
- spec/reek/long_parameter_list_spec.rb
|
81
87
|
- spec/reek/method_checker_spec.rb
|
82
|
-
- spec/reek/nested_iterators_spec.rb
|
83
88
|
- spec/reek/object_refs_spec.rb
|
84
89
|
- spec/reek/options_spec.rb
|
85
90
|
- spec/reek/printer_spec.rb
|
86
91
|
- spec/reek/report_spec.rb
|
87
|
-
- spec/reek/
|
88
|
-
- spec/reek/
|
89
|
-
- spec/reek/
|
92
|
+
- spec/reek/smells/control_couple_spec.rb
|
93
|
+
- spec/reek/smells/duplication_spec.rb
|
94
|
+
- spec/reek/smells/feature_envy_spec.rb
|
95
|
+
- spec/reek/smells/large_class_spec.rb
|
96
|
+
- spec/reek/smells/long_method_spec.rb
|
97
|
+
- spec/reek/smells/long_parameter_list_spec.rb
|
98
|
+
- spec/reek/smells/nested_iterators_spec.rb
|
99
|
+
- spec/reek/smells/smell_spec.rb
|
100
|
+
- spec/reek/smells/uncommunicative_name_spec.rb
|
101
|
+
- spec/reek/smells/utility_function_spec.rb
|
90
102
|
- spec/reek_source_spec.rb
|
91
103
|
- spec/samples/inline.rb
|
92
104
|
- spec/samples/inline.reek
|
data/lib/reek/smells.rb
DELETED
@@ -1,192 +0,0 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__)
|
2
|
-
|
3
|
-
require 'reek/printer'
|
4
|
-
require 'reek/options'
|
5
|
-
|
6
|
-
module Reek
|
7
|
-
|
8
|
-
class Smell
|
9
|
-
include Comparable
|
10
|
-
|
11
|
-
def self.convert_camel_case(class_name)
|
12
|
-
class_name.gsub(/([a-z])([A-Z])/) { |s| "#{$1} #{$2}"}
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(context, arg=nil)
|
16
|
-
@context = context
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.check(exp, context, arg=nil)
|
20
|
-
smell = new(context, arg)
|
21
|
-
return false unless smell.recognise?(exp)
|
22
|
-
context.report(smell)
|
23
|
-
true
|
24
|
-
end
|
25
|
-
|
26
|
-
def recognise?(stuff)
|
27
|
-
@context != nil
|
28
|
-
end
|
29
|
-
|
30
|
-
def hash # :nodoc:
|
31
|
-
report.hash
|
32
|
-
end
|
33
|
-
|
34
|
-
def <=>(other) # :nodoc:
|
35
|
-
Options[:sort_order].compare(self, other)
|
36
|
-
end
|
37
|
-
|
38
|
-
alias eql? <=>
|
39
|
-
|
40
|
-
def name
|
41
|
-
self.class.convert_camel_case(self.class.name.split(/::/)[1])
|
42
|
-
end
|
43
|
-
|
44
|
-
def report
|
45
|
-
"[#{name}] #{detailed_report}"
|
46
|
-
end
|
47
|
-
|
48
|
-
alias inspect report
|
49
|
-
|
50
|
-
def to_s
|
51
|
-
report
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class LongParameterList < Smell
|
56
|
-
MAX_ALLOWED = 3
|
57
|
-
|
58
|
-
def self.count_parameters(exp)
|
59
|
-
result = exp.length - 1
|
60
|
-
result -= 1 if Array === exp[-1] and exp[-1][0] == :block
|
61
|
-
result
|
62
|
-
end
|
63
|
-
|
64
|
-
def recognise?(args)
|
65
|
-
@num_params = LongParameterList.count_parameters(args)
|
66
|
-
@num_params > MAX_ALLOWED
|
67
|
-
end
|
68
|
-
|
69
|
-
def detailed_report
|
70
|
-
"#{@context.to_s} has #{@num_params} parameters"
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
class LongYieldList < LongParameterList
|
75
|
-
def recognise?(args)
|
76
|
-
@num_params = args.length
|
77
|
-
Array === args and @num_params > MAX_ALLOWED
|
78
|
-
end
|
79
|
-
|
80
|
-
def detailed_report
|
81
|
-
"#{@context} yields #{@num_params} parameters"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
class LongMethod < Smell
|
86
|
-
MAX_ALLOWED = 5
|
87
|
-
|
88
|
-
def recognise?(num_stmts)
|
89
|
-
@num_stmts = num_stmts
|
90
|
-
num_stmts > MAX_ALLOWED
|
91
|
-
end
|
92
|
-
|
93
|
-
def detailed_report
|
94
|
-
"#{@context} has approx #{@num_stmts} statements"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
class FeatureEnvy < Smell
|
99
|
-
|
100
|
-
def recognise?(refs)
|
101
|
-
@refs = refs
|
102
|
-
!refs.self_is_max?
|
103
|
-
end
|
104
|
-
|
105
|
-
def detailed_report
|
106
|
-
receiver = @refs.max_keys.map {|r| Printer.print(r)}.sort.join(' and ')
|
107
|
-
"#{@context} uses #{receiver} more than self"
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
class UtilityFunction < Smell
|
112
|
-
def initialize(context, num_stmts)
|
113
|
-
super
|
114
|
-
@num_stmts = num_stmts
|
115
|
-
end
|
116
|
-
|
117
|
-
def recognise?(depends_on_self)
|
118
|
-
@num_stmts > 0 and !depends_on_self
|
119
|
-
end
|
120
|
-
|
121
|
-
def detailed_report
|
122
|
-
"#{@context} doesn't depend on instance state"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
class LargeClass < Smell
|
127
|
-
MAX_ALLOWED = 25
|
128
|
-
|
129
|
-
def self.non_inherited_methods(klass)
|
130
|
-
return klass.instance_methods if klass.superclass.nil?
|
131
|
-
klass.instance_methods - klass.superclass.instance_methods
|
132
|
-
end
|
133
|
-
|
134
|
-
def recognise?(name)
|
135
|
-
klass = Object.const_get(name) rescue return
|
136
|
-
@num_methods = LargeClass.non_inherited_methods(klass).length
|
137
|
-
@num_methods > MAX_ALLOWED
|
138
|
-
end
|
139
|
-
|
140
|
-
def detailed_report
|
141
|
-
"#{@context} has #{@num_methods} methods"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
class UncommunicativeName < Smell
|
146
|
-
def initialize(context, symbol_type)
|
147
|
-
super
|
148
|
-
@symbol_type = symbol_type
|
149
|
-
end
|
150
|
-
|
151
|
-
def self.effective_length(name)
|
152
|
-
return 500 if name == '*'
|
153
|
-
name = name[1..-1] while /^@/ === name
|
154
|
-
name.length
|
155
|
-
end
|
156
|
-
|
157
|
-
def recognise?(symbol)
|
158
|
-
@symbol = symbol.to_s
|
159
|
-
UncommunicativeName.effective_length(@symbol) < 2
|
160
|
-
end
|
161
|
-
|
162
|
-
def detailed_report
|
163
|
-
"#{@context} uses the #{@symbol_type} name '#{@symbol}'"
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
class NestedIterators < Smell
|
168
|
-
def recognise?(already_in_iter)
|
169
|
-
already_in_iter
|
170
|
-
end
|
171
|
-
|
172
|
-
def detailed_report
|
173
|
-
"#{@context} has nested iterators"
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
class ControlCouple < Smell
|
178
|
-
def initialize(context, args)
|
179
|
-
super
|
180
|
-
@args = args
|
181
|
-
end
|
182
|
-
|
183
|
-
def recognise?(cond)
|
184
|
-
@couple = cond
|
185
|
-
cond[0] == :lvar and @args.include?(@couple[1])
|
186
|
-
end
|
187
|
-
|
188
|
-
def detailed_report
|
189
|
-
"#{@context} is controlled by argument #{Printer.print(@couple)}"
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|