indirect-metric_fu 0.8.2 → 0.9.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/HISTORY +19 -0
- data/MIT-LICENSE +1 -1
- data/Manifest.txt +25 -0
- data/README +74 -21
- data/Rakefile +4 -10
- data/lib/metric_fu/base.rb +116 -9
- data/lib/metric_fu/churn.rb +8 -7
- data/lib/metric_fu/flay.rb +17 -0
- data/lib/metric_fu/flog.rb +129 -0
- data/lib/metric_fu/reek.rb +17 -0
- data/lib/metric_fu/roodi.rb +17 -0
- data/lib/metric_fu.rb +17 -3
- data/lib/tasks/churn.rake +1 -3
- data/lib/tasks/coverage.rake +19 -10
- data/lib/tasks/flay.rake +1 -4
- data/lib/tasks/flog.rake +10 -10
- data/lib/tasks/metric_fu.rake +8 -4
- data/lib/tasks/metric_fu.rb +1 -1
- data/lib/tasks/railroad.rake +39 -0
- data/lib/tasks/reek.rake +6 -0
- data/lib/tasks/roodi.rake +7 -0
- data/lib/tasks/saikuro.rake +1 -1
- data/lib/tasks/stats.rake +2 -3
- data/lib/templates/churn.html.erb +7 -4
- data/lib/templates/default.css +45 -0
- data/lib/templates/flay.html.erb +17 -10
- data/lib/templates/flog.html.erb +27 -15
- data/lib/templates/flog_page.html.erb +15 -3
- data/lib/templates/reek.html.erb +30 -0
- data/lib/templates/roodi.html.erb +26 -0
- data/spec/base_spec.rb +31 -9
- data/spec/churn_spec.rb +11 -4
- data/spec/config_spec.rb +110 -0
- data/spec/{flay_reporter_spec.rb → flay_spec.rb} +10 -3
- data/spec/flog_spec.rb +208 -0
- data/spec/md5_tracker_spec.rb +1 -3
- data/spec/reek_spec.rb +26 -0
- data/spec/spec_helper.rb +7 -3
- metadata +42 -18
- data/lib/metric_fu/flay_reporter.rb +0 -17
- data/lib/metric_fu/flog_reporter/base.rb +0 -49
- data/lib/metric_fu/flog_reporter/generator.rb +0 -39
- data/lib/metric_fu/flog_reporter/operator.rb +0 -10
- data/lib/metric_fu/flog_reporter/page.rb +0 -33
- data/lib/metric_fu/flog_reporter/scanned_method.rb +0 -28
- data/lib/metric_fu/flog_reporter.rb +0 -5
- data/lib/templates/churn.css +0 -38
- data/lib/templates/flay.css +0 -38
- data/lib/templates/flog.css +0 -39
- data/spec/flog_reporter/base_spec.rb +0 -69
@@ -0,0 +1,45 @@
|
|
1
|
+
body {
|
2
|
+
background-color: #efefef;
|
3
|
+
margin: 20px;
|
4
|
+
padding: 0;
|
5
|
+
font: 12px verdana, arial, helvetica;
|
6
|
+
}
|
7
|
+
|
8
|
+
table {
|
9
|
+
border-collapse: collapse;
|
10
|
+
border: 1px solid #666;
|
11
|
+
background: #fff;
|
12
|
+
margin-bottom: 20px;
|
13
|
+
}
|
14
|
+
|
15
|
+
table tr.light {
|
16
|
+
background: #fff;
|
17
|
+
}
|
18
|
+
|
19
|
+
table tr.dark {
|
20
|
+
background: #f9f9f9;
|
21
|
+
}
|
22
|
+
|
23
|
+
table td, table th {
|
24
|
+
padding: 4px 10px;
|
25
|
+
font-size: 13px;
|
26
|
+
}
|
27
|
+
table th {
|
28
|
+
text-align: center;
|
29
|
+
color: #fc0;
|
30
|
+
background: #336;
|
31
|
+
font-weight: bold;
|
32
|
+
border: #d0d0d0 1px solid;
|
33
|
+
}
|
34
|
+
|
35
|
+
table td {
|
36
|
+
border: #d0d0d0 1px solid;
|
37
|
+
}
|
38
|
+
|
39
|
+
table td.score {
|
40
|
+
text-align: right;
|
41
|
+
}
|
42
|
+
|
43
|
+
.warning {
|
44
|
+
background: yellow;
|
45
|
+
}
|
data/lib/templates/flay.html.erb
CHANGED
@@ -2,22 +2,29 @@
|
|
2
2
|
<head>
|
3
3
|
<title>Flay Results</title>
|
4
4
|
<style>
|
5
|
-
<%=
|
5
|
+
<%= inline_css("default.css") %>
|
6
6
|
</style>
|
7
7
|
</head>
|
8
8
|
|
9
9
|
<body>
|
10
10
|
<h1>Flay Results</h1>
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
<p><a href='http://ruby.sadi.st/Flay.html'>Flay</a> analyzes ruby code for structural similarities.</p>
|
12
|
+
<table>
|
13
|
+
<tr>
|
14
|
+
<th>Files</th>
|
15
|
+
<th>Matches</th>
|
16
|
+
</tr>
|
17
|
+
<% @matches.each_with_index do |match, count| %>
|
18
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
19
|
+
<td>
|
20
|
+
<% match[1..-1].each do |filename| %>
|
21
|
+
<%= link_to_filename(*filename.split(":")) %><br>
|
22
|
+
<% end %>
|
23
|
+
</td>
|
24
|
+
<td><%= match.first %></td>
|
25
|
+
</tr>
|
20
26
|
<% end %>
|
21
27
|
</table>
|
28
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
22
29
|
</body>
|
23
30
|
</html>
|
data/lib/templates/flog.html.erb
CHANGED
@@ -2,25 +2,37 @@
|
|
2
2
|
<head>
|
3
3
|
<title>Flog Reporter</title>
|
4
4
|
<style>
|
5
|
-
<%=
|
5
|
+
<%= inline_css("default.css") %>
|
6
6
|
</style>
|
7
7
|
</head>
|
8
8
|
<body>
|
9
|
-
<h1>
|
10
|
-
<p
|
11
|
-
<table
|
12
|
-
<tr
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
<td class='score'><%= flog_hash[:page].scanned_methods.length %></td>
|
19
|
-
<td class='score'><%= sprintf(SCORE_FORMAT, flog_hash[:page].average_score) %></td>
|
20
|
-
<td class='score'><%= sprintf(SCORE_FORMAT, flog_hash[:page].highest_score) %></td>
|
9
|
+
<h1>Flog Results</h1>
|
10
|
+
<p><a href='http://ruby.sadi.st/Flog.html'>Flog</a> measures code complexity.</p>
|
11
|
+
<table>
|
12
|
+
<tr>
|
13
|
+
<th>File</th>
|
14
|
+
<th>Total score</th>
|
15
|
+
<th>Methods</th>
|
16
|
+
<th>Average score</th>
|
17
|
+
<th>Highest score</th>
|
21
18
|
</tr>
|
22
|
-
<%
|
19
|
+
<% pages.sort {|x,y| y.highest_score <=> x.highest_score }.each_with_index do |page, count| %>
|
20
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
21
|
+
<td><a href='<%= page.path %>'><%= page.path.sub('.html', '.rb') %></a></td>
|
22
|
+
<td class='score'><%= sprintf(SCORE_FORMAT, page.score) %></td>
|
23
|
+
<td class='score'><%= page.scanned_methods.length %></td>
|
24
|
+
<td class='score'><%= sprintf(SCORE_FORMAT, page.average_score) %></td>
|
25
|
+
<td class='score'><%= sprintf(SCORE_FORMAT, page.highest_score) %></td>
|
26
|
+
</tr>
|
23
27
|
<% end %>
|
28
|
+
<tr>
|
29
|
+
<td><strong>Totals</strong></td>
|
30
|
+
<td class='score'><strong><%= sprintf(SCORE_FORMAT, pages.inject(0){|sum, page| sum + page.score }) %></strong></td>
|
31
|
+
<td class='score'><strong><%= pages.inject(0){|sum, page| sum + page.scanned_methods.length } %></strong></td>
|
32
|
+
<td class='score'></td>
|
33
|
+
<td class='score'></td>
|
34
|
+
</tr>
|
24
35
|
</table>
|
36
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
25
37
|
</body>
|
26
|
-
</html>
|
38
|
+
</html>
|
@@ -1,13 +1,25 @@
|
|
1
1
|
<html>
|
2
2
|
<head>
|
3
3
|
<style>
|
4
|
-
<%=
|
4
|
+
<%= inline_css("default.css") %>
|
5
5
|
</style>
|
6
6
|
</head>
|
7
7
|
<body>
|
8
8
|
<p>Score: <%= score %></p>
|
9
9
|
<% scanned_methods.each do |sm| %>
|
10
|
-
|
11
|
-
|
10
|
+
<p><strong><%= sm.name %> (<%= sm.score %>)</strong></p>
|
11
|
+
<table>
|
12
|
+
<tr>
|
13
|
+
<th>Score</th>
|
14
|
+
<th>Operator</th>
|
15
|
+
</tr>
|
16
|
+
<% sm.operators.each_with_index do |operator, count| %>
|
17
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
18
|
+
<td class='score'><%= sprintf(SCORE_FORMAT, operator.score) %></td>
|
19
|
+
<td class='score'><%= operator.operator %></td>
|
20
|
+
</tr>
|
21
|
+
<% end %>
|
22
|
+
</table>
|
23
|
+
<% end %>
|
12
24
|
</body>
|
13
25
|
</html>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Reek Results</title>
|
4
|
+
<style>
|
5
|
+
<%= inline_css("default.css") %>
|
6
|
+
</style>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<h1>Reek Results</h1>
|
11
|
+
<p><a href="http://reek.rubyforge.org/">Reek</a> detects common code smells in ruby code.</p>
|
12
|
+
<table>
|
13
|
+
<tr>
|
14
|
+
<th>File Path</th>
|
15
|
+
<th>Code Smell</th>
|
16
|
+
</tr>
|
17
|
+
<% @matches.each_with_index do |match, count| %>
|
18
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
19
|
+
<td><%= match.first %></td>
|
20
|
+
<td>
|
21
|
+
<% match[1..-1].each do |line| %>
|
22
|
+
<%= line %><br>
|
23
|
+
<% end %>
|
24
|
+
</td>
|
25
|
+
</tr>
|
26
|
+
<% end %>
|
27
|
+
</table>
|
28
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
29
|
+
</body>
|
30
|
+
</html>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Roodi Results</title>
|
4
|
+
<style>
|
5
|
+
<%= inline_css("default.css") %>
|
6
|
+
</style>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<h1>Roodi Results</h1>
|
11
|
+
<p><a href="http://roodi.rubyforge.org/">Roodi</a> parses your Ruby code and warns you about design issues you have based on the checks that is has configured.</p>
|
12
|
+
<table>
|
13
|
+
<tr>
|
14
|
+
<th>File Path</th>
|
15
|
+
<th>Warning</th>
|
16
|
+
</tr>
|
17
|
+
<% @matches.each_with_index do |match, count| %>
|
18
|
+
<tr class='<%= cycle("light", "dark", count) %>'>
|
19
|
+
<td><%= link_to_filename(match.first.split(':').first) if match.first %></td>
|
20
|
+
<td><%= match[1] %></td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
</table>
|
24
|
+
<p>Generated on <%= Time.now.localtime %></p>
|
25
|
+
</body>
|
26
|
+
</html>
|
data/spec/base_spec.rb
CHANGED
@@ -3,15 +3,15 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
3
3
|
describe MetricFu::Base::Generator do
|
4
4
|
describe "save_html" do
|
5
5
|
it "should save to a index.html in the base_dir" do
|
6
|
-
@generator = MetricFu::Base::Generator.new
|
7
|
-
@generator.should_receive(:open).with("
|
6
|
+
@generator = MetricFu::Base::Generator.new
|
7
|
+
@generator.should_receive(:open).with("#{MetricFu::BASE_DIRECTORY}/generator/index.html", "w")
|
8
8
|
@generator.save_html("<html>")
|
9
9
|
end
|
10
10
|
|
11
11
|
it "should save to a custom.html to the base_dir if 'custom' is passed as name" do
|
12
|
-
@generator = MetricFu::Base::Generator.new
|
13
|
-
@generator.should_receive(:open).with("
|
14
|
-
@generator.save_html("<html>", 'metric_fu/custom')
|
12
|
+
@generator = MetricFu::Base::Generator.new
|
13
|
+
@generator.should_receive(:open).with("#{MetricFu::BASE_DIRECTORY}/generator/metric_fu/custom.html", "w")
|
14
|
+
@generator.save_html("<html>", 'metric_fu/custom.html')
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -24,12 +24,34 @@ describe MetricFu::Base::Generator do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
describe "
|
27
|
+
describe "generate_html" do
|
28
28
|
it "should create a new Generator and call generate_report on it" do
|
29
|
-
@generator = MetricFu::Base::Generator.new
|
30
|
-
@generator.should_receive(:open).with("
|
29
|
+
@generator = MetricFu::Base::Generator.new
|
30
|
+
@generator.should_receive(:open).with("#{MetricFu::BASE_DIRECTORY}/generator/index.html", "w")
|
31
31
|
@generator.should_receive(:generate_html).and_return('<html>')
|
32
32
|
@generator.generate_report
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
describe "cycle" do
|
37
|
+
it "should create a new Generator and call generate_report on it" do
|
38
|
+
@generator = MetricFu::Base::Generator.new
|
39
|
+
@generator.cycle("light", "dark", 0).should == 'light'
|
40
|
+
@generator.cycle("light", "dark", 1).should == 'dark'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "template_name" do
|
45
|
+
it "should return the class name in lowercase" do
|
46
|
+
@generator = MetricFu::Base::Generator.new
|
47
|
+
@generator.template_name.should == 'generator'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "metric_dir" do
|
52
|
+
it "should return tmp/metric_fu/{the class name in lowercase}" do
|
53
|
+
MetricFu::Base::Generator.metric_dir.should == "#{MetricFu::BASE_DIRECTORY}/generator"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/spec/churn_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe MetricFu::Churn do
|
|
11
11
|
git_mock = mock('git')
|
12
12
|
git_mock.should_receive(:get_logs).and_return(logs)
|
13
13
|
Churn::Git.should_receive(:new).and_return(git_mock)
|
14
|
-
churn = Churn.new(
|
14
|
+
churn = Churn.new(:scm => :git, :minimum_churn_count => 3)
|
15
15
|
churn.analyze
|
16
16
|
churn.instance_variable_get(:@changes).should == {"accept"=>3}
|
17
17
|
end
|
@@ -23,6 +23,13 @@ describe MetricFu::Churn do
|
|
23
23
|
|
24
24
|
end
|
25
25
|
|
26
|
+
describe "template_name" do
|
27
|
+
it "should return the class name in lowercase" do
|
28
|
+
churn = Churn.new
|
29
|
+
churn.template_name.should == 'churn'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
26
33
|
describe "parse_log_for_changes" do
|
27
34
|
it "should count the changes with git" do
|
28
35
|
logs = ["home_page/index.html", "README", "History.txt", "README", "History.txt", "README"]
|
@@ -30,7 +37,7 @@ describe MetricFu::Churn do
|
|
30
37
|
git_mock.should_receive(:get_logs).and_return(logs)
|
31
38
|
Churn::Git.should_receive(:new).and_return(git_mock)
|
32
39
|
File.should_receive(:exist?).with(".git").and_return(true)
|
33
|
-
changes = Churn.new
|
40
|
+
changes = Churn.new.send(:parse_log_for_changes)
|
34
41
|
changes["home_page/index.html"].should == 1
|
35
42
|
changes["History.txt"].should == 2
|
36
43
|
changes["README"].should == 3
|
@@ -43,7 +50,7 @@ describe MetricFu::Churn do
|
|
43
50
|
Churn::Svn.should_receive(:new).and_return(svn_mock)
|
44
51
|
File.should_receive(:exist?).with(".git").and_return(false)
|
45
52
|
File.should_receive(:exist?).with(".svn").and_return(true)
|
46
|
-
changes = Churn.new
|
53
|
+
changes = Churn.new.send(:parse_log_for_changes)
|
47
54
|
changes["home_page/index.html"].should == 1
|
48
55
|
changes["History.txt"].should == 2
|
49
56
|
changes["README"].should == 3
|
@@ -107,4 +114,4 @@ describe MetricFu::Churn::Git do
|
|
107
114
|
@churn.get_logs
|
108
115
|
end
|
109
116
|
end
|
110
|
-
end
|
117
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe MetricFu::Configuration do
|
4
|
+
before do
|
5
|
+
MetricFu.configuration.reset
|
6
|
+
end
|
7
|
+
after do
|
8
|
+
ENV['CC_BUILD_ARTIFACTS'] = nil
|
9
|
+
end
|
10
|
+
describe "open_in_browser" do
|
11
|
+
it "should return false if running in cruise" do
|
12
|
+
unless ENV['CC_BUILD_ARTIFACTS']
|
13
|
+
MetricFu.open_in_browser?.should == !!PLATFORM['darwin']
|
14
|
+
ENV['CC_BUILD_ARTIFACTS'] = ''
|
15
|
+
MetricFu.open_in_browser?.should == false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "metrics" do
|
21
|
+
it "should be configurable" do
|
22
|
+
MetricFu.metrics.should == [:coverage, :churn, :flog, :flay, :reek, :roodi, :saikuro]
|
23
|
+
MetricFu::Configuration.run do |config|
|
24
|
+
config.metrics = [:coverage, :flog]
|
25
|
+
end
|
26
|
+
MetricFu.metrics.should == [:coverage, :flog]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "churn" do
|
31
|
+
it "should be configurable" do
|
32
|
+
now = Time.now
|
33
|
+
MetricFu.churn.should == {}
|
34
|
+
MetricFu::Configuration.run do |config|
|
35
|
+
config.churn[:start_date] = now
|
36
|
+
end
|
37
|
+
MetricFu.churn.should == {:start_date => now }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "coverage" do
|
42
|
+
it "should be configurable" do
|
43
|
+
MetricFu.coverage[:test_files].should == ['test/**/*_test.rb', 'spec/**/*_spec.rb']
|
44
|
+
MetricFu::Configuration.run do |config|
|
45
|
+
config.coverage[:test_files] = ['test/**/test_*.rb']
|
46
|
+
end
|
47
|
+
MetricFu.coverage[:test_files].should == ['test/**/test_*.rb']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "flay" do
|
52
|
+
it "should be configurable" do
|
53
|
+
now = Time.now
|
54
|
+
MetricFu.flay.should == { :dirs_to_flay => ['lib'] }
|
55
|
+
MetricFu::Configuration.run do |config|
|
56
|
+
config.flay[:dirs_to_flay] = ['cms/app', 'cms/lib']
|
57
|
+
end
|
58
|
+
MetricFu.flay.should == { :dirs_to_flay => ['cms/app', 'cms/lib'] }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "flog" do
|
63
|
+
it "should be configurable" do
|
64
|
+
MetricFu.flog.should == { :dirs_to_flog => ['lib'] }
|
65
|
+
MetricFu::Configuration.run do |config|
|
66
|
+
config.flog[:dirs_to_flog] = ['cms/app', 'cms/lib']
|
67
|
+
end
|
68
|
+
MetricFu.flog.should == { :dirs_to_flog => ['cms/app', 'cms/lib'] }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "saikuro" do
|
73
|
+
it "should be configurable" do
|
74
|
+
MetricFu.saikuro.should == {}
|
75
|
+
MetricFu::Configuration.run do |config|
|
76
|
+
config.saikuro = { "--warn_cyclo" => "3", "--error_cyclo" => "4" }
|
77
|
+
end
|
78
|
+
MetricFu.saikuro.should == { "--warn_cyclo" => "3", "--error_cyclo" => "4" }
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should only accept a Hash" do
|
82
|
+
MetricFu.saikuro.should == {}
|
83
|
+
lambda {
|
84
|
+
MetricFu::Configuration.run do |config|
|
85
|
+
config.saikuro = ''
|
86
|
+
end
|
87
|
+
}.should raise_error
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "reek" do
|
92
|
+
it "should be configurable" do
|
93
|
+
MetricFu.reek.should == { :dirs_to_reek => ['lib'] }
|
94
|
+
MetricFu::Configuration.run do |config|
|
95
|
+
config.reek[:dirs_to_reek] = ['cms/app', 'cms/lib']
|
96
|
+
end
|
97
|
+
MetricFu.reek.should == { :dirs_to_reek => ['cms/app', 'cms/lib'] }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "roodi" do
|
102
|
+
it "should be configurable" do
|
103
|
+
MetricFu.roodi.should == { :dirs_to_roodi => ['lib'] }
|
104
|
+
MetricFu::Configuration.run do |config|
|
105
|
+
config.roodi[:dirs_to_roodi] = ['cms/app', 'cms/lib']
|
106
|
+
end
|
107
|
+
MetricFu.roodi.should == { :dirs_to_roodi => ['cms/app', 'cms/lib'] }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|