metric_fu 4.11.1 → 4.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +6 -0
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +69 -0
- data/.simplecov +35 -3
- data/.travis.yml +6 -10
- data/CONTRIBUTORS +12 -11
- data/Gemfile +48 -29
- data/Guardfile +9 -9
- data/HISTORY.md +47 -1
- data/README.md +70 -57
- data/Rakefile +1 -15
- data/appveyor.yml +34 -0
- data/certs/bf4.pem +20 -20
- data/checksum/metric_fu-4.11.1.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.2.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.3.gem.sha512 +1 -0
- data/checksum/metric_fu-4.11.4.gem.sha512 +1 -0
- data/checksum/metric_fu-4.12.0.gem.sha512 +1 -0
- data/checksum/metric_fu-4.13.0.gem.sha512 +1 -0
- data/config/rubocop.yml +269 -0
- data/gem_tasks/build.rake +1 -0
- data/gem_tasks/rubocop.rake +10 -0
- data/gem_tasks/yard.rake +24 -0
- data/lib/metric_fu.rb +20 -9
- data/lib/metric_fu/calculate.rb +0 -1
- data/lib/metric_fu/cli/client.rb +6 -6
- data/lib/metric_fu/cli/helper.rb +22 -13
- data/lib/metric_fu/cli/parser.rb +14 -18
- data/lib/metric_fu/configuration.rb +7 -11
- data/lib/metric_fu/constantize.rb +4 -4
- data/lib/metric_fu/data_structures/line_numbers.rb +10 -11
- data/lib/metric_fu/data_structures/location.rb +12 -14
- data/lib/metric_fu/data_structures/sexp_node.rb +31 -13
- data/lib/metric_fu/environment.rb +29 -31
- data/lib/metric_fu/formatter.rb +4 -6
- data/lib/metric_fu/formatter/html.rb +13 -13
- data/lib/metric_fu/formatter/syntax.rb +5 -7
- data/lib/metric_fu/formatter/yaml.rb +1 -1
- data/lib/metric_fu/gem_run.rb +13 -15
- data/lib/metric_fu/gem_version.rb +10 -12
- data/lib/metric_fu/generator.rb +6 -9
- data/lib/metric_fu/io.rb +13 -15
- data/lib/metric_fu/loader.rb +17 -18
- data/lib/metric_fu/logger.rb +15 -18
- data/lib/metric_fu/logging/mf_debugger.rb +4 -4
- data/lib/metric_fu/metric.rb +11 -12
- data/lib/metric_fu/metrics/cane/generator.rb +10 -9
- data/lib/metric_fu/metrics/cane/grapher.rb +5 -7
- data/lib/metric_fu/metrics/cane/metric.rb +6 -8
- data/lib/metric_fu/metrics/cane/report.html.erb +3 -3
- data/lib/metric_fu/metrics/cane/violations.rb +6 -6
- data/lib/metric_fu/metrics/churn/generator.rb +2 -6
- data/lib/metric_fu/metrics/churn/hotspot.rb +1 -3
- data/lib/metric_fu/metrics/churn/metric.rb +5 -7
- data/lib/metric_fu/metrics/flay/generator.rb +7 -11
- data/lib/metric_fu/metrics/flay/grapher.rb +5 -6
- data/lib/metric_fu/metrics/flay/hotspot.rb +5 -7
- data/lib/metric_fu/metrics/flay/metric.rb +5 -7
- data/lib/metric_fu/metrics/flog/generator.rb +35 -24
- data/lib/metric_fu/metrics/flog/grapher.rb +11 -11
- data/lib/metric_fu/metrics/flog/hotspot.rb +3 -5
- data/lib/metric_fu/metrics/flog/metric.rb +3 -5
- data/lib/metric_fu/metrics/hotspots/analysis/analyzed_problems.rb +0 -1
- data/lib/metric_fu/metrics/hotspots/analysis/analyzer_tables.rb +19 -18
- data/lib/metric_fu/metrics/hotspots/analysis/grouping.rb +0 -2
- data/lib/metric_fu/metrics/hotspots/analysis/groupings.rb +1 -3
- data/lib/metric_fu/metrics/hotspots/analysis/problems.rb +4 -6
- data/lib/metric_fu/metrics/hotspots/analysis/ranked_problem_location.rb +14 -17
- data/lib/metric_fu/metrics/hotspots/analysis/ranking.rb +4 -5
- data/lib/metric_fu/metrics/hotspots/analysis/rankings.rb +1 -3
- data/lib/metric_fu/metrics/hotspots/analysis/record.rb +3 -5
- data/lib/metric_fu/metrics/hotspots/analysis/scoring_strategies.rb +0 -2
- data/lib/metric_fu/metrics/hotspots/analysis/table.rb +3 -4
- data/lib/metric_fu/metrics/hotspots/generator.rb +3 -6
- data/lib/metric_fu/metrics/hotspots/hotspot.rb +13 -13
- data/lib/metric_fu/metrics/hotspots/hotspot_analyzer.rb +5 -8
- data/lib/metric_fu/metrics/hotspots/metric.rb +1 -3
- data/lib/metric_fu/metrics/hotspots/report.html.erb +1 -1
- data/lib/metric_fu/metrics/rails_best_practices/generator.rb +14 -12
- data/lib/metric_fu/metrics/rails_best_practices/grapher.rb +5 -6
- data/lib/metric_fu/metrics/rails_best_practices/metric.rb +5 -4
- data/lib/metric_fu/metrics/rcov/external_client.rb +1 -3
- data/lib/metric_fu/metrics/rcov/generator.rb +13 -15
- data/lib/metric_fu/metrics/rcov/grapher.rb +6 -7
- data/lib/metric_fu/metrics/rcov/hotspot.rb +5 -7
- data/lib/metric_fu/metrics/rcov/metric.rb +5 -7
- data/lib/metric_fu/metrics/rcov/rcov_format_coverage.rb +16 -55
- data/lib/metric_fu/metrics/rcov/rcov_line.rb +48 -0
- data/lib/metric_fu/metrics/rcov/report.html.erb +2 -2
- data/lib/metric_fu/metrics/rcov/simplecov_formatter.rb +10 -11
- data/lib/metric_fu/metrics/reek/generator.rb +36 -82
- data/lib/metric_fu/metrics/reek/grapher.rb +5 -6
- data/lib/metric_fu/metrics/reek/hotspot.rb +5 -7
- data/lib/metric_fu/metrics/reek/metric.rb +2 -4
- data/lib/metric_fu/metrics/roodi/generator.rb +9 -10
- data/lib/metric_fu/metrics/roodi/grapher.rb +5 -6
- data/lib/metric_fu/metrics/roodi/hotspot.rb +1 -3
- data/lib/metric_fu/metrics/roodi/metric.rb +2 -4
- data/lib/metric_fu/metrics/saikuro/generator.rb +23 -27
- data/lib/metric_fu/metrics/saikuro/hotspot.rb +1 -3
- data/lib/metric_fu/metrics/saikuro/metric.rb +7 -8
- data/lib/metric_fu/metrics/saikuro/parsing_element.rb +6 -8
- data/lib/metric_fu/metrics/saikuro/report.html.erb +1 -1
- data/lib/metric_fu/metrics/saikuro/scratch_file.rb +24 -29
- data/lib/metric_fu/metrics/stats/generator.rb +9 -12
- data/lib/metric_fu/metrics/stats/grapher.rb +8 -9
- data/lib/metric_fu/metrics/stats/hotspot.rb +1 -3
- data/lib/metric_fu/metrics/stats/metric.rb +3 -5
- data/lib/metric_fu/reporter.rb +1 -1
- data/lib/metric_fu/reporting/graphs/graph.rb +8 -12
- data/lib/metric_fu/reporting/graphs/grapher.rb +7 -9
- data/lib/metric_fu/reporting/result.rb +0 -3
- data/lib/metric_fu/run.rb +12 -3
- data/lib/metric_fu/tasks/metric_fu.rake +8 -8
- data/lib/metric_fu/templates/configuration.rb +2 -5
- data/lib/metric_fu/templates/metrics_template.rb +45 -32
- data/lib/metric_fu/templates/report.rb +5 -8
- data/lib/metric_fu/templates/template.rb +20 -24
- data/lib/metric_fu/utility.rb +15 -8
- data/lib/metric_fu/version.rb +7 -1
- data/metric_fu.gemspec +29 -32
- data/spec/capture_warnings.rb +29 -22
- data/spec/cli/helper_spec.rb +9 -16
- data/spec/dummy/lib/bad_encoding.rb +1 -1
- data/spec/fixtures/coverage-153.rb +2 -2
- data/spec/fixtures/coverage.rb +2 -2
- data/spec/metric_fu/calculate_spec.rb +3 -3
- data/spec/metric_fu/configuration_spec.rb +71 -83
- data/spec/metric_fu/data_structures/line_numbers_spec.rb +3 -5
- data/spec/metric_fu/data_structures/location_spec.rb +13 -31
- data/spec/metric_fu/formatter/configuration_spec.rb +18 -20
- data/spec/metric_fu/formatter/html_spec.rb +21 -28
- data/spec/metric_fu/formatter/yaml_spec.rb +9 -17
- data/spec/metric_fu/formatter_spec.rb +16 -16
- data/spec/metric_fu/gem_version_spec.rb +4 -6
- data/spec/metric_fu/generator_spec.rb +33 -43
- data/spec/metric_fu/loader_spec.rb +5 -4
- data/spec/metric_fu/metric_spec.rb +21 -25
- data/spec/metric_fu/metrics/cane/configuration_spec.rb +14 -14
- data/spec/metric_fu/metrics/cane/generator_spec.rb +26 -29
- data/spec/metric_fu/metrics/churn/configuration_spec.rb +7 -9
- data/spec/metric_fu/metrics/churn/generator_spec.rb +6 -11
- data/spec/metric_fu/metrics/flay/configuration_spec.rb +7 -9
- data/spec/metric_fu/metrics/flay/generator_spec.rb +36 -37
- data/spec/metric_fu/metrics/flay/grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/flog/configuration_spec.rb +12 -14
- data/spec/metric_fu/metrics/flog/generator_spec.rb +31 -32
- data/spec/metric_fu/metrics/flog/grapher_spec.rb +8 -10
- data/spec/metric_fu/metrics/hotspots/analysis/analyzed_problems_spec.rb +18 -24
- data/spec/metric_fu/metrics/hotspots/analysis/analyzer_tables_spec.rb +12 -17
- data/spec/metric_fu/metrics/hotspots/analysis/ranking_spec.rb +2 -6
- data/spec/metric_fu/metrics/hotspots/analysis/rankings_spec.rb +5 -14
- data/spec/metric_fu/metrics/hotspots/analysis/table_spec.rb +1 -3
- data/spec/metric_fu/metrics/hotspots/generator_spec.rb +6 -8
- data/spec/metric_fu/metrics/hotspots/hotspot_analyzer_spec.rb +1 -3
- data/spec/metric_fu/metrics/hotspots/hotspot_spec.rb +4 -5
- data/spec/metric_fu/metrics/rails_best_practices/configuration_spec.rb +25 -17
- data/spec/metric_fu/metrics/rails_best_practices/generator_spec.rb +2 -3
- data/spec/metric_fu/metrics/rails_best_practices/grapher_spec.rb +3 -3
- data/spec/metric_fu/metrics/rcov/configuration_spec.rb +21 -23
- data/spec/metric_fu/metrics/rcov/generator_spec.rb +6 -10
- data/spec/metric_fu/metrics/rcov/grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/rcov/hotspot_spec.rb +8 -8
- data/spec/metric_fu/metrics/rcov/rcov_line_spec.rb +89 -0
- data/spec/metric_fu/metrics/rcov/simplecov_formatter_spec.rb +31 -33
- data/spec/metric_fu/metrics/reek/configuration_spec.rb +7 -7
- data/spec/metric_fu/metrics/reek/generator_spec.rb +131 -111
- data/spec/metric_fu/metrics/reek/grapher_spec.rb +4 -4
- data/spec/metric_fu/metrics/roodi/configuration_spec.rb +8 -10
- data/spec/metric_fu/metrics/roodi/generator_spec.rb +3 -3
- data/spec/metric_fu/metrics/roodi/grapher_spec.rb +2 -2
- data/spec/metric_fu/metrics/saikuro/configuration_spec.rb +22 -23
- data/spec/metric_fu/metrics/saikuro/generator_spec.rb +7 -7
- data/spec/metric_fu/metrics/stats/generator_spec.rb +10 -10
- data/spec/metric_fu/metrics/stats/grapher_spec.rb +2 -2
- data/spec/metric_fu/reporter_spec.rb +8 -9
- data/spec/metric_fu/reporting/graphs/graph_spec.rb +1 -4
- data/spec/metric_fu/reporting/graphs/grapher_spec.rb +5 -5
- data/spec/metric_fu/reporting/result_spec.rb +12 -14
- data/spec/metric_fu/run_spec.rb +19 -33
- data/spec/metric_fu/templates/configuration_spec.rb +34 -40
- data/spec/metric_fu/templates/metrics_template_spec.rb +11 -0
- data/spec/metric_fu/templates/report_spec.rb +4 -4
- data/spec/metric_fu/templates/template_spec.rb +78 -64
- data/spec/metric_fu/utility_spec.rb +3 -3
- data/spec/metric_fu_spec.rb +23 -6
- data/spec/quality_spec.rb +43 -15
- data/spec/shared/configured.rb +9 -11
- data/spec/shared/test_coverage.rb +5 -9
- data/spec/spec_helper.rb +13 -31
- data/spec/{dummy → support}/.metrics +0 -0
- data/spec/support/deferred_garbaged_collection.rb +1 -2
- data/spec/support/matcher_create_file.rb +6 -4
- data/spec/support/matcher_create_files.rb +6 -4
- data/spec/support/samples/reek/alfa.rb +1 -0
- data/spec/support/suite.rb +3 -3
- data/spec/support/test_fixtures.rb +5 -7
- data/spec/support/timeout.rb +1 -1
- data/spec/support/usage_test.rb +24 -25
- data/spec/usage_test_spec.rb +30 -32
- metadata +104 -103
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/gemfiles/Gemfile.travis +0 -10
- metadata.gz.sig +0 -0
@@ -1,4 +1,4 @@
|
|
1
|
-
MetricFu.reporting_require {
|
1
|
+
MetricFu.reporting_require { "graphs/grapher" }
|
2
2
|
module MetricFu
|
3
3
|
class RcovGrapher < Grapher
|
4
4
|
attr_accessor :rcov_percent, :labels
|
@@ -15,24 +15,23 @@ module MetricFu
|
|
15
15
|
|
16
16
|
def get_metrics(metrics, date)
|
17
17
|
if metrics && metrics[:rcov]
|
18
|
-
|
19
|
-
|
18
|
+
rcov_percent.push(metrics[:rcov][:global_percent_run])
|
19
|
+
labels.update(labels.size => date)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
def title
|
24
|
-
|
24
|
+
"Rcov: code coverage"
|
25
25
|
end
|
26
26
|
|
27
27
|
def data
|
28
28
|
[
|
29
|
-
[
|
29
|
+
["rcov", @rcov_percent.join(",")]
|
30
30
|
]
|
31
31
|
end
|
32
32
|
|
33
33
|
def output_filename
|
34
|
-
|
34
|
+
"rcov.js"
|
35
35
|
end
|
36
|
-
|
37
36
|
end
|
38
37
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class MetricFu::RcovHotspot < MetricFu::Hotspot
|
2
|
-
|
3
2
|
COLUMNS = %w{percentage_uncovered}
|
4
3
|
|
5
4
|
def columns
|
@@ -23,18 +22,18 @@ class MetricFu::RcovHotspot < MetricFu::Hotspot
|
|
23
22
|
end
|
24
23
|
|
25
24
|
def generate_records(data, table)
|
26
|
-
return if data==nil
|
25
|
+
return if data == nil
|
27
26
|
data.each do |file_name, info|
|
28
27
|
next if (file_name == :global_percent_run) || (info[:methods].nil?)
|
29
28
|
info[:methods].each do |method_name, percentage_uncovered|
|
30
29
|
location = MetricFu::Location.for(method_name)
|
31
30
|
table << {
|
32
31
|
"metric" => :rcov,
|
33
|
-
|
34
|
-
|
32
|
+
"file_path" => file_name,
|
33
|
+
"class_name" => location.class_name,
|
35
34
|
"method_name" => location.method_name,
|
36
35
|
"percentage_uncovered" => percentage_uncovered
|
37
|
-
|
36
|
+
}
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
@@ -42,7 +41,6 @@ class MetricFu::RcovHotspot < MetricFu::Hotspot
|
|
42
41
|
def present_group(group)
|
43
42
|
occurences = group.size
|
44
43
|
average_code_uncoverage = get_mean(group.column("percentage_uncovered"))
|
45
|
-
"#{
|
44
|
+
"#{'average ' if occurences > 1}uncovered code is %.1f%" % average_code_uncoverage
|
46
45
|
end
|
47
|
-
|
48
46
|
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
module MetricFu
|
2
2
|
class MetricRcov < Metric
|
3
|
-
|
4
3
|
def name
|
5
4
|
:rcov
|
6
5
|
end
|
7
6
|
|
8
7
|
def default_run_options
|
9
8
|
{
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
9
|
+
environment: "test",
|
10
|
+
test_files: Dir["{spec,test}/**/*_{spec,test}.rb"],
|
11
|
+
rcov_opts: rcov_opts,
|
12
|
+
external: nil,
|
14
13
|
}
|
15
14
|
end
|
16
15
|
|
17
16
|
def coverage_file=(coverage_file)
|
18
|
-
configured_run_options.update(:
|
17
|
+
configured_run_options.update(external: coverage_file)
|
19
18
|
end
|
20
19
|
|
21
20
|
def has_graph?
|
@@ -58,6 +57,5 @@ module MetricFu
|
|
58
57
|
rcov_opts << "-Ispec" if File.exist?("spec")
|
59
58
|
rcov_opts
|
60
59
|
end
|
61
|
-
|
62
60
|
end
|
63
61
|
end
|
@@ -7,41 +7,6 @@ module MetricFu
|
|
7
7
|
@rcov_text = rcov_text
|
8
8
|
end
|
9
9
|
|
10
|
-
class Line
|
11
|
-
attr_accessor :content, :was_run
|
12
|
-
|
13
|
-
def initialize(content, was_run)
|
14
|
-
@content = content
|
15
|
-
@was_run = was_run
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_h
|
19
|
-
{:content => @content, :was_run => @was_run}
|
20
|
-
end
|
21
|
-
|
22
|
-
def covered?
|
23
|
-
@was_run.one?
|
24
|
-
end
|
25
|
-
def missed?
|
26
|
-
@was_run.zero?
|
27
|
-
end
|
28
|
-
def ignored?
|
29
|
-
@was_run.nil?
|
30
|
-
end
|
31
|
-
def self.line_coverage(lines)
|
32
|
-
lines.map{|line| line[:was_run] }
|
33
|
-
end
|
34
|
-
def self.covered_lines(line_coverage)
|
35
|
-
line_coverage.count(1)
|
36
|
-
end
|
37
|
-
def self.missed_lines(line_coverage)
|
38
|
-
line_coverage.count(0)
|
39
|
-
end
|
40
|
-
def self.ignored_lines(line_coverage)
|
41
|
-
line_coverage.count(nil)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
10
|
def to_h
|
46
11
|
rcov_text = @rcov_text.split(NEW_FILE_MARKER)
|
47
12
|
|
@@ -49,7 +14,6 @@ module MetricFu
|
|
49
14
|
|
50
15
|
files = assemble_files(rcov_text)
|
51
16
|
|
52
|
-
|
53
17
|
TestCoverage.new(files).to_h
|
54
18
|
end
|
55
19
|
|
@@ -57,21 +21,21 @@ module MetricFu
|
|
57
21
|
|
58
22
|
def assemble_files(rcov_text)
|
59
23
|
files = {}
|
60
|
-
rcov_text.each_slice(2) {|out| files[out.first.strip] = out.last}
|
61
|
-
files.each_pair {|fname, content| files[fname] = content.split("\n") }
|
24
|
+
rcov_text.each_slice(2) { |out| files[out.first.strip] = out.last }
|
25
|
+
files.each_pair { |fname, content| files[fname] = content.split("\n") }
|
62
26
|
files.each_pair do |fname, content|
|
63
27
|
content.map! do |raw_line|
|
64
|
-
covered_line = if raw_line.start_with?(
|
28
|
+
covered_line = if raw_line.start_with?("--")
|
65
29
|
nil # simplecov ignores some lines
|
66
|
-
elsif raw_line.start_with?(
|
30
|
+
elsif raw_line.start_with?("!!")
|
67
31
|
0
|
68
32
|
else
|
69
33
|
1
|
70
34
|
end
|
71
|
-
|
35
|
+
RCovLine.new(raw_line[3..-1], covered_line).to_h
|
72
36
|
end
|
73
|
-
content.reject! {|line| line[:content].to_s ==
|
74
|
-
files[fname] = {:
|
37
|
+
content.reject! { |line| line[:content].to_s == "" }
|
38
|
+
files[fname] = { lines: content }
|
75
39
|
end
|
76
40
|
files
|
77
41
|
end
|
@@ -101,9 +65,9 @@ module MetricFu
|
|
101
65
|
end
|
102
66
|
|
103
67
|
def self.percent_run(lines)
|
104
|
-
line_coverage =
|
105
|
-
covered_lines =
|
106
|
-
ignored_lines =
|
68
|
+
line_coverage = RCovLine.line_coverage(lines)
|
69
|
+
covered_lines = RCovLine.covered_lines(line_coverage)
|
70
|
+
ignored_lines = RCovLine.ignored_lines(line_coverage)
|
107
71
|
relevant_lines = lines.count - ignored_lines
|
108
72
|
if block_given?
|
109
73
|
yield covered_lines, relevant_lines
|
@@ -113,6 +77,7 @@ module MetricFu
|
|
113
77
|
end
|
114
78
|
|
115
79
|
private
|
80
|
+
|
116
81
|
# TODO: remove multiple side effects
|
117
82
|
# sets global ivars and
|
118
83
|
# modifies the param passed in
|
@@ -131,9 +96,9 @@ module MetricFu
|
|
131
96
|
|
132
97
|
def add_global_percent_run(test_coverage, total_lines, total_lines_run)
|
133
98
|
percentage = self.class.floating_percent(total_lines_run, total_lines)
|
134
|
-
test_coverage.update(
|
135
|
-
:
|
136
|
-
|
99
|
+
test_coverage.update(
|
100
|
+
global_percent_run: round_to_tenths(percentage)
|
101
|
+
)
|
137
102
|
end
|
138
103
|
|
139
104
|
def add_method_data(test_coverage)
|
@@ -141,7 +106,7 @@ module MetricFu
|
|
141
106
|
file_contents = ""
|
142
107
|
coverage = []
|
143
108
|
|
144
|
-
info[:lines].each_with_index do |line,
|
109
|
+
info[:lines].each_with_index do |line, _index|
|
145
110
|
file_contents << "#{line[:content]}\n"
|
146
111
|
coverage << line[:was_run]
|
147
112
|
end
|
@@ -172,17 +137,13 @@ module MetricFu
|
|
172
137
|
method_coverage_map.each do |method_name, coverage_data|
|
173
138
|
test_coverage[file_path][:methods][method_name] = (coverage_data[:uncovered] / coverage_data[:total].to_f) * 100.0
|
174
139
|
end
|
175
|
-
|
176
140
|
end
|
177
141
|
end
|
178
142
|
|
179
143
|
def round_to_tenths(decimal)
|
180
|
-
decimal = 0.0 if decimal.to_s.eql?(
|
144
|
+
decimal = 0.0 if decimal.to_s.eql?("NaN")
|
181
145
|
(decimal * 10).round / 10.0
|
182
146
|
end
|
183
|
-
|
184
|
-
|
185
147
|
end
|
186
|
-
|
187
148
|
end
|
188
149
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module MetricFu
|
2
|
+
class RCovLine
|
3
|
+
attr_accessor :content, :was_run
|
4
|
+
|
5
|
+
def initialize(content, was_run)
|
6
|
+
@content = content
|
7
|
+
@was_run = was_run
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
{ content: @content, was_run: @was_run }
|
12
|
+
end
|
13
|
+
|
14
|
+
def covered?
|
15
|
+
@was_run == 1
|
16
|
+
end
|
17
|
+
|
18
|
+
def missed?
|
19
|
+
@was_run == 0
|
20
|
+
end
|
21
|
+
|
22
|
+
def ignored?
|
23
|
+
@was_run.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.line_coverage(lines)
|
27
|
+
lines.map { |line| line[:was_run] }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.covered_lines(line_coverage)
|
31
|
+
line_coverage.count(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.missed_lines(line_coverage)
|
35
|
+
line_coverage.count(0)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.ignored_lines(line_coverage)
|
39
|
+
line_coverage.count(nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
def css_class
|
43
|
+
return "rcov_not_run" if missed?
|
44
|
+
|
45
|
+
"rcov_run"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -29,8 +29,8 @@
|
|
29
29
|
<table class="rcov_code">
|
30
30
|
<% file[:lines].each_with_index do |line, index| %>
|
31
31
|
<tr>
|
32
|
-
<%
|
33
|
-
<td class="<%= css_class %>"><%= link_to_filename(fname, index + 1, "<pre>#{line[:content]}</pre>") %></td>
|
32
|
+
<% rcov_line = RCovLine.new(line[:content], line[:was_run]) %>
|
33
|
+
<td class="<%= rcov_line.css_class %>"><%= link_to_filename(fname, index + 1, "<pre>#{line[:content]}</pre>") %></td>
|
34
34
|
</tr>
|
35
35
|
<% end %>
|
36
36
|
</table>
|
@@ -7,12 +7,12 @@ if defined?(JRUBY_VERSION)
|
|
7
7
|
# https://github.com/colszowka/simplecov/issues/86
|
8
8
|
end
|
9
9
|
end
|
10
|
-
require
|
11
|
-
|
12
|
-
require_relative
|
10
|
+
require "simplecov"
|
11
|
+
require "metric_fu/logger"
|
12
|
+
require_relative "external_client"
|
13
|
+
require_relative "rcov_format_coverage"
|
13
14
|
|
14
15
|
class SimpleCov::Formatter::MetricFu
|
15
|
-
|
16
16
|
def format(result)
|
17
17
|
rcov_text = FormatLikeRCov.new(result).format
|
18
18
|
client = MetricFu::RCovTestCoverageClient.new(coverage_file_path)
|
@@ -26,7 +26,7 @@ class SimpleCov::Formatter::MetricFu
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def default_coverage_file_path
|
29
|
-
File.join(SimpleCov.root,
|
29
|
+
File.join(SimpleCov.root, "coverage", "rcov", output_file_name)
|
30
30
|
end
|
31
31
|
|
32
32
|
# TODO: Read in from legacy coverage/rcov/rcov.txt path, when set
|
@@ -40,7 +40,7 @@ class SimpleCov::Formatter::MetricFu
|
|
40
40
|
# going forward, the file name will be in a date-stamped
|
41
41
|
# format like for all other reported metrics.
|
42
42
|
def output_file_name
|
43
|
-
|
43
|
+
"rcov.txt"
|
44
44
|
end
|
45
45
|
|
46
46
|
# report should reference file used to build it
|
@@ -57,9 +57,9 @@ class SimpleCov::Formatter::MetricFu
|
|
57
57
|
content << "=" * 80
|
58
58
|
content << "\n"
|
59
59
|
source_file.lines.each do |line|
|
60
|
-
content <<
|
61
|
-
content <<
|
62
|
-
content <<
|
60
|
+
content << "!!" if line.missed?
|
61
|
+
content << "--" if line.never? || line.skipped?
|
62
|
+
content << " " if line.covered?
|
63
63
|
content << " #{line.src.chomp}\n"
|
64
64
|
end
|
65
65
|
content << "\n"
|
@@ -68,8 +68,7 @@ class SimpleCov::Formatter::MetricFu
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def simple_file_name(source_file)
|
71
|
-
source_file.filename.gsub(SimpleCov.root,
|
71
|
+
source_file.filename.gsub(SimpleCov.root, ".")
|
72
72
|
end
|
73
73
|
end
|
74
|
-
|
75
74
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
module MetricFu
|
2
|
-
|
3
2
|
class ReekGenerator < Generator
|
4
|
-
REEK_REGEX = /^(\S+) (.*) \((.*)\)$/
|
5
|
-
|
6
3
|
def self.metric
|
7
4
|
:reek
|
8
5
|
end
|
@@ -11,34 +8,27 @@ module MetricFu
|
|
11
8
|
files = files_to_analyze
|
12
9
|
if files.empty?
|
13
10
|
mf_log "Skipping Reek, no files found to analyze"
|
14
|
-
@output =
|
11
|
+
@output = run!([], config_files)
|
15
12
|
else
|
16
|
-
|
17
|
-
@output = run!(args)
|
18
|
-
@output = massage_for_reek_12 if reek_12?
|
13
|
+
@output = run!(files, config_files)
|
19
14
|
end
|
20
15
|
end
|
21
16
|
|
17
|
+
def run!(files, config_files)
|
18
|
+
files.map do |file|
|
19
|
+
examiner.new(File.new(file), filter_by_smells: config_files)
|
20
|
+
end
|
21
|
+
end
|
22
22
|
|
23
23
|
def analyze
|
24
|
-
@matches = @output.
|
25
|
-
|
26
|
-
|
27
|
-
file_path = match.shift.split(' -- ').first
|
28
|
-
file_path = file_path.gsub('"', ' ').strip
|
29
|
-
code_smells = match.map do |smell|
|
30
|
-
match_object = smell.match(REEK_REGEX)
|
31
|
-
next unless match_object
|
32
|
-
{:method => match_object[1].strip,
|
33
|
-
:message => match_object[2].strip,
|
34
|
-
:type => match_object[3].strip}
|
35
|
-
end.compact
|
36
|
-
{:file_path => file_path, :code_smells => code_smells}
|
24
|
+
@matches = @output.flat_map(&:smells).group_by(&:source).collect do |file_path, smells|
|
25
|
+
{ file_path: file_path,
|
26
|
+
code_smells: analyze_smells(smells) }
|
37
27
|
end
|
38
28
|
end
|
39
29
|
|
40
30
|
def to_h
|
41
|
-
{:
|
31
|
+
{ reek: { matches: @matches } }
|
42
32
|
end
|
43
33
|
|
44
34
|
def per_file_info(out)
|
@@ -46,7 +36,7 @@ module MetricFu
|
|
46
36
|
file_path = file_data[:file_path]
|
47
37
|
next if File.extname(file_path) =~ /\.erb|\.html|\.haml/
|
48
38
|
begin
|
49
|
-
line_numbers = MetricFu::LineNumbers.new(File.read(file_path),file_path)
|
39
|
+
line_numbers = MetricFu::LineNumbers.new(File.read(file_path), file_path)
|
50
40
|
rescue StandardError => e
|
51
41
|
raise e unless e.message =~ /you shouldn't be able to get here/
|
52
42
|
mf_log "ruby_parser blew up while trying to parse #{file_path}. You won't have method level reek information for this file."
|
@@ -55,86 +45,50 @@ module MetricFu
|
|
55
45
|
|
56
46
|
file_data[:code_smells].each do |smell_data|
|
57
47
|
line = line_numbers.start_line_for_method(smell_data[:method])
|
58
|
-
out[file_data[:file_path]][line.to_s] << {:
|
59
|
-
|
48
|
+
out[file_data[:file_path]][line.to_s] << { type: :reek,
|
49
|
+
description: "#{smell_data[:type]} - #{smell_data[:message]}" }
|
60
50
|
end
|
61
51
|
end
|
62
52
|
end
|
63
53
|
|
64
|
-
def reek_12?
|
65
|
-
return false if @output.length == 0
|
66
|
-
(@output =~ /^"/) != 0
|
67
|
-
end
|
68
|
-
|
69
|
-
def massage_for_reek_12
|
70
|
-
section_break = ''
|
71
|
-
@output.split("\n").map do |line|
|
72
|
-
case line
|
73
|
-
when /^ /
|
74
|
-
"#{line.gsub(/^ /, '')}\n"
|
75
|
-
else
|
76
|
-
parts = line.split(" -- ")
|
77
|
-
if parts[1].nil?
|
78
|
-
"#{line}\n"
|
79
|
-
else
|
80
|
-
warnings = parts[1].gsub(/ \(.*\):/, ':')
|
81
|
-
result = "#{section_break}\"#{parts[0]}\" -- #{warnings}\n"
|
82
|
-
section_break = "\n"
|
83
|
-
result
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end.join
|
87
|
-
end
|
88
|
-
|
89
54
|
private
|
90
55
|
|
91
56
|
def files_to_analyze
|
92
57
|
dirs_to_reek = options[:dirs_to_reek]
|
93
|
-
files_to_reek = dirs_to_reek.map{|dir| Dir[File.join(dir, "**","*.rb")] }.flatten
|
58
|
+
files_to_reek = dirs_to_reek.map { |dir| Dir[File.join(dir, "**", "*.rb")] }.flatten
|
94
59
|
remove_excluded_files(files_to_reek)
|
95
60
|
end
|
96
61
|
|
97
|
-
def cli_options(files)
|
98
|
-
[
|
99
|
-
disable_line_number_option,
|
100
|
-
turn_off_color,
|
101
|
-
config_option,
|
102
|
-
files.join(' ')
|
103
|
-
].join(' ')
|
104
|
-
end
|
105
|
-
|
106
62
|
# TODO: Check that specified line config file exists
|
107
|
-
def
|
108
|
-
|
109
|
-
if config_file_pattern.to_s.empty?
|
110
|
-
''
|
111
|
-
else
|
112
|
-
"--config #{config_file_pattern}"
|
113
|
-
end
|
63
|
+
def config_files
|
64
|
+
Array(options[:config_file_pattern])
|
114
65
|
end
|
115
66
|
|
116
|
-
|
117
|
-
|
118
|
-
if reek_version >= '1.3.7'
|
119
|
-
'--no-color'
|
120
|
-
else
|
121
|
-
''
|
122
|
-
end
|
67
|
+
def analyze_smells(smells)
|
68
|
+
smells.collect(&method(:smell_data))
|
123
69
|
end
|
124
70
|
|
125
|
-
def
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
71
|
+
def smell_data(smell)
|
72
|
+
{ method: smell.context,
|
73
|
+
message: smell.message,
|
74
|
+
type: smell_type(smell),
|
75
|
+
lines: smell.lines }
|
130
76
|
end
|
131
77
|
|
132
|
-
def
|
133
|
-
|
78
|
+
def smell_type(smell)
|
79
|
+
return smell.subclass if smell.respond_to?(:subclass)
|
80
|
+
|
81
|
+
smell.smell_type
|
134
82
|
end
|
135
83
|
|
136
|
-
def
|
137
|
-
|
84
|
+
def examiner
|
85
|
+
require "reek"
|
86
|
+
# To load any changing dependencies such as "reek/configuration/app_configuration"
|
87
|
+
# Added in 1.6.0 https://github.com/troessner/reek/commit/7f4ed2be442ca926e08ccc41945e909e8f710947
|
88
|
+
# But not always loaded
|
89
|
+
require "reek/cli/application"
|
90
|
+
|
91
|
+
Reek.const_defined?(:Examiner) ? Reek.const_get(:Examiner) : Reek.const_get(:Core).const_get(:Examiner)
|
138
92
|
end
|
139
93
|
end
|
140
94
|
end
|