pjstadig-metric_fu 1.1.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/HISTORY +155 -0
  2. data/MIT-LICENSE +22 -0
  3. data/Manifest.txt +25 -0
  4. data/README +1 -0
  5. data/Rakefile +18 -0
  6. data/TODO +9 -0
  7. data/lib/base/base_template.rb +146 -0
  8. data/lib/base/configuration.rb +187 -0
  9. data/lib/base/generator.rb +160 -0
  10. data/lib/base/graph.rb +38 -0
  11. data/lib/base/md5_tracker.rb +52 -0
  12. data/lib/base/report.rb +100 -0
  13. data/lib/generators/churn.rb +90 -0
  14. data/lib/generators/flay.rb +33 -0
  15. data/lib/generators/flog.rb +140 -0
  16. data/lib/generators/rcov.rb +91 -0
  17. data/lib/generators/reek.rb +37 -0
  18. data/lib/generators/roodi.rb +31 -0
  19. data/lib/generators/saikuro.rb +208 -0
  20. data/lib/generators/stats.rb +43 -0
  21. data/lib/graphs/flay_grapher.rb +35 -0
  22. data/lib/graphs/flog_grapher.rb +51 -0
  23. data/lib/graphs/grapher.rb +19 -0
  24. data/lib/graphs/rcov_grapher.rb +34 -0
  25. data/lib/graphs/reek_grapher.rb +44 -0
  26. data/lib/graphs/roodi_grapher.rb +34 -0
  27. data/lib/metric_fu.rb +30 -0
  28. data/lib/templates/awesome/awesome_template.rb +30 -0
  29. data/lib/templates/awesome/churn.html.erb +19 -0
  30. data/lib/templates/awesome/css/buttons.css +82 -0
  31. data/lib/templates/awesome/css/default.css +75 -0
  32. data/lib/templates/awesome/css/integrity.css +335 -0
  33. data/lib/templates/awesome/css/reset.css +7 -0
  34. data/lib/templates/awesome/flay.html.erb +27 -0
  35. data/lib/templates/awesome/flog.html.erb +47 -0
  36. data/lib/templates/awesome/index.html.erb +28 -0
  37. data/lib/templates/awesome/layout.html.erb +27 -0
  38. data/lib/templates/awesome/rcov.html.erb +36 -0
  39. data/lib/templates/awesome/reek.html.erb +34 -0
  40. data/lib/templates/awesome/roodi.html.erb +21 -0
  41. data/lib/templates/awesome/saikuro.html.erb +71 -0
  42. data/lib/templates/awesome/stats.html.erb +41 -0
  43. data/lib/templates/standard/churn.html.erb +31 -0
  44. data/lib/templates/standard/default.css +64 -0
  45. data/lib/templates/standard/flay.html.erb +34 -0
  46. data/lib/templates/standard/flog.html.erb +53 -0
  47. data/lib/templates/standard/index.html.erb +38 -0
  48. data/lib/templates/standard/rcov.html.erb +43 -0
  49. data/lib/templates/standard/reek.html.erb +42 -0
  50. data/lib/templates/standard/roodi.html.erb +29 -0
  51. data/lib/templates/standard/saikuro.html.erb +84 -0
  52. data/lib/templates/standard/standard_template.rb +26 -0
  53. data/lib/templates/standard/stats.html.erb +55 -0
  54. data/spec/base/base_template_spec.rb +161 -0
  55. data/spec/base/configuration_spec.rb +300 -0
  56. data/spec/base/generator_spec.rb +181 -0
  57. data/spec/base/graph_spec.rb +24 -0
  58. data/spec/base/md5_tracker_spec.rb +57 -0
  59. data/spec/base/report_spec.rb +139 -0
  60. data/spec/generators/churn_spec.rb +152 -0
  61. data/spec/generators/flay_spec.rb +104 -0
  62. data/spec/generators/flog_spec.rb +219 -0
  63. data/spec/generators/reek_spec.rb +60 -0
  64. data/spec/generators/saikuro_spec.rb +58 -0
  65. data/spec/generators/stats_spec.rb +74 -0
  66. data/spec/graphs/flay_grapher_spec.rb +44 -0
  67. data/spec/graphs/flog_grapher_spec.rb +61 -0
  68. data/spec/graphs/grapher_spec.rb +9 -0
  69. data/spec/graphs/rcov_grapher_spec.rb +44 -0
  70. data/spec/graphs/reek_grapher_spec.rb +53 -0
  71. data/spec/graphs/roodi_grapher_spec.rb +44 -0
  72. data/spec/resources/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
  73. data/spec/resources/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
  74. data/spec/resources/saikuro/index_cyclo.html +155 -0
  75. data/spec/resources/saikuro_sfiles/thing.rb_cyclo.html +11 -0
  76. data/spec/resources/yml/20090630.yml +7844 -0
  77. data/spec/spec.opts +8 -0
  78. data/spec/spec_helper.rb +6 -0
  79. data/tasks/metric_fu.rake +22 -0
  80. data/vendor/_fonts/monaco.ttf +0 -0
  81. data/vendor/saikuro/saikuro.rb +1219 -0
  82. metadata +180 -0
