indirect-metric_fu 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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