metric_fu 2.0.0 → 2.0.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 (85) hide show
  1. data/HISTORY +13 -5
  2. data/README +2 -2
  3. data/Rakefile +1 -1
  4. data/TODO +3 -1
  5. data/lib/base/base_template.rb +16 -16
  6. data/lib/base/churn_analyzer.rb +3 -3
  7. data/lib/base/code_issue.rb +8 -8
  8. data/lib/base/configuration.rb +24 -22
  9. data/lib/base/flay_analyzer.rb +2 -2
  10. data/lib/base/flog_analyzer.rb +4 -4
  11. data/lib/base/generator.rb +21 -21
  12. data/lib/base/graph.rb +15 -10
  13. data/lib/base/line_numbers.rb +56 -55
  14. data/lib/base/location.rb +68 -66
  15. data/lib/base/metric_analyzer.rb +21 -21
  16. data/lib/base/ranking.rb +23 -22
  17. data/lib/base/rcov_analyzer.rb +3 -3
  18. data/lib/base/reek_analyzer.rb +12 -10
  19. data/lib/base/report.rb +9 -9
  20. data/lib/base/roodi_analyzer.rb +2 -2
  21. data/lib/base/saikuro_analyzer.rb +4 -4
  22. data/lib/base/scoring_strategies.rb +5 -5
  23. data/lib/base/stats_analyzer.rb +2 -2
  24. data/lib/base/table.rb +4 -4
  25. data/lib/generators/churn.rb +1 -1
  26. data/lib/generators/flay.rb +1 -1
  27. data/lib/generators/hotspots.rb +4 -4
  28. data/lib/generators/rails_best_practices.rb +1 -1
  29. data/lib/generators/rcov.rb +17 -17
  30. data/lib/generators/reek.rb +2 -2
  31. data/lib/generators/saikuro.rb +42 -42
  32. data/lib/generators/stats.rb +6 -6
  33. data/lib/graphs/engines/bluff.rb +1 -1
  34. data/lib/graphs/engines/gchart.rb +7 -7
  35. data/lib/graphs/flog_grapher.rb +3 -3
  36. data/lib/graphs/grapher.rb +1 -1
  37. data/lib/metric_fu.rb +2 -2
  38. data/lib/templates/awesome/churn.html.erb +1 -1
  39. data/lib/templates/awesome/css/integrity.css +0 -1
  40. data/lib/templates/awesome/flay.html.erb +2 -2
  41. data/lib/templates/awesome/flog.html.erb +2 -2
  42. data/lib/templates/awesome/hotspots.html.erb +4 -4
  43. data/lib/templates/awesome/index.html.erb +2 -2
  44. data/lib/templates/awesome/rails_best_practices.html.erb +1 -1
  45. data/lib/templates/awesome/rcov.html.erb +1 -1
  46. data/lib/templates/awesome/roodi.html.erb +1 -1
  47. data/lib/templates/awesome/saikuro.html.erb +3 -3
  48. data/lib/templates/awesome/stats.html.erb +1 -1
  49. data/lib/templates/standard/churn.html.erb +2 -2
  50. data/lib/templates/standard/default.css +4 -4
  51. data/lib/templates/standard/flay.html.erb +4 -4
  52. data/lib/templates/standard/flog.html.erb +1 -1
  53. data/lib/templates/standard/hotspots.html.erb +4 -4
  54. data/lib/templates/standard/index.html.erb +2 -2
  55. data/lib/templates/standard/rails_best_practices.html.erb +2 -2
  56. data/lib/templates/standard/rcov.html.erb +2 -2
  57. data/lib/templates/standard/reek.html.erb +1 -1
  58. data/lib/templates/standard/roodi.html.erb +2 -2
  59. data/lib/templates/standard/saikuro.html.erb +4 -4
  60. data/lib/templates/standard/stats.html.erb +2 -2
  61. data/spec/base/base_template_spec.rb +1 -1
  62. data/spec/base/configuration_spec.rb +36 -36
  63. data/spec/base/generator_spec.rb +10 -10
  64. data/spec/base/graph_spec.rb +41 -4
  65. data/spec/base/line_numbers_spec.rb +22 -22
  66. data/spec/base/report_spec.rb +9 -9
  67. data/spec/generators/churn_spec.rb +4 -4
  68. data/spec/generators/flay_spec.rb +31 -31
  69. data/spec/generators/flog_spec.rb +18 -18
  70. data/spec/generators/rails_best_practices_spec.rb +6 -6
  71. data/spec/generators/rcov_spec.rb +18 -18
  72. data/spec/generators/reek_spec.rb +10 -10
  73. data/spec/generators/roodi_spec.rb +2 -2
  74. data/spec/generators/saikuro_spec.rb +7 -7
  75. data/spec/generators/stats_spec.rb +6 -6
  76. data/spec/graphs/engines/gchart_spec.rb +8 -8
  77. data/spec/graphs/flog_grapher_spec.rb +8 -8
  78. data/spec/resources/line_numbers/foo.rb +7 -7
  79. data/spec/resources/line_numbers/module.rb +2 -2
  80. data/spec/resources/line_numbers/module_surrounds_class.rb +6 -6
  81. data/spec/resources/saikuro/index_cyclo.html +2 -2
  82. data/spec/resources/yml/20090630.yml +349 -349
  83. data/spec/resources/yml/metric_missing.yml +1 -1
  84. data/tasks/metric_fu.rake +4 -4
  85. metadata +4 -4
