metric_fu 3.0.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.metrics +1 -0
- data/.travis.yml +1 -1
- data/HISTORY.md +6 -1
- data/README.md +6 -3
- data/bin/mf-cane +9 -0
- data/lib/metric_fu/metrics/cane/cane.rb +72 -0
- data/lib/metric_fu/metrics/cane/cane_grapher.rb +19 -0
- data/lib/metric_fu/metrics/cane/init.rb +12 -0
- data/lib/metric_fu/metrics/cane/template_awesome/cane.html.erb +78 -0
- data/lib/metric_fu/metrics/cane/template_standard/cane.html.erb +69 -0
- data/lib/metric_fu/metrics/cane/violations.rb +30 -0
- data/lib/metric_fu/metrics/rails_best_practices/init.rb +1 -3
- data/lib/metric_fu/reporting/graphs/engines/bluff.rb +14 -0
- data/lib/metric_fu/reporting/templates/awesome/index.html.erb +3 -0
- data/lib/metric_fu/reporting/templates/standard/index.html.erb +3 -0
- data/lib/metric_fu/version.rb +1 -1
- data/lib/metric_fu_requires.rb +6 -0
- data/metric_fu.gemspec +3 -1
- data/spec/cli/helper_spec.rb +11 -0
- data/spec/metric_fu/configuration_spec.rb +20 -17
- data/spec/metric_fu/metrics/cane/cane_spec.rb +133 -0
- metadata +45 -3
data/.gitignore
CHANGED
data/.metrics
CHANGED
@@ -8,6 +8,7 @@ mf_debug "Metrics config loaded"
|
|
8
8
|
# config.add_metric(:rcov)
|
9
9
|
# config.add_graph(:rcov)
|
10
10
|
# config.configure_metric(:rcov, {:external => coverage_file})
|
11
|
+
# config.cane = {:abc_max => 15, :line_length => 80, :no_doc => 'y'}
|
11
12
|
# end
|
12
13
|
# or
|
13
14
|
# MetricFu::Configuration.run do |config|
|
data/.travis.yml
CHANGED
data/HISTORY.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
=== master ===
|
2
2
|
|
3
|
+
== MetricFu 3.0.2 / 2013-03-02
|
4
|
+
|
5
|
+
* Adding cane metrics (Sathish, pull request #49)
|
6
|
+
* Not yet included in hotspots
|
7
|
+
|
3
8
|
== MetricFu 3.0.1 / 2013-03-01
|
4
|
-
|
9
|
+
|
5
10
|
* Fixed typo in Flay generator (Sathish, pull request #47)
|
6
11
|
|
7
12
|
=== MetricFu 3.0.0 / 2013-02-07
|
data/README.md
CHANGED
@@ -16,14 +16,17 @@ See `metric_fu --help` for more options
|
|
16
16
|
|
17
17
|
## Compatibility
|
18
18
|
|
19
|
-
It is currently testing on MRI 1.
|
19
|
+
* It is currently testing on MRI 1.9.2, 1.9.3 and 2.0.0. Ruby 1.8 is no longer supported due to the cane library.
|
20
|
+
|
21
|
+
* For 1.8.7 support, see version 3.0.0 for partial support, or 2.1.3.7.18.1 (where [Semantic Versioning](http://semver.org/) goes to die)
|
20
22
|
|
21
23
|
* The `japgolly-Saikuro` fork and `metric_fu-roodi` fork are a part of an attempt to get metric_fu working in a modern Ruby environment, specifically compatibility with Ruby 1.9 and Bundler.
|
22
|
-
* rails_best_practices is disabled in ruby 1.8
|
23
24
|
* metric_fu no longer runs rcov itself. You may still use rcov metrics as documented below
|
24
25
|
|
25
26
|
## Documentation
|
26
27
|
|
28
|
+
* Cane code quality threshold checking is not included in the hotspots report
|
29
|
+
|
27
30
|
### Configuration
|
28
31
|
|
29
32
|
see the .metrics file
|
@@ -49,7 +52,7 @@ To generate the same metrics metric_fu has been generating run from the root of
|
|
49
52
|
|
50
53
|
RAILS_ENV=test rcov $(ruby -e "puts Dir['{spec,test}/**/*_{spec,test}.rb'].join(' ')") --sort coverage --no-html --text-coverage --no-color --profile --exclude-only '.*' --include-file "\Aapp,\Alib" -Ispec >> coverage/rcov/rcov.txt
|
51
54
|
|
52
|
-
#### Simplecov metrics with Ruby 1.9
|
55
|
+
#### Simplecov metrics with Ruby 1.9 and 2.0
|
53
56
|
|
54
57
|
Add to your Gemfile or otherwise install
|
55
58
|
|
data/bin/mf-cane
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'cane'
|
2
|
+
|
3
|
+
module MetricFu
|
4
|
+
class Cane < Generator
|
5
|
+
attr_reader :violations, :total_violations
|
6
|
+
|
7
|
+
def emit
|
8
|
+
command = %Q{mf-cane#{abc_max_param}#{style_measure_param}#{no_doc_param}}
|
9
|
+
mf_debug = "** #{command}"
|
10
|
+
@output = `#{command}`
|
11
|
+
end
|
12
|
+
|
13
|
+
def analyze
|
14
|
+
@violations = violations_by_category
|
15
|
+
extract_total_violations
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_h
|
19
|
+
{:cane => {:total_violations => @total_violations, :violations => @violations}}
|
20
|
+
end
|
21
|
+
private
|
22
|
+
|
23
|
+
def abc_max_param
|
24
|
+
MetricFu.cane[:abc_max] ? " --abc-max #{MetricFu.cane[:abc_max]}" : ""
|
25
|
+
end
|
26
|
+
|
27
|
+
def style_measure_param
|
28
|
+
MetricFu.cane[:line_length] ? " --style-measure #{MetricFu.cane[:line_length]}" : ""
|
29
|
+
end
|
30
|
+
|
31
|
+
def no_doc_param
|
32
|
+
MetricFu.cane[:no_doc] == 'y' ? " --no-doc" : ""
|
33
|
+
end
|
34
|
+
|
35
|
+
def violations_by_category
|
36
|
+
violations_output = @output.scan(/(.*?)\n\n(.*?)\n\n/m)
|
37
|
+
violations_output.each_with_object({}) do |(category_desc, violation_list), violations|
|
38
|
+
category = category_from(category_desc)
|
39
|
+
violations[category] = violations_for(category, violation_list)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def category_from(description)
|
44
|
+
category_descriptions = {
|
45
|
+
:abc_complexity => /ABC complexity/,
|
46
|
+
:line_style => /style requirements/,
|
47
|
+
:comment => /comment/
|
48
|
+
}
|
49
|
+
category_descriptions.find {|k,v| description =~ v}[0]
|
50
|
+
end
|
51
|
+
|
52
|
+
def violations_for(category, violation_list)
|
53
|
+
violation_type_for(category).parse(violation_list)
|
54
|
+
end
|
55
|
+
|
56
|
+
def violation_type_for(category)
|
57
|
+
case category
|
58
|
+
when :abc_complexity
|
59
|
+
CaneViolations::AbcComplexity
|
60
|
+
when :line_style
|
61
|
+
CaneViolations::LineStyle
|
62
|
+
when :comment
|
63
|
+
CaneViolations::Comment
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def extract_total_violations
|
68
|
+
total = @output.match(/Total Violations: (\d+)/)[1]
|
69
|
+
@total_violations = total.to_i if total
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MetricFu
|
2
|
+
class CaneGrapher < Grapher
|
3
|
+
attr_accessor :cane_violations, :labels
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@cane_violations = []
|
8
|
+
@labels = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_metrics(metrics, date)
|
12
|
+
if metrics && metrics[:cane]
|
13
|
+
@cane_violations.push(metrics[:cane][:total_violations].to_i)
|
14
|
+
@labels.update( { @labels.size => date })
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
MetricFu::Configuration.run do |config|
|
2
|
+
config.add_metric(:cane)
|
3
|
+
config.add_graph(:cane)
|
4
|
+
config.configure_metric(:cane, {
|
5
|
+
:dirs_to_cane => MetricFu.code_dirs,
|
6
|
+
:abc_max => 15,
|
7
|
+
:line_length => 80,
|
8
|
+
:no_doc => 'n',
|
9
|
+
:filetypes => ['rb']
|
10
|
+
})
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,78 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Cane Results</title>
|
4
|
+
<style>
|
5
|
+
<%= inline_css("css/default.css") %>
|
6
|
+
</style>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<h1>Cane Results</h1>
|
11
|
+
<a href="index.html">back to menu</a>
|
12
|
+
<h2>Total Violations: <%= @cane[:total_violations] %></h2>
|
13
|
+
<p><a href='https://github.com/square/cane'>Cane</a> reports code quality threshold violations.</p>
|
14
|
+
|
15
|
+
<% graph_name = 'cane' %>
|
16
|
+
<% if MetricFu.configuration.graph_engine == :gchart %>
|
17
|
+
<img src="<%= graph_name %>.png?<%= Time.now.to_i %>" />
|
18
|
+
<% else %>
|
19
|
+
<canvas id="graph"></canvas>
|
20
|
+
<script language="javascript" src="<%= graph_name %>.js?<%= Time.now.to_i %>" type="text/javascript"></script>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% if @cane[:violations][:abc_complexity] && @cane[:violations][:abc_complexity].size > 0 %>
|
24
|
+
<h3>Methods exceeding allowed Abc complexity (<%= @cane[:violations][:abc_complexity].size %>)</h3>
|
25
|
+
<table>
|
26
|
+
<tr>
|
27
|
+
<th>File</th>
|
28
|
+
<th>Method</th>
|
29
|
+
<th>Complexity</th>
|
30
|
+
</tr>
|
31
|
+
<% count = 0 %>
|
32
|
+
<% @cane[:violations][:abc_complexity].each do |violation| %>
|
33
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
34
|
+
<td><%=violation[:file]%></td>
|
35
|
+
<td><%=violation[:method]%></td>
|
36
|
+
<td><%=violation[:complexity]%></td>
|
37
|
+
</tr>
|
38
|
+
<% count += 1 %>
|
39
|
+
<% end %>
|
40
|
+
</table>
|
41
|
+
<% end %>
|
42
|
+
<% if @cane[:violations][:line_style] && @cane[:violations][:line_style].size > 0 %>
|
43
|
+
<h3>Lines violating style requirements (<%= @cane[:violations][:line_style].size %>)</h3>
|
44
|
+
<table>
|
45
|
+
<tr>
|
46
|
+
<th>File</th>
|
47
|
+
<th>Description</th>
|
48
|
+
</tr>
|
49
|
+
<% count = 0 %>
|
50
|
+
<% @cane[:violations][:line_style].each do |violation| %>
|
51
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
52
|
+
<td><%=violation[:line]%></td>
|
53
|
+
<td><%=violation[:description]%></td>
|
54
|
+
</tr>
|
55
|
+
<% count += 1 %>
|
56
|
+
<% end %>
|
57
|
+
</table>
|
58
|
+
<% end %>
|
59
|
+
<% if @cane[:violations][:comment] && @cane[:violations][:comment].size > 0 %>
|
60
|
+
<h3>Class definitions requiring comments (<%= @cane[:violations][:comment].size %>)</h3>
|
61
|
+
<table>
|
62
|
+
<tr>
|
63
|
+
<th>File</th>
|
64
|
+
<th>Class</th>
|
65
|
+
</tr>
|
66
|
+
<% count = 0 %>
|
67
|
+
<% @cane[:violations][:comment].each do |violation| %>
|
68
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
69
|
+
<td><%=violation[:line]%></td>
|
70
|
+
<td><%=violation[:class_name]%></td>
|
71
|
+
</tr>
|
72
|
+
<% count += 1 %>
|
73
|
+
<% end %>
|
74
|
+
</table>
|
75
|
+
<% end %>
|
76
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
77
|
+
</body>
|
78
|
+
</html>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Cane Results</title>
|
4
|
+
<style>
|
5
|
+
<%= inline_css("default.css") %>
|
6
|
+
</style>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<h1>Cane Results</h1>
|
11
|
+
<a href="index.html">back to menu</a>
|
12
|
+
<h2>Total Violations: <%= @cane[:total_violations] %></h2>
|
13
|
+
<p><a href='https://github.com/square/cane'>Cane</a> reports code quality threshold violations.</p>
|
14
|
+
<% if @cane[:violations][:abc_complexity] && @cane[:violations][:abc_complexity].size > 0 %>
|
15
|
+
<h3>Methods exceeding allowed Abc complexity (<%= @cane[:violations][:abc_complexity].size %>)</h3>
|
16
|
+
<table>
|
17
|
+
<tr>
|
18
|
+
<th>File</th>
|
19
|
+
<th>Method</th>
|
20
|
+
<th>Complexity</th>
|
21
|
+
</tr>
|
22
|
+
<% count = 0 %>
|
23
|
+
<% @cane[:violations][:abc_complexity].each do |violation| %>
|
24
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
25
|
+
<td><%=violation[:file]%></td>
|
26
|
+
<td><%=violation[:method]%></td>
|
27
|
+
<td><%=violation[:complexity]%></td>
|
28
|
+
</tr>
|
29
|
+
<% count += 1 %>
|
30
|
+
<% end %>
|
31
|
+
</table>
|
32
|
+
<% end %>
|
33
|
+
<% if @cane[:violations][:line_style] && @cane[:violations][:line_style].size > 0 %>
|
34
|
+
<h3>Lines violating style requirements (<%= @cane[:violations][:line_style].size %>)</h3>
|
35
|
+
<table>
|
36
|
+
<tr>
|
37
|
+
<th>File</th>
|
38
|
+
<th>Description</th>
|
39
|
+
</tr>
|
40
|
+
<% count = 0 %>
|
41
|
+
<% @cane[:violations][:line_style].each do |violation| %>
|
42
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
43
|
+
<td><%=violation[:line]%></td>
|
44
|
+
<td><%=violation[:description]%></td>
|
45
|
+
</tr>
|
46
|
+
<% count += 1 %>
|
47
|
+
<% end %>
|
48
|
+
</table>
|
49
|
+
<% end %>
|
50
|
+
<% if @cane[:violations][:comment] && @cane[:violations][:comment].size > 0 %>
|
51
|
+
<h3>Class definitions requiring comments (<%= @cane[:violations][:comment].size %>)</h3>
|
52
|
+
<table>
|
53
|
+
<tr>
|
54
|
+
<th>File</th>
|
55
|
+
<th>Description</th>
|
56
|
+
</tr>
|
57
|
+
<% count = 0 %>
|
58
|
+
<% @cane[:violations][:comment].each do |violation| %>
|
59
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
60
|
+
<td><%=violation[:line]%></td>
|
61
|
+
<td><%=violation[:class_name]%></td>
|
62
|
+
</tr>
|
63
|
+
<% count += 1 %>
|
64
|
+
<% end %>
|
65
|
+
</table>
|
66
|
+
<% end %>
|
67
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
68
|
+
</body>
|
69
|
+
</html>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MetricFu
|
2
|
+
module CaneViolations
|
3
|
+
class AbcComplexity
|
4
|
+
def self.parse(violation_list)
|
5
|
+
violation_list.split(/\n/).map do |violation|
|
6
|
+
file, method, complexity = violation.split
|
7
|
+
{:file => file, :method => method, :complexity => complexity}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class LineStyle
|
13
|
+
def self.parse(violation_list)
|
14
|
+
violation_list.split(/\n/).map do |violation|
|
15
|
+
line, description = violation.split(/\s{2,}/).reject{|x|x.strip==''}
|
16
|
+
{:line => line, :description => description}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Comment
|
22
|
+
def self.parse(violation_list)
|
23
|
+
violation_list.split(/\n/).map do |violation|
|
24
|
+
line, class_name = violation.split
|
25
|
+
{:line => line, :class_name => class_name}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
MetricFu::Configuration.run do |config|
|
2
|
-
if
|
3
|
-
config.mf_debug "rails_best_practices is not compatible with #{RUBY_VERSION}"
|
4
|
-
elsif config.rails?
|
2
|
+
if config.rails?
|
5
3
|
config.add_metric(:rails_best_practices)
|
6
4
|
config.add_graph(:rails_best_practices)
|
7
5
|
config.configure_metric(:rails_best_practices, {})
|
@@ -110,4 +110,18 @@ module MetricFu
|
|
110
110
|
File.open(File.join(MetricFu.output_directory, 'rails_best_practices.js'), 'w') {|f| f << content }
|
111
111
|
end
|
112
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
|
+
|
113
127
|
end
|
@@ -21,6 +21,9 @@
|
|
21
21
|
<% if @saikuro %>
|
22
22
|
<li class='even failure'><a href="saikuro.html">Saikuro</a></li>
|
23
23
|
<% end %>
|
24
|
+
<% if @cane %>
|
25
|
+
<li class='even failure'><a href="cane.html">Cane</a></li>
|
26
|
+
<% end %>
|
24
27
|
<% if @stats %>
|
25
28
|
<li class='even failure'><a href="stats.html">Stats</a></li>
|
26
29
|
<% end %>
|
data/lib/metric_fu/version.rb
CHANGED
data/lib/metric_fu_requires.rb
CHANGED
data/metric_fu.gemspec
CHANGED
@@ -29,10 +29,12 @@ Gem::Specification.new do |s|
|
|
29
29
|
"flog" => ["= #{MetricFu::MetricVersion.flog}"],
|
30
30
|
"reek" => ["= #{MetricFu::MetricVersion.reek}"],
|
31
31
|
"churn" => ["= #{MetricFu::MetricVersion.churn}"],
|
32
|
-
|
32
|
+
"cane" => ["= #{MetricFu::MetricVersion.cane}"],
|
33
|
+
# specifying dependencies for flay, reek, churn, flog, and cane
|
33
34
|
"ruby_parser" => ["~> 3.0", ">= #{MetricFu::MetricVersion.ruby_parser}"],
|
34
35
|
"sexp_processor" => ["#{MetricFu::MetricVersion.sexp_processor}"],
|
35
36
|
"ruby2ruby" => ["= #{MetricFu::MetricVersion.ruby2ruby}"],
|
37
|
+
"parallel" => ["= #{MetricFu::MetricVersion.parallel}"],
|
36
38
|
"activesupport" => [">= 2.0.0"], # ok
|
37
39
|
"coderay" => [],
|
38
40
|
"fattr" => ["= 2.2.1"],
|
data/spec/cli/helper_spec.rb
CHANGED
@@ -39,6 +39,10 @@ describe MetricFu::Cli::Helper do
|
|
39
39
|
defaults[:saikuro].should be_true
|
40
40
|
end
|
41
41
|
|
42
|
+
it "enables Cane" do
|
43
|
+
defaults[:cane].should be_true
|
44
|
+
end
|
45
|
+
|
42
46
|
it "enables RCov" do
|
43
47
|
defaults[:rcov].should be_true
|
44
48
|
end
|
@@ -142,6 +146,13 @@ describe MetricFu::Cli::Helper do
|
|
142
146
|
helper.process_options(["--roodi"])[:roodi].should be_true
|
143
147
|
end
|
144
148
|
|
149
|
+
it "turns cane off" do
|
150
|
+
helper.process_options(["--no-cane"])[:cane].should be_false
|
151
|
+
end
|
152
|
+
|
153
|
+
it "turns cane on" do
|
154
|
+
helper.process_options(["--cane"])[:cane].should be_true
|
155
|
+
end
|
145
156
|
end
|
146
157
|
|
147
158
|
end
|
@@ -126,6 +126,17 @@ describe MetricFu::Configuration do
|
|
126
126
|
should == { :start_date => %q("1 year ago"), :minimum_churn_count => 10}
|
127
127
|
end
|
128
128
|
|
129
|
+
it 'should set @cane to ' +
|
130
|
+
%q(:dirs_to_cane => @code_dirs, :abc_max => 15, :line_length => 80, :no_doc => 'n') do
|
131
|
+
load_metric 'cane'
|
132
|
+
@config.send(:cane).
|
133
|
+
should == {
|
134
|
+
:dirs_to_cane => MetricFu.code_dirs,
|
135
|
+
:filetypes => ["rb"],
|
136
|
+
:abc_max => 15,
|
137
|
+
:line_length => 80,
|
138
|
+
:no_doc => "n"}
|
139
|
+
end
|
129
140
|
|
130
141
|
it 'should set @rcov to ' +
|
131
142
|
%q(:test_files => Dir['{spec,test}/**/*_{spec,test}.rb'],
|
@@ -194,14 +205,8 @@ describe MetricFu::Configuration do
|
|
194
205
|
end
|
195
206
|
|
196
207
|
describe '#set_graphs ' do
|
197
|
-
|
198
|
-
|
199
|
-
@config.graphs.should_not include(:rails_best_practices)
|
200
|
-
end
|
201
|
-
else
|
202
|
-
it 'should set the graphs to include rails_best_practices' do
|
203
|
-
@config.graphs.should include(:rails_best_practices)
|
204
|
-
end
|
208
|
+
it 'should set the graphs to include rails_best_practices' do
|
209
|
+
@config.graphs.should include(:rails_best_practices)
|
205
210
|
end
|
206
211
|
end
|
207
212
|
|
@@ -217,12 +222,10 @@ describe MetricFu::Configuration do
|
|
217
222
|
should == {}
|
218
223
|
end
|
219
224
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
should == {}
|
225
|
-
end
|
225
|
+
it 'should set @rails_best_practices to {}' do
|
226
|
+
load_metric 'rails_best_practices'
|
227
|
+
@config.send(:rails_best_practices).
|
228
|
+
should == {}
|
226
229
|
end
|
227
230
|
end
|
228
231
|
|
@@ -236,7 +239,7 @@ describe MetricFu::Configuration do
|
|
236
239
|
end
|
237
240
|
|
238
241
|
it 'should set the available metrics' do
|
239
|
-
@config.metrics.should =~ [:churn, :flog, :flay, :reek, :roodi, :rcov, :hotspots, :saikuro]
|
242
|
+
@config.metrics.should =~ [:churn, :flog, :flay, :reek, :roodi, :rcov, :hotspots, :saikuro, :cane]
|
240
243
|
end
|
241
244
|
|
242
245
|
it 'should set the @code_dirs instance var to ["lib"]' do
|
@@ -268,13 +271,13 @@ describe MetricFu::Configuration do
|
|
268
271
|
|
269
272
|
before(:each) { get_new_config }
|
270
273
|
|
271
|
-
[:churn, :flog, :flay, :reek, :roodi, :rcov, :hotspots, :saikuro].each do |metric|
|
274
|
+
[:churn, :flog, :flay, :reek, :roodi, :rcov, :hotspots, :saikuro, :cane].each do |metric|
|
272
275
|
it "should add a #{metric} class method to the MetricFu module " do
|
273
276
|
MetricFu.should respond_to(metric)
|
274
277
|
end
|
275
278
|
end
|
276
279
|
|
277
|
-
[:churn, :flog, :flay, :reek, :roodi, :rcov, :hotspots, :saikuro].each do |graph|
|
280
|
+
[:churn, :flog, :flay, :reek, :roodi, :rcov, :hotspots, :saikuro, :cane].each do |graph|
|
278
281
|
it "should add a #{graph} class metrhod to the MetricFu module" do
|
279
282
|
MetricFu.should respond_to(graph)
|
280
283
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cane do
|
4
|
+
describe "emit method" do
|
5
|
+
def configure_cane_with(options={})
|
6
|
+
MetricFu::Configuration.run {|config|
|
7
|
+
config.add_metric(:cane)
|
8
|
+
config.configure_metric(:cane, options)
|
9
|
+
}
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should execute cane command" do
|
13
|
+
configure_cane_with({})
|
14
|
+
@cane = MetricFu::Cane.new('base_dir')
|
15
|
+
@cane.should_receive(:`).with("mf-cane")
|
16
|
+
output = @cane.emit
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should use abc max option" do
|
20
|
+
configure_cane_with({abc_max: 20})
|
21
|
+
@cane = MetricFu::Cane.new('base_dir')
|
22
|
+
@cane.should_receive(:`).with("mf-cane --abc-max 20")
|
23
|
+
output = @cane.emit
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should use style max line length option" do
|
27
|
+
configure_cane_with({line_length: 100})
|
28
|
+
@cane = MetricFu::Cane.new('base_dir')
|
29
|
+
@cane.should_receive(:`).with("mf-cane --style-measure 100")
|
30
|
+
output = @cane.emit
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should use no-doc if specified" do
|
34
|
+
configure_cane_with({no_doc: 'y'})
|
35
|
+
@cane = MetricFu::Cane.new('base_dir')
|
36
|
+
@cane.should_receive(:`).with("mf-cane --no-doc")
|
37
|
+
output = @cane.emit
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should include doc violations if no_doc != 'y'" do
|
41
|
+
configure_cane_with({no_doc: 'n'})
|
42
|
+
@cane = MetricFu::Cane.new('base_dir')
|
43
|
+
@cane.should_receive(:`).with("mf-cane")
|
44
|
+
output = @cane.emit
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "parse cane output" do
|
49
|
+
before :each do
|
50
|
+
lines = sample_cane_output
|
51
|
+
MetricFu::Configuration.run {}
|
52
|
+
File.stub!(:directory?).and_return(true)
|
53
|
+
@cane = MetricFu::Cane.new('base_dir')
|
54
|
+
@cane.instance_variable_set(:@output, lines)
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "analyze method" do
|
58
|
+
|
59
|
+
it "should find total violations" do
|
60
|
+
@cane.analyze
|
61
|
+
@cane.total_violations.should == 6
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should extract abc complexity violations" do
|
65
|
+
@cane.analyze
|
66
|
+
@cane.violations[:abc_complexity].should == [
|
67
|
+
{file: 'lib/abc/foo.rb', method: 'Abc::Foo#method', complexity: '11'},
|
68
|
+
{file: 'lib/abc/bar.rb', method: 'Abc::Bar#method', complexity: '22'}
|
69
|
+
]
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should extract line style violations" do
|
73
|
+
@cane.analyze
|
74
|
+
@cane.violations[:line_style].should == [
|
75
|
+
{line: 'lib/line/foo.rb:1', description: 'Line is >80 characters (135)'},
|
76
|
+
{line: 'lib/line/bar.rb:2', description: 'Line contains trailing whitespace'}
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should extract comment violations" do
|
81
|
+
@cane.analyze
|
82
|
+
@cane.violations[:comment].should == [
|
83
|
+
{line: 'lib/comments/foo.rb:1', class_name: 'Foo'},
|
84
|
+
{line: 'lib/comments/bar.rb:2', class_name: 'Bar'}
|
85
|
+
]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "to_h method" do
|
90
|
+
it "should have total violations" do
|
91
|
+
@cane.analyze
|
92
|
+
@cane.to_h[:cane][:total_violations].should == 6
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have violations by category" do
|
96
|
+
@cane.analyze
|
97
|
+
@cane.to_h[:cane][:violations][:abc_complexity].should == [
|
98
|
+
{file: 'lib/abc/foo.rb', method: 'Abc::Foo#method', complexity: '11'},
|
99
|
+
{file: 'lib/abc/bar.rb', method: 'Abc::Bar#method', complexity: '22'}
|
100
|
+
]
|
101
|
+
@cane.to_h[:cane][:violations][:line_style].should == [
|
102
|
+
{line: 'lib/line/foo.rb:1', description: 'Line is >80 characters (135)'},
|
103
|
+
{line: 'lib/line/bar.rb:2', description: 'Line contains trailing whitespace'}
|
104
|
+
]
|
105
|
+
@cane.to_h[:cane][:violations][:comment].should == [
|
106
|
+
{line: 'lib/comments/foo.rb:1', class_name: 'Foo'},
|
107
|
+
{line: 'lib/comments/bar.rb:2', class_name: 'Bar'}
|
108
|
+
]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def sample_cane_output
|
114
|
+
<<-OUTPUT
|
115
|
+
Methods exceeded maximum allowed ABC complexity (33):
|
116
|
+
|
117
|
+
lib/abc/foo.rb Abc::Foo#method 11
|
118
|
+
lib/abc/bar.rb Abc::Bar#method 22
|
119
|
+
|
120
|
+
Lines violated style requirements (340):
|
121
|
+
|
122
|
+
lib/line/foo.rb:1 Line is >80 characters (135)
|
123
|
+
lib/line/bar.rb:2 Line contains trailing whitespace
|
124
|
+
|
125
|
+
Class definitions require explanatory comments on preceding line (2):
|
126
|
+
|
127
|
+
lib/comments/foo.rb:1 Foo
|
128
|
+
lib/comments/bar.rb:2 Bar
|
129
|
+
|
130
|
+
Total Violations: 6
|
131
|
+
OUTPUT
|
132
|
+
end
|
133
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metric_fu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -19,7 +19,7 @@ authors:
|
|
19
19
|
autorequire:
|
20
20
|
bindir: bin
|
21
21
|
cert_chain: []
|
22
|
-
date: 2013-03-
|
22
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
25
|
name: rails_best_practices
|
@@ -133,6 +133,22 @@ dependencies:
|
|
133
133
|
- - '='
|
134
134
|
- !ruby/object:Gem::Version
|
135
135
|
version: 0.0.28
|
136
|
+
- !ruby/object:Gem::Dependency
|
137
|
+
name: cane
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - '='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 2.5.2
|
144
|
+
type: :runtime
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - '='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: 2.5.2
|
136
152
|
- !ruby/object:Gem::Dependency
|
137
153
|
name: ruby_parser
|
138
154
|
requirement: !ruby/object:Gem::Requirement
|
@@ -187,6 +203,22 @@ dependencies:
|
|
187
203
|
- - '='
|
188
204
|
- !ruby/object:Gem::Version
|
189
205
|
version: 2.0.2
|
206
|
+
- !ruby/object:Gem::Dependency
|
207
|
+
name: parallel
|
208
|
+
requirement: !ruby/object:Gem::Requirement
|
209
|
+
none: false
|
210
|
+
requirements:
|
211
|
+
- - '='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: 0.6.2
|
214
|
+
type: :runtime
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - '='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 0.6.2
|
190
222
|
- !ruby/object:Gem::Dependency
|
191
223
|
name: activesupport
|
192
224
|
requirement: !ruby/object:Gem::Requirement
|
@@ -304,6 +336,7 @@ description: Code metrics from Flog, Flay, Saikuro, Churn, Reek, Roodi, Rails' s
|
|
304
336
|
email: github@benjaminfleischer.com
|
305
337
|
executables:
|
306
338
|
- metric_fu
|
339
|
+
- mf-cane
|
307
340
|
- mf-churn
|
308
341
|
- mf-flay
|
309
342
|
- mf-rails_best_practices
|
@@ -326,6 +359,7 @@ files:
|
|
326
359
|
- Rakefile
|
327
360
|
- TODO.md
|
328
361
|
- bin/metric_fu
|
362
|
+
- bin/mf-cane
|
329
363
|
- bin/mf-churn
|
330
364
|
- bin/mf-flay
|
331
365
|
- bin/mf-rails_best_practices
|
@@ -368,6 +402,12 @@ files:
|
|
368
402
|
- lib/metric_fu/load_files.rb
|
369
403
|
- lib/metric_fu/logging/mf_debugger.rb
|
370
404
|
- lib/metric_fu/metrics/base_template.rb
|
405
|
+
- lib/metric_fu/metrics/cane/cane.rb
|
406
|
+
- lib/metric_fu/metrics/cane/cane_grapher.rb
|
407
|
+
- lib/metric_fu/metrics/cane/init.rb
|
408
|
+
- lib/metric_fu/metrics/cane/template_awesome/cane.html.erb
|
409
|
+
- lib/metric_fu/metrics/cane/template_standard/cane.html.erb
|
410
|
+
- lib/metric_fu/metrics/cane/violations.rb
|
371
411
|
- lib/metric_fu/metrics/churn/churn.rb
|
372
412
|
- lib/metric_fu/metrics/churn/churn_hotspot.rb
|
373
413
|
- lib/metric_fu/metrics/churn/init.rb
|
@@ -461,6 +501,7 @@ files:
|
|
461
501
|
- spec/metric_fu/data_structures/line_numbers_spec.rb
|
462
502
|
- spec/metric_fu/data_structures/location_spec.rb
|
463
503
|
- spec/metric_fu/metrics/base_template_spec.rb
|
504
|
+
- spec/metric_fu/metrics/cane/cane_spec.rb
|
464
505
|
- spec/metric_fu/metrics/churn/churn_spec.rb
|
465
506
|
- spec/metric_fu/metrics/flay/flay_grapher_spec.rb
|
466
507
|
- spec/metric_fu/metrics/flay/flay_spec.rb
|
@@ -521,7 +562,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
521
562
|
version: 1.3.6
|
522
563
|
requirements: []
|
523
564
|
rubyforge_project: metric_fu
|
524
|
-
rubygems_version: 1.8.
|
565
|
+
rubygems_version: 1.8.24
|
525
566
|
signing_key:
|
526
567
|
specification_version: 3
|
527
568
|
summary: A fistful of code metrics, with awesome templates and graphs
|
@@ -531,6 +572,7 @@ test_files:
|
|
531
572
|
- spec/metric_fu/data_structures/line_numbers_spec.rb
|
532
573
|
- spec/metric_fu/data_structures/location_spec.rb
|
533
574
|
- spec/metric_fu/metrics/base_template_spec.rb
|
575
|
+
- spec/metric_fu/metrics/cane/cane_spec.rb
|
534
576
|
- spec/metric_fu/metrics/churn/churn_spec.rb
|
535
577
|
- spec/metric_fu/metrics/flay/flay_grapher_spec.rb
|
536
578
|
- spec/metric_fu/metrics/flay/flay_spec.rb
|