jscruggs-metric_fu 0.8.0 → 0.8.9
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.txt → HISTORY} +12 -0
- data/MIT-LICENSE +1 -1
- data/Manifest.txt +3 -6
- data/README +66 -16
- data/Rakefile +11 -0
- data/TODO +13 -0
- data/lib/metric_fu/base.rb +159 -0
- data/lib/metric_fu/churn.rb +88 -0
- data/lib/metric_fu/flay.rb +17 -0
- data/lib/metric_fu/flog.rb +129 -0
- data/lib/metric_fu/md5_tracker.rb +6 -6
- data/lib/metric_fu/reek.rb +17 -0
- data/lib/metric_fu/roodi.rb +17 -0
- data/lib/metric_fu.rb +3 -7
- data/lib/tasks/churn.rake +4 -106
- data/lib/tasks/coverage.rake +25 -9
- data/lib/tasks/flay.rake +6 -0
- data/lib/tasks/flog.rake +28 -21
- data/lib/tasks/metric_fu.rake +21 -8
- data/lib/tasks/metric_fu.rb +1 -1
- data/lib/tasks/railroad.rake +36 -0
- data/lib/tasks/reek.rake +6 -0
- data/lib/tasks/roodi.rake +7 -0
- data/lib/tasks/saikuro.rake +20 -19
- data/lib/tasks/stats.rake +3 -3
- data/lib/templates/churn.html.erb +22 -0
- data/lib/templates/default.css +45 -0
- data/lib/templates/flay.html.erb +30 -0
- data/lib/templates/flog.html.erb +31 -0
- data/lib/templates/flog_page.html.erb +25 -0
- data/lib/templates/reek.html.erb +30 -0
- data/lib/templates/roodi.html.erb +26 -0
- data/spec/base_spec.rb +57 -0
- data/spec/churn_spec.rb +117 -0
- data/spec/config_spec.rb +110 -0
- data/spec/flay_spec.rb +19 -0
- data/spec/flog_spec.rb +208 -0
- data/spec/md5_tracker_spec.rb +57 -0
- data/spec/reek_spec.rb +26 -0
- data/spec/spec_helper.rb +11 -0
- metadata +76 -27
- data/TODO.txt +0 -9
- data/lib/metric_fu/flog_reporter/base.rb +0 -58
- data/lib/metric_fu/flog_reporter/flog_reporter.css +0 -39
- data/lib/metric_fu/flog_reporter/generator.rb +0 -71
- data/lib/metric_fu/flog_reporter/operator.rb +0 -10
- data/lib/metric_fu/flog_reporter/page.rb +0 -36
- data/lib/metric_fu/flog_reporter/scanned_method.rb +0 -28
- data/lib/metric_fu/flog_reporter.rb +0 -5
- data/lib/metric_fu/saikuro/SAIKURO_README +0 -142
- data/metric_fu.gemspec +0 -16
- data/test/test_helper.rb +0 -4
- data/test/test_md5_tracker.rb +0 -59
@@ -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
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe MetricFu::Base::Generator do
|
4
|
+
describe "save_html" do
|
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("#{MetricFu::BASE_DIRECTORY}/generator/index.html", "w")
|
8
|
+
@generator.save_html("<html>")
|
9
|
+
end
|
10
|
+
|
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("#{MetricFu::BASE_DIRECTORY}/generator/metric_fu/custom.html", "w")
|
14
|
+
@generator.save_html("<html>", 'metric_fu/custom.html')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "generate_report class method" do
|
19
|
+
it "should create a new Generator and call generate_report on it" do
|
20
|
+
@generator = mock('generator')
|
21
|
+
@generator.should_receive(:generate_report)
|
22
|
+
MetricFu::Base::Generator.should_receive(:new).and_return(@generator)
|
23
|
+
MetricFu::Base::Generator.generate_report('base_dir')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "generate_html" do
|
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("#{MetricFu::BASE_DIRECTORY}/generator/index.html", "w")
|
31
|
+
@generator.should_receive(:generate_html).and_return('<html>')
|
32
|
+
@generator.generate_report
|
33
|
+
end
|
34
|
+
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
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe MetricFu::Churn do
|
4
|
+
describe "generate_report" do
|
5
|
+
after do
|
6
|
+
load File.dirname(__FILE__) + '/../lib/metric_fu/churn.rb' #need to reload file to wipe out mock of private static
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should strip out files that have less than the min count" do
|
10
|
+
logs = ["accept", "accept", "accept", "reject", "reject"]
|
11
|
+
git_mock = mock('git')
|
12
|
+
git_mock.should_receive(:get_logs).and_return(logs)
|
13
|
+
Churn::Git.should_receive(:new).and_return(git_mock)
|
14
|
+
churn = Churn.new(:scm => :git, :minimum_churn_count => 3)
|
15
|
+
churn.analyze
|
16
|
+
churn.instance_variable_get(:@changes).should == {"accept"=>3}
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should have a default min count of 5" do
|
20
|
+
churn = Churn.new('base_dir')
|
21
|
+
churn.instance_variable_get(:@minimum_churn_count).should == 5
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
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
|
+
|
33
|
+
describe "parse_log_for_changes" do
|
34
|
+
it "should count the changes with git" do
|
35
|
+
logs = ["home_page/index.html", "README", "History.txt", "README", "History.txt", "README"]
|
36
|
+
git_mock = mock('git')
|
37
|
+
git_mock.should_receive(:get_logs).and_return(logs)
|
38
|
+
Churn::Git.should_receive(:new).and_return(git_mock)
|
39
|
+
File.should_receive(:exist?).with(".git").and_return(true)
|
40
|
+
changes = Churn.new.send(:parse_log_for_changes)
|
41
|
+
changes["home_page/index.html"].should == 1
|
42
|
+
changes["History.txt"].should == 2
|
43
|
+
changes["README"].should == 3
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should count the changes with svn" do
|
47
|
+
logs = ["home_page/index.html", "README", "History.txt", "README", "History.txt", "README"]
|
48
|
+
svn_mock = mock('svn')
|
49
|
+
svn_mock.should_receive(:get_logs).and_return(logs)
|
50
|
+
Churn::Svn.should_receive(:new).and_return(svn_mock)
|
51
|
+
File.should_receive(:exist?).with(".git").and_return(false)
|
52
|
+
File.should_receive(:exist?).with(".svn").and_return(true)
|
53
|
+
changes = Churn.new.send(:parse_log_for_changes)
|
54
|
+
changes["home_page/index.html"].should == 1
|
55
|
+
changes["History.txt"].should == 2
|
56
|
+
changes["README"].should == 3
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe MetricFu::Churn::Svn do
|
62
|
+
|
63
|
+
describe "get_logs" do
|
64
|
+
it "should use the start date if supplied" do
|
65
|
+
@churn = Churn::Svn.new
|
66
|
+
@churn.should_receive(:`).with('svn log --verbose').and_return("")
|
67
|
+
@churn.get_logs
|
68
|
+
end
|
69
|
+
it "should use the start date if supplied" do
|
70
|
+
Time.should_receive(:now).and_return(Date.new(2001, 1, 2))
|
71
|
+
@churn = Churn::Svn.new(lambda{Date.new(2000, 1, 1)})
|
72
|
+
@churn.should_receive(:require_rails_env)
|
73
|
+
@churn.should_receive(:`).with("svn log --revision {2000-01-01}:{2001-01-02} --verbose").and_return("")
|
74
|
+
@churn.get_logs
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "clean_up_svn_line" do
|
79
|
+
it "should return nil for non matches" do
|
80
|
+
Churn::Svn.new.send(:clean_up_svn_line, "Adding Google analytics").should be_nil
|
81
|
+
Churn::Svn.new.send(:clean_up_svn_line, "A bunch of new files").should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should strip out all but the full path" do
|
85
|
+
Churn::Svn.new.send(:clean_up_svn_line, " A /trunk/lib/server.rb ").should == "/trunk/lib/server.rb"
|
86
|
+
Churn::Svn.new.send(:clean_up_svn_line, "A /trunk/lib/server.rb ").should == "/trunk/lib/server.rb"
|
87
|
+
Churn::Svn.new.send(:clean_up_svn_line, " A /trunk/lib/server.rb ").should == "/trunk/lib/server.rb"
|
88
|
+
Churn::Svn.new.send(:clean_up_svn_line, " A /trunk/lib/server.rb").should == "/trunk/lib/server.rb"
|
89
|
+
Churn::Svn.new.send(:clean_up_svn_line, "A /trunk/lib/server.rb").should == "/trunk/lib/server.rb"
|
90
|
+
Churn::Svn.new.send(:clean_up_svn_line, "A /trunk/lib/server.rb").should == "/trunk/lib/server.rb"
|
91
|
+
|
92
|
+
Churn::Svn.new.send(:clean_up_svn_line, " M /trunk/lib/server.rb ").should == "/trunk/lib/server.rb"
|
93
|
+
Churn::Svn.new.send(:clean_up_svn_line, "M /trunk/lib/server.rb ").should == "/trunk/lib/server.rb"
|
94
|
+
Churn::Svn.new.send(:clean_up_svn_line, " M /trunk/lib/server.rb ").should == "/trunk/lib/server.rb"
|
95
|
+
Churn::Svn.new.send(:clean_up_svn_line, " M /trunk/lib/server.rb").should == "/trunk/lib/server.rb"
|
96
|
+
Churn::Svn.new.send(:clean_up_svn_line, "M /trunk/lib/server.rb").should == "/trunk/lib/server.rb"
|
97
|
+
Churn::Svn.new.send(:clean_up_svn_line, "M /trunk/lib/server.rb").should == "/trunk/lib/server.rb"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe MetricFu::Churn::Git do
|
103
|
+
|
104
|
+
describe "get_logs" do
|
105
|
+
it "should use the start date if supplied" do
|
106
|
+
@churn = Churn::Git.new
|
107
|
+
@churn.should_receive(:`).with('git log --name-only --pretty=format:').and_return("")
|
108
|
+
@churn.get_logs
|
109
|
+
end
|
110
|
+
it "should use the start date if supplied" do
|
111
|
+
@churn = Churn::Git.new(lambda{Date.new(2000, 1, 1)})
|
112
|
+
@churn.should_receive(:require_rails_env)
|
113
|
+
@churn.should_receive(:`).with("git log --after=2000-01-01 --name-only --pretty=format:").and_return("")
|
114
|
+
@churn.get_logs
|
115
|
+
end
|
116
|
+
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
|
data/spec/flay_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe MetricFu::Flay do
|
4
|
+
|
5
|
+
describe "generate_html" do
|
6
|
+
it "should create a new Generator and call generate_report on it" do
|
7
|
+
@generator = MetricFu::Flay.new('other_dir')
|
8
|
+
@generator.should_receive(:`).and_return("Matches found in :call (mass = 55)\n\tlib/metric_fu/flog_reporter.rb:2\n\tlib/metric_fu/flog_reporter.rb:3")
|
9
|
+
@generator.generate_html
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "template_name" do
|
14
|
+
it "should return the class name in lowercase" do
|
15
|
+
flay = MetricFu::Flay.new('base_dir')
|
16
|
+
flay.template_name.should == 'flay'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/flog_spec.rb
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
include MetricFu::Flog
|
3
|
+
|
4
|
+
describe "Flog::Base" do
|
5
|
+
before do
|
6
|
+
@alpha_only_method = <<-AOM
|
7
|
+
Total flog = 13.6283678106927
|
8
|
+
|
9
|
+
ErrorMailer#errormail: (12.5)
|
10
|
+
12.0: assignment
|
11
|
+
1.2: []
|
12
|
+
1.2: now
|
13
|
+
1.2: content_type
|
14
|
+
AOM
|
15
|
+
|
16
|
+
@method_that_has_digits = <<-MTHD
|
17
|
+
Total flog = 7.08378429936994
|
18
|
+
|
19
|
+
NoImmunizationReason#to_c32: (7.1)
|
20
|
+
3.0: code
|
21
|
+
2.3: branch
|
22
|
+
1.4: templateId
|
23
|
+
1.2: act
|
24
|
+
1.1: entryRelationship
|
25
|
+
MTHD
|
26
|
+
|
27
|
+
@bang_method = <<-BM
|
28
|
+
Total flog = 7.08378429936994
|
29
|
+
|
30
|
+
NoImmunizationReason#to_c32!: (7.1)
|
31
|
+
3.0: code
|
32
|
+
2.3: branch
|
33
|
+
1.4: templateId
|
34
|
+
1.2: act
|
35
|
+
1.1: entryRelationship
|
36
|
+
BM
|
37
|
+
|
38
|
+
@invalid_method = <<-IM
|
39
|
+
Total flog = 7.08378429936994
|
40
|
+
|
41
|
+
3.0: code
|
42
|
+
2.3: branch
|
43
|
+
1.4: templateId
|
44
|
+
1.2: act
|
45
|
+
1.1: entryRelationship
|
46
|
+
IM
|
47
|
+
|
48
|
+
@assignment_method = <<-MTHD
|
49
|
+
Total Flog = 21.6 (5.4 +/- 3.3 flog / method)
|
50
|
+
|
51
|
+
ActivityReport#existing_measure_attributes=: (8.5)
|
52
|
+
4.1: assignment
|
53
|
+
1.8: id
|
54
|
+
1.6: to_s
|
55
|
+
1.4: []
|
56
|
+
1.4: activity_report_measures
|
57
|
+
1.2: each
|
58
|
+
1.2: branch
|
59
|
+
MTHD
|
60
|
+
|
61
|
+
@class_methods_grouped_together = <<-MTHD
|
62
|
+
Total Flog = 61.8 (7.7 +/- 95.3 flog / method)
|
63
|
+
|
64
|
+
User#none: (32.8)
|
65
|
+
7.2: include
|
66
|
+
3.6: validates_length_of
|
67
|
+
3.6: validates_format_of
|
68
|
+
2.4: validates_presence_of
|
69
|
+
2.4: validates_uniqueness_of
|
70
|
+
1.4: bad_login_message
|
71
|
+
1.4: name_regex
|
72
|
+
1.4: bad_email_message
|
73
|
+
1.4: bad_name_message
|
74
|
+
1.4: login_regex
|
75
|
+
1.4: email_regex
|
76
|
+
1.2: private
|
77
|
+
1.2: has_and_belongs_to_many
|
78
|
+
1.2: before_create
|
79
|
+
1.2: attr_accessible
|
80
|
+
0.4: lit_fixnum
|
81
|
+
MTHD
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be able to parse class_methods_grouped_together" do
|
85
|
+
page = Base.parse(@class_methods_grouped_together)
|
86
|
+
page.should_not be_nil
|
87
|
+
page.score.should == 61.8
|
88
|
+
page.scanned_methods.size.should == 1
|
89
|
+
sm = page.scanned_methods.first
|
90
|
+
sm.name.should == 'User#none'
|
91
|
+
sm.score.should == 32.8
|
92
|
+
|
93
|
+
sm.operators.size.should == 16
|
94
|
+
sm.operators.first.score.should == 7.2
|
95
|
+
sm.operators.first.operator.should == "include"
|
96
|
+
|
97
|
+
sm.operators.last.score.should == 0.4
|
98
|
+
sm.operators.last.operator.should == "lit_fixnum"
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should be able to parse an assignment method" do
|
102
|
+
page = Base.parse(@assignment_method)
|
103
|
+
page.should_not be_nil
|
104
|
+
page.score.should == 21.6
|
105
|
+
page.scanned_methods.size.should == 1
|
106
|
+
sm = page.scanned_methods.first
|
107
|
+
sm.name.should == 'ActivityReport#existing_measure_attributes='
|
108
|
+
sm.score.should == 8.5
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should be able to parse an alpha only method" do
|
112
|
+
page = Base.parse(@alpha_only_method)
|
113
|
+
page.should_not be_nil
|
114
|
+
page.score.should == 13.6283678106927
|
115
|
+
page.scanned_methods.size.should == 1
|
116
|
+
sm = page.scanned_methods.first
|
117
|
+
sm.name.should == 'ErrorMailer#errormail'
|
118
|
+
sm.score.should == 12.5
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should be able to parse method that has digits" do
|
122
|
+
page = Base.parse(@method_that_has_digits)
|
123
|
+
page.should_not be_nil
|
124
|
+
page.score.should == 7.08378429936994
|
125
|
+
page.scanned_methods.size.should == 1
|
126
|
+
sm = page.scanned_methods.first
|
127
|
+
sm.name.should == 'NoImmunizationReason#to_c32'
|
128
|
+
sm.score.should == 7.1
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should be able to parse bang method" do
|
132
|
+
page = Base.parse(@bang_method)
|
133
|
+
page.should_not be_nil
|
134
|
+
page.score.should == 7.08378429936994
|
135
|
+
page.scanned_methods.size.should == 1
|
136
|
+
sm = page.scanned_methods.first
|
137
|
+
sm.name.should == 'NoImmunizationReason#to_c32!'
|
138
|
+
sm.score.should == 7.1
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should return nil when parsing invalid method" do
|
142
|
+
page = Base.parse(@invalid_method)
|
143
|
+
page.should be_nil
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
IM = <<-IM
|
148
|
+
Total flog = 7.08378429936994
|
149
|
+
|
150
|
+
3.0: code
|
151
|
+
2.3: branch
|
152
|
+
1.4: templateId
|
153
|
+
1.2: act
|
154
|
+
1.1: entryRelationship
|
155
|
+
IM
|
156
|
+
describe MetricFu::Flog do
|
157
|
+
|
158
|
+
describe "generate_report" do
|
159
|
+
it "should generate reports" do
|
160
|
+
generator = Flog::Generator.new('other_dir')
|
161
|
+
generator.should_receive(:flog_results).and_return(['A', 'B'])
|
162
|
+
generator.should_receive(:save_html).at_least(3).times.and_return('')
|
163
|
+
generator.should_receive(:open).any_number_of_times.and_return(['Total Flog = 1273.9 (9.3 +/- 259.2 flog / method)', 'TokenCounter#list_tokens_per_line: (15.2)', '9.0: assignment'].join("\n"))
|
164
|
+
generator.generate_report
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should be able to handle InvalidFlogs" do
|
168
|
+
generator = Flog::Generator.new('other_dir')
|
169
|
+
generator.should_receive(:flog_results).and_return(['A', 'B'])
|
170
|
+
generator.should_receive(:inline_css).any_number_of_times.and_return('')
|
171
|
+
generator.should_receive(:save_html).once
|
172
|
+
generator.should_receive(:open).any_number_of_times.and_return(IM)
|
173
|
+
generator.generate_report
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "template_name" do
|
178
|
+
it "should return the class name in lowercase" do
|
179
|
+
flog = Flog::Generator.new('base_dir')
|
180
|
+
Flog::Generator.template_name.should == 'flog'
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
describe MetricFu::Flog::Page do
|
186
|
+
|
187
|
+
describe "average_score" do
|
188
|
+
it "should calculate the average score" do
|
189
|
+
page = Page.new(10)
|
190
|
+
page.should_receive(:scanned_methods).any_number_of_times.and_return([ScannedMethod.new(:test, 10), ScannedMethod.new(:test, 20)])
|
191
|
+
page.average_score.should == 15
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should be able to handle divide by zero" do
|
195
|
+
page = Page.new(10)
|
196
|
+
page.should_receive(:scanned_methods).any_number_of_times.and_return([])
|
197
|
+
page.average_score.should == 0
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
describe "highest_score" do
|
202
|
+
it "should calculate the average score" do
|
203
|
+
page = Page.new(10)
|
204
|
+
page.should_receive(:scanned_methods).any_number_of_times.and_return([ScannedMethod.new(:test, 10), ScannedMethod.new(:test, 20)])
|
205
|
+
page.highest_score.should == 20
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe MetricFu::MD5Tracker do
|
4
|
+
before do
|
5
|
+
@tmp_dir = File.join(File.dirname(__FILE__), 'tmp')
|
6
|
+
FileUtils.mkdir_p(@tmp_dir, :verbose => false) unless File.directory?(@tmp_dir)
|
7
|
+
@file1 = File.new(File.join(@tmp_dir, 'file1.txt'), 'w')
|
8
|
+
@file2 = File.new(File.join(@tmp_dir, 'file2.txt'), 'w')
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
FileUtils.rm_rf(@tmp_dir, :verbose => false)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "identical files should match" do
|
16
|
+
@file1.puts("Hello World")
|
17
|
+
@file1.close
|
18
|
+
file1_md5 = MD5Tracker.track(@file1.path, @tmp_dir)
|
19
|
+
|
20
|
+
@file2.puts("Hello World")
|
21
|
+
@file2.close
|
22
|
+
file2_md5 = MD5Tracker.track(@file2.path, @tmp_dir)
|
23
|
+
|
24
|
+
file2_md5.should == file1_md5
|
25
|
+
end
|
26
|
+
|
27
|
+
it "different files should not match" do
|
28
|
+
@file1.puts("Hello World")
|
29
|
+
@file1.close
|
30
|
+
file1_md5 = MD5Tracker.track(@file1.path, @tmp_dir)
|
31
|
+
|
32
|
+
@file2.puts("Goodbye World")
|
33
|
+
@file2.close
|
34
|
+
file2_md5 = MD5Tracker.track(@file2.path, @tmp_dir)
|
35
|
+
|
36
|
+
file2_md5.should_not == file1_md5
|
37
|
+
end
|
38
|
+
|
39
|
+
it "file_changed? should detect a change" do
|
40
|
+
@file2.close
|
41
|
+
|
42
|
+
@file1.puts("Hello World")
|
43
|
+
@file1.close
|
44
|
+
file1_md5 = MD5Tracker.track(@file1.path, @tmp_dir)
|
45
|
+
|
46
|
+
@file1 = File.new(File.join(@tmp_dir, 'file1.txt'), 'w')
|
47
|
+
@file1.puts("Goodbye World")
|
48
|
+
@file1.close
|
49
|
+
MD5Tracker.file_changed?(@file1.path, @tmp_dir).should be_true
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should detect a new file" do
|
53
|
+
@file2.close
|
54
|
+
MD5Tracker.file_changed?(@file1.path, @tmp_dir).should be_true
|
55
|
+
File.exist?(MD5Tracker.md5_file(@file1.path, @tmp_dir)).should be_true
|
56
|
+
end
|
57
|
+
end
|
data/spec/reek_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
REEK_RESULT = %("lib/metric_fu/base.rb" -- 5 warnings:
|
4
|
+
[Utility Function] #configuration doesn't depend on instance state
|
5
|
+
[Utility Function] #open_in_browser? doesn't depend on instance state
|
6
|
+
[Long Method] Configuration#reset has approx 6 statements
|
7
|
+
[Utility Function] Generator#cycle doesn't depend on instance state
|
8
|
+
[Utility Function] Generator#link_to_filename doesn't depend on instance state)
|
9
|
+
|
10
|
+
describe MetricFu::Reek do
|
11
|
+
|
12
|
+
describe "generate_html" do
|
13
|
+
it "should create a new Generator and call generate_report on it" do
|
14
|
+
@generator = MetricFu::Reek.new('other_dir')
|
15
|
+
@generator.should_receive(:`).and_return(REEK_RESULT)
|
16
|
+
@generator.generate_html
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "template_name" do
|
21
|
+
it "should return the class name in lowercase" do
|
22
|
+
flay = MetricFu::Reek.new('base_dir')
|
23
|
+
flay.template_name.should == 'reek'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
require File.join(File.dirname(__FILE__), '/../lib/metric_fu/base')
|
6
|
+
require File.join(File.dirname(__FILE__), '/../lib/metric_fu/flay')
|
7
|
+
require File.join(File.dirname(__FILE__), '/../lib/metric_fu/flog')
|
8
|
+
require File.join(File.dirname(__FILE__), '/../lib/metric_fu/md5_tracker')
|
9
|
+
require File.join(File.dirname(__FILE__), '/../lib/metric_fu/churn')
|
10
|
+
require File.join(File.dirname(__FILE__), '/../lib/metric_fu/reek')
|
11
|
+
include MetricFu
|