@@ -2,18 +2,18 @@ module MetricFu
2
2
 
3
3
  # = Generator
4
4
  #
5
- # The Generator class is an abstract class that provides the
5
+ # The Generator class is an abstract class that provides the
6
6
  # skeleton for producing different types of metrics.
7
7
  #
8
- # It drives the production of the metrics through a template
8
+ # It drives the production of the metrics through a template
9
9
  # method - #generate_report(options={}). This method calls
10
10
  # #emit, #analyze and #to_h in order to produce the metrics.
11
11
  #
12
12
  # To implement a concrete class to generate a metric, therefore,
13
- # the class must implement those three methods.
13
+ # the class must implement those three methods.
14
14
  #
15
- # * #emit should take care of running the metric tool and
16
- # gathering its output.
15
+ # * #emit should take care of running the metric tool and
16
+ # gathering its output.
17
17
  # * #analyze should take care of manipulating the output from
18
18
  # #emit and making it possible to store it in a programmatic way.
19
19
  # * #to_h should provide a hash representation of the output from
@@ -37,9 +37,9 @@ module MetricFu
37
37
  create_output_dir_if_missing
38
38
  create_data_dir_if_missing
39
39
  end
40
-
41
- # Creates a new generator and returns the output of the
42
- # #generate_report method. This is the typical way to
40
+
41
+ # Creates a new generator and returns the output of the
42
+ # #generate_report method. This is the typical way to
43
43
  # generate a new MetricFu report. For more information see
44
44
  # the #generate_report instance method.
45
45
  #
@@ -66,27 +66,27 @@ module MetricFu
66
66
  def self.class_name
67
67
  self.to_s.split('::').last.downcase
68
68
  end
69
-
69
+
70
70
  # Returns the directory where the Generator will write any output
71
71
  def self.metric_directory
72
- File.join(MetricFu.scratch_directory, class_name)
72
+ File.join(MetricFu.scratch_directory, class_name)
73
73
  end
74
74
 
75
75
  def create_metric_dir_if_missing #:nodoc:
76
76
  unless File.directory?(metric_directory)
77
- FileUtils.mkdir_p(metric_directory, :verbose => false)
77
+ FileUtils.mkdir_p(metric_directory, :verbose => false)
78
78
  end
79
79
  end
80
-
80
+
81
81
  def create_output_dir_if_missing #:nodoc:
82
82
  unless File.directory?(MetricFu.output_directory)
83
- FileUtils.mkdir_p(MetricFu.output_directory, :verbose => false)
83
+ FileUtils.mkdir_p(MetricFu.output_directory, :verbose => false)
84
84
  end
85
85
  end
86
-
86
+
87
87
  def create_data_dir_if_missing #:nodoc:
88
88
  unless File.directory?(MetricFu.data_directory)
89
- FileUtils.mkdir_p(MetricFu.data_directory, :verbose => false)
89
+ FileUtils.mkdir_p(MetricFu.data_directory, :verbose => false)
90
90
  end
91
91
  end
92
92
 
@@ -103,7 +103,7 @@ module MetricFu
103
103
  end
104
104
  paths - files_to_remove
105
105
  end
106
-
106
+
107
107
  # Defines some hook methods for the concrete classes to hook into.
