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,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
2
 
3
3
  require 'reek/method_checker'
4
4
  require 'reek/report'
@@ -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
- [Feature Envy] C#crap_for_windoze uses Config::CONFIG more than self
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
- [Feature Envy] C#initialize uses stack more than self
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
- [Nested Iterators] C#module_name has nested iterators
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
@@ -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
- [Feature Envy] CompletingHash#order uses argv more than self
14
- [Feature Envy] CompletingHash#parse uses argv more than self
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
- [Feature Envy] CompletingHash#permute uses argv more than self
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 uses pat more than self
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 uses candidates more than self
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 uses arg more than self
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 uses left more than self
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'
@@ -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 uses text more than self
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 uses style and text more than self
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 uses codepre more than self
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 == 1
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] [source_files]</code>
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>, 15th September 2008<br>
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] [source_files]@
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.0
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-02 00:00:00 +00:00
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/smell_spec.rb
88
- - spec/reek/uncommunicative_name_spec.rb
89
- - spec/reek/utility_function_spec.rb
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