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,276 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe MetricFu::Configuration do
4
+
5
+ def get_new_config
6
+ @config = Configuration.new
7
+ end
8
+
9
+ def base_directory
10
+ @config.instance_variable_get(:@base_directory)
11
+ end
12
+
13
+ def output_directory
14
+ @config.instance_variable_get(:@output_directory)
15
+ end
16
+
17
+ def scratch_directory
18
+ @config.instance_variable_get(:@scratch_directory)
19
+ end
20
+
21
+ def template_directory
22
+ @config.instance_variable_get(:@template_directory)
23
+ end
24
+
25
+ def template_class
26
+ @config.instance_variable_get(:@template_class)
27
+ end
28
+
29
+ def metric_fu_root
30
+ @config.instance_variable_get(:@metric_fu_root_directory)
31
+ end
32
+
33
+ describe "#reset" do
34
+
35
+ before(:each) { get_new_config }
36
+
37
+ describe 'when there is a CC_BUILD_ARTIFACTS environment variable' do
38
+ before(:each) { ENV['CC_BUILD_ARTIFACTS'] = 'foo' }
39
+
40
+ it 'should return the CC_BUILD_ARTIFACTS environment variable' do
41
+ get_new_config
42
+ base_directory.should == ENV['CC_BUILD_ARTIFACTS']
43
+ end
44
+ end
45
+
46
+ describe 'when there is no CC_BUILD_ARTIFACTS environment variable' do
47
+ before(:each) { ENV['CC_BUILD_ARTIFACTS'] = nil }
48
+
49
+ it 'should return "tmp/metric_fu"' do
50
+ get_new_config
51
+ base_directory.should == "tmp/metric_fu"
52
+ end
53
+ end
54
+
55
+ it 'should set @metric_fu_root_directory to the base of the '+
56
+ 'metric_fu application' do
57
+ app_root = File.join(File.dirname(__FILE__), '..', '..')
58
+ app_root_absolute_path = File.expand_path(app_root)
59
+ metric_fu_absolute_path = File.expand_path(metric_fu_root)
60
+ metric_fu_absolute_path.should == app_root_absolute_path
61
+ end
62
+
63
+ it 'should set @template_directory to the lib/templates relative '+
64
+ 'to @metric_fu_root_directory' do
65
+ template_dir = File.join(File.dirname(__FILE__),
66
+ '..', '..', 'lib','templates')
67
+ template_dir_abs_path = File.expand_path(template_dir)
68
+ calc_template_dir_abs_path = File.expand_path(template_directory)
69
+ calc_template_dir_abs_path.should == template_dir_abs_path
70
+ end
71
+
72
+ it 'should set @scratch_directory to scratch relative '+
73
+ 'to @base_directory' do
74
+ scratch_dir = File.join(base_directory, 'scratch')
75
+ scratch_directory.should == scratch_dir
76
+ end
77
+
78
+ it 'should set @output_directory to output relative '+
79
+ 'to @base_directory' do
80
+ output_dir = File.join(base_directory, 'output')
81
+ output_directory.should == output_dir
82
+ end
83
+
84
+ it 'should set @template_class to AwesomeTemplate' do
85
+ template_class.should == AwesomeTemplate
86
+ end
87
+
88
+ it 'should set @flay to {:dirs_to_flay => @code_dirs}' do
89
+ @config.instance_variable_get(:@flay).
90
+ should == {:dirs_to_flay => ['lib'], :filetypes=>["rb"], :minimum_score => 100}
91
+ end
92
+
93
+ it 'should set @flog to {:dirs_to_flog => @code_dirs}' do
94
+ @config.instance_variable_get(:@flog).
95
+ should == {:dirs_to_flog => ['lib']}
96
+ end
97
+
98
+ it 'should set @reek to {:dirs_to_reek => @code_dirs}' do
99
+ @config.instance_variable_get(:@reek).
100
+ should == {:config_file_pattern=>nil, :dirs_to_reek => ['lib']}
101
+ end
102
+
103
+ it 'should set @roodi to {:dirs_to_roodi => @code_dirs}' do
104
+ @config.instance_variable_get(:@roodi).
105
+ should == {:roodi_config=>nil, :dirs_to_roodi => ['lib']}
106
+ end
107
+
108
+ it 'should set @churn to {}' do
109
+ @config.instance_variable_get(:@churn).
110
+ should == {}
111
+ end
112
+
113
+ it 'should set @stats to {}' do
114
+ @config.instance_variable_get(:@stats).
115
+ should == {}
116
+ end
117
+
118
+ it 'should set @rails_best_practices to {}' do
119
+ @config.instance_variable_get(:@rails_best_practices).
120
+ should == {}
121
+ end
122
+
123
+ it 'should set @rcov to { :test_files => ["test/**/*_test.rb",
124
+ "spec/**/*_spec.rb"]
125
+ :rcov_opts => ["--sort coverage",
126
+ "--no-html",
127
+ "--text-coverage",
128
+ "--no-color",
129
+ "--profile",
130
+ "--rails",
131
+ "--exclude /gems/,/Library/,/usr/,spec"]}' do
132
+ @config.instance_variable_get(:@rcov).
133
+ should == { :environment => 'test',
134
+ :test_files => ['test/**/*_test.rb',
135
+ 'spec/**/*_spec.rb'],
136
+ :rcov_opts => ["--sort coverage",
137
+ "--no-html",
138
+ "--text-coverage",
139
+ "--no-color",
140
+ "--profile",
141
+ "--rails",
142
+ "--exclude /gems/,/Library/,/usr/,spec"],
143
+ :external => nil}
144
+ end
145
+
146
+ it 'should set @saikuro to { :output_directory => @scratch_directory + "/saikuro",
147
+ :input_directory => @code_dirs,
148
+ :cyclo => "",
149
+ :filter_cyclo => "0",
150
+ :warn_cyclo => "5",
151
+ :error_cyclo => "7",
152
+ :formater => "text" }' do
153
+ @config.instance_variable_get(:@saikuro).
154
+ should == { :output_directory => "#{scratch_directory}/saikuro",
155
+ :input_directory => ['lib'],
156
+ :cyclo => "",
157
+ :filter_cyclo => "0",
158
+ :warn_cyclo => "5",
159
+ :error_cyclo => "7",
160
+ :formater => "text"}
161
+ end
162
+
163
+ describe 'if #rails? is true ' do
164
+ before(:each) do
165
+ @config.stub!(:rails?).and_return(true)
166
+ end
167
+
168
+ describe '#set_metrics ' do
169
+ it 'should set the @metrics instance var to AVAILABLE_METRICS + '\
170
+ +'[:stats]' do
171
+ @config.instance_variable_get(:@metrics).
172
+ should == MetricFu::AVAILABLE_METRICS << [:stats]
173
+ end
174
+ end
175
+
176
+ describe '#set_graphs ' do
177
+ it 'should set the @graphs instance var to AVAILABLE_GRAPHS' do
178
+ @config.instance_variable_get(:@graphs).
179
+ should == MetricFu::AVAILABLE_GRAPHS
180
+ end
181
+ end
182
+
183
+ describe '#set_code_dirs ' do
184
+ it 'should set the @code_dirs instance var to ["app", "lib"]' do
185
+ # This is hard to spec properly because the @code_dirs variable
186
+ # is set during the reset process.
187
+ #@config.instance_variable_get(:@code_dirs).
188
+ # should == ['app','lib']
189
+ end
190
+ end
191
+ end
192
+
193
+ describe 'if #rails? is false ' do
194
+ before(:each) do
195
+ @config.stub!(:rails?).and_return(false)
196
+ end
197
+
198
+ describe '#set_metrics ' do
199
+ it 'should set the @metrics instance var to AVAILABLE_METRICS' do
200
+ @config.instance_variable_get(:@metrics).
201
+ should == MetricFu::AVAILABLE_METRICS
202
+ end
203
+ end
204
+
205
+ describe '#set_code_dirs ' do
206
+ it 'should set the @code_dirs instance var to ["lib"]' do
207
+ @config.instance_variable_get(:@code_dirs).should == ['lib']
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ describe '#add_attr_accessors_to_self' do
214
+
215
+ before(:each) { get_new_config }
216
+
217
+ MetricFu::AVAILABLE_METRICS.each do |metric|
218
+ it "should have a reader for #{metric}" do
219
+ @config.respond_to?(metric).should be_true
220
+ end
221
+
222
+ it "should have a writer for #{metric}=" do
223
+ @config.respond_to?((metric.to_s + '=').to_sym).should be_true
224
+ end
225
+ end
226
+ end
227
+
228
+ describe '#add_class_methods_to_metric_fu' do
229
+
230
+ before(:each) { get_new_config }
231
+
232
+ MetricFu::AVAILABLE_METRICS.each do |metric|
233
+ it "should add a #{metric} class method to the MetricFu module " do
234
+ MetricFu.should respond_to(metric)
235
+ end
236
+ end
237
+
238
+ MetricFu::AVAILABLE_GRAPHS.each do |graph|
239
+ it "should add a #{graph} class metrhod to the MetricFu module" do
240
+ MetricFu.should respond_to(graph)
241
+ end
242
+ end
243
+ end
244
+
245
+ describe '#platform' do
246
+
247
+ before(:each) { get_new_config }
248
+
249
+ it 'should return the value of the PLATFORM constant' do
250
+ this_platform = RUBY_PLATFORM
251
+ @config.platform.should == this_platform
252
+ end
253
+ end
254
+
255
+ describe '#is_cruise_control_rb? ' do
256
+
257
+ before(:each) { get_new_config }
258
+ describe "when the CC_BUILD_ARTIFACTS env var is not nil" do
259
+
260
+ before(:each) { ENV['CC_BUILD_ARTIFACTS'] = 'is set' }
261
+
262
+ it 'should return true' do
263
+ @config.is_cruise_control_rb?.should be_true
264
+ end
265
+
266
+ end
267
+
268
+ describe "when the CC_BUILD_ARTIFACTS env var is nil" do
269
+ before(:each) { ENV['CC_BUILD_ARTIFACTS'] = nil }
270
+
271
+ it 'should return false' do
272
+ @config.is_cruise_control_rb?.should be_false
273
+ end
274
+ end
275
+ end
276
+ end
@@ -0,0 +1,223 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe MetricFu::Generator do
4
+
5
+ include Construct::Helpers
6
+
7
+ MetricFu::Configuration.run do |config|
8
+ end
9
+
10
+ class ConcreteClass < MetricFu::Generator
11
+ def emit
12
+ end
13
+
14
+ def analyze
15
+ end
16
+
17
+ def to_h
18
+ end
19
+ end
20
+
21
+ before(:each) do
22
+ @concrete_class = ConcreteClass.new
23
+ end
24
+
25
+ describe "ConcreteClass#class_name" do
26
+ it "should be 'concreteclass'" do
27
+ ConcreteClass.class_name.should == 'concreteclass'
28
+ end
29
+ end
30
+
31
+ describe "ConcreteClass#metric_directory" do
32
+ it "should be 'tmp/metric_fu/scratch/concreteclass'" do
33
+ ConcreteClass.metric_directory.
34
+ should == "tmp/metric_fu/scratch/concreteclass"
35
+ end
36
+ end
37
+
38
+ describe "#create_metric_dir_if_missing " do
39
+ describe "when the metric_dir exists " do
40
+ it 'should not call mkdir_p on FileUtils' do
41
+ File.stub!(:directory?).and_return(true)
42
+ FileUtils.should_not_receive(:mkdir_p)
43
+ @concrete_class.create_metric_dir_if_missing
44
+ end
45
+ end
46
+
47
+ describe "when the metric_dir does not exist " do
48
+ it 'should call mkdir_p on FileUtils' do
49
+ File.stub!(:directory?).and_return(false)
50
+ FileUtils.should_receive(:mkdir_p)
51
+ @concrete_class.create_metric_dir_if_missing
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#create_output_dir_if_missing" do
57
+ describe "when the output_dir exists " do
58
+ it 'should not call mkdir_p on FileUtils' do
59
+ File.stub!(:directory?).and_return(true)
60
+ FileUtils.should_not_receive(:mkdir_p)
61
+ @concrete_class.create_output_dir_if_missing
62
+ end
63
+ end
64
+
65
+ describe "when the output_dir does not exist " do
66
+ it 'should call mkdir_p on FileUtils' do
67
+ File.stub!(:directory?).and_return(false)
68
+ FileUtils.should_receive(:mkdir_p)
69
+ @concrete_class.create_output_dir_if_missing
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#metric_directory' do
75
+ it 'should return the results of ConcreteClass#metric_directory' do
76
+ ConcreteClass.stub!(:metric_directory).and_return('foo')
77
+ @concrete_class.metric_directory.should == 'foo'
78
+ end
79
+ end
80
+
81
+ describe 'ConcreteClass#generate_report' do
82
+ it 'should create a new instance of ConcreteClass' do
83
+ ConcreteClass.should_receive(:new).and_return(@concrete_class)
84
+ @concrete_class.should_receive(:generate_report).and_return(true)
85
+ ConcreteClass.generate_report
86
+ end
87
+
88
+ it 'should call #generate_report on the new ConcreteClass' do
89
+ ConcreteClass.should_receive(:new).and_return(@concrete_class)
90
+ @concrete_class.should_receive(:generate_report).and_return(true)
91
+ ConcreteClass.generate_report
92
+ end
93
+ end
94
+
95
+ describe '@concrete_class should have hook methods for '\
96
+ +'[before|after]_[emit|analyze|to_h]' do
97
+
98
+ %w[emit analyze].each do |meth|
99
+
100
+ it "should respond to #before_#{meth}" do
101
+ @concrete_class.respond_to?("before_#{meth}".to_sym).should be_true
102
+ end
103
+
104
+ it "should respond to #after_#{meth}" do
105
+ @concrete_class.respond_to?("after_#{meth}".to_sym).should be_true
106
+ end
107
+ end
108
+
109
+ it "should respond to #before_to_h" do
110
+ @concrete_class.respond_to?("before_to_h".to_sym).should be_true
111
+ end
112
+ end
113
+
114
+ describe "#generate_report" do
115
+ it 'should raise an error when calling #emit' do
116
+ @abstract_class = MetricFu::Generator.new
117
+ lambda { @abstract_class.generate_report }.should raise_error
118
+ end
119
+
120
+ it 'should call #analyze' do
121
+ @abstract_class = MetricFu::Generator.new
122
+ lambda { @abstract_class.generate_report }.should raise_error
123
+ end
124
+
125
+ it 'should call #to_h' do
126
+ @abstract_class = MetricFu::Generator.new
127
+ lambda { @abstract_class.generate_report }.should raise_error
128
+ end
129
+ end
130
+
131
+ describe "#generate_report (in a concrete class)" do
132
+
133
+ %w[emit analyze].each do |meth|
134
+ it "should call #before_#{meth}" do
135
+ @concrete_class.should_receive("before_#{meth}")
136
+ @concrete_class.generate_report
137
+ end
138
+
139
+ it "should call ##{meth}" do
140
+ @concrete_class.should_receive("#{meth}")
141
+ @concrete_class.generate_report
142
+ end
143
+
144
+ it "should call #after_#{meth}" do
145
+ @concrete_class.should_receive("after_#{meth}")
146
+ @concrete_class.generate_report
147
+ end
148
+ end
149
+
150
+ it "should call #before_to_h" do
151
+ @concrete_class.should_receive("before_to_h")
152
+ @concrete_class.generate_report
153
+ end
154
+
155
+ it "should call #to_h" do
156
+ @concrete_class.should_receive(:to_h)
157
+ @concrete_class.generate_report
158
+ end
159
+
160
+ end
161
+
162
+ describe "path filter" do
163
+
164
+ context "given a list of paths" do
165
+
166
+ before do
167
+ @paths = %w(lib/fake/fake.rb
168
+ lib/this/dan_file.rb
169
+ lib/this/ben_file.rb
170
+ lib/this/avdi_file.rb
171
+ basic.rb
172
+ lib/bad/one.rb
173
+ lib/bad/two.rb
174
+ lib/bad/three.rb
175
+ lib/worse/four.rb)
176
+ @container = create_construct
177
+ @paths.each do |path|
178
+ @container.file(path)
179
+ end
180
+ @old_dir = Dir.pwd
181
+ Dir.chdir(@container)
182
+ end
183
+
184
+ after do
185
+ Dir.chdir(@old_dir)
186
+ @container.destroy!
187
+ end
188
+
189
+ it "should return entire pathlist given no exclude pattens" do
190
+ files = @concrete_class.remove_excluded_files(@paths)
191
+ files.should be == @paths
192
+ end
193
+
194
+ it "should filter filename at root level" do
195
+ files = @concrete_class.remove_excluded_files(@paths, ['basic.rb'])
196
+ files.should_not include('basic.rb')
197
+ end
198
+
199
+ it "should remove files that are two levels deep" do
200
+ files = @concrete_class.remove_excluded_files(@paths, ['**/fake.rb'])
201
+ files.should_not include('lib/fake/fake.rb')
202
+ end
203
+
204
+ it "should remove files from an excluded directory" do
205
+ files = @concrete_class.remove_excluded_files(@paths, ['lib/bad/**'])
206
+ files.should_not include('lib/bad/one.rb')
207
+ files.should_not include('lib/bad/two.rb')
208
+ files.should_not include('lib/bad/three.rb')
209
+ end
210
+
211
+ it "should support shell alternation globs" do
212
+ files = @concrete_class.remove_excluded_files(@paths, ['lib/this/{ben,dan}_file.rb'])
213
+ files.should_not include('lib/this/dan_file.rb')
214
+ files.should_not include('lib/this/ben_file.rb')
215
+ files.should include('lib/this/avdi_file.rb')
216
+ end
217
+
218
+ end
219
+
220
+
221
+ end
222
+
223
+ end
@@ -0,0 +1,61 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe MetricFu do
4
+
5
+ describe "responding to #graph" do
6
+ it "should return an instance of Graph" do
7
+ MetricFu.graph.should be_a(Graph)
8
+ end
9
+ end
10
+ end
11
+
12
+ describe MetricFu::Graph do
13
+
14
+ before(:each) do
15
+ @graph = MetricFu::Graph.new
16
+ end
17
+
18
+ describe "responding to #add with gchart enabled" do
19
+ it 'should instantiate a grapher and push it to clazz' do
20
+ @graph.clazz.should_receive(:push).with(an_instance_of(RcovGchartGrapher))
21
+ @graph.add("rcov", 'gchart')
22
+ end
23
+ end
24
+
25
+ describe "responding to #add with gchart enabled" do
26
+ it 'should instantiate a grapher and push it to clazz' do
27
+ @graph.clazz.should_receive(:push).with(an_instance_of(RcovGchartGrapher))
28
+ @graph.add("rcov", 'gchart')
29
+ end
30
+ end
31
+
32
+ describe "setting the date on the graph" do
33
+ before(:each) do
34
+ @graph.stub!(:puts)
35
+ end
36
+
37
+ it "should set the date once for one data point" do
38
+ Dir.should_receive(:[]).and_return(["metric_fu/tmp/_data/20101105.yml"])
39
+ File.should_receive(:join)
40
+ File.should_receive(:open).and_return("Metrics")
41
+ mock_grapher = stub
42
+ mock_grapher.should_receive(:get_metrics).with("Metrics", "11/5")
43
+ mock_grapher.should_receive(:graph!)
44
+
45
+ @graph.clazz = [mock_grapher]
46
+ @graph.generate
47
+ end
48
+
49
+ it "should set the date when the data directory isn't in the default place" do
50
+ Dir.should_receive(:[]).and_return(["/some/kind/of/weird/directory/somebody/configured/_data/20101105.yml"])
51
+ File.should_receive(:join)
52
+ File.should_receive(:open).and_return("Metrics")
53
+ mock_grapher = stub
54
+ mock_grapher.should_receive(:get_metrics).with("Metrics", "11/5")
55
+ mock_grapher.should_receive(:graph!)
56
+
57
+ @graph.clazz = [mock_grapher]
58
+ @graph.generate
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,62 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe MetricFu::LineNumbers do
4
+
5
+ describe "in_method?" do
6
+ it "should know if a line is NOT in a method" do
7
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
8
+ ln.in_method?(2).should == false
9
+ end
10
+
11
+ it "should know if a line is in an instance method" do
12
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
13
+ ln.in_method?(8).should == true
14
+ end
15
+
16
+ it "should know if a line is in an class method" do
17
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
18
+ ln.in_method?(3).should == true
19
+ end
20
+ end
21
+
22
+ describe "method_at_line" do
23
+ it "should know the name of an instance method at a particular line" do
24
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
25
+ ln.method_at_line(8).should == "Foo#what"
26
+ end
27
+
28
+ it "should know the name of a class method at a particular line" do
29
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
30
+ ln.method_at_line(3).should == "Foo::awesome"
31
+ end
32
+
33
+ it "should know the name of a private method at a particular line" do
34
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
35
+ ln.method_at_line(28).should == "Foo#whoop"
36
+ end
37
+
38
+ it "should know the name of a class method defined in a 'class << self block at a particular line" do
39
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/foo.rb"))
40
+ ln.method_at_line(23).should == "Foo::neat"
41
+ end
42
+
43
+ it "should know the name of an instance method at a particular line in a file with two classes" do
44
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/two_classes.rb"))
45
+ ln.method_at_line(3).should == "Foo#stuff"
46
+ ln.method_at_line(9).should == "Bar#stuff"
47
+ end
48
+
49
+ it "should work with modules" do
50
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/module.rb"))
51
+ ln.method_at_line(4).should == 'KickAss#get_beat_up?'
52
+ end
53
+
54
+ it "should work with module surrounding class" do
55
+ ln = MetricFu::LineNumbers.new(File.read(File.dirname(__FILE__) + "/../resources/line_numbers/module_surrounds_class.rb"))
56
+ ln.method_at_line(5).should == "StuffModule::ThingClass#do_it"
57
+ # ln.method_at_line(12).should == "StuffModule#blah" #why no work?
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
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