108
108
  %w[emit analyze].each do |meth|
109
109
  define_method("before_#{meth}".to_sym) {}
@@ -132,13 +132,13 @@ module MetricFu
132
132
 
133
133
  def round_to_tenths(decimal)
134
134
  decimal = 0.0 if decimal.to_s.eql?('NaN')
135
- (decimal * 10).round / 10.0
135
+ (decimal * 10).round / 10.0
136
136
  end
137
137
 
138
138
  def emit #:nodoc:
139
139
  raise <<-EOF
140
140
  This method must be implemented by a concrete class descending
141
- from Generator. See generator class documentation for more
141
+ from Generator. See generator class documentation for more
142
142
  information.
143
143
  EOF
144
144
  end
@@ -146,15 +146,15 @@ module MetricFu
146
146
  def analyze #:nodoc:
147
147
  raise <<-EOF
148
148
  This method must be implemented by a concrete class descending
149
- from Generator. See generator class documentation for more
149
+ from Generator. See generator class documentation for more
150
150
  information.
151
151
  EOF
152
152
  end
153
-
153
+
154
154
  def to_graph #:nodoc:
155
155
  raise <<-EOF
156
156
  This method must be implemented by a concrete class descending
157
- from Generator. See generator class documentation for more
157
+ from Generator. See generator class documentation for more
158
158
  information.
159
159
  EOF
160
160
  end
@@ -5,35 +5,40 @@ module MetricFu
5
5
  end
6
6
 
7
7
  class Graph
8
-
8
+
9
9
  attr_accessor :clazz
10
-
10
+
11
11
  def initialize
12
12
  self.clazz = []
13
13
  end
14
-
14
+
15
15
  def add(graph_type, graph_engine)
16
16
  grapher_name = graph_type.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } + graph_engine.to_s.capitalize + "Grapher"
17
17
  self.clazz.push MetricFu.const_get(grapher_name).new
18
18
  end
19
-
20
-
19
+
20
+
21
21
  def generate
22
22
  return if self.clazz.empty?
23
23
  puts "Generating graphs"
24
24
  Dir[File.join(MetricFu.data_directory, '*.yml')].sort.each do |metric_file|
25
25
  puts "Generating graphs for #{metric_file}"
26
- date = metric_file.split('/')[3].split('.')[0]
27
- y, m, d = date[0..3].to_i, date[4..5].to_i, date[6..7].to_i
26
+ date_parts = year_month_day_from_filename(metric_file)
28
27
  metrics = YAML::load(File.open(metric_file))
29
-
28
+
30
29
  self.clazz.each do |grapher|
31
- grapher.get_metrics(metrics, "#{m}/#{d}")
30
+ grapher.get_metrics(metrics, "#{date_parts[:m]}/#{date_parts[:d]}")
32
31
  end
33
32
  end
34
33
  self.clazz.each do |grapher|
35
34
  grapher.graph!
36
35
  end
37
36
  end
37
+
38
+ private
39
+ def year_month_day_from_filename(path_to_file_with_date)
40
+ date = path_to_file_with_date.match(/\/(\d+).yml$/)[1]
41
+ {:y => date[0..3].to_i, :m => date[4..5].to_i, :d => date[6..7].to_i}
42
+ end
38
43
  end
39
- end
44
+ end
@@ -1,65 +1,66 @@
1
1
  require 'ruby_parser'
2
+ module MetricFu
3
+ class LineNumbers
2
4
 
3
- class LineNumbers
5
+ def initialize(contents)
6
+ rp = RubyParser.new
7
+ file_sexp = rp.parse(contents)
8
+ @locations = {}
9
+ case file_sexp[0]
10
+ when :class
11
+ process_class(file_sexp)
12
+ when :module
13
+ process_module(file_sexp)
14
+ when :block
15
+ file_sexp.each_of_type(:class) { |sexp| process_class(sexp) }
16
+ else
17
+ end
18
+ end
4
19
 
5
- def initialize(contents)
6
- rp = RubyParser.new
7
- file_sexp = rp.parse(contents)
8
- @locations = {}
9
- case file_sexp[0]
10
- when :class
11
- process_class(file_sexp)
12
- when :module
13
- process_module(file_sexp)
14
- when :block
15
- file_sexp.each_of_type(:class) { |sexp| process_class(sexp) }
16
- else
20
+ def in_method? line_number
21
+ !!@locations.detect do |method_name, line_number_range|
22
+ line_number_range.include?(line_number)
23
+ end
17
24
  end
