rferraz-metric_fu 2.1.1

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 (120) hide show
  1. data/HISTORY +237 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README +29 -0
  4. data/Rakefile +18 -0
  5. data/TODO +6 -0
  6. data/lib/base/base_template.rb +172 -0
  7. data/lib/base/churn_analyzer.rb +38 -0
  8. data/lib/base/code_issue.rb +97 -0
  9. data/lib/base/configuration.rb +199 -0
  10. data/lib/base/flay_analyzer.rb +50 -0
  11. data/lib/base/flog_analyzer.rb +43 -0
  12. data/lib/base/generator.rb +166 -0
  13. data/lib/base/graph.rb +44 -0
  14. data/lib/base/line_numbers.rb +74 -0
  15. data/lib/base/location.rb +85 -0
  16. data/lib/base/md5_tracker.rb +52 -0
  17. data/lib/base/metric_analyzer.rb +404 -0
  18. data/lib/base/ranking.rb +34 -0
  19. data/lib/base/rcov_analyzer.rb +43 -0
  20. data/lib/base/reek_analyzer.rb +163 -0
  21. data/lib/base/report.rb +108 -0
  22. data/lib/base/roodi_analyzer.rb +37 -0
  23. data/lib/base/saikuro_analyzer.rb +48 -0
  24. data/lib/base/scoring_strategies.rb +29 -0
  25. data/lib/base/stats_analyzer.rb +37 -0
  26. data/lib/base/table.rb +102 -0
  27. data/lib/generators/churn.rb +28 -0
  28. data/lib/generators/flay.rb +31 -0
  29. data/lib/generators/flog.rb +111 -0
  30. data/lib/generators/hotspots.rb +52 -0
  31. data/lib/generators/rails_best_practices.rb +53 -0
  32. data/lib/generators/rcov.rb +122 -0
  33. data/lib/generators/reek.rb +81 -0
  34. data/lib/generators/roodi.rb +35 -0
  35. data/lib/generators/saikuro.rb +256 -0
  36. data/lib/generators/stats.rb +58 -0
  37. data/lib/graphs/engines/bluff.rb +113 -0
  38. data/lib/graphs/engines/gchart.rb +157 -0
  39. data/lib/graphs/flay_grapher.rb +18 -0
  40. data/lib/graphs/flog_grapher.rb +57 -0
  41. data/lib/graphs/grapher.rb +11 -0
  42. data/lib/graphs/rails_best_practices_grapher.rb +19 -0
  43. data/lib/graphs/rcov_grapher.rb +18 -0
  44. data/lib/graphs/reek_grapher.rb +30 -0
  45. data/lib/graphs/roodi_grapher.rb +18 -0
  46. data/lib/graphs/stats_grapher.rb +20 -0
  47. data/lib/metric_fu.rb +40 -0
  48. data/lib/templates/awesome/awesome_template.rb +73 -0
  49. data/lib/templates/awesome/churn.html.erb +58 -0
  50. data/lib/templates/awesome/css/buttons.css +82 -0
  51. data/lib/templates/awesome/css/default.css +91 -0
  52. data/lib/templates/awesome/css/integrity.css +334 -0
  53. data/lib/templates/awesome/css/reset.css +7 -0
  54. data/lib/templates/awesome/css/syntax.css +19 -0
  55. data/lib/templates/awesome/flay.html.erb +34 -0
  56. data/lib/templates/awesome/flog.html.erb +55 -0
  57. data/lib/templates/awesome/hotspots.html.erb +62 -0
  58. data/lib/templates/awesome/index.html.erb +34 -0
  59. data/lib/templates/awesome/layout.html.erb +30 -0
  60. data/lib/templates/awesome/rails_best_practices.html.erb +27 -0
  61. data/lib/templates/awesome/rcov.html.erb +42 -0
  62. data/lib/templates/awesome/reek.html.erb +40 -0
  63. data/lib/templates/awesome/roodi.html.erb +27 -0
  64. data/lib/templates/awesome/saikuro.html.erb +71 -0
  65. data/lib/templates/awesome/stats.html.erb +51 -0
  66. data/lib/templates/javascripts/bluff-min.js +1 -0
  67. data/lib/templates/javascripts/excanvas.js +35 -0
  68. data/lib/templates/javascripts/js-class.js +1 -0
  69. data/lib/templates/standard/churn.html.erb +31 -0
  70. data/lib/templates/standard/default.css +64 -0
  71. data/lib/templates/standard/flay.html.erb +34 -0
  72. data/lib/templates/standard/flog.html.erb +57 -0
  73. data/lib/templates/standard/hotspots.html.erb +54 -0
  74. data/lib/templates/standard/index.html.erb +41 -0
  75. data/lib/templates/standard/rails_best_practices.html.erb +29 -0
  76. data/lib/templates/standard/rcov.html.erb +43 -0
  77. data/lib/templates/standard/reek.html.erb +42 -0
  78. data/lib/templates/standard/roodi.html.erb +29 -0
  79. data/lib/templates/standard/saikuro.html.erb +84 -0
  80. data/lib/templates/standard/standard_template.rb +26 -0
  81. data/lib/templates/standard/stats.html.erb +55 -0
  82. data/spec/base/base_template_spec.rb +177 -0
  83. data/spec/base/configuration_spec.rb +276 -0
  84. data/spec/base/generator_spec.rb +223 -0
  85. data/spec/base/graph_spec.rb +61 -0
  86. data/spec/base/line_numbers_spec.rb +62 -0
  87. data/spec/base/md5_tracker_spec.rb +57 -0
  88. data/spec/base/report_spec.rb +146 -0
  89. data/spec/generators/churn_spec.rb +41 -0
  90. data/spec/generators/flay_spec.rb +105 -0
  91. data/spec/generators/flog_spec.rb +70 -0
  92. data/spec/generators/rails_best_practices_spec.rb +52 -0
  93. data/spec/generators/rcov_spec.rb +180 -0
  94. data/spec/generators/reek_spec.rb +134 -0
  95. data/spec/generators/roodi_spec.rb +24 -0
  96. data/spec/generators/saikuro_spec.rb +74 -0
  97. data/spec/generators/stats_spec.rb +74 -0
  98. data/spec/graphs/engines/bluff_spec.rb +19 -0
  99. data/spec/graphs/engines/gchart_spec.rb +156 -0
  100. data/spec/graphs/flay_grapher_spec.rb +56 -0
  101. data/spec/graphs/flog_grapher_spec.rb +108 -0
  102. data/spec/graphs/rails_best_practices_grapher_spec.rb +61 -0
  103. data/spec/graphs/rcov_grapher_spec.rb +56 -0
  104. data/spec/graphs/reek_grapher_spec.rb +65 -0
  105. data/spec/graphs/roodi_grapher_spec.rb +56 -0
  106. data/spec/graphs/stats_grapher_spec.rb +68 -0
  107. data/spec/resources/line_numbers/foo.rb +33 -0
  108. data/spec/resources/line_numbers/module.rb +11 -0
  109. data/spec/resources/line_numbers/module_surrounds_class.rb +15 -0
  110. data/spec/resources/line_numbers/two_classes.rb +11 -0
  111. data/spec/resources/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
  112. data/spec/resources/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
  113. data/spec/resources/saikuro/index_cyclo.html +155 -0
  114. data/spec/resources/saikuro_sfiles/thing.rb_cyclo.html +11 -0
  115. data/spec/resources/yml/20090630.yml +7922 -0
  116. data/spec/resources/yml/metric_missing.yml +1 -0
  117. data/spec/spec.opts +6 -0
  118. data/spec/spec_helper.rb +7 -0
  119. data/tasks/metric_fu.rake +22 -0
  120. metadata +448 -0