@@ -0,0 +1,219 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ describe Flog do
3
+ before :each do
4
+ @text = <<-HERE
5
+ 157.9: flog total
6
+ 11.3: flog/method average
7
+
8
+ 34.8: UsersController#create
9
+ 9.2: branch
10
+ 6.8: current_user
11
+ 5.2: assignment
12
+ 3.4: role
13
+ 3.0: render
14
+ 3.0: ==
15
+ 2.8: flash
16
+ 1.6: after_create_page
17
+ 1.6: params
18
+ 1.5: activate!
19
+ 1.5: errors
20
+ 1.4: login
21
+ 1.4: redirect_to
22
+ 1.4: []
23
+ 1.3: empty?
24
+ 1.3: save
25
+ 1.2: new
26
+ 24.2: UsersController#authorize_user
27
+ 4.8: branch
28
+ 4.7: current_user
29
+ 3.6: params
30
+ 3.2: []
31
+ 2.6: ==
32
+ 1.5: role
33
+ 1.5: to_i
34
+ 1.5: id
35
+ 1.4: new_session_path
36
+ 1.3: include?
37
+ 1.2: assignment
38
+ 1.2: flash
39
+ 1.2: redirect_to
40
+ 16.4: UsersController#thank_you
41
+ 4.0: assignment
42
+ 3.3: params
43
+ 2.9: []
44
+ 2.7: redirect_to
45
+ 2.4: branch
46
+ 1.5: new_session_path
47
+ 1.4: flash
48
+ 1.4: activate!
49
+ 1.3: can_activate?
50
+ 1.2: find_by_id
51
+ 14.2: UsersController#update
52
+ 3.2: params
53
+ 2.8: []
54
+ 2.6: assignment
55
+ 1.4: login
56
+ 1.4: flash
57
+ 1.4: redirect_to
58
+ 1.3: render
59
+ 1.2: branch
60
+ 1.2: update_attributes
61
+ 1.2: find_by_id
62
+ 12.5: UsersController#sanitize_params
63
+ 3.9: assignment
64
+ 3.6: branch
65
+ 3.0: current_user
66
+ 1.6: params
67
+ 1.5: role
68
+ 1.4: []
69
+ 1.3: include?
70
+ 1.3: ==
71
+ 1.2: reject!
72
+ 10.6: UsersController#users_have_changed
73
+ 3.9: assignment
74
+ 2.6: branch
75
+ 1.6: params
76
+ 1.5: refresh_from_external
77
+ 1.4: find_by_id
78
+ 1.4: []
79
+ 1.2: split
80
+ 1.2: each
81
+ 1.2: head
82
+ 10.0: UsersController#after_create_page
83
+ 3.0: current_user
84
+ 2.6: id
85
+ 2.4: branch
86
+ 1.5: role
87
+ 1.3: login
88
+ 1.3: ==
89
+ 8.4: UsersController#add_primary_site
90
+ 2.4: assignment
91
+ 1.6: params
92
+ 1.4: []
93
+ 1.4: new
94
+ 1.2: find_by_id
95
+ 1.2: all
96
+ 1.2: render
97
+ 7.7: UsersController#none
98
+ 3.3: before_filter
99
+ 1.1: private
100
+ 1.1: caches_page
101
+ 1.1: after_filter
102
+ 1.1: skip_before_filter
103
+ 7.2: UsersController#destroy
104
+ 1.8: params
105
+ 1.6: []
106
+ 1.4: find_by_id
107
+ 1.2: destroy
108
+ 1.2: redirect_to
109
+ 5.9: UsersController#edit
110
+ 2.4: assignment
111
+ 1.6: params
112
+ 1.4: []
113
+ 1.2: all
114
+ 1.2: find_by_id
115
+ 2.7: UsersController#signup
116
+ 1.2: render
117
+ 1.2: assignment
118
+ 1.2: new
119
+ 1.7: UsersController#new
120
+ 1.2: assignment
121
+ 1.2: new
122
+ 1.7: UsersController#index
123
+ 1.2: assignment
124
+ 1.2: all
125
+ HERE
126
+ MetricFu::Flog.stub!(:verify_dependencies!).and_return(true)
127
+ end
128
+
129
+ describe "parse method" do
130
+ before :each do
131
+ MetricFu::Configuration.run {}
132
+ File.stub!(:directory?).and_return(true)
133
+ flog = MetricFu::Flog.new('base_dir')
134
+ @flog_page = flog.parse(@text)
135
+ end
136
+
137
+ it "should find the total score" do
138
+ @flog_page.score.should == 157.9
139
+ end
140
+
141
+ it "should find the average score" do
142
+ @flog_page.average_score.should == 11.3
143
+ end
144
+
145
+ it "should find the scanned method score" do
146
+ @flog_page.scanned_methods.first.score.should == 34.8
147
+ end
148
+
149
+ it "should find the scanned method name" do
150
+ @flog_page.scanned_methods.first.name.should == "UsersController#create"
151
+ end
152
+
153
+ it "should find the scanned method opperators names" do
154
+ @flog_page.scanned_methods.first.operators.first.operator.should == "branch"
155
+ end
156
+
157
+ it "should find the scanned method opperators scores" do
158
+ @flog_page.scanned_methods.first.operators.first.score.should == 9.2
159
+ end
160
+
161
+ it "should find the name of the method even if namespaced" do
162
+ text = <<-HERE
163
+ 157.9: flog total
164
+ 11.3: flog/method average
165
+
166
+ 34.8: SomeNamespace::UsersController#create
167
+ HERE
168
+ flog = MetricFu::Flog.new('base_dir')
169
+ flog_page = flog.parse(text)
170
+ flog_page.scanned_methods.first.name.should == "SomeNamespace::UsersController#create"
171
+ end
172
+
173
+ it "should parse empty flog files" do
174
+ text = ""
175
+ flog = MetricFu::Flog.new('base_dir')
176
+ flog_page = flog.parse(text)
177
+ flog_page.should be_nil
178
+ end
179
+ end
180
+
181
+ describe "to_h function with results" do
182
+ before :each do
183
+ MetricFu::Configuration.run {}
184
+ File.stub!(:directory?).and_return(true)
185
+ flog = MetricFu::Flog.new('base_dir')
186
+ flog.should_receive(:open).and_return(@text)
187
+ Dir.should_receive(:glob).and_return(["tmp/metric_fu/scratch/flog/app/controllers/user_controller.txt"])
188
+ flog.analyze
189
+ @flog_hash = flog.to_h
190
+ end
191
+
192
+ it "should put the total in the hash" do
193
+ @flog_hash[:flog][:total].should == 157.9
194
+ end
195
+
196
+ it "should put the average in the hash" do
197
+ @flog_hash[:flog][:average].should == 11.3
198
+ end
199
+
200
+ it "should put pages into the hash" do
201
+ @flog_hash[:flog][:pages].first[:scanned_methods].first[:score].should == 34.8
202
+ end
203
+
204
+ it "should put the filename into the hash" do
205
+ @flog_hash[:flog][:pages].first[:path].should == "/app/controllers/user_controller.rb"
206
+ end
207
+ end
208
+
209
+ describe "to_h function with zero total" do
210
+ it "should not blow up" do
211
+ MetricFu::Configuration.run {}
212
+ File.stub!(:directory?).and_return(true)
213
+ flog = MetricFu::Flog.new('base_dir')
214
+ flog.should_receive(:open).and_return("") # some sort of empty or unparsable file
215
+ Dir.should_receive(:glob).and_return(["empty_file.txt"])
216
+ flog.analyze
217
+ end
218
+ end
219
+ end
@@ -0,0 +1,60 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Reek do
4
+ describe "analyze method" do
5
+ before :each do
6
+ MetricFu::Reek.stub!(:verify_dependencies!).and_return(true)
7
+ @lines = <<-HERE
8
+ "app/controllers/activity_reports_controller.rb" -- 4 warnings:
9
+ ActivityReportsController#authorize_user calls current_user.primary_site_ids multiple times (Duplication)
10
+ ActivityReportsController#authorize_user calls params[id] multiple times (Duplication)
11
+ ActivityReportsController#authorize_user calls params[primary_site_id] multiple times (Duplication)
12
+ ActivityReportsController#authorize_user has approx 6 statements (Long Method)
13
+
14
+ "app/controllers/application.rb" -- 1 warnings:
15
+ ApplicationController#start_background_task/block/block is nested (Nested Iterators)
16
+
17
+ "app/controllers/link_targets_controller.rb" -- 1 warnings:
18
+ LinkTargetsController#authorize_user calls current_user.role multiple times (Duplication)
19
+
20
+ "app/controllers/newline_controller.rb" -- 1 warnings:
21
+ NewlineController#some_method calls current_user.<< "new line\n" multiple times (Duplication)
22
+ HERE
23
+ MetricFu::Configuration.run {}
24
+ File.stub!(:directory?).and_return(true)
25
+ reek = MetricFu::Reek.new
26
+ reek.instance_variable_set(:@output, @lines)
27
+ @matches = reek.analyze
28
+ end
29
+
30
+ it "should find the code smell's method name" do
31
+ smell = @matches.first[:code_smells].first
32
+ smell[:method].should == "ActivityReportsController#authorize_user"
33
+ end
34
+
35
+ it "should find the code smell's type" do
36
+ smell = @matches[1][:code_smells].first
37
+ smell[:type].should == "Nested Iterators"
38
+ end
39
+
40
+ it "should find the code smell's message" do
41
+ smell = @matches[1][:code_smells].first
42
+ smell[:message].should == "is nested"
43
+ end
44
+
45
+ it "should find the code smell's type" do
46
+ smell = @matches.first
47
+ smell[:file_path].should == "app/controllers/activity_reports_controller.rb"
48
+ end
49
+
50
+ it "should NOT insert nil smells into the array when there's a newline in the method call" do
51
+ @matches.last[:code_smells].should == @matches.last[:code_smells].compact
52
+ @matches.last.should == {:file_path=>"app/controllers/newline_controller.rb",
53
+ :code_smells=>[{:type=>"Duplication",
54
+ :method=>"\"",
55
+ :message=>"multiple times"}]}
56
+ # Note: hopefully a temporary solution until I figure out how to deal with newlines in the method call more effectively -Jake 5/11/2009
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Saikuro do
4
+ describe "to_h method" do
5
+ before :all do
6
+ MetricFu::Configuration.run {}
7
+ File.stub!(:directory?).and_return(true)
8
+ saikuro = MetricFu::Saikuro.new
9
+ saikuro.stub!(:metric_directory).and_return(File.join(File.dirname(__FILE__), "..", "resources", "saikuro"))
10
+ saikuro.analyze
11
+ @output = saikuro.to_h
12
+ end
13
+
14
+ it "should find the filename of a file" do
15
+ @output[:saikuro][:files].first[:filename].should == 'users_controller.rb'
16
+ end
17
+
18
+ it "should find the name of the classes" do
19
+ @output[:saikuro][:classes].first[:name].should == "UsersController"
20
+ @output[:saikuro][:classes][1][:name].should == "SessionsController"
21
+ end
22
+
23
+ it "should put the most complex method first" do
24
+ @output[:saikuro][:methods].first[:name].should == "UsersController#create"
25
+ @output[:saikuro][:methods].first[:complexity].should == 4
26
+ end
27
+
28
+ it "should find the complexity of a method" do
29
+ @output[:saikuro][:methods].first[:complexity].should == 4
30
+ end
31
+
32
+ it "should find the lines of a method" do
33
+ @output[:saikuro][:methods].first[:lines].should == 15
34
+ end
35
+ end
36
+
37
+ describe "format_directories method" do
38
+ it "should format the directories" do
39
+ MetricFu::Configuration.run {}
40
+ File.stub!(:directory?).and_return(true)
41
+ saikuro = MetricFu::Saikuro.new
42
+
43
+ MetricFu.saikuro[:input_directory] = ["app", "lib"]
44
+
45
+ saikuro.format_directories.should == "\"app | lib\""
46
+ end
47
+ end
48
+
49
+ describe Saikuro::SFile do
50
+ describe "getting elements from a Saikuro result file" do
51
+ it "should parse nested START/END sections" do
52
+ path = File.join(File.dirname(__FILE__), "..", "resources", "saikuro_sfiles", "thing.rb_cyclo.html")
53
+ sfile = Saikuro::SFile.new path
54
+ sfile.elements.map { |e| e.complexity }.sort.should eql(["0","0","2"])
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,74 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Stats do
4
+ describe "emit method" do
5
+ it "should gather the raw data" do
6
+ MetricFu::Configuration.run {}
7
+ File.stub!(:directory?).and_return(true)
8
+ stats = MetricFu::Stats.new
9
+ stats.should_receive(:`).with("rake stats > tmp/metric_fu/scratch/stats/stats.txt")
10
+ stats.emit
11
+ end
12
+ end
13
+
14
+ describe "analyze method" do
15
+ before :each do
16
+ @lines = <<-HERE.gsub(/^\s*/, "")
17
+ +----------------------+-------+-------+---------+---------+-----+-------+
18
+ | Name | Lines | LOC | Classes | Methods | M/C | LOC/M |
19
+ +----------------------+-------+-------+---------+---------+-----+-------+
20
+ | Controllers | 470 | 382 | 7 | 53 | 7 | 5 |
21
+ | Helpers | 128 | 65 | 0 | 6 | 0 | 8 |
22
+ | Models | 351 | 285 | 9 | 31 | 3 | 7 |
23
+ | Libraries | 305 | 183 | 2 | 30 | 15 | 4 |
24
+ | Model specs | 860 | 719 | 0 | 2 | 0 | 357 |
25
+ | View specs | 0 | 0 | 0 | 0 | 0 | 0 |
26
+ | Controller specs | 1570 | 1308 | 1 | 10 | 10 | 128 |
27
+ | Helper specs | 191 | 172 | 0 | 0 | 0 | 0 |
28
+ | Library specs | 31 | 27 | 0 | 0 | 0 | 0 |
29
+ +----------------------+-------+-------+---------+---------+-----+-------+
30
+ | Total | 3906 | 3141 | 19 | 132 | 6 | 21 |
31
+ +----------------------+-------+-------+---------+---------+-----+-------+
32
+ Code LOC: 915 Test LOC: 2226 Code to Test Ratio: 1:2.4
33
+
34
+ HERE
35
+ MetricFu::Configuration.run {}
36
+ File.stub!(:directory?).and_return(true)
37
+ stats = MetricFu::Stats.new
38
+ File.should_receive(:open).and_return(mock("file", :read => @lines))
39
+ @results = stats.analyze
40
+ end
41
+
42
+ it "should get code Lines Of Code" do
43
+ @results[:codeLOC].should == 915
44
+ end
45
+
46
+ it "should get test Lines Of Code" do
47
+ @results[:testLOC].should == 2226
48
+ end
49
+
50
+ it "should get code to test ratio" do
51
+ @results[:code_to_test_ratio].should == 2.4
52
+ end
53
+
54
+ it "should get data on models" do
55
+ model_data = @results[:lines].find {|line| line[:name] == "Models"}
56
+ model_data[:classes].should == 9
57
+ model_data[:methods].should == 31
58
+ model_data[:loc].should == 285
59
+ model_data[:lines].should == 351
60
+ model_data[:methods_per_class].should == 3
61
+ model_data[:loc_per_method].should == 7
62
+ end
63
+ end
64
+
65
+ describe "to_h method" do
66
+ it "should put things into a hash" do
67
+ MetricFu::Configuration.run {}
68
+ File.stub!(:directory?).and_return(true)
69
+ stats = MetricFu::Stats.new
70
+ stats.instance_variable_set(:@stats, "the_stats")
71
+ stats.to_h[:stats].should == "the_stats"
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe FlayGrapher do
4
+ before :each do
5
+ @flay_grapher = MetricFu::FlayGrapher.new
6
+ MetricFu.configuration
7
+ end
8
+
9
+ it "should respond to flay_score and labels" do
10
+ @flay_grapher.should respond_to(:flay_score)
11
+ @flay_grapher.should respond_to(:labels)
12
+ end
13
+
14
+ describe "responding to #initialize" do
15
+ it "should initialise flay_score and labels" do
16
+ @flay_grapher.flay_score.should == []
17
+ @flay_grapher.labels.should == {}
18
+ end
19
+ end
20
+
21
+ describe "responding to #get_metrics" do
22
+ before(:each) do
23
+ @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
24
+ @date = "01022003"
25
+ end
26
+
27
+ it "should push 476 to flay_score" do
28
+ @flay_grapher.flay_score.should_receive(:push).with(476)
29
+ @flay_grapher.get_metrics(@metrics, @date)
30
+ end
31
+
32
+ it "should update labels with the date" do
33
+ @flay_grapher.labels.should_receive(:update).with({ 0 => "01022003" })
34
+ @flay_grapher.get_metrics(@metrics, @date)
35
+ end
36
+ end
37
+
38
+ describe "responding to #graph!" do
39
+ it "should write flay.png" do
40
+ @flay_grapher.graph!
41
+ lambda{ File.open(File.join(MetricFu.output_directory, 'flay.png')) }.should_not raise_error
42
+ end
43
+ end
44
+ end