18
- end
19
-
20
- def in_method? line_number
21
- !!@locations.detect do |method_name, line_number_range|
22
- line_number_range.include?(line_number)
25
+
26
+ def method_at_line line_number
27
+ found_method_and_range = @locations.detect do |method_name, line_number_range|
28
+ line_number_range.include?(line_number)
29
+ end
30
+ return nil unless found_method_and_range
31
+ found_method_and_range.first
23
32
  end
24
- end
25
-
26
- def method_at_line line_number
27
- found_method_and_range = @locations.detect do |method_name, line_number_range|
28
- line_number_range.include?(line_number)
33
+
34
+ private
35
+
36
+ def process_module(sexp)
37
+ module_name = sexp[1]
38
+ sexp.each_of_type(:class) do |sexp|
39
+ process_class(sexp, module_name)
40
+ hide_methods_from_next_round(sexp)
41
+ end
42
+ process_class(sexp)
29
43
  end
30
- return nil unless found_method_and_range
31
- found_method_and_range.first
32
- end
33
-
34
- private
35
-
36
- def process_module(sexp)
37
- module_name = sexp[1]
38
- sexp.each_of_type(:class) do |sexp|
39
- process_class(sexp, module_name)
40
- hide_methods_from_next_round(sexp)
44
+
45
+ def process_class(sexp, module_name=nil)
46
+ class_name = sexp[1]
47
+ process_class_self_blocks(sexp, class_name)
48
+ module_name_string = module_name ? "#{module_name}::" : nil
49
+ sexp.each_of_type(:defn) { |s| @locations["#{module_name_string}#{class_name}##{s[1]}"] = (s.line)..(s.last.line) }
50
+ sexp.each_of_type(:defs) { |s| @locations["#{module_name_string}#{class_name}::#{s[2]}"] = (s.line)..(s.last.line) }
41
51
  end
42
- process_class(sexp)
43
- end
44
-
45
- def process_class(sexp, module_name=nil)
46
- class_name = sexp[1]
47
- process_class_self_blocks(sexp, class_name)
48
- module_name_string = module_name ? "#{module_name}::" : nil
49
- sexp.each_of_type(:defn) { |s| @locations["#{module_name_string}#{class_name}##{s[1]}"] = (s.line)..(s.last.line) }
50
- sexp.each_of_type(:defs) { |s| @locations["#{module_name_string}#{class_name}::#{s[2]}"] = (s.line)..(s.last.line) }
51
- end
52
-
53
- def process_class_self_blocks(sexp, class_name)
54
- sexp.each_of_type(:sclass) do |sexp_in_class_self_block|
55
- sexp_in_class_self_block.each_of_type(:defn) { |s| @locations["#{class_name}::#{s[1]}"] = (s.line)..(s.last.line) }
56
- hide_methods_from_next_round(sexp_in_class_self_block)
52
+
53
+ def process_class_self_blocks(sexp, class_name)
54
+ sexp.each_of_type(:sclass) do |sexp_in_class_self_block|
55
+ sexp_in_class_self_block.each_of_type(:defn) { |s| @locations["#{class_name}::#{s[1]}"] = (s.line)..(s.last.line) }
56
+ hide_methods_from_next_round(sexp_in_class_self_block)
57
+ end
57
58
  end
59
+
60
+ def hide_methods_from_next_round(sexp)
61
+ sexp.find_and_replace_all(:defn, :ignore_me)
62
+ sexp.find_and_replace_all(:defs, :ignore_me)
63
+ end
64
+
58
65
  end
59
-
60
- def hide_methods_from_next_round(sexp)
61
- sexp.find_and_replace_all(:defn, :ignore_me)
62
- sexp.find_and_replace_all(:defs, :ignore_me)
63
- end
64
-
65
66
  end
@@ -1,83 +1,85 @@
1
- class Location
2
- include Comparable
1
+ module MetricFu
2
+ class Location
3
+ include Comparable
3
4
 
4
- attr_accessor :class_name, :method_name, :file_path, :simple_method_name, :hash
5
+ attr_accessor :class_name, :method_name, :file_path, :simple_method_name, :hash
5
6
 
