metric_fu 4.1.0 → 4.1.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 (62) hide show
  1. data/Gemfile +1 -1
  2. data/HISTORY.md +12 -1
  3. data/README.md +3 -0
  4. data/TODO.md +0 -41
  5. data/lib/metric_fu.rb +9 -1
  6. data/lib/metric_fu/configuration.rb +9 -1
  7. data/lib/metric_fu/initial_requires.rb +11 -11
  8. data/lib/metric_fu/load_files.rb +1 -0
  9. data/lib/metric_fu/metrics/cane/cane.rb +5 -4
  10. data/lib/metric_fu/metrics/cane/cane_bluff_grapher.rb +15 -0
  11. data/lib/metric_fu/metrics/cane/cane_grapher.rb +1 -0
  12. data/lib/metric_fu/metrics/cane/init.rb +1 -0
  13. data/lib/metric_fu/metrics/churn/churn_hotspot.rb +9 -1
  14. data/lib/metric_fu/metrics/flay/flay.rb +0 -2
  15. data/lib/metric_fu/metrics/flay/flay_bluff_grapher.rb +15 -0
  16. data/lib/metric_fu/metrics/flay/flay_gchart_grapher.rb +17 -0
  17. data/lib/metric_fu/metrics/flay/flay_grapher.rb +1 -0
  18. data/lib/metric_fu/metrics/flay/flay_hotspot.rb +18 -1
  19. data/lib/metric_fu/metrics/flay/init.rb +1 -0
  20. data/lib/metric_fu/metrics/flog/flog.rb +6 -4
  21. data/lib/metric_fu/metrics/flog/flog_bluff_grapher.rb +16 -0
  22. data/lib/metric_fu/metrics/flog/flog_gchart_grapher.rb +21 -0
  23. data/lib/metric_fu/metrics/flog/flog_grapher.rb +1 -0
  24. data/lib/metric_fu/metrics/flog/flog_hotspot.rb +13 -1
  25. data/lib/metric_fu/metrics/flog/init.rb +1 -0
  26. data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +73 -0
  27. data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +116 -0
  28. data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +21 -0
  29. data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +21 -0
  30. data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +81 -0
  31. data/lib/metric_fu/metrics/hotspots/hotspot.rb +29 -0
  32. data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +62 -308
  33. data/lib/metric_fu/metrics/hotspots/hotspots.rb +1 -27
  34. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_bluff_grapher.rb +15 -0
  35. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_gchart_grapher.rb +21 -0
  36. data/lib/metric_fu/metrics/rails_best_practices/rails_best_practices_grapher.rb +1 -0
  37. data/lib/metric_fu/metrics/rcov/rcov_bluff_grapher.rb +15 -0
  38. data/lib/metric_fu/metrics/rcov/rcov_gchart_grapher.rb +17 -0
  39. data/lib/metric_fu/metrics/rcov/rcov_grapher.rb +1 -0
  40. data/lib/metric_fu/metrics/rcov/rcov_hotspot.rb +28 -16
  41. data/lib/metric_fu/metrics/reek/reek_bluff_grapher.rb +20 -0
  42. data/lib/metric_fu/metrics/reek/reek_gchart_grapher.rb +25 -0
  43. data/lib/metric_fu/metrics/reek/reek_grapher.rb +1 -0
  44. data/lib/metric_fu/metrics/reek/reek_hotspot.rb +16 -1
  45. data/lib/metric_fu/metrics/roodi/roodi_bluff_grapher.rb +15 -0
  46. data/lib/metric_fu/metrics/roodi/roodi_gchart_grapher.rb +17 -0
  47. data/lib/metric_fu/metrics/roodi/roodi_grapher.rb +1 -0
  48. data/lib/metric_fu/metrics/roodi/roodi_hotspot.rb +16 -1
  49. data/lib/metric_fu/metrics/saikuro/saikuro_hotspot.rb +13 -1
  50. data/lib/metric_fu/metrics/stats/stats_bluff_grapher.rb +16 -0
  51. data/lib/metric_fu/metrics/stats/stats_gchart_grapher.rb +20 -0
  52. data/lib/metric_fu/metrics/stats/stats_grapher.rb +1 -0
  53. data/lib/metric_fu/metrics/stats/stats_hotspot.rb +1 -1
  54. data/lib/metric_fu/reporting/graphs/engines/bluff.rb +0 -114
  55. data/lib/metric_fu/reporting/graphs/engines/gchart.rb +0 -123
  56. data/lib/metric_fu/run.rb +1 -0
  57. data/lib/metric_fu/version.rb +1 -1
  58. data/metric_fu.gemspec +1 -0
  59. data/spec/metric_fu/metrics/cane/cane_spec.rb +17 -0
  60. data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +11 -0
  61. data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +7 -0
  62. metadata +180 -134
