slather 1.8.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +1 -0
- data/CHANGELOG.md +21 -1
- data/README.md +15 -10
- data/README_Images/test_scheme.png +0 -0
- data/Rakefile +6 -0
- data/bin/slather +45 -6
- data/lib/slather/coverage_file.rb +37 -90
- data/lib/slather/coverage_info.rb +84 -0
- data/lib/slather/coverage_service/cobertura_xml_output.rb +10 -6
- data/lib/slather/coverage_service/coveralls.rb +5 -1
- data/lib/slather/coverage_service/gutter_json_output.rb +12 -8
- data/lib/slather/coverage_service/hardcover.rb +5 -1
- data/lib/slather/coverage_service/html_output.rb +32 -19
- data/lib/slather/coverage_service/simple_output.rb +5 -1
- data/lib/slather/{coveralls_coverage_file.rb → coveralls_coverage.rb} +1 -1
- data/lib/slather/profdata_coverage_file.rb +130 -0
- data/lib/slather/project.rb +191 -27
- data/lib/slather/version.rb +1 -1
- data/lib/slather.rb +9 -1
- data/slather.gemspec +4 -4
- data/spec/fixtures/cobertura.xml +56 -79
- data/spec/fixtures/fixtures/Fixtures.swift +15 -0
- data/spec/fixtures/fixtures/other_fixtures.m +23 -0
- data/spec/fixtures/fixtures_html/Branches.m.html +244 -258
- data/spec/fixtures/fixtures_html/BranchesTests.m.html +209 -225
- data/spec/fixtures/fixtures_html/fixtures.m.html +134 -148
- data/spec/fixtures/fixtures_html/fixturesTests.m.html +199 -213
- data/spec/fixtures/fixtures_html/index.html +68 -131
- data/spec/fixtures/fixtures_html/peekaviewTests.m.html +189 -203
- data/spec/fixtures/gutter.json +1 -1
- data/spec/slather/coverage_file_spec.rb +20 -12
- data/spec/slather/coverage_service/cobertura_xml_spec.rb +7 -3
- data/spec/slather/coverage_service/coveralls_spec.rb +61 -20
- data/spec/slather/coverage_service/gutter_json_spec.rb +6 -2
- data/spec/slather/coverage_service/hardcover_spec.rb +33 -3
- data/spec/slather/coverage_service/html_output_spec.rb +48 -7
- data/spec/slather/coverage_service/simple_output_spec.rb +12 -13
- data/spec/slather/profdata_coverage_spec.rb +128 -0
- data/spec/slather/project_spec.rb +222 -49
- data/spec/spec_helper.rb +28 -2
- metadata +58 -46
- data/spec/fixtures/fixtures_html/Empty.m.html +0 -30
- data/spec/fixtures/fixtures_html/fixtures_cpp.cpp.html +0 -30
- data/spec/fixtures/fixtures_html/fixtures_m.m.html +0 -30
- data/spec/fixtures/fixtures_html/fixtures_mm.mm.html +0 -30
- data/spec/fixtures/fixtures_html/peekaview.m.html +0 -190
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e29925c45c07bc530dfadabea493ce213e7c463e
|
4
|
+
data.tar.gz: 4349b2ddac614dc2743cf512ca537637bb765c04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12f3d539e348aea80bb1ef490ff281ef4b250de56e21682cdfdfbb1a8371ca62253d693e87ddf14496fee037df2b86b0fff11181e14282eb358232ac0a40b47b
|
7
|
+
data.tar.gz: e2025df52453c14802781dd7f41bfa2c0f991ef8893febe01a6a14ccff2136d8c50a4c6360b117d34037bc0eb69d8667b437d98b68b8677f581702271febd68f
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,27 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
-
##
|
5
|
+
## v2.0.0
|
6
|
+
* Correct html rendering when using profdata format
|
7
|
+
[cutz](https://github.com/cutz)
|
8
|
+
[#124](https://github.com/SlatherOrg/slather/pull/124)
|
9
|
+
|
10
|
+
* Making HTML directory self contained
|
11
|
+
[Colin Cornaby](https://github.com/colincornaby)
|
12
|
+
[#137](https://github.com/SlatherOrg/slather/pull/137)
|
13
|
+
|
14
|
+
* Add `binary_basename` configuration option
|
15
|
+
[Boris Bügling](https://github.com/neonichu)
|
16
|
+
[#128](https://github.com/SlatherOrg/slather/pull/128)
|
17
|
+
|
18
|
+
* Add support to profdata file format
|
19
|
+
[Simone Civetta](https://github.com/viteinfinite)
|
20
|
+
[Olivier Halligon](https://github.com/AliSoftware)
|
21
|
+
[Matt Delves](https://github.com/mattdelves)
|
22
|
+
[Pierre-Marc Airoldi](https://github.com/petester42)
|
23
|
+
[#92](https://github.com/venmo/slather/pull/92)
|
24
|
+
|
25
|
+
## v1.8.3
|
6
26
|
* Add buildkite support to coveralls
|
7
27
|
[David Hardiman](https://github.com/dhardiman)
|
8
28
|
[#98](https://github.com/venmo/slather/pull/98)
|
data/README.md
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
|
2
2
|
|
3
|
-
![Slather Logo](https://raw.githubusercontent.com/
|
3
|
+
![Slather Logo](https://raw.githubusercontent.com/SlatherOrg/slather/master/docs/logo.jpg)
|
4
4
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/slather.svg)](http://badge.fury.io/rb/slather)
|
6
|
-
[![Build Status](https://travis-ci.org/
|
7
|
-
[![Coverage Status](https://coveralls.io/repos/
|
6
|
+
[![Build Status](https://travis-ci.org/SlatherOrg/slather.svg?branch=master)](https://travis-ci.org/SlatherOrg/slather)
|
7
|
+
[![Coverage Status](https://coveralls.io/repos/SlatherOrg/slather/badge.svg?branch=master)](https://coveralls.io/r/SlatherOrg/slather?branch=master)
|
8
8
|
|
9
9
|
Generate test coverage reports for Xcode projects & hook it into CI.
|
10
10
|
|
@@ -33,21 +33,26 @@ $ bundle
|
|
33
33
|
|
34
34
|
## Usage
|
35
35
|
|
36
|
-
|
36
|
+
Apple drastically improved the support for code coverage in Xcode 7, including dedicated UI for enabling it. You can now setup your project for test coverage inside the scheme editor, by ticking the *"Gather coverage data"* checkbox:
|
37
|
+
|
38
|
+
![](README_Images/test_scheme.png)
|
39
|
+
|
40
|
+
To verify you're ready to generate test coverage, run your test suite on your project, and then run:
|
37
41
|
|
38
42
|
```sh
|
39
|
-
$ slather
|
43
|
+
$ slather coverage -s path/to/project.xcodeproj
|
40
44
|
```
|
41
45
|
|
42
|
-
|
43
|
-
|
46
|
+
### Previous versions of Xcode
|
44
47
|
|
45
|
-
|
48
|
+
Set up your project for test coverage:
|
46
49
|
|
47
50
|
```sh
|
48
|
-
$ slather
|
51
|
+
$ slather setup path/to/project.xcodeproj
|
49
52
|
```
|
50
53
|
|
54
|
+
This will enable the `Generate Test Coverage` and `Instrument Program Flow` flags for your project.
|
55
|
+
|
51
56
|
### Usage with Codecov
|
52
57
|
|
53
58
|
Login to [Codecov](https://codecov.io/) (no need to activate a repository, this happens automatically). Right now, `slather` supports Codecov via **all** supported CI providers [listed here](https://github.com/codecov/codecov-bash#ci-providers).
|
@@ -193,7 +198,7 @@ Slather will look for the test coverage files in `DerivedData` by default. If yo
|
|
193
198
|
|
194
199
|
## Contributing
|
195
200
|
|
196
|
-
We’d love to see your ideas for improving this library! The best way to contribute is by submitting a pull request. We’ll do our best to respond to your patch as soon as possible. You can also submit a [new GitHub issue](https://github.com/
|
201
|
+
We’d love to see your ideas for improving this library! The best way to contribute is by submitting a pull request. We’ll do our best to respond to your patch as soon as possible. You can also submit a [new GitHub issue](https://github.com/SlatherOrg/slather/issues/new) if you find bugs or have questions. :octocat:
|
197
202
|
|
198
203
|
Please make sure to follow our general coding style and add test coverage for new features!
|
199
204
|
|
Binary file
|
data/Rakefile
CHANGED
data/bin/slather
CHANGED
@@ -9,7 +9,7 @@ Clamp do
|
|
9
9
|
|
10
10
|
subcommand "coverage", "Computes coverage for the supplied project" do
|
11
11
|
|
12
|
-
parameter "[
|
12
|
+
parameter "[PROJECT]", "Path to the xcodeproj", :attribute_name => :xcodeproj_path
|
13
13
|
|
14
14
|
option ["--travis", "-t"], :flag, "Indicate that the builds are running on Travis CI"
|
15
15
|
option ["--circleci"], :flag, "Indicate that the builds are running on CircleCI"
|
@@ -27,6 +27,12 @@ Clamp do
|
|
27
27
|
option ["--source-directory"], "SOURCE_DIRECTORY", "The directory where your source files are located."
|
28
28
|
option ["--output-directory"], "OUTPUT_DIRECTORY", "The directory where your Cobertura XML report will be written to."
|
29
29
|
option ["--ignore", "-i"], "IGNORE", "ignore files conforming to a path", :multivalued => true
|
30
|
+
option ["--verbose", "-v"], :flag, "Enable verbose mode"
|
31
|
+
|
32
|
+
option ["--input-format"], "INPUT_FORMAT", "Input format (gcov, profdata)"
|
33
|
+
option ["--scheme"], "SCHEME", "The scheme for which the coverage was generated"
|
34
|
+
option ["--binary-file"], "BINARY_FILE", "The binary file against the which the coverage will be run"
|
35
|
+
option ["--binary-basename"], "BINARY_BASENAME", "Basename of the file against which the coverage will be run"
|
30
36
|
|
31
37
|
def execute
|
32
38
|
puts "Slathering..."
|
@@ -37,6 +43,13 @@ Clamp do
|
|
37
43
|
setup_source_directory
|
38
44
|
setup_output_directory
|
39
45
|
setup_coverage_service
|
46
|
+
setup_verbose_mode
|
47
|
+
setup_input_format
|
48
|
+
setup_scheme
|
49
|
+
setup_binary_file
|
50
|
+
setup_binary_basename
|
51
|
+
|
52
|
+
project.configure
|
40
53
|
|
41
54
|
post
|
42
55
|
|
@@ -81,7 +94,7 @@ Clamp do
|
|
81
94
|
if xcodeproj_path_to_open
|
82
95
|
project = Slather::Project.open(xcodeproj_path_to_open)
|
83
96
|
else
|
84
|
-
raise StandardError, "Must provide an xcodeproj through .slather.yml"
|
97
|
+
raise StandardError, "Must provide an xcodeproj either via the 'slather [SUBCOMMAND] [PROJECT].xcodeproj' command or through .slather.yml"
|
85
98
|
end
|
86
99
|
end
|
87
100
|
end
|
@@ -101,15 +114,41 @@ Clamp do
|
|
101
114
|
end
|
102
115
|
end
|
103
116
|
|
117
|
+
def setup_verbose_mode
|
118
|
+
project.verbose_mode = verbose?
|
119
|
+
end
|
120
|
+
|
121
|
+
def setup_input_format
|
122
|
+
project.input_format = input_format
|
123
|
+
end
|
124
|
+
|
125
|
+
def setup_scheme
|
126
|
+
project.scheme = scheme
|
127
|
+
end
|
128
|
+
|
129
|
+
def setup_binary_file
|
130
|
+
project.binary_file = binary_file
|
131
|
+
end
|
132
|
+
|
133
|
+
def setup_binary_basename
|
134
|
+
project.binary_basename = binary_basename
|
135
|
+
end
|
136
|
+
|
104
137
|
end
|
105
138
|
|
106
|
-
subcommand "setup", "Configures
|
139
|
+
subcommand "setup", "Configures a .xcodeproj for test coverage generation" do
|
140
|
+
|
141
|
+
parameter "[PROJECT]", "Path to the .xcodeproj", :attribute_name => :xcodeproj_path
|
107
142
|
|
108
|
-
|
143
|
+
option ["--format"], "FORMAT", "Type of coverage to use (gcov, clang, auto)"
|
109
144
|
|
110
145
|
def execute
|
111
|
-
|
112
|
-
|
146
|
+
xcodeproj_path_to_open = xcodeproj_path || Slather::Project.yml["xcodeproj"]
|
147
|
+
unless xcodeproj_path_to_open
|
148
|
+
raise StandardError, "Must provide a .xcodeproj either via the 'slather [SUBCOMMAND] [PROJECT].xcodeproj' command or through .slather.yml"
|
149
|
+
end
|
150
|
+
project = Slather::Project.open(xcodeproj_path_to_open)
|
151
|
+
project.setup_for_coverage(format ? format.to_sym : :auto)
|
113
152
|
project.save
|
114
153
|
end
|
115
154
|
|
@@ -1,6 +1,12 @@
|
|
1
|
+
require 'slather/coverage_info'
|
2
|
+
require 'slather/coveralls_coverage'
|
3
|
+
|
1
4
|
module Slather
|
2
5
|
class CoverageFile
|
3
6
|
|
7
|
+
include CoverageInfo
|
8
|
+
include CoverallsCoverage
|
9
|
+
|
4
10
|
attr_accessor :project, :gcno_file_pathname
|
5
11
|
|
6
12
|
def initialize(project, gcno_file_pathname)
|
@@ -11,7 +17,6 @@ module Slather
|
|
11
17
|
def source_file_pathname
|
12
18
|
@source_file_pathname ||= begin
|
13
19
|
base_filename = gcno_file_pathname.basename.sub_ext("")
|
14
|
-
# TODO: Handle Swift
|
15
20
|
path = nil
|
16
21
|
if project.source_directory
|
17
22
|
path = Dir["#{project.source_directory}/**/#{base_filename}.{#{supported_file_extensions.join(",")}}"].first
|
@@ -36,10 +41,6 @@ module Slather
|
|
36
41
|
source_file.read
|
37
42
|
end
|
38
43
|
|
39
|
-
def source_file_pathname_relative_to_repo_root
|
40
|
-
source_file_pathname.realpath.relative_path_from(Pathname("./").realpath)
|
41
|
-
end
|
42
|
-
|
43
44
|
def gcov_data
|
44
45
|
@gcov_data ||= begin
|
45
46
|
gcov_output = `gcov "#{source_file_pathname}" --object-directory "#{gcno_file_pathname.parent}" --branch-probabilities --branch-counts`
|
@@ -58,6 +59,24 @@ module Slather
|
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
62
|
+
def all_lines
|
63
|
+
unless cleaned_gcov_data.empty?
|
64
|
+
first_line_start = cleaned_gcov_data =~ /^\s+(-|#+|[0-9+]):\s+1:/
|
65
|
+
cleaned_gcov_data[first_line_start..-1].split("\n").map
|
66
|
+
else
|
67
|
+
[]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def cleaned_gcov_data
|
72
|
+
data = gcov_data.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/^function(.*) called [0-9]+ returned [0-9]+% blocks executed(.*)$\r?\n/, '')
|
73
|
+
data.gsub(/^branch(.*)$\r?\n/, '')
|
74
|
+
end
|
75
|
+
|
76
|
+
def raw_data
|
77
|
+
self.gcov_data
|
78
|
+
end
|
79
|
+
|
61
80
|
def line_coverage_data
|
62
81
|
unless cleaned_gcov_data.empty?
|
63
82
|
first_line_start = cleaned_gcov_data =~ /^\s+(-|#+|[0-9+]):\s+1:/
|
@@ -70,9 +89,8 @@ module Slather
|
|
70
89
|
end
|
71
90
|
end
|
72
91
|
|
73
|
-
def
|
74
|
-
|
75
|
-
data.gsub(/^branch(.*)$\r?\n/, '')
|
92
|
+
def line_number_in_line(line)
|
93
|
+
line.split(':')[1].strip.to_i
|
76
94
|
end
|
77
95
|
|
78
96
|
def coverage_for_line(line)
|
@@ -89,102 +107,31 @@ module Slather
|
|
89
107
|
end
|
90
108
|
end
|
91
109
|
|
92
|
-
def num_lines_tested
|
93
|
-
line_coverage_data.compact.select { |cd| cd > 0 }.count
|
94
|
-
end
|
95
|
-
|
96
|
-
def num_lines_testable
|
97
|
-
line_coverage_data.compact.count
|
98
|
-
end
|
99
|
-
|
100
|
-
def rate_lines_tested
|
101
|
-
if num_lines_testable > 0
|
102
|
-
(num_lines_tested / num_lines_testable.to_f)
|
103
|
-
else
|
104
|
-
0
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def percentage_lines_tested
|
109
|
-
if num_lines_testable == 0
|
110
|
-
100
|
111
|
-
else
|
112
|
-
rate_lines_tested * 100
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
110
|
def branch_coverage_data
|
117
111
|
@branch_coverage_data ||= begin
|
118
112
|
branch_coverage_data = Hash.new
|
119
113
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
end
|
114
|
+
gcov_data.scan(/(^(\s+(-|#+|[0-9]+):\s+[1-9]+:(.*)$\r?\n)(^branch\s+[0-9]+\s+[a-zA-Z0-9]+\s+[a-zA-Z0-9]+$\r?\n)+)+/) do |data|
|
115
|
+
lines = data[0].split("\n")
|
116
|
+
line_number = lines[0].split(':')[1].strip.to_i
|
117
|
+
branch_coverage_data[line_number] = lines[1..-1].map do |line|
|
118
|
+
if line.split(' ')[2].strip == "never"
|
119
|
+
0
|
120
|
+
else
|
121
|
+
line.split(' ')[3].strip.to_i
|
129
122
|
end
|
130
123
|
end
|
124
|
+
end
|
131
125
|
branch_coverage_data
|
132
126
|
end
|
133
127
|
end
|
134
128
|
|
135
|
-
def branch_coverage_data_for_statement_on_line(line_number)
|
136
|
-
branch_coverage_data[line_number] || []
|
137
|
-
end
|
138
|
-
|
139
|
-
def num_branches_for_statement_on_line(line_number)
|
140
|
-
branch_coverage_data_for_statement_on_line(line_number).length
|
141
|
-
end
|
142
|
-
|
143
|
-
def num_branch_hits_for_statement_on_line(line_number)
|
144
|
-
branch_coverage_data_for_statement_on_line(line_number).count { |hit_count| hit_count > 0 }
|
145
|
-
end
|
146
|
-
|
147
|
-
def rate_branch_coverage_for_statement_on_line(line_number)
|
148
|
-
branch_data = branch_coverage_data_for_statement_on_line(line_number)
|
149
|
-
if branch_data.empty?
|
150
|
-
0.0
|
151
|
-
else
|
152
|
-
(num_branch_hits_for_statement_on_line(line_number) / branch_data.length.to_f)
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def percentage_branch_coverage_for_statement_on_line(line_number)
|
157
|
-
rate_branch_coverage_for_statement_on_line(line_number) * 100
|
158
|
-
end
|
159
|
-
|
160
|
-
def num_branches_testable
|
161
|
-
branch_coverage_data.keys.reduce(0) do |sum, line_number|
|
162
|
-
sum += num_branches_for_statement_on_line(line_number)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def num_branches_tested
|
167
|
-
branch_coverage_data.keys.reduce(0) do |sum, line_number|
|
168
|
-
sum += num_branch_hits_for_statement_on_line(line_number)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
def rate_branches_tested
|
173
|
-
if (num_branches_testable > 0)
|
174
|
-
(num_branches_tested / num_branches_testable.to_f)
|
175
|
-
else
|
176
|
-
0.0
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
129
|
def source_file_basename
|
181
130
|
File.basename(source_file_pathname, '.m')
|
182
131
|
end
|
183
132
|
|
184
|
-
def
|
185
|
-
|
186
|
-
File.fnmatch(ignore, source_file_pathname_relative_to_repo_root)
|
187
|
-
end
|
133
|
+
def line_number_separator
|
134
|
+
":"
|
188
135
|
end
|
189
136
|
|
190
137
|
def supported_file_extensions
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Slather
|
2
|
+
module CoverageInfo
|
3
|
+
|
4
|
+
def num_lines_tested
|
5
|
+
line_coverage_data.compact.select { |cd| cd > 0 }.count
|
6
|
+
end
|
7
|
+
|
8
|
+
def num_lines_testable
|
9
|
+
line_coverage_data.compact.count
|
10
|
+
end
|
11
|
+
|
12
|
+
def rate_lines_tested
|
13
|
+
if num_lines_testable > 0
|
14
|
+
(num_lines_tested / num_lines_testable.to_f)
|
15
|
+
else
|
16
|
+
0
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def percentage_lines_tested
|
21
|
+
if num_lines_testable == 0
|
22
|
+
100
|
23
|
+
else
|
24
|
+
rate_lines_tested * 100
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def branch_coverage_data_for_statement_on_line(line_number)
|
29
|
+
branch_coverage_data[line_number] || []
|
30
|
+
end
|
31
|
+
|
32
|
+
def num_branches_for_statement_on_line(line_number)
|
33
|
+
branch_coverage_data_for_statement_on_line(line_number).length
|
34
|
+
end
|
35
|
+
|
36
|
+
def num_branch_hits_for_statement_on_line(line_number)
|
37
|
+
branch_coverage_data_for_statement_on_line(line_number).count { |hit_count| hit_count > 0 }
|
38
|
+
end
|
39
|
+
|
40
|
+
def rate_branch_coverage_for_statement_on_line(line_number)
|
41
|
+
branch_data = branch_coverage_data_for_statement_on_line(line_number)
|
42
|
+
if branch_data.empty?
|
43
|
+
0.0
|
44
|
+
else
|
45
|
+
(num_branch_hits_for_statement_on_line(line_number) / branch_data.length.to_f)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def percentage_branch_coverage_for_statement_on_line(line_number)
|
50
|
+
rate_branch_coverage_for_statement_on_line(line_number) * 100
|
51
|
+
end
|
52
|
+
|
53
|
+
def num_branches_testable
|
54
|
+
branch_coverage_data.keys.reduce(0) do |sum, line_number|
|
55
|
+
sum += num_branches_for_statement_on_line(line_number)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def num_branches_tested
|
60
|
+
branch_coverage_data.keys.reduce(0) do |sum, line_number|
|
61
|
+
sum += num_branch_hits_for_statement_on_line(line_number)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def rate_branches_tested
|
66
|
+
if (num_branches_testable > 0)
|
67
|
+
(num_branches_tested / num_branches_testable.to_f)
|
68
|
+
else
|
69
|
+
0.0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def source_file_pathname_relative_to_repo_root
|
74
|
+
source_file_pathname.realpath.relative_path_from(Pathname("./").realpath)
|
75
|
+
end
|
76
|
+
|
77
|
+
def ignored?
|
78
|
+
project.ignore_list.any? do |ignore|
|
79
|
+
File.fnmatch(ignore, source_file_pathname_relative_to_repo_root)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -5,7 +5,11 @@ module Slather
|
|
5
5
|
module CoberturaXmlOutput
|
6
6
|
|
7
7
|
def coverage_file_class
|
8
|
-
|
8
|
+
if input_format == "profdata"
|
9
|
+
Slather::ProfdataCoverageFile
|
10
|
+
else
|
11
|
+
Slather::CoverageFile
|
12
|
+
end
|
9
13
|
end
|
10
14
|
private :coverage_file_class
|
11
15
|
|
@@ -23,9 +27,10 @@ module Slather
|
|
23
27
|
File.write(output_file, report.to_s)
|
24
28
|
end
|
25
29
|
|
26
|
-
def grouped_coverage_files
|
30
|
+
def grouped_coverage_files(coverage_files)
|
27
31
|
groups = Hash.new
|
28
32
|
coverage_files.each do |coverage_file|
|
33
|
+
next if coverage_file == nil
|
29
34
|
path = File.dirname(coverage_file.source_file_pathname_relative_to_repo_root)
|
30
35
|
if groups[path] == nil
|
31
36
|
groups[path] = Array.new
|
@@ -50,7 +55,7 @@ module Slather
|
|
50
55
|
packages_node = @doc.at_css "packages"
|
51
56
|
|
52
57
|
# group files by path
|
53
|
-
|
58
|
+
grouped_coverage_files(coverage_files).each do |path , package_coverage_files|
|
54
59
|
package_node = Nokogiri::XML::Node.new "package", @doc
|
55
60
|
package_node.parent = packages_node
|
56
61
|
classes_node = Nokogiri::XML::Node.new "classes", @doc
|
@@ -127,8 +132,7 @@ module Slather
|
|
127
132
|
lines_node = Nokogiri::XML::Node.new "lines", @doc
|
128
133
|
lines_node.parent = class_node
|
129
134
|
|
130
|
-
coverage_file.
|
131
|
-
line_segments = line.split(':')
|
135
|
+
coverage_file.all_lines.each do |line|
|
132
136
|
if coverage_file.coverage_for_line(line)
|
133
137
|
line_node = create_line_node(line, coverage_file)
|
134
138
|
line_node.parent = lines_node
|
@@ -138,7 +142,7 @@ module Slather
|
|
138
142
|
end
|
139
143
|
|
140
144
|
def create_line_node(line, coverage_file)
|
141
|
-
line_number =
|
145
|
+
line_number = coverage_file.line_number_in_line(line)
|
142
146
|
line_node = Nokogiri::XML::Node.new "line", @doc
|
143
147
|
line_node['number'] = line_number
|
144
148
|
line_node['branch'] = "false"
|
@@ -3,7 +3,11 @@ module Slather
|
|
3
3
|
module GutterJsonOutput
|
4
4
|
|
5
5
|
def coverage_file_class
|
6
|
-
|
6
|
+
if input_format == "profdata"
|
7
|
+
Slather::ProfdataCoverageFile
|
8
|
+
else
|
9
|
+
Slather::CoverageFile
|
10
|
+
end
|
7
11
|
end
|
8
12
|
private :coverage_file_class
|
9
13
|
|
@@ -12,24 +16,24 @@ module Slather
|
|
12
16
|
symbols = {}
|
13
17
|
|
14
18
|
coverage_files.each do |coverage_file|
|
15
|
-
next unless coverage_file.
|
19
|
+
next unless coverage_file.raw_data
|
16
20
|
|
17
21
|
filename = coverage_file.source_file_pathname.to_s
|
18
22
|
filename = filename.sub(Pathname.pwd.to_s, '').reverse.chomp("/").reverse
|
19
23
|
|
20
|
-
coverage_file.
|
21
|
-
data = line.split(':')
|
24
|
+
coverage_file.all_lines.each do |line|
|
22
25
|
|
23
|
-
line_number =
|
26
|
+
line_number = coverage_file.line_number_in_line(line)
|
24
27
|
next unless line_number > 0
|
25
28
|
|
26
|
-
coverage =
|
29
|
+
coverage = coverage_file.coverage_for_line(line)
|
30
|
+
short_text = coverage != nil ? coverage.to_s : "-"
|
27
31
|
|
28
32
|
symbol = { 'line' => line_number,
|
29
33
|
'long_text' => '',
|
30
|
-
'short_text' =>
|
34
|
+
'short_text' => short_text }
|
31
35
|
|
32
|
-
if coverage !=
|
36
|
+
if coverage != nil
|
33
37
|
symbol['background_color'] = coverage.to_i > 0 ? '0x35CC4B' : '0xFC635E'
|
34
38
|
end
|
35
39
|
|