6
- def self.get(file_path, class_name, method_name)
7
- # This could be more 'confident' using Maybe, but we want it to be as fast as possible
8
- file_path_copy = file_path == nil ? nil : file_path.clone
9
- class_name_copy = class_name == nil ? nil : class_name.clone
10
- method_name_copy = method_name == nil ? nil : method_name.clone
11
- key = [file_path_copy, class_name_copy, method_name_copy]
12
- @@locations ||= {}
13
- if @@locations.has_key?(key)
14
- @@locations[key]
15
- else
16
- location = self.new(file_path_copy, class_name_copy, method_name_copy)
17
- @@locations[key] = location
18
- location.freeze # we cache a lot of method call results, so we want location to be immutable
19
- location
7
+ def self.get(file_path, class_name, method_name)
8
+ # This could be more 'confident' using Maybe, but we want it to be as fast as possible
9
+ file_path_copy = file_path == nil ? nil : file_path.clone
10
+ class_name_copy = class_name == nil ? nil : class_name.clone
11
+ method_name_copy = method_name == nil ? nil : method_name.clone
12
+ key = [file_path_copy, class_name_copy, method_name_copy]
13
+ @@locations ||= {}
14
+ if @@locations.has_key?(key)
15
+ @@locations[key]
16
+ else
17
+ location = self.new(file_path_copy, class_name_copy, method_name_copy)
18
+ @@locations[key] = location
19
+ location.freeze # we cache a lot of method call results, so we want location to be immutable
20
+ location
21
+ end
20
22
  end
21
- end
22
23
 
23
- def initialize(file_path, class_name, method_name)
24
- @file_path = file_path
25
- @class_name = class_name
26
- @method_name = method_name
27
- @simple_method_name = @method_name.sub(@class_name,'') unless @method_name == nil
28
- @hash = [@file_path, @class_name, @method_name].hash
29
- end
24
+ def initialize(file_path, class_name, method_name)
25
+ @file_path = file_path
26
+ @class_name = class_name
27
+ @method_name = method_name
28
+ @simple_method_name = @method_name.sub(@class_name,'') unless @method_name == nil
29
+ @hash = [@file_path, @class_name, @method_name].hash
30
+ end
30
31
 
31
- # TODO - we need this method (and hash accessor above) as a temporary hack where we're using Location as a hash key
32
- def eql?(other)
33
- [self.file_path.to_s, self.class_name.to_s, self.method_name.to_s] == [other.file_path.to_s, other.class_name.to_s, other.method_name.to_s]
34
- end
32
+ # TODO - we need this method (and hash accessor above) as a temporary hack where we're using Location as a hash key
33
+ def eql?(other)
34
+ [self.file_path.to_s, self.class_name.to_s, self.method_name.to_s] == [other.file_path.to_s, other.class_name.to_s, other.method_name.to_s]
35
+ end
36
+ # END we need these methods as a temporary hack where we're using Location as a hash key
35
37
 