@@ -16,33 +16,7 @@ module MetricFu
16
16
  end
17
17
 
18
18
  def analyze
19
- num = nil
20
- worst_items = {}
21
- if @analyzer
22
- worst_items[:files] =
23
- @analyzer.worst_files(num).inject([]) do |array, worst_file|
24
- array <<
25
- {:location => @analyzer.location(:file, worst_file),
26
- :details => @analyzer.problems_with(:file, worst_file)}
27
- array
28
- end
29
- worst_items[:classes] = @analyzer.worst_classes(num).inject([]) do |array, class_name|
30
- location = @analyzer.location(:class, class_name)
31
- array <<
32
- {:location => location,
33
- :details => @analyzer.problems_with(:class, class_name)}
34
- array
35
- end
36
- worst_items[:methods] = @analyzer.worst_methods(num).inject([]) do |array, method_name|
37
- location = @analyzer.location(:method, method_name)
38
- array <<
39
- {:location => location,
40
- :details => @analyzer.problems_with(:method, method_name)}
41
- array
42
- end
43
- end
44
-
45
- @hotspots = worst_items
19
+ @hotspots = @analyzer && @analyzer.hotspots || {}
46
20
  end
47
21
 
48
22
  def to_h
@@ -0,0 +1,15 @@
1
+ MetricFu.metrics_require { 'rails_best_practices/rails_best_practices_grapher' }
2
+ module MetricFu
3
+ class RailsBestPracticesBluffGrapher < RailsBestPracticesGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Rails Best Practices: design problems';
8
+ g.data('rails_best_practices', [#{@rails_best_practices_count.join(',')}]);
9
+ g.labels = #{@labels.to_json};
10
+ g.draw();
11
+ EOS
12
+ File.open(File.join(MetricFu.output_directory, 'rails_best_practices.js'), 'w') {|f| f << content }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ MetricFu.metrics_require { 'rails_best_practices/rails_best_practices_grapher' }
2
+ module MetricFu
3
+ class RailsBestPracticesGchartGrapher < RailsBestPracticesGrapher
4
+ def graph!
5
+ determine_y_axis_scale(@rails_best_practices_count)
6
+ url = Gchart.line(
7
+ :size => GCHART_GRAPH_SIZE,
8
+ :title => URI.escape("Rails Best Practices: design problems"),
9
+ :data => self.rails_best_practices_count,
10
+ :bar_colors => COLORS[0..1],
11
+ :legend => ['Problems'],
12
+ :custom => "chdlp=t",
13
+ :max_value => @max_value,
14
+ :axis_with_labels => 'x,y',
15
+ :axis_labels => [@labels.values, @yaxis],
16
+ :format => 'file',
17
+ :filename => File.join(MetricFu.output_directory, 'rails_best_practices.png')
18
+ )
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class RailsBestPracticesGrapher < Grapher
3
4
  attr_accessor :rails_best_practices_count, :labels
@@ -0,0 +1,15 @@
1
+ MetricFu.metrics_require { 'rcov/rcov_grapher' }
2
+ module MetricFu
3
+ class RcovBluffGrapher < RcovGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Rcov: code coverage';
8
+ g.data('rcov', [#{@rcov_percent.join(',')}]);
9
+ g.labels = #{@labels.to_json};
10
+ g.draw();
11
+ EOS
12
+ File.open(File.join(MetricFu.output_directory, 'rcov.js'), 'w') {|f| f << content }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ MetricFu.metrics_require { 'rcov/rcov_grapher' }
2
+ module MetricFu
3
+ class RcovGchartGrapher < RcovGrapher
4
+ def graph!
5
+ url = Gchart.line(
6
+ :size => GCHART_GRAPH_SIZE,
7
+ :title => URI.escape("Rcov: code coverage"),
8
+ :data => self.rcov_percent,
9
+ :max_value => 101,
10
+ :axis_with_labels => 'x,y',
11
+ :axis_labels => [self.labels.values, [0,20,40,60,80,100]],
12
+ :format => 'file',
13
+ :filename => File.join(MetricFu.output_directory, 'rcov.png')
14
+ )
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class RcovGrapher < Grapher
3
4
  attr_accessor :rcov_percent, :labels
@@ -1,4 +1,4 @@
1
- class RcovHotspot
1
+ class RcovHotspot < MetricFu::Hotspot
2
2
  include MetricFu::HotspotScoringStrategies
3
3
 
4
4
  COLUMNS = %w{percentage_uncovered}
@@ -24,20 +24,32 @@ class RcovHotspot
24
24
  end
25
25
 
26
26
  def generate_records(data, table)
27
- return if data==nil
28
- data.each do |file_name, info|
29
- next if (file_name == :global_percent_run) || (info[:methods].nil?)
30
- info[:methods].each do |method_name, percentage_uncovered|
31
- location = MetricFu::Location.for(method_name)
32
- table << {
33
- "metric" => :rcov,
34
- 'file_path' => file_name,
35
- 'class_name' => location.class_name,
36
- "method_name" => location.method_name,
37
- "percentage_uncovered" => percentage_uncovered
38
- }
39
- end
40
- end
41
- end
27
+ return if data==nil
28
+ data.each do |file_name, info|
29
+ next if (file_name == :global_percent_run) || (info[:methods].nil?)
30
+ info[:methods].each do |method_name, percentage_uncovered|
31
+ location = MetricFu::Location.for(method_name)
32
+ table << {
33
+ "metric" => :rcov,
34
+ 'file_path' => file_name,
35
+ 'class_name' => location.class_name,
36
+ "method_name" => location.method_name,
37
+ "percentage_uncovered" => percentage_uncovered
38
+ }
39
+ end
40
+ end
41
+ end
42
+
43
+ def present_group(group)
44
+ occurences = group.size
45
+ average_code_uncoverage = get_mean(group.column("percentage_uncovered"))
46
+ "#{"average " if occurences > 1}uncovered code is %.1f%" % average_code_uncoverage
47
+ end
48
+
49
+ # TODO determine if no-op in pre-factored
50
+ # code was intentional
51
+ def present_group_details(group)
52
+
53
+ end
42
54
 
43
55
  end
@@ -0,0 +1,20 @@
1
+ MetricFu.metrics_require { 'reek/reek_grapher' }
2
+ module MetricFu
3
+ class ReekBluffGrapher < ReekGrapher
4
+ def graph!
5
+ legend = @reek_count.keys.sort
6
+ data = ""
7
+ legend.each do |name|
8
+ data += "g.data('#{name}', [#{@reek_count[name].join(',')}])\n"
9
+ end
10
+ content = <<-EOS
11
+ #{BLUFF_DEFAULT_OPTIONS}
12
+ g.title = 'Reek: code smells';
13
+ #{data}
14
+ g.labels = #{@labels.to_json};
15
+ g.draw();
16
+ EOS
17
+ File.open(File.join(MetricFu.output_directory, 'reek.js'), 'w') {|f| f << content }
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ MetricFu.metrics_require { 'reek/reek_grapher' }
2
+ module MetricFu
3
+ class ReekGchartGrapher < ReekGrapher
4
+ def graph!
5
+ determine_y_axis_scale(@reek_count.values.flatten.uniq)
6
+ values = []
7
+ legend = @reek_count.keys.sort
8
+ legend.collect {|k| values << @reek_count[k]}
9
+
10
+ url = Gchart.line(
11
+ :size => GCHART_GRAPH_SIZE,
12
+ :title => URI.escape("Reek: code smells"),
13
+ :data => values,
14
+ :stacked => false,
15
+ :bar_colors => COLORS,
16
+ :legend => legend,
17
+ :custom => "chdlp=t",
18
+ :max_value => @max_value,
19
+ :axis_with_labels => 'x,y',
20
+ :axis_labels => [@labels.values, @yaxis],
21
+ :format => 'file',
22
+ :filename => File.join(MetricFu.output_directory, 'reek.png'))
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class ReekGrapher < Grapher
3
4
  attr_accessor :reek_count, :labels
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- class ReekHotspot
3
+ class ReekHotspot < MetricFu::Hotspot
4
4
  include MetricFu::HotspotScoringStrategies
5
5
 
6
6
  REEK_ISSUE_INFO = {
@@ -127,6 +127,21 @@ class ReekHotspot
127
127
  ["Large Class", "Long Method", "Long Parameter List"].include?(type)
128
128
  end
129
129
 
130
+ def present_group(group)
131
+ occurences = group.size
132
+ "found #{occurences} code smells"
133
+ end
134
+ def present_group_details(group)
135
+ occurences = group.size
136
+ message = "found #{occurences} code smells<br/>"
137
+ group.each do |item|
138
+ type = item.data["reek__type_name"]
139
+ reek_message = item.data["reek__message"]
140
+ message << "* #{type}: #{reek_message}<br/>"
141
+ end
142
+ message
143
+ end
144
+
130
145
  private
131
146
 
132
147
  def comparable_message(type_name, message)
@@ -0,0 +1,15 @@
1
+ MetricFu.metrics_require { 'roodi/roodi_grapher' }
2
+ module MetricFu
3
+ class RoodiBluffGrapher < RoodiGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Roodi: design problems';
8
+ g.data('roodi', [#{@roodi_count.join(',')}]);
9
+ g.labels = #{@labels.to_json};
10
+ g.draw();
11
+ EOS
12
+ File.open(File.join(MetricFu.output_directory, 'roodi.js'), 'w') {|f| f << content }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ MetricFu.metrics_require { 'roodi/roodi_grapher' }
2
+ module MetricFu
3
+ class RoodiGchartGrapher < RoodiGrapher
4
+ def graph!
5
+ determine_y_axis_scale(@roodi_count)
6
+ url = Gchart.line(
7
+ :size => GCHART_GRAPH_SIZE,
8
+ :title => URI.escape("Roodi: potential design problems"),
9
+ :data => @roodi_count,
10
+ :max_value => @max_value,
11
+ :axis_with_labels => 'x,y',
12
+ :axis_labels => [@labels.values, @yaxis],
13
+ :format => 'file',
14
+ :filename => File.join(MetricFu.output_directory, 'roodi.png'))
15
+ end
16
+ end
17
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class RoodiGrapher < Grapher
3
4
  attr_accessor :roodi_count, :labels
@@ -1,4 +1,4 @@
1
- class RoodiHotspot
1
+ class RoodiHotspot < MetricFu::Hotspot
2
2
  include MetricFu::HotspotScoringStrategies
3
3
 
4
4
  COLUMNS = %w{problems}
@@ -34,4 +34,19 @@ class RoodiHotspot
34
34
  end
35
35
  end
36
36
 
37
+ def present_group(group)
38
+ occurences = group.size
39
+ "found #{occurences} design problems"
40
+ end
41
+
42
+ def present_group_details(group)
43
+ occurences = group.size
44
+ message = "found #{occurences} design problems<br/>"
45
+ group.each do |item|
46
+ problem = item.data["problems"]
47
+ message << "* #{problem}<br/>"
48
+ end
49
+ message
50
+ end
51
+
37
52
  end
@@ -1,4 +1,4 @@
1
- class SaikuroHotspot
1
+ class SaikuroHotspot < MetricFu::Hotspot
2
2
  include MetricFu::HotspotScoringStrategies
3
3
 
4
4
  COLUMNS = %w{lines complexity}
@@ -45,4 +45,16 @@ class SaikuroHotspot
45
45
  end
46
46
  end
47
47
 
48
+ def present_group(group)
49
+ occurences = group.size
50
+ complexity = get_mean(group.column("complexity"))
51
+ "#{"average " if occurences > 1}complexity is %.1f" % complexity
52
+ end
53
+
54
+ def present_group_details(group)
55
+ occurences = group.size
56
+ complexity = get_mean(group.column("complexity"))
57
+ "#{"average " if occurences > 1}complexity is %.1f" % complexity
58
+ end
59
+
48
60
  end
@@ -0,0 +1,16 @@
1
+ MetricFu.metrics_require { 'stats/stats_grapher' }
2
+ module MetricFu
3
+ class StatsBluffGrapher < StatsGrapher
4
+ def graph!
5
+ content = <<-EOS
6
+ #{BLUFF_DEFAULT_OPTIONS}
7
+ g.title = 'Stats: LOC & LOT';
8
+ g.data('LOC', [#{@loc_counts.join(',')}]);
9
+ g.data('LOT', [#{@lot_counts.join(',')}])
10
+ g.labels = #{@labels.to_json};
11
+ g.draw();
12
+ EOS
13
+ File.open(File.join(MetricFu.output_directory, 'stats.js'), 'w') {|f| f << content }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ MetricFu.metrics_require { 'stats/stats_grapher' }
2
+ module MetricFu
3
+ class StatsGchartGrapher < StatsGrapher
4
+ def graph!
5
+ determine_y_axis_scale(@loc_counts + @lot_counts)
6
+ url = Gchart.line(
7
+ :size => GCHART_GRAPH_SIZE,
8
+ :title => URI.escape("Stats: LOC & LOT"),
9
+ :data => [@loc_counts, @lot_counts],
10
+ :bar_colors => COLORS[0..1],
11
+ :legend => ['Lines of code', 'Lines of test'],
12
+ :custom => "chdlp=t",
13
+ :max_value => @max_value,
14
+ :axis_with_labels => 'x,y',
15
+ :axis_labels => [@labels.values, @yaxis],
16
+ :format => 'file',
17
+ :filename => File.join(MetricFu.output_directory, 'stats.png'))
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,4 @@
1
+ MetricFu.reporting_require { 'graphs/grapher' }
1
2
  module MetricFu
2
3
  class StatsGrapher < Grapher
3
4
  attr_accessor :loc_counts, :lot_counts, :labels
@@ -1,4 +1,4 @@
1
- class StatsHotspot
1
+ class StatsHotspot < MetricFu::Hotspot
2
2
 
3
3
  COLUMNS = %w{stat_name stat_value}
4
4
 
@@ -1,5 +1,3 @@
1
- require 'active_support'
2
-
3
1
  module MetricFu
4
2
  class Grapher
5
3
  BLUFF_GRAPH_SIZE = "1000x600"
@@ -12,116 +10,4 @@ module MetricFu
12
10
  g.marker_font_size = "10px"
13
11
  EOS
14
12
  end
15
-
16
- class FlayBluffGrapher < FlayGrapher
17
- def graph!
18
- content = <<-EOS
19
- #{BLUFF_DEFAULT_OPTIONS}
20
- g.title = 'Flay: duplication';
21
- g.data('flay', [#{@flay_score.join(',')}]);
22
- g.labels = #{@labels.to_json};
23
- g.draw();
24
- EOS
25
- File.open(File.join(MetricFu.output_directory, 'flay.js'), 'w') {|f| f << content }
26
- end
27
- end
28
-
29
- class FlogBluffGrapher < FlogGrapher
30
- def graph!
31
- content = <<-EOS
32
- #{BLUFF_DEFAULT_OPTIONS}
33
- g.title = 'Flog: code complexity';
34
- g.data('average', [#{@flog_average.join(',')}]);
35
- g.data('top 5% average', [#{@top_five_percent_average.join(',')}])
36
- g.labels = #{@labels.to_json};
37
- g.draw();
38
- EOS
39
- File.open(File.join(MetricFu.output_directory, 'flog.js'), 'w') {|f| f << content }
40
- end
41
- end
42
-
43
- class RcovBluffGrapher < RcovGrapher
44
- def graph!
45
- content = <<-EOS
46
- #{BLUFF_DEFAULT_OPTIONS}
47
- g.title = 'Rcov: code coverage';
48
- g.data('rcov', [#{@rcov_percent.join(',')}]);
49
- g.labels = #{@labels.to_json};
50
- g.draw();
51
- EOS
52
- File.open(File.join(MetricFu.output_directory, 'rcov.js'), 'w') {|f| f << content }
53
- end
54
- end
55
-
56
- class ReekBluffGrapher < ReekGrapher
57
- def graph!
58
- legend = @reek_count.keys.sort
59
- data = ""
60
- legend.each do |name|
61
- data += "g.data('#{name}', [#{@reek_count[name].join(',')}])\n"
62
- end
63
- content = <<-EOS
64
- #{BLUFF_DEFAULT_OPTIONS}
65
- g.title = 'Reek: code smells';
66
- #{data}
67
- g.labels = #{@labels.to_json};
68
- g.draw();
69
- EOS
70
- File.open(File.join(MetricFu.output_directory, 'reek.js'), 'w') {|f| f << content }
71
- end
72
- end
73
-
74
- class RoodiBluffGrapher < RoodiGrapher
75
- def graph!
76
- content = <<-EOS
77
- #{BLUFF_DEFAULT_OPTIONS}
78
- g.title = 'Roodi: design problems';
79
- g.data('roodi', [#{@roodi_count.join(',')}]);
80
- g.labels = #{@labels.to_json};
81
- g.draw();
82
- EOS
83
- File.open(File.join(MetricFu.output_directory, 'roodi.js'), 'w') {|f| f << content }
84
- end
85
- end
86
-
87
- class StatsBluffGrapher < StatsGrapher
88
- def graph!
89
- content = <<-EOS
90
- #{BLUFF_DEFAULT_OPTIONS}
91
- g.title = 'Stats: LOC & LOT';
92
- g.data('LOC', [#{@loc_counts.join(',')}]);
93
- g.data('LOT', [#{@lot_counts.join(',')}])
94
- g.labels = #{@labels.to_json};
95
- g.draw();
96
- EOS
97
- File.open(File.join(MetricFu.output_directory, 'stats.js'), 'w') {|f| f << content }
98
- end
99
- end
100
-
101
- class RailsBestPracticesBluffGrapher < RailsBestPracticesGrapher
102
- def graph!
103
- content = <<-EOS
104
- #{BLUFF_DEFAULT_OPTIONS}
105
- g.title = 'Rails Best Practices: design problems';
106
- g.data('rails_best_practices', [#{@rails_best_practices_count.join(',')}]);
107
- g.labels = #{@labels.to_json};
108
- g.draw();
109
- EOS
110
- File.open(File.join(MetricFu.output_directory, 'rails_best_practices.js'), 'w') {|f| f << content }
111
- end
112
- end
113
-
114
- class CaneBluffGrapher < CaneGrapher
115
- def graph!
116
- content = <<-EOS
117
- #{BLUFF_DEFAULT_OPTIONS}
118
- g.title = 'Cane: code quality threshold violations';
119
- g.data('cane', [#{@cane_violations.join(',')}]);
120
- g.labels = #{@labels.to_json};
121
- g.draw();
122
- EOS
123
- File.open(File.join(MetricFu.output_directory, 'cane.js'), 'w') {|f| f << content }
124
- end
125
- end
126
-
127
13
  end