bf4-metric_fu 2.1.3.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.
- data/HISTORY +252 -0
- data/MIT-LICENSE +22 -0
- data/README.md +49 -0
- data/Rakefile +22 -0
- data/TODO +6 -0
- data/lib/base/base_template.rb +182 -0
- data/lib/base/churn_analyzer.rb +38 -0
- data/lib/base/code_issue.rb +100 -0
- data/lib/base/configuration.rb +219 -0
- data/lib/base/flay_analyzer.rb +50 -0
- data/lib/base/flog_analyzer.rb +43 -0
- data/lib/base/generator.rb +166 -0
- data/lib/base/graph.rb +44 -0
- data/lib/base/grouping.rb +42 -0
- data/lib/base/line_numbers.rb +79 -0
- data/lib/base/location.rb +87 -0
- data/lib/base/md5_tracker.rb +52 -0
- data/lib/base/metric_analyzer.rb +331 -0
- data/lib/base/ranking.rb +34 -0
- data/lib/base/rcov_analyzer.rb +43 -0
- data/lib/base/record.rb +43 -0
- data/lib/base/reek_analyzer.rb +164 -0
- data/lib/base/report.rb +110 -0
- data/lib/base/roodi_analyzer.rb +37 -0
- data/lib/base/saikuro_analyzer.rb +48 -0
- data/lib/base/scoring_strategies.rb +29 -0
- data/lib/base/stats_analyzer.rb +37 -0
- data/lib/base/table.rb +108 -0
- data/lib/generators/churn.rb +28 -0
- data/lib/generators/flay.rb +31 -0
- data/lib/generators/flog.rb +113 -0
- data/lib/generators/hotspots.rb +52 -0
- data/lib/generators/rails_best_practices.rb +53 -0
- data/lib/generators/rcov.rb +124 -0
- data/lib/generators/reek.rb +81 -0
- data/lib/generators/roodi.rb +35 -0
- data/lib/generators/saikuro.rb +259 -0
- data/lib/generators/stats.rb +58 -0
- data/lib/graphs/engines/bluff.rb +113 -0
- data/lib/graphs/engines/gchart.rb +157 -0
- data/lib/graphs/flay_grapher.rb +18 -0
- data/lib/graphs/flog_grapher.rb +57 -0
- data/lib/graphs/grapher.rb +11 -0
- data/lib/graphs/rails_best_practices_grapher.rb +19 -0
- data/lib/graphs/rcov_grapher.rb +18 -0
- data/lib/graphs/reek_grapher.rb +30 -0
- data/lib/graphs/roodi_grapher.rb +18 -0
- data/lib/graphs/stats_grapher.rb +20 -0
- data/lib/metric_fu.rb +80 -0
- data/lib/tasks/metric_fu.rake +36 -0
- data/lib/templates/awesome/awesome_template.rb +92 -0
- data/lib/templates/awesome/churn.html.erb +58 -0
- data/lib/templates/awesome/css/buttons.css +82 -0
- data/lib/templates/awesome/css/default.css +91 -0
- data/lib/templates/awesome/css/integrity.css +334 -0
- data/lib/templates/awesome/css/reset.css +7 -0
- data/lib/templates/awesome/css/syntax.css +19 -0
- data/lib/templates/awesome/flay.html.erb +34 -0
- data/lib/templates/awesome/flog.html.erb +55 -0
- data/lib/templates/awesome/hotspots.html.erb +62 -0
- data/lib/templates/awesome/index.html.erb +34 -0
- data/lib/templates/awesome/layout.html.erb +30 -0
- data/lib/templates/awesome/rails_best_practices.html.erb +27 -0
- data/lib/templates/awesome/rcov.html.erb +42 -0
- data/lib/templates/awesome/reek.html.erb +40 -0
- data/lib/templates/awesome/roodi.html.erb +27 -0
- data/lib/templates/awesome/saikuro.html.erb +71 -0
- data/lib/templates/awesome/stats.html.erb +51 -0
- data/lib/templates/javascripts/bluff-min.js +1 -0
- data/lib/templates/javascripts/excanvas.js +35 -0
- data/lib/templates/javascripts/js-class.js +1 -0
- data/lib/templates/standard/churn.html.erb +31 -0
- data/lib/templates/standard/default.css +64 -0
- data/lib/templates/standard/flay.html.erb +34 -0
- data/lib/templates/standard/flog.html.erb +57 -0
- data/lib/templates/standard/hotspots.html.erb +54 -0
- data/lib/templates/standard/index.html.erb +41 -0
- data/lib/templates/standard/rails_best_practices.html.erb +29 -0
- data/lib/templates/standard/rcov.html.erb +43 -0
- data/lib/templates/standard/reek.html.erb +42 -0
- data/lib/templates/standard/roodi.html.erb +29 -0
- data/lib/templates/standard/saikuro.html.erb +84 -0
- data/lib/templates/standard/standard_template.rb +27 -0
- data/lib/templates/standard/stats.html.erb +55 -0
- data/spec/base/base_template_spec.rb +194 -0
- data/spec/base/configuration_spec.rb +277 -0
- data/spec/base/generator_spec.rb +223 -0
- data/spec/base/graph_spec.rb +61 -0
- data/spec/base/line_numbers_spec.rb +62 -0
- data/spec/base/location_spec.rb +127 -0
- data/spec/base/md5_tracker_spec.rb +57 -0
- data/spec/base/metric_analyzer_spec.rb +452 -0
- data/spec/base/ranking_spec.rb +42 -0
- data/spec/base/report_spec.rb +146 -0
- data/spec/base/table_spec.rb +36 -0
- data/spec/generators/churn_spec.rb +41 -0
- data/spec/generators/flay_spec.rb +105 -0
- data/spec/generators/flog_spec.rb +70 -0
- data/spec/generators/hotspots_spec.rb +88 -0
- data/spec/generators/rails_best_practices_spec.rb +52 -0
- data/spec/generators/rcov_spec.rb +180 -0
- data/spec/generators/reek_spec.rb +134 -0
- data/spec/generators/roodi_spec.rb +24 -0
- data/spec/generators/saikuro_spec.rb +74 -0
- data/spec/generators/stats_spec.rb +74 -0
- data/spec/graphs/engines/bluff_spec.rb +19 -0
- data/spec/graphs/engines/gchart_spec.rb +156 -0
- data/spec/graphs/flay_grapher_spec.rb +56 -0
- data/spec/graphs/flog_grapher_spec.rb +108 -0
- data/spec/graphs/rails_best_practices_grapher_spec.rb +61 -0
- data/spec/graphs/rcov_grapher_spec.rb +56 -0
- data/spec/graphs/reek_grapher_spec.rb +65 -0
- data/spec/graphs/roodi_grapher_spec.rb +56 -0
- data/spec/graphs/stats_grapher_spec.rb +68 -0
- data/spec/resources/line_numbers/foo.rb +33 -0
- data/spec/resources/line_numbers/module.rb +11 -0
- data/spec/resources/line_numbers/module_surrounds_class.rb +15 -0
- data/spec/resources/line_numbers/two_classes.rb +11 -0
- data/spec/resources/saikuro/app/controllers/sessions_controller.rb_cyclo.html +10 -0
- data/spec/resources/saikuro/app/controllers/users_controller.rb_cyclo.html +16 -0
- data/spec/resources/saikuro/index_cyclo.html +155 -0
- data/spec/resources/saikuro_sfiles/thing.rb_cyclo.html +11 -0
- data/spec/resources/yml/20090630.yml +7922 -0
- data/spec/resources/yml/metric_missing.yml +1 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +7 -0
- metadata +560 -0
|
@@ -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,127 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
|
2
|
+
|
|
3
|
+
describe MetricFu::Location do
|
|
4
|
+
|
|
5
|
+
context "with non-standard Reek method names" do
|
|
6
|
+
# reek reports the method with :: not # on modules like
|
|
7
|
+
# module ApplicationHelper \n def signed_in?, convert it so it records correctly
|
|
8
|
+
# class_or_method_name = class_or_method_name.gsub(/\:\:/,"#") if method_bug_conversion
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
@location = Location.for("ApplicationHelper::section_link")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "has method name" do
|
|
15
|
+
@location.method_name.should == 'ApplicationHelper#section_link'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "has nil file path" do
|
|
19
|
+
@location.file_path.should == nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "has class name" do
|
|
23
|
+
@location.class_name.should == 'ApplicationHelper'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "using new" do
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
@location = Location.new("lib/foo.rb", "Foo", "Foo#some_method")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should return fully qualified method" do
|
|
35
|
+
@location.method_name.should == 'Foo#some_method'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "using .for with class" do
|
|
41
|
+
|
|
42
|
+
before do
|
|
43
|
+
@location = Location.for("Module::Foo")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "has nil method_name" do
|
|
47
|
+
@location.method_name.should be nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "has nil file_path" do
|
|
51
|
+
@location.file_path.should be nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "has class_name" do
|
|
55
|
+
@location.class_name.should == 'Foo'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
context "using .for with method" do
|
|
61
|
+
|
|
62
|
+
before do
|
|
63
|
+
@location = Location.for("Module::Foo#some_method")
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "strips module from class name" do
|
|
67
|
+
@location.class_name.should == 'Foo'
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "strips module from method name" do
|
|
71
|
+
@location.method_name.should == 'Foo#some_method'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "has nil file_path" do
|
|
75
|
+
@location.file_path.should be nil
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context "with class method" do
|
|
81
|
+
|
|
82
|
+
it "provides non-qualified name" do
|
|
83
|
+
location = Location.for("Foo.some_class_method")
|
|
84
|
+
location.simple_method_name.should == '.some_class_method'
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "with instance method" do
|
|
90
|
+
|
|
91
|
+
it "provides non-qualified name" do
|
|
92
|
+
location = Location.for("Foo#some_class_method")
|
|
93
|
+
location.simple_method_name.should == '#some_class_method'
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
context "testing equality" do
|
|
98
|
+
before :each do
|
|
99
|
+
|
|
100
|
+
@location1 = MetricFu::Location.get('/some/path','some_class','some_method')
|
|
101
|
+
|
|
102
|
+
# ensure that we get a new object
|
|
103
|
+
@location2 = MetricFu::Location.new('/some/path','some_class','some_method')
|
|
104
|
+
end
|
|
105
|
+
it "should match two locations with the same paths as equal" do
|
|
106
|
+
|
|
107
|
+
hsh1 = {}
|
|
108
|
+
hsh1[@location1] = 1
|
|
109
|
+
|
|
110
|
+
hsh2 = {}
|
|
111
|
+
hsh2[@location2] = 1
|
|
112
|
+
|
|
113
|
+
hsh1.should == hsh2
|
|
114
|
+
hsh1.eql?(hsh2).should be_true
|
|
115
|
+
|
|
116
|
+
@location1.eql?(@location2).should be_true
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
it "should produce the same hash value given the same paths" do
|
|
121
|
+
|
|
122
|
+
@location1.hash.should == @location2.hash
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|