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.
Files changed (50) hide show
  1. data/HISTORY +19 -0
  2. data/MIT-LICENSE +1 -1
  3. data/Manifest.txt +25 -0
  4. data/README +74 -21
  5. data/Rakefile +4 -10
  6. data/lib/metric_fu/base.rb +116 -9
  7. data/lib/metric_fu/churn.rb +8 -7
  8. data/lib/metric_fu/flay.rb +17 -0
  9. data/lib/metric_fu/flog.rb +129 -0
  10. data/lib/metric_fu/reek.rb +17 -0
  11. data/lib/metric_fu/roodi.rb +17 -0
  12. data/lib/metric_fu.rb +17 -3
  13. data/lib/tasks/churn.rake +1 -3
  14. data/lib/tasks/coverage.rake +19 -10
  15. data/lib/tasks/flay.rake +1 -4
  16. data/lib/tasks/flog.rake +10 -10
  17. data/lib/tasks/metric_fu.rake +8 -4
  18. data/lib/tasks/metric_fu.rb +1 -1
  19. data/lib/tasks/railroad.rake +39 -0
  20. data/lib/tasks/reek.rake +6 -0
  21. data/lib/tasks/roodi.rake +7 -0
  22. data/lib/tasks/saikuro.rake +1 -1
  23. data/lib/tasks/stats.rake +2 -3
  24. data/lib/templates/churn.html.erb +7 -4
  25. data/lib/templates/default.css +45 -0
  26. data/lib/templates/flay.html.erb +17 -10
  27. data/lib/templates/flog.html.erb +27 -15
  28. data/lib/templates/flog_page.html.erb +15 -3
  29. data/lib/templates/reek.html.erb +30 -0
  30. data/lib/templates/roodi.html.erb +26 -0
  31. data/spec/base_spec.rb +31 -9
  32. data/spec/churn_spec.rb +11 -4
  33. data/spec/config_spec.rb +110 -0
  34. data/spec/{flay_reporter_spec.rb → flay_spec.rb} +10 -3
  35. data/spec/flog_spec.rb +208 -0
  36. data/spec/md5_tracker_spec.rb +1 -3
  37. data/spec/reek_spec.rb +26 -0
  38. data/spec/spec_helper.rb +7 -3
  39. metadata +42 -18
  40. data/lib/metric_fu/flay_reporter.rb +0 -17
  41. data/lib/metric_fu/flog_reporter/base.rb +0 -49
  42. data/lib/metric_fu/flog_reporter/generator.rb +0 -39
  43. data/lib/metric_fu/flog_reporter/operator.rb +0 -10
  44. data/lib/metric_fu/flog_reporter/page.rb +0 -33
  45. data/lib/metric_fu/flog_reporter/scanned_method.rb +0 -28
  46. data/lib/metric_fu/flog_reporter.rb +0 -5
  47. data/lib/templates/churn.css +0 -38
  48. data/lib/templates/flay.css +0 -38
  49. data/lib/templates/flog.css +0 -39
  50. 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
+ }
@@ -2,22 +2,29 @@
2
2
  <head>
3
3
  <title>Flay Results</title>
4
4
  <style>
5
- <%= open(File.join(MetricFu::TEMPLATE_DIR, "#{template_name}.css")) { |f| f.read } %>
5
+ <%= inline_css("default.css") %>
6
6
  </style>
7
7
  </head>
8
8
 
9
9
  <body>
10
10
  <h1>Flay Results</h1>
11
-
12
- <% @matches.each do |match| %>
13
- <table width="80%" border="1">
14
- <tr><th><%= match.first %></th></tr>
15
- <tr><td>
16
- <% match[1..-1].each do |filename| %>
17
- <%= link_to_filename(*filename.split(":")) %><br>
18
- <% end %>
19
- </td></tr>
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>
@@ -2,25 +2,37 @@
2
2
  <head>
3
3
  <title>Flog Reporter</title>
4
4
  <style>
5
- <%= open(File.join(MetricFu::TEMPLATE_DIR, "#{template_name}.css")) { |f| f.read } %>
5
+ <%= inline_css("default.css") %>
6
6
  </style>
7
7
  </head>
8
8
  <body>
9
- <h1>Flogged files</h1>
10
- <p>Generated on <%= Time.now.localtime %> with <a href='http://ruby.sadi.st/Flog.html'>flog</a></p>
11
- <table class='report'>
12
- <tr><th>File</th><th>Total score</th><th>Methods</th><th>Average score</th><th>Highest score</th></tr>
13
- <% count = 0 %>
14
- <% flog_hashes.sort {|x,y| y[:page].highest_score <=> x[:page].highest_score }.each do |flog_hash| %>
15
- <tr class='<%= Base.cycle("light", "dark", count) %>'>
16
- <td><a href='<%= flog_hash[:path]%>'><%= flog_hash[:path].sub('.html', '.rb') %></a></td>
17
- <td class='score'><%= sprintf(SCORE_FORMAT, flog_hash[:page].score) %></td>
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
- <% count += 1 %>
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
- <%= open(File.join(MetricFu::TEMPLATE_DIR, "flog.css")) { |f| f.read } %>
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
- <%= sm.to_html %>
11
- <% end %>
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('base_dir')
7
- @generator.should_receive(:open).with("base_dir/index.html", "w")
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('base_dir')
13
- @generator.should_receive(:open).with("base_dir/metric_fu/custom.html", "w")
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 "generate_report" do
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('other_dir')
30
- @generator.should_receive(:open).with("other_dir/index.html", "w")
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
- end
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('base_dir', :scm => :git, :minimum_churn_count => 3)
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('base_dir').send(:parse_log_for_changes)
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('base_dir').send(:parse_log_for_changes)
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
@@ -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