36
- # END we need these methods as a temporary hack where we're using Location as a hash key
37
-
38
- def self.for(class_or_method_name)
39
- class_or_method_name = strip_modules(class_or_method_name)
40
- if(class_or_method_name)
41
- begin
42
- match = class_or_method_name.match(/(.*)((\.|\#|\:\:[a-z])(.+))/)
43
- rescue => error
44
- #new error during port to metric_fu occasionally a unintialized
45
- #MatchData object shows up here. Not expected.
46
- match = nil
47
- end
38
+ def self.for(class_or_method_name)
39
+ class_or_method_name = strip_modules(class_or_method_name)
40
+ if(class_or_method_name)
41
+ begin
42
+ match = class_or_method_name.match(/(.*)((\.|\#|\:\:[a-z])(.+))/)
43
+ rescue => error
44
+ #new error during port to metric_fu occasionally a unintialized
45
+ #MatchData object shows up here. Not expected.
46
+ match = nil
47
+ end
48
48
 
49
- # reek reports the method with :: not # on modules like
50
- # module ApplicationHelper \n def signed_in?, convert it so it records correctly
51
- # but classes have to start with a capital letter... HACK for REEK bug, reported underlying issue to REEK
52
- if(match)
53
- class_name = strip_modules(match[1])
54
- method_name = class_or_method_name.gsub(/\:\:/,"#")
49
+ # reek reports the method with :: not # on modules like
50
+ # module ApplicationHelper \n def signed_in?, convert it so it records correctly
51
+ # but classes have to start with a capital letter... HACK for REEK bug, reported underlying issue to REEK
52
+ if(match)
53
+ class_name = strip_modules(match[1])
54
+ method_name = class_or_method_name.gsub(/\:\:/,"#")
55
+ else
56
+ class_name = strip_modules(class_or_method_name)
57
+ method_name = nil
58
+ end
55
59
  else
56
- class_name = strip_modules(class_or_method_name)
60
+ class_name = nil
57
61
  method_name = nil
58
62
  end
59
- else
60
- class_name = nil
61
- method_name = nil
63
+ self.get(nil, class_name, method_name)
62
64
  end
63
- self.get(nil, class_name, method_name)
64
- end
65
65
 
66
- def <=>(other)
67
- [self.file_path.to_s, self.class_name.to_s, self.method_name.to_s] <=> [other.file_path.to_s, other.class_name.to_s, other.method_name.to_s]
68
- end
66
+ def <=>(other)
67
+ [self.file_path.to_s, self.class_name.to_s, self.method_name.to_s] <=> [other.file_path.to_s, other.class_name.to_s, other.method_name.to_s]
68
+ end
69
69
 
70
- private
70
+ private
71
+
72
+ def self.strip_modules(class_or_method_name)
73
+ # reek reports the method with :: not # on modules like
74
+ # module ApplicationHelper \n def signed_in?, convert it so it records correctly
75
+ # but classes have to start with a capital letter... HACK for REEK bug, reported underlying issue to REEK
76
+ if(class_or_method_name=~/\:\:[A-Z]/)
77
+ class_or_method_name.split("::").last
78
+ else
79
+ class_or_method_name
80
+ end
71
81
 
72
- def self.strip_modules(class_or_method_name)
73
- # reek reports the method with :: not # on modules like
74
- # module ApplicationHelper \n def signed_in?, convert it so it records correctly
75
- # but classes have to start with a capital letter... HACK for REEK bug, reported underlying issue to REEK
76
- if(class_or_method_name=~/\:\:[A-Z]/)
77
- class_or_method_name.split("::").last
78
- else
79
- class_or_method_name
80
82
  end
81
- end
82
83
 
84
+ end
83
85
  end
@@ -13,9 +13,9 @@ class MetricAnalyzer
13
13
  else
14
14
  @yaml = yaml
15
15
  end
16
- @file_ranking = Ranking.new
17
- @class_ranking = Ranking.new
18
- @method_ranking = Ranking.new
16
+ @file_ranking = MetricFu::Ranking.new
17
+ @class_ranking = MetricFu::Ranking.new
18
+ @method_ranking = MetricFu::Ranking.new
19
19
  rankings = [@file_ranking, @class_ranking, @method_ranking]
20
20
 
21
21
  tool_analyzers = [ReekAnalyzer.new, RoodiAnalyzer.new,
@@ -27,14 +27,14 @@ class MetricAnalyzer
27
27
  columns = COMMON_COLUMNS + GRANULARITIES + tool_analyzers.map{|analyzer| analyzer.columns}.flatten
28
28
 
29
29
  @table = make_table(columns)
30
-
30
+
31
31
  # These tables are an optimization. They contain subsets of the master table.
32
32
  # TODO - these should be pushed into the Table class now
33
33
  @tool_tables = make_table_hash(columns)
34
34
  @file_tables = make_table_hash(columns)
35
35
  @class_tables = make_table_hash(columns)
36
36
  @method_tables = make_table_hash(columns)
37
-
37
+
38
38
  tool_analyzers.each do |analyzer|
39
39
  analyzer.generate_records(@yaml[analyzer.name], @table)
40
40
  end
@@ -62,11 +62,11 @@ class MetricAnalyzer
62
62
  first_row = sub_table[0]
63
63
  case item
64
64
  when :class
65
- Location.get(first_row.file_path, first_row.class_name, nil)
65
+ MetricFu::Location.get(first_row.file_path, first_row.class_name, nil)
66
66
  when :method
67
- Location.get(first_row.file_path, first_row.class_name, first_row.method_name)
67
+ MetricFu::Location.get(first_row.file_path, first_row.class_name, first_row.method_name)
68
68
  when :file
69
- Location.get(first_row.file_path, nil, nil)
69
+ MetricFu::Location.get(first_row.file_path, nil, nil)
70
70
  else
71
71
  raise ArgumentError, "Item must be :class, :method, or :file"
72
72
  end
@@ -147,7 +147,7 @@ class MetricAnalyzer
147
147
 
148
148
  def fix_row_file_path!(row)
149
149
  # We know that Saikuro rows are broken
150
- next unless row['metric'] == :saikuro
150
+ # next unless row['metric'] == :saikuro
151
151
  key = [row['class_name'], row['method_name']]
152
152
  current_file_path = row['file_path'].to_s
153
153
  correct_file_path = @class_and_method_to_file[key]
@@ -155,7 +155,7 @@ class MetricAnalyzer
155
155
  row['file_path'] = correct_file_path
156
156
  else
157
157
  # There wasn't an exact match, so we can do a substring match
158
- matching_file_path = file_paths.detect {|file_path|
158
+ matching_file_path = file_paths.detect {|file_path|
159
159
  file_path!=nil && file_path.include?(current_file_path)
160
160
  }
161
161
  if(matching_file_path)
@@ -180,32 +180,32 @@ class MetricAnalyzer
180
180
  raise ArgumentError, "Invalid column name #{column_name}"
181
181
  end
182
182
  end
183
-
183
+
184
184
  def calculate_metric_scores(granularity, analyzer)
185
- metric_ranking = Ranking.new
185
+ metric_ranking = MetricFu::Ranking.new
186
186
  metric_violations = @tool_tables[analyzer.name]
187
187
  metric_violations.each do |row|
188
188
  location = row[granularity]
189
189
  metric_ranking[location] ||= []
190
190
  metric_ranking[location] << analyzer.map(row)
191
191
  end
192
-
192
+
193
193
  metric_ranking.each do |item, scores|
194
194
  metric_ranking[item] = analyzer.reduce(scores)
195
195
  end
196
-
196
+
197
197
  metric_ranking
198
198
  end
199
199
 
200
200
  def add_to_master_ranking(master_ranking, metric_ranking, analyzer)
201
201
  metric_ranking.each do |item, _|
202
202
  master_ranking[item] ||= 0
203
- master_ranking[item] += analyzer.score(metric_ranking, item)
203
+ master_ranking[item] += analyzer.score(metric_ranking, item) # scaling? Do we just add in the raw score?
204
204
  end
205
205
  end
206
206
 
207
207
  def most_common_column(column_name, size)
208
- #grouping = Ruport::Data::Grouping.new(@table,
208
+ #grouping = Ruport::Data::Grouping.new(@table,
209
209
  # :by => column_name,
210
210
  # :order => lambda { |g| -g.size})
211
211
  get_grouping(@table, :by => column_name, :order => lambda {|g| -g.size})
@@ -223,7 +223,7 @@ class MetricAnalyzer
223
223
  return values
224
224
  end
225
225
  end
226
-
226
+
227
227
  # TODO: As we get fancier, the presenter should
228
228
  # be its own class, not just a method with a long
229
229
  # case statement
@@ -246,7 +246,7 @@ class MetricAnalyzer
246
246
  "found #{occurences} code duplications"
247
247
  when :rcov
248
248
  average_code_uncoverage = get_mean(group.column("percentage_uncovered"))
249
- "#{"average " if occurences > 1}uncovered code is %.1f%" % average_code_uncoverage
249
+ "#{"average " if occurences > 1}uncovered code is %.1f%" % average_code_uncoverage
250
250
  else
251
251
  raise AnalysisError, "Unknown metric #{metric}"
252
252
  end
@@ -320,13 +320,13 @@ class MetricAnalyzer
320
320
  sum = collection.inject( nil ) { |sum,x| sum ? sum+x : x }
321
321
  (sum.to_f / collection_length.to_f)
322
322
  end
323
-
323
+
324
324
  end
325
325
 
326
326
  class Record
327
327
 
328
328
  attr_reader :data
329
-
329
+
330
330
  def initialize(data, columns)
331
331
  @data = data
332
332
  @columns = columns
@@ -380,7 +380,7 @@ class Grouping
380
380
  end
381
381
  end
382
382
  if order
383
- @arr = hash.sort_by &order
383
+ @arr = hash.sort_by &order
384
384
  else
385
385
  @arr = hash.to_a
386
386
  end