metric_fu 4.4.1 → 4.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +14 -6
- data/CONTRIBUTORS +1 -0
- data/Gemfile +1 -1
- data/HISTORY.md +13 -0
- data/checksum/metric_fu-4.4.1.gem.sha512 +1 -0
- data/lib/metric_fu/cli/parser.rb +7 -0
- data/lib/metric_fu/data_structures/line_numbers.rb +70 -59
- data/lib/metric_fu/data_structures/location.rb +36 -20
- data/lib/metric_fu/data_structures/sexp_node.rb +89 -0
- data/lib/metric_fu/environment.rb +48 -0
- data/lib/metric_fu/io.rb +1 -7
- data/lib/metric_fu/metrics/base_template.rb +28 -9
- data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +8 -44
- data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +3 -0
- data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +6 -2
- data/lib/metric_fu/metrics/hotspots/analysis/ranked_problem_location.rb +71 -0
- data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +8 -1
- data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +0 -1
- data/lib/metric_fu/metrics/hotspots/hotspots.rb +8 -3
- data/lib/metric_fu/metrics/hotspots/template_awesome/hotspots.html.erb +12 -12
- data/lib/metric_fu/metrics/saikuro/init.rb +3 -0
- data/lib/metric_fu/metrics/saikuro/parsing_element.rb +39 -0
- data/lib/metric_fu/metrics/saikuro/saikuro.rb +4 -145
- data/lib/metric_fu/metrics/saikuro/scratch_file.rb +114 -0
- data/lib/metric_fu/version.rb +1 -1
- data/spec/metric_fu/configuration_spec.rb +0 -7
- data/spec/metric_fu/formatter/html_spec.rb +0 -1
- data/spec/metric_fu/formatter/yaml_spec.rb +0 -1
- data/spec/metric_fu/metrics/base_template_spec.rb +1 -2
- data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +8 -16
- data/spec/metric_fu/metrics/hotspots/hotspots_spec.rb +26 -69
- data/spec/metric_fu/metrics/saikuro/saikuro_spec.rb +5 -5
- data/spec/metric_fu/reporting/graphs/engines/gchart_spec.rb +1 -0
- data/spec/resources/yml/hotspots/generator.yml +47 -0
- data/spec/resources/yml/hotspots/generator_analysis.yml +53 -0
- data/spec/run_spec.rb +0 -1
- data/spec/support/helper_methods.rb +10 -0
- data/spec/support/suite.rb +13 -14
- metadata +35 -25
@@ -1,6 +1,8 @@
|
|
1
|
+
MetricFu.metrics_require { 'saikuro/scratch_file' }
|
2
|
+
MetricFu.metrics_require { 'saikuro/parsing_element' }
|
1
3
|
module MetricFu
|
2
4
|
|
3
|
-
class
|
5
|
+
class SaikuroGenerator < MetricFu::Generator
|
4
6
|
|
5
7
|
def self.metric
|
6
8
|
:saikuro
|
@@ -102,152 +104,9 @@ module MetricFu
|
|
102
104
|
end
|
103
105
|
|
104
106
|
def assemble_files
|
105
|
-
|
106
|
-
Dir.glob("#{metric_directory}/**/*.html").each do |path|
|
107
|
-
if Saikuro::SFile.is_valid_text_file?(path)
|
108
|
-
file = Saikuro::SFile.new(path)
|
109
|
-
if file
|
110
|
-
files << file
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
files
|
107
|
+
SaikuroScratchFile.assemble_files( Dir.glob("#{metric_directory}/**/*.html") )
|
115
108
|
end
|
116
109
|
|
117
110
|
end
|
118
111
|
|
119
|
-
class Saikuro::SFile
|
120
|
-
|
121
|
-
attr_reader :elements
|
122
|
-
|
123
|
-
def initialize(path)
|
124
|
-
@path = path
|
125
|
-
@file_handle = File.open(@path, "r")
|
126
|
-
@elements = []
|
127
|
-
get_elements
|
128
|
-
ensure
|
129
|
-
@file_handle.close if @file_handle
|
130
|
-
end
|
131
|
-
|
132
|
-
def self.is_valid_text_file?(path)
|
133
|
-
File.open(path, "r") do |f|
|
134
|
-
if f.eof? || !f.readline.match(/--/)
|
135
|
-
return false
|
136
|
-
else
|
137
|
-
return true
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def filename
|
143
|
-
File.basename(@path, '_cyclo.html')
|
144
|
-
end
|
145
|
-
|
146
|
-
def filepath
|
147
|
-
File.dirname(@path)
|
148
|
-
end
|
149
|
-
|
150
|
-
def to_h
|
151
|
-
merge_classes
|
152
|
-
{:classes => @elements}
|
153
|
-
end
|
154
|
-
|
155
|
-
def get_elements
|
156
|
-
begin
|
157
|
-
while (line = @file_handle.readline) do
|
158
|
-
return [] if line.nil? || line !~ /\S/
|
159
|
-
element ||= nil
|
160
|
-
if line.match(/START/)
|
161
|
-
unless element.nil?
|
162
|
-
@elements << element
|
163
|
-
element = nil
|
164
|
-
end
|
165
|
-
line = @file_handle.readline
|
166
|
-
element = Saikuro::ParsingElement.new(line)
|
167
|
-
elsif line.match(/END/)
|
168
|
-
@elements << element if element
|
169
|
-
element = nil
|
170
|
-
else
|
171
|
-
element << line if element
|
172
|
-
end
|
173
|
-
end
|
174
|
-
rescue EOFError
|
175
|
-
nil
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
|
180
|
-
def merge_classes
|
181
|
-
new_elements = []
|
182
|
-
get_class_names.each do |target_class|
|
183
|
-
elements = @elements.find_all {|el| el.name == target_class }
|
184
|
-
complexity = 0
|
185
|
-
lines = 0
|
186
|
-
defns = []
|
187
|
-
elements.each do |el|
|
188
|
-
complexity += el.complexity.to_i
|
189
|
-
lines += el.lines.to_i
|
190
|
-
defns << el.defs
|
191
|
-
end
|
192
|
-
|
193
|
-
new_element = {:class_name => target_class,
|
194
|
-
:complexity => complexity,
|
195
|
-
:lines => lines,
|
196
|
-
:methods => defns.flatten.map {|d| d.to_h}}
|
197
|
-
new_element[:methods] = new_element[:methods].
|
198
|
-
sort_by {|x| x[:complexity] }.
|
199
|
-
reverse
|
200
|
-
|
201
|
-
new_elements << new_element
|
202
|
-
end
|
203
|
-
@elements = new_elements if new_elements
|
204
|
-
end
|
205
|
-
|
206
|
-
def get_class_names
|
207
|
-
class_names = []
|
208
|
-
@elements.each do |element|
|
209
|
-
unless class_names.include?(element.name)
|
210
|
-
class_names << element.name
|
211
|
-
end
|
212
|
-
end
|
213
|
-
class_names
|
214
|
-
end
|
215
|
-
|
216
|
-
end
|
217
|
-
|
218
|
-
class Saikuro::ParsingElement
|
219
|
-
TYPE_REGEX=/Type:(.*) Name/
|
220
|
-
NAME_REGEX=/Name:(.*) Complexity/
|
221
|
-
COMPLEXITY_REGEX=/Complexity:(.*) Lines/
|
222
|
-
LINES_REGEX=/Lines:(.*)/
|
223
|
-
|
224
|
-
attr_reader :complexity, :lines, :defs, :element_type
|
225
|
-
attr_accessor :name
|
226
|
-
|
227
|
-
def initialize(line)
|
228
|
-
@line = line
|
229
|
-
@element_type = line.match(TYPE_REGEX)[1].strip
|
230
|
-
@name = line.match(NAME_REGEX)[1].strip
|
231
|
-
@complexity = line.match(COMPLEXITY_REGEX)[1].strip
|
232
|
-
@lines = line.match(LINES_REGEX)[1].strip
|
233
|
-
@defs = []
|
234
|
-
end
|
235
|
-
|
236
|
-
def <<(line)
|
237
|
-
@defs << Saikuro::ParsingElement.new(line)
|
238
|
-
end
|
239
|
-
|
240
|
-
def to_h
|
241
|
-
base = {:name => @name, :complexity => @complexity.to_i, :lines => @lines.to_i}
|
242
|
-
unless @defs.empty?
|
243
|
-
defs = @defs.map do |my_def|
|
244
|
-
my_def = my_def.to_h
|
245
|
-
my_def.delete(:defs)
|
246
|
-
my_def
|
247
|
-
end
|
248
|
-
base[:defs] = defs
|
249
|
-
end
|
250
|
-
return base
|
251
|
-
end
|
252
|
-
end
|
253
112
|
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
MetricFu.metrics_require { 'saikuro/parsing_element' }
|
2
|
+
module MetricFu
|
3
|
+
class SaikuroScratchFile
|
4
|
+
|
5
|
+
def self.assemble_files(glob)
|
6
|
+
files = []
|
7
|
+
glob.each do |path|
|
8
|
+
if is_valid_text_file?(path)
|
9
|
+
file = new(path)
|
10
|
+
if file
|
11
|
+
files << file
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
files
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :elements
|
19
|
+
|
20
|
+
def initialize(path)
|
21
|
+
@path = path
|
22
|
+
@file_handle = File.open(@path, "r")
|
23
|
+
@elements = []
|
24
|
+
get_elements
|
25
|
+
ensure
|
26
|
+
@file_handle.close if @file_handle
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.is_valid_text_file?(path)
|
30
|
+
File.open(path, "r") do |f|
|
31
|
+
if f.eof? || !f.readline.match(/--/)
|
32
|
+
return false
|
33
|
+
else
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def filename
|
40
|
+
File.basename(@path, '_cyclo.html')
|
41
|
+
end
|
42
|
+
|
43
|
+
def filepath
|
44
|
+
File.dirname(@path)
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_h
|
48
|
+
merge_classes
|
49
|
+
{:classes => @elements}
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_elements
|
53
|
+
begin
|
54
|
+
while (line = @file_handle.readline) do
|
55
|
+
return [] if line.nil? || line !~ /\S/
|
56
|
+
element ||= nil
|
57
|
+
if line.match(/START/)
|
58
|
+
unless element.nil?
|
59
|
+
@elements << element
|
60
|
+
element = nil
|
61
|
+
end
|
62
|
+
line = @file_handle.readline
|
63
|
+
element = MetricFu::SaikuroParsingElement.new(line)
|
64
|
+
elsif line.match(/END/)
|
65
|
+
@elements << element if element
|
66
|
+
element = nil
|
67
|
+
else
|
68
|
+
element << line if element
|
69
|
+
end
|
70
|
+
end
|
71
|
+
rescue EOFError
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def merge_classes
|
78
|
+
new_elements = []
|
79
|
+
get_class_names.each do |target_class|
|
80
|
+
elements = @elements.find_all {|el| el.name == target_class }
|
81
|
+
complexity = 0
|
82
|
+
lines = 0
|
83
|
+
defns = []
|
84
|
+
elements.each do |el|
|
85
|
+
complexity += el.complexity.to_i
|
86
|
+
lines += el.lines.to_i
|
87
|
+
defns << el.defs
|
88
|
+
end
|
89
|
+
|
90
|
+
new_element = {:class_name => target_class,
|
91
|
+
:complexity => complexity,
|
92
|
+
:lines => lines,
|
93
|
+
:methods => defns.flatten.map {|d| d.to_h}}
|
94
|
+
new_element[:methods] = new_element[:methods].
|
95
|
+
sort_by {|x| x[:complexity] }.
|
96
|
+
reverse
|
97
|
+
|
98
|
+
new_elements << new_element
|
99
|
+
end
|
100
|
+
@elements = new_elements if new_elements
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_class_names
|
104
|
+
class_names = []
|
105
|
+
@elements.each do |element|
|
106
|
+
unless class_names.include?(element.name)
|
107
|
+
class_names << element.name
|
108
|
+
end
|
109
|
+
end
|
110
|
+
class_names
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
data/lib/metric_fu/version.rb
CHANGED
@@ -225,13 +225,6 @@ describe MetricFu::Configuration do
|
|
225
225
|
end
|
226
226
|
end
|
227
227
|
|
228
|
-
describe '#set_code_dirs ' do
|
229
|
-
it 'should set the @code_dirs instance var to ["app", "lib"]' do
|
230
|
-
directory('code_dirs').
|
231
|
-
should == ['app','lib']
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
228
|
it 'should set @rails_best_practices to {}' do
|
236
229
|
load_metric 'rails_best_practices'
|
237
230
|
expect(MetricFu::Metric.get_metric(:rails_best_practices).run_options).to eql({})
|
@@ -10,11 +10,10 @@ describe MetricFu::Template do
|
|
10
10
|
describe "#erbify" do
|
11
11
|
it 'should evaluate a erb doc' do
|
12
12
|
section = 'section'
|
13
|
-
File.stub(:read).and_return('foo')
|
14
13
|
erb = double('erb')
|
15
14
|
erb.should_receive(:result)
|
16
|
-
ERB.should_receive(:new).with('foo').and_return(erb)
|
17
15
|
@template.should_receive(:template).and_return('foo')
|
16
|
+
@template.should_receive(:erb_template_source).with('foo').and_return(erb)
|
18
17
|
@template.send(:erbify, section)
|
19
18
|
end
|
20
19
|
end
|
@@ -37,16 +37,14 @@ describe MetricFu::HotspotAnalyzedProblems do
|
|
37
37
|
:flog => "complexity is 37.9"
|
38
38
|
}
|
39
39
|
# TODO Unsure if we want to make problems_with and location public or private at this point
|
40
|
-
@
|
41
|
-
expect(@worst_items[:classes].first[:details]).to eq(expected)
|
40
|
+
expect(@worst_items[:classes].first.problems).to eq(expected)
|
42
41
|
end
|
43
42
|
|
44
43
|
it "gives all issues for a method" do
|
45
44
|
expected = {
|
46
45
|
:reek => "found 1 code smells",
|
47
46
|
:flog => "complexity is 37.9"}
|
48
|
-
@
|
49
|
-
expect(@worst_items[:methods].first[:details]).to eq(expected)
|
47
|
+
expect(@worst_items[:methods].first.problems).to eq(expected)
|
50
48
|
end
|
51
49
|
|
52
50
|
it "gives all issues for a file" do
|
@@ -54,32 +52,28 @@ describe MetricFu::HotspotAnalyzedProblems do
|
|
54
52
|
:reek => "found 2 code smells" ,
|
55
53
|
:flog => "complexity is 37.9",
|
56
54
|
:churn => "detected high level of churn (changed 54 times)"}
|
57
|
-
@
|
58
|
-
expect(@worst_items[:files].first[:details]).to eq(expected)
|
55
|
+
expect(@worst_items[:files].first.problems).to eq(expected)
|
59
56
|
end
|
60
57
|
|
61
58
|
it "provide location for a method" do
|
62
59
|
expected = MetricFu::Location.new("lib/client/client.rb",
|
63
60
|
"Client",
|
64
61
|
"Client#client_requested_sync")
|
65
|
-
@
|
66
|
-
expect(@worst_items[:methods].first[:location]).to eq(expected)
|
62
|
+
expect(@worst_items[:methods].first.location).to eq(expected)
|
67
63
|
end
|
68
64
|
|
69
65
|
it "provides location for a class" do
|
70
66
|
expected = MetricFu::Location.new("lib/client/client.rb",
|
71
67
|
"Client",
|
72
68
|
nil)
|
73
|
-
@
|
74
|
-
expect(@worst_items[:classes].first[:location]).to eq(expected)
|
69
|
+
expect(@worst_items[:classes].first.location).to eq(expected)
|
75
70
|
end
|
76
71
|
|
77
72
|
it "provides location for a file" do
|
78
73
|
expected = MetricFu::Location.new("lib/client/client.rb",
|
79
74
|
nil,
|
80
75
|
nil)
|
81
|
-
@
|
82
|
-
expect(@worst_items[:files].first[:location]).to eq(expected)
|
76
|
+
expect(@worst_items[:files].first.location).to eq(expected)
|
83
77
|
end
|
84
78
|
|
85
79
|
end
|
@@ -96,16 +90,14 @@ describe MetricFu::HotspotAnalyzedProblems do
|
|
96
90
|
expected = {
|
97
91
|
:saikuro => "complexity is 1.0"
|
98
92
|
}
|
99
|
-
@
|
100
|
-
expect(@worst_items[:methods].last[:details]).to eq(expected)
|
93
|
+
expect(@worst_items[:methods].last.problems).to eq(expected)
|
101
94
|
end
|
102
95
|
|
103
96
|
it "gives average complexity for class" do
|
104
97
|
expected = {
|
105
98
|
:saikuro => "average complexity is 5.0"
|
106
99
|
}
|
107
|
-
@
|
108
|
-
expect(@worst_items[:classes].last[:details]).to eq(expected)
|
100
|
+
expect(@worst_items[:classes].last.problems).to eq(expected)
|
109
101
|
end
|
110
102
|
|
111
103
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'multi_json'
|
2
1
|
require "spec_helper"
|
3
2
|
|
4
3
|
describe MetricFu::HotspotsGenerator do
|
@@ -7,90 +6,48 @@ describe MetricFu::HotspotsGenerator do
|
|
7
6
|
before :each do
|
8
7
|
MetricFu::Configuration.run {}
|
9
8
|
File.stub(:directory?).and_return(true)
|
10
|
-
@yaml
|
11
|
-
---
|
12
|
-
:reek:
|
13
|
-
:matches:
|
14
|
-
- :file_path: lib/client/client.rb
|
15
|
-
:code_smells:
|
16
|
-
- :type: Large Class
|
17
|
-
:message: has at least 27 methods
|
18
|
-
:method: Devver::Client
|
19
|
-
- :type: Long Method
|
20
|
-
:message: has approx 6 statements
|
21
|
-
:method: Devver::Client#client_requested_sync
|
22
|
-
:flog:
|
23
|
-
:method_containers:
|
24
|
-
- :highest_score: 61.5870319141946
|
25
|
-
:path: /lib/client/client.rb
|
26
|
-
:methods:
|
27
|
-
Client#client_requested_sync:
|
28
|
-
:path: /lib/client/client.rb
|
29
|
-
:score: 37.9270319141946
|
30
|
-
:operators:
|
31
|
-
:+: 1.70000000000001
|
32
|
-
:/: 1.80000000000001
|
33
|
-
:method_at_line: 1.90000000000001
|
34
|
-
:puts: 1.70000000000001
|
35
|
-
:assignment: 33.0000000000001
|
36
|
-
:in_method?: 1.70000000000001
|
37
|
-
:message: 1.70000000000001
|
38
|
-
:branch: 12.6
|
39
|
-
:<<: 3.40000000000001
|
40
|
-
:each: 1.50000000000001
|
41
|
-
:lit_fixnum: 1.45
|
42
|
-
:raise: 1.80000000000001
|
43
|
-
:each_pair: 1.3
|
44
|
-
:*: 1.60000000000001
|
45
|
-
:to_f: 2.00000000000001
|
46
|
-
:each_with_index: 3.00000000000001
|
47
|
-
:[]: 22.3000000000001
|
48
|
-
:new: 1.60000000000001
|
49
|
-
:average_score: 11.1209009055421
|
50
|
-
:total_score: 1817.6
|
51
|
-
:name: Client#client_requested_sync
|
52
|
-
:churn:
|
53
|
-
:changes:
|
54
|
-
- :file_path: lib/client/client.rb
|
55
|
-
:times_changed: 54
|
56
|
-
- :file_path: lib/client/foo.rb
|
57
|
-
:times_changed: 52
|
58
|
-
END
|
9
|
+
@yaml = metric_data('hotspots/generator.yml')
|
59
10
|
end
|
60
11
|
|
61
12
|
it "should be empty on error" do
|
62
13
|
hotspots = MetricFu::HotspotsGenerator.new
|
63
14
|
hotspots.instance_variable_set(:@analyzer, nil)
|
64
15
|
result = hotspots.analyze
|
65
|
-
result.should == {}
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should return yaml results" do
|
69
|
-
hotspots = MetricFu::HotspotsGenerator.new
|
70
|
-
analyzer = HotspotAnalyzer.new(@yaml)
|
71
|
-
hotspots.instance_variable_set(:@analyzer, analyzer)
|
72
|
-
result = hotspots.analyze
|
73
|
-
expected = MultiJson.load("{\"methods\":[{\"location\":{\"class_name\":\"Client\",\"method_name\":\"Client#client_requested_sync\",\"file_path\":\"lib/client/client.rb\",\"hash\":7919384682,\"simple_method_name\":\"#client_requested_sync\"},\"details\":{\"reek\":\"found 1 code smells\",\"flog\":\"complexity is 37.9\"}}],\"classes\":[{\"location\":{\"class_name\":\"Client\",\"method_name\":null,\"file_path\":\"lib/client/client.rb\",\"hash\":7995629750},\"details\":{\"reek\":\"found 2 code smells\",\"flog\":\"complexity is 37.9\"}}],\"files\":[{\"location\":{\"class_name\":null,\"method_name\":null,\"file_path\":\"lib/client/client.rb\",\"hash\":-5738801681},\"details\":{\"reek\":\"found 2 code smells\",\"flog\":\"complexity is 37.9\",\"churn\":\"detected high level of churn (changed 54 times)\"}},{\"location\":{\"class_name\":null,\"method_name\":null,\"file_path\":\"lib/client/foo.rb\",\"hash\":-7081271905},\"details\":{\"churn\":\"detected high level of churn (changed 52 times)\"}}]}")
|
74
|
-
compare_hashes(MultiJson.load(MultiJson.dump(hotspots.to_h[:hotspots])), expected)
|
16
|
+
result.should == {:files => [], :classes => [], :methods => []}
|
75
17
|
end
|
76
18
|
|
77
19
|
it "should put the changes into a hash" do
|
20
|
+
MetricFu.result.should_receive(:result_hash).and_return(@yaml)
|
78
21
|
hotspots = MetricFu::HotspotsGenerator.new
|
79
|
-
analyzer = HotspotAnalyzer.new(@yaml)
|
80
|
-
hotspots.instance_variable_set(:@analyzer, analyzer)
|
81
22
|
hotspots.analyze
|
82
|
-
|
83
|
-
|
23
|
+
result = hotspots.to_h[:hotspots]
|
24
|
+
expected = metric_data('hotspots/generator_analysis.yml')
|
25
|
+
# ensure expected granularities
|
26
|
+
expect(result.keys).to eq(expected.keys)
|
27
|
+
|
28
|
+
# for each granularity's location details
|
29
|
+
result.each do |granularity,location_details|
|
30
|
+
# map 2d array for this granularity of [details, location]
|
31
|
+
expected_result = expected.fetch(granularity).map {|ld| [ld.fetch('details'), ld.fetch('location')] }
|
32
|
+
# verify all the location details for this granularity match elements of expected_result
|
33
|
+
location_details.each do |location_detail|
|
34
|
+
location = location_detail.fetch('location')
|
35
|
+
details = location_detail.fetch('details')
|
36
|
+
# get the location_detail array where the where the locations (second element) match
|
37
|
+
expected_location_details = expected_result.rassoc(location)
|
38
|
+
# get the details (first element) from the expected location_details array
|
39
|
+
expected_details = expected_location_details[0]
|
40
|
+
expect(details).to eq(expected_details)
|
41
|
+
end
|
42
|
+
end
|
84
43
|
end
|
44
|
+
|
85
45
|
# really testing the output of analyzed_problems#worst_items
|
86
46
|
it "should return the worst item granularities: files, classes, methods" do
|
87
47
|
hotspots = MetricFu::HotspotsGenerator.new
|
88
48
|
analyzer = HotspotAnalyzer.new(@yaml)
|
89
|
-
hotspots.
|
90
|
-
hotspots.analyze.keys.should =~ [:files, :classes, :methods]
|
49
|
+
expect(hotspots.analyze.keys).to eq([:files, :classes, :methods])
|
91
50
|
end
|
92
51
|
end
|
93
|
-
|
94
|
-
def compare_hashes(got,expected)
|
95
|
-
got.hash == expected.hash
|
52
|
+
|
96
53
|
end
|