metric_fu 3.0.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.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
|