@@ -0,0 +1,134 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Reek do
4
+ describe "emit" do
5
+ it "should include config parameters" do
6
+ MetricFu::Configuration.run do |config|
7
+ config.reek = {:config_file_pattern => 'lib/config/*.reek', :dirs_to_reek => []}
8
+ end
9
+ reek = MetricFu::Reek.new
10
+ reek.should_receive(:`).with(/--config lib\/config\/\*\.reek/).and_return("")
11
+ reek.emit
12
+ end
13
+ end
14
+
15
+ describe "analyze method" do
16
+ before :each do
17
+ @lines = <<-HERE
18
+ "app/controllers/activity_reports_controller.rb" -- 4 warnings:
19
+ ActivityReportsController#authorize_user calls current_user.primary_site_ids multiple times (Duplication)
20
+ ActivityReportsController#authorize_user calls params[id] multiple times (Duplication)
21
+ ActivityReportsController#authorize_user calls params[primary_site_id] multiple times (Duplication)
22
+ ActivityReportsController#authorize_user has approx 6 statements (Long Method)
23
+
24
+ "app/controllers/application.rb" -- 1 warnings:
25
+ ApplicationController#start_background_task/block/block is nested (Nested Iterators)
26
+
27
+ "app/controllers/link_targets_controller.rb" -- 1 warnings:
28
+ LinkTargetsController#authorize_user calls current_user.role multiple times (Duplication)
29
+
30
+ "app/controllers/newline_controller.rb" -- 1 warnings:
31
+ NewlineController#some_method calls current_user.<< "new line\n" multiple times (Duplication)
32
+ HERE
33
+ MetricFu::Configuration.run {}
34
+ File.stub!(:directory?).and_return(true)
35
+ reek = MetricFu::Reek.new
36
+ reek.instance_variable_set(:@output, @lines)
37
+ @matches = reek.analyze
38
+ end
39
+
40
+ it "should find the code smell's method name" do
41
+ smell = @matches.first[:code_smells].first
42
+ smell[:method].should == "ActivityReportsController#authorize_user"
43
+ end
44
+
45
+ it "should find the code smell's type" do
46
+ smell = @matches[1][:code_smells].first
47
+ smell[:type].should == "Nested Iterators"
48
+ end
49
+
50
+ it "should find the code smell's message" do
51
+ smell = @matches[1][:code_smells].first
52
+ smell[:message].should == "is nested"
53
+ end
54
+
55
+ it "should find the code smell's type" do
56
+ smell = @matches.first
57
+ smell[:file_path].should == "app/controllers/activity_reports_controller.rb"
58
+ end
59
+
60
+ it "should NOT insert nil smells into the array when there's a newline in the method call" do
61
+ @matches.last[:code_smells].should == @matches.last[:code_smells].compact
62
+ @matches.last.should == {:file_path=>"app/controllers/newline_controller.rb",
63
+ :code_smells=>[{:type=>"Duplication",
64
+ :method=>"\"",
65
+ :message=>"multiple times"}]}
66
+ # Note: hopefully a temporary solution until I figure out how to deal with newlines in the method call more effectively -Jake 5/11/2009
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ describe Reek do
73
+ before :each do
74
+ MetricFu::Configuration.run {}
75
+ @reek = MetricFu::Reek.new
76
+ @lines11 = <<-HERE
77
+ "app/controllers/activity_reports_controller.rb" -- 4 warnings:
78
+ ActivityReportsController#authorize_user calls current_user.primary_site_ids multiple times (Duplication)
79
+ ActivityReportsController#authorize_user calls params[id] multiple times (Duplication)
80
+ ActivityReportsController#authorize_user calls params[primary_site_id] multiple times (Duplication)
81
+ ActivityReportsController#authorize_user has approx 6 statements (Long Method)
82
+
83
+ "app/controllers/application.rb" -- 1 warnings:
84
+ ApplicationController#start_background_task/block/block is nested (Nested Iterators)
85
+
86
+ "app/controllers/link_targets_controller.rb" -- 1 warnings:
87
+ LinkTargetsController#authorize_user calls current_user.role multiple times (Duplication)
88
+
89
+ "app/controllers/newline_controller.rb" -- 1 warnings:
90
+ NewlineController#some_method calls current_user.<< "new line\n" multiple times (Duplication)
91
+ HERE
92
+ @lines12 = <<-HERE
93
+ app/controllers/activity_reports_controller.rb -- 4 warnings (+3 masked):
94
+ ActivityReportsController#authorize_user calls current_user.primary_site_ids multiple times (Duplication)
95
+ ActivityReportsController#authorize_user calls params[id] multiple times (Duplication)
96
+ ActivityReportsController#authorize_user calls params[primary_site_id] multiple times (Duplication)
97
+ ActivityReportsController#authorize_user has approx 6 statements (Long Method)
98
+ app/controllers/application.rb -- 1 warnings:
99
+ ApplicationController#start_background_task/block/block is nested (Nested Iterators)
100
+ app/controllers/link_targets_controller.rb -- 1 warnings (+1 masked):
101
+ LinkTargetsController#authorize_user calls current_user.role multiple times (Duplication)
102
+ app/controllers/newline_controller.rb -- 1 warnings:
103
+ NewlineController#some_method calls current_user.<< "new line\n" multiple times (Duplication)
104
+ HERE
105
+ end
106
+
107
+ context 'with Reek 1.1 output format' do
108
+ it 'reports 1.1 style when the output is empty' do
109
+ @reek.instance_variable_set(:@output, "")
110
+ @reek.should_not be_reek_12
111
+ end
112
+ it 'detects 1.1 format output' do
113
+ @reek.instance_variable_set(:@output, @lines11)
114
+ @reek.should_not be_reek_12
115
+ end
116
+
117
+ it 'massages empty output to be unchanged' do
118
+ @reek.instance_variable_set(:@output, "")
119
+ @reek.massage_for_reek_12.should be_empty
120
+ end
121
+ end
122
+
123
+ context 'with Reek 1.2 output format' do
124
+ it 'detects 1.2 format output' do
125
+ @reek.instance_variable_set(:@output, @lines12)
126
+ @reek.should be_reek_12
127
+ end
128
+
129
+ it 'correctly massages 1.2 output' do
130
+ @reek.instance_variable_set(:@output, @lines12)
131
+ @reek.massage_for_reek_12.should == @lines11
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Roodi do
4
+ describe "emit" do
5
+ it "should add config options when present" do
6
+ MetricFu::Configuration.run do |config|
7
+ config.roodi = {:roodi_config => 'lib/config/roodi_config.yml', :dirs_to_roodi => []}
8
+ end
9
+ roodi = MetricFu::Roodi.new
10
+ roodi.should_receive(:`).with(/-config=lib\/config\/roodi_config\.yml/).and_return("")
11
+ roodi.emit
12
+ end
13
+
14
+ it "should NOT add config options when NOT present" do
15
+ MetricFu::Configuration.run do |config|
16
+ config.roodi = {:dirs_to_roodi => []}
17
+ end
18
+ roodi = MetricFu::Roodi.new
19
+ roodi.stub(:`)
20
+ roodi.should_receive(:`).with(/-config/).never
21
+ roodi.emit
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,74 @@
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 == 'app/controllers/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 "per_file_info method" do
38
+ before :all do
39
+ MetricFu::Configuration.run {}
40
+ File.stub!(:directory?).and_return(true)
41
+ @saikuro = MetricFu::Saikuro.new
42
+ @saikuro.stub!(:metric_directory).and_return(File.join(File.dirname(__FILE__), "..", "resources", "saikuro"))
43
+ @saikuro.analyze
44
+ @output = @saikuro.to_h
45
+ end
46
+
47
+ it "doesn't try to get information if the file does not exist" do
48
+ File.should_receive(:exists?).at_least(:once).and_return(false)
49
+ @saikuro.per_file_info('ignore_me')
50
+ end
51
+ end
52
+
53
+ describe "format_directories method" do
54
+ it "should format the directories" do
55
+ MetricFu::Configuration.run {}
56
+ File.stub!(:directory?).and_return(true)
57
+ saikuro = MetricFu::Saikuro.new
58
+
59
+ MetricFu.saikuro[:input_directory] = ["app", "lib"]
60
+
61
+ saikuro.format_directories.should == "\"app | lib\""
62
+ end
63
+ end
64
+
65
+ describe Saikuro::SFile do
66
+ describe "getting elements from a Saikuro result file" do
67
+ it "should parse nested START/END sections" do
68
+ path = File.join(File.dirname(__FILE__), "..", "resources", "saikuro_sfiles", "thing.rb_cyclo.html")
69
+ sfile = Saikuro::SFile.new path
70
+ sfile.elements.map { |e| e.complexity }.sort.should eql(["0","0","2"])
71
+ end
72
+ end
73
+ end
74
+ 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,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+
3
+ describe "Bluff graphers responding to #graph!" do
4
+ it "should write chart file" do
5
+ MetricFu.configuration
6
+ graphs = {}
7
+ available_graphs = MetricFu::AVAILABLE_GRAPHS + [:stats]
8
+ available_graphs.each do |graph|
9
+ grapher_name = graph.to_s.gsub("MetricFu::",'').gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
10
+ grapher_name = grapher_name+"BluffGrapher"
11
+ graphs[graph] = MetricFu.const_get(grapher_name).new
12
+ end
13
+ graphs.each do |key, val|
14
+ val.graph!
15
+ output_dir = File.expand_path(File.join(MetricFu.output_directory))
16
+ lambda{ File.open(File.join(output_dir, "#{key.to_s.downcase}.js")) }.should_not raise_error
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,156 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
+ describe MetricFu::Grapher do
3
+ describe "require_graphing_gem" do
4
+ it "should give a warning if trying to use gchart but gem is not installed" do
5
+ MetricFu::Configuration.run {|config| config.graph_engine = :gchart}
6
+ MetricFu::Grapher.should_receive(:require).with('gchart').and_raise(LoadError)
7
+ MetricFu::Grapher.should_receive(:puts).with(/If you want to use google charts/)
8
+ MetricFu::Grapher.require_graphing_gem
9
+ end
10
+ end
11
+ end
12
+
13
+ describe MetricFu::GchartGrapher do
14
+ describe "determine_y_axis_scale" do
15
+ it "should set defaults when empty array" do
16
+ grapher = Object.new.extend(MetricFu::GchartGrapher)
17
+ grapher.determine_y_axis_scale([])
18
+ grapher.instance_variable_get(:@max_value).should == 10
19
+ grapher.instance_variable_get(:@yaxis).should == [0, 2, 4, 6, 8, 10]
20
+ end
21
+
22
+ it "should set max value of the graph above largest value" do
23
+ grapher = Object.new.extend(MetricFu::GchartGrapher)
24
+ grapher.determine_y_axis_scale([19])
25
+ grapher.instance_variable_get(:@max_value).should == 20
26
+
27
+ grapher.determine_y_axis_scale([20])
28
+ grapher.instance_variable_get(:@max_value).should == 25
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "Gchart graphers" do
34
+ before :each do
35
+ MetricFu::Configuration.run {|config| config.graph_engine = :gchart}
36
+ end
37
+
38
+ describe "FlayGchartGrapher graph! method" do
39
+ it "should set static values for graph" do
40
+ grapher = FlayGchartGrapher.new
41
+ expected = {
42
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
43
+ :title => URI.escape("Flay: duplication"),
44
+ :axis_with_labels => 'x,y',
45
+ :format => 'file',
46
+ :filename => File.join(MetricFu.output_directory, 'flay.png'),
47
+ }
48
+ Gchart.should_receive(:line).with(hash_including(expected))
49
+ grapher.graph!
50
+ end
51
+ end
52
+
53
+ describe "FlogGchartGrapher graph! method" do
54
+ it "should set static values for graph" do
55
+ grapher = FlogGchartGrapher.new
56
+ expected = {
57
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
58
+ :title => URI.escape("Flog: code complexity"),
59
+ :stacked => false,
60
+ :bar_colors => MetricFu::GchartGrapher::COLORS[0..1],
61
+ :legend => ['average', 'top 5% average'],
62
+ :custom => "chdlp=t",
63
+ :axis_with_labels => 'x,y',
64
+ :format => 'file',
65
+ :filename => File.join(MetricFu.output_directory, 'flog.png'),
66
+ }
67
+ Gchart.should_receive(:line).with(hash_including(expected))
68
+ grapher.graph!
69
+ end
70
+ end
71
+
72
+ describe "RcovGchartGrapher graph! method" do
73
+ it "should set static values for graph" do
74
+ grapher = RcovGchartGrapher.new
75
+ expected = {
76
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
77
+ :title => URI.escape("Rcov: code coverage"),
78
+ :max_value => 101,
79
+ :axis_with_labels => 'x,y',
80
+ :axis_labels => [grapher.labels.values, [0,20,40,60,80,100]],
81
+ :format => 'file',
82
+ :filename => File.join(MetricFu.output_directory, 'rcov.png'),
83
+ }
84
+ Gchart.should_receive(:line).with(hash_including(expected))
85
+ grapher.graph!
86
+ end
87
+ end
88
+
89
+ describe "ReekGchartGrapher graph! method" do
90
+ it "should set static values for graph" do
91
+ grapher = ReekGchartGrapher.new
92
+ expected = {
93
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
94
+ :title => URI.escape("Reek: code smells"),
95
+ :stacked => false,
96
+ :bar_colors => MetricFu::GchartGrapher::COLORS,
97
+ :axis_with_labels => 'x,y',
98
+ :format => 'file',
99
+ :filename => File.join(MetricFu.output_directory, 'reek.png'),
100
+ }
101
+ Gchart.should_receive(:line).with(hash_including(expected))
102
+ grapher.graph!
103
+ end
104
+ end
105
+
106
+ describe "RoodiGchartGrapher graph! method" do
107
+ it "should set static values for graph" do
108
+ grapher = RoodiGchartGrapher.new
109
+ expected = {
110
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
111
+ :title => URI.escape("Roodi: potential design problems"),
112
+ :axis_with_labels => 'x,y',
113
+ :format => 'file',
114
+ :filename => File.join(MetricFu.output_directory, 'roodi.png'),
115
+ }
116
+ Gchart.should_receive(:line).with(hash_including(expected))
117
+ grapher.graph!
118
+ end
119
+ end
120
+
121
+ describe "StatsGchartGrapher graph! method" do
122
+ it "should set static values for graph" do
123
+ grapher = StatsGchartGrapher.new
124
+ expected = {
125
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
126
+ :title => URI.escape("Stats: LOC & LOT"),
127
+ :bar_colors => MetricFu::GchartGrapher::COLORS[0..1],
128
+ :legend => ['Lines of code', 'Lines of test'],
129
+ :custom => "chdlp=t",
130
+ :axis_with_labels => 'x,y',
131
+ :format => 'file',
132
+ :filename => File.join(MetricFu.output_directory, 'stats.png'),
133
+ }
134
+ Gchart.should_receive(:line).with(hash_including(expected))
135
+ grapher.graph!
136
+ end
137
+ end
138
+
139
+ describe "RailsBestPracticesGchartGrapher graph! method" do
140
+ it "should set static values for graph" do
141
+ grapher = RailsBestPracticesGchartGrapher.new
142
+ expected = {
143
+ :size => MetricFu::GchartGrapher::GCHART_GRAPH_SIZE,
144
+ :title => URI.escape("Rails Best Practices: design problems"),
145
+ :bar_colors => MetricFu::GchartGrapher::COLORS[0..1],
146
+ :legend => ['Problems'],
147
+ :custom => "chdlp=t",
148
+ :axis_with_labels => 'x,y',
149
+ :format => 'file',
150
+ :filename => File.join(MetricFu.output_directory, 'rails_best_practices.png'),
151
+ }
152
+ Gchart.should_receive(:line).with(hash_including(expected))
153
+ grapher.graph!
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,56 @@
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
+ context "when metrics were not generated" do
23
+ before(:each) do
24
+ @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "metric_missing.yml")))
25
+ @date = "1/2"
26
+ end
27
+
28
+ it "should not push to flay_score" do
29
+ @flay_grapher.flay_score.should_not_receive(:push)
30
+ @flay_grapher.get_metrics(@metrics, @date)
31
+ end
32
+
33
+ it "should not update labels with the date" do
34
+ @flay_grapher.labels.should_not_receive(:update)
35
+ @flay_grapher.get_metrics(@metrics, @date)
36
+ end
37
+ end
38
+
39
+ context "when metrics have been generated" do
40
+ before(:each) do
41
+ @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
42
+ @date = "1/2"
43
+ end
44
+
45
+ it "should push to flay_score" do
46
+ @flay_grapher.flay_score.should_receive(:push).with(476)
47
+ @flay_grapher.get_metrics(@metrics, @date)
48
+ end
49
+
50
+ it "should update labels with the date" do
51
+ @flay_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
52
+ @flay_grapher.get_metrics(@metrics, @date)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,108 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe MetricFu::FlogGrapher do
4
+ before :each do
5
+ MetricFu.configuration
6
+ @flog_grapher = MetricFu::FlogGrapher.new
7
+
8
+ end
9
+
10
+ it "should respond to flog_total, flog_average and labels" do
11
+ @flog_grapher.should respond_to(:flog_average)
12
+ @flog_grapher.should respond_to(:labels)
13
+ @flog_grapher.should respond_to(:top_five_percent_average)
14
+ end
15
+
16
+ describe "responding to #initialize" do
17
+ it "should initialize top_five_percent_average, flog_average and labels" do
18
+ @flog_grapher.flog_average.should == []
19
+ @flog_grapher.labels.should == {}
20
+ @flog_grapher.top_five_percent_average.should == []
21
+ end
22
+ end
23
+
24
+ describe "responding to #get_metrics" do
25
+ before(:each) do
26
+ methods = {}
27
+ 100.times do |i|
28
+ methods["method_name_#{i}"] = {:score => i.to_f}
29
+ end
30
+
31
+ @metrics = {:flog => {:total => 111.1,
32
+ :average => 7.7,
33
+ :method_containers => [ {:methods => methods } ] } }
34
+ @date = "1/2"
35
+ end
36
+
37
+ it "should push to top_five_percent_average" do
38
+ average = (99.0 + 98.0 + 97.0 + 96.0 + 95.0) / 5.0
39
+ @flog_grapher.top_five_percent_average.should_receive(:push).with(average)
40
+ @flog_grapher.get_metrics(@metrics, @date)
41
+ end
42
+
43
+ it "should push 9.9 to flog_average" do
44
+ @flog_grapher.flog_average.should_receive(:push).with(7.7)
45
+ @flog_grapher.get_metrics(@metrics, @date)
46
+ end
47
+
48
+ context "when metrics were not generated" do
49
+ before(:each) do
50
+ @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "metric_missing.yml")))
51
+ @date = "1/2"
52
+ end
53
+
54
+ it "should not push to top_five_percent_average" do
55
+ @flog_grapher.top_five_percent_average.should_not_receive(:push)
56
+ @flog_grapher.get_metrics(@metrics, @date)
57
+ end
58
+
59
+ it "should not push to flog_average" do
60
+ @flog_grapher.flog_average.should_not_receive(:push)
61
+ @flog_grapher.get_metrics(@metrics, @date)
62
+ end
63
+
64
+ it "should not update labels with the date" do
65
+ @flog_grapher.labels.should_not_receive(:update)
66
+ @flog_grapher.get_metrics(@metrics, @date)
67
+ end
68
+ end
69
+
70
+ context "when metrics have been generated" do
71
+ before(:each) do
72
+ @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
73
+ @date = "1/2"
74
+ end
75
+
76
+ it "should push to top_five_percent_average" do
77
+ average = (73.6 + 68.5 + 66.1 + 46.6 + 44.8 + 44.1 + 41.2 + 36.0) / 8.0
78
+ @flog_grapher.top_five_percent_average.should_receive(:push).with(average)
79
+ @flog_grapher.get_metrics(@metrics, @date)
80
+ end
81
+
82
+ it "should push to flog_average" do
83
+ @flog_grapher.flog_average.should_receive(:push).with(9.9)
84
+ @flog_grapher.get_metrics(@metrics, @date)
85
+ end
86
+
87
+ it "should update labels with the date" do
88
+ @flog_grapher.labels.should_receive(:update).with({ 0 => "1/2" })
89
+ @flog_grapher.get_metrics(@metrics, @date)
90
+ end
91
+ end
92
+ end
93
+
94
+ describe "responding to #get_metrics with legacy data" do
95
+ before(:each) do
96
+ @metrics = YAML::load(File.open(File.join(File.dirname(__FILE__), "..", "resources", "yml", "20090630.yml")))
97
+
98
+ @date = "1/2"
99
+ end
100
+
101
+ it "should push to top_five_percent_average" do
102
+ average = (73.6 + 68.5 + 66.1 + 46.6 + 44.8 + 44.1 + 41.2 + 36.0) / 8.0
103
+ @flog_grapher.top_five_percent_average.should_receive(:push).with(average)
104
+ @flog_grapher.get_metrics(@metrics, @date)
105
+ end
106
+ end
107
+
108
+ end