slather 1.7.1 → 1.8
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +20 -9
- data/assets/highlight.pack.js +1 -0
- data/assets/list.min.js +1 -0
- data/assets/slather.css +316 -0
- data/bin/slather +9 -1
- data/lib/slather.rb +2 -0
- data/lib/slather/coverage_file.rb +1 -1
- data/lib/slather/coverage_service/coveralls.rb +55 -10
- data/lib/slather/coverage_service/hardcover.rb +61 -0
- data/lib/slather/coverage_service/html_output.rb +244 -0
- data/lib/slather/project.rb +10 -7
- data/lib/slather/version.rb +1 -1
- data/spec/fixtures/fixtures_html/Branches.m.html +261 -0
- data/spec/fixtures/fixtures_html/BranchesTests.m.html +228 -0
- data/spec/fixtures/fixtures_html/Empty.m.html +30 -0
- data/spec/fixtures/fixtures_html/fixtures.m.html +151 -0
- data/spec/fixtures/fixtures_html/fixturesTests.m.html +216 -0
- data/spec/fixtures/fixtures_html/fixtures_cpp.cpp.html +30 -0
- data/spec/fixtures/fixtures_html/fixtures_m.m.html +30 -0
- data/spec/fixtures/fixtures_html/fixtures_mm.mm.html +30 -0
- data/spec/fixtures/fixtures_html/index.html +134 -0
- data/spec/fixtures/fixtures_html/peekaview.m.html +190 -0
- data/spec/fixtures/fixtures_html/peekaviewTests.m.html +206 -0
- data/spec/slather/coverage_service/coveralls_spec.rb +25 -6
- data/spec/slather/coverage_service/hardcover_spec.rb +87 -0
- data/spec/slather/coverage_service/html_output_spec.rb +179 -0
- data/spec/slather/project_spec.rb +13 -6
- data/spec/spec_helper.rb +2 -1
- metadata +33 -2
data/lib/slather.rb
CHANGED
@@ -4,8 +4,10 @@ require 'slather/coverage_file'
|
|
4
4
|
require 'slather/coveralls_coverage_file'
|
5
5
|
require 'slather/coverage_service/cobertura_xml_output'
|
6
6
|
require 'slather/coverage_service/coveralls'
|
7
|
+
require 'slather/coverage_service/hardcover'
|
7
8
|
require 'slather/coverage_service/gutter_json_output'
|
8
9
|
require 'slather/coverage_service/simple_output'
|
10
|
+
require 'slather/coverage_service/html_output'
|
9
11
|
|
10
12
|
module Slather
|
11
13
|
|
@@ -71,7 +71,7 @@ module Slather
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def cleaned_gcov_data
|
74
|
-
data = gcov_data.gsub(/^function(.*) called [0-9]+ returned [0-9]+% blocks executed(.*)$\r?\n/, '')
|
74
|
+
data = gcov_data.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').gsub(/^function(.*) called [0-9]+ returned [0-9]+% blocks executed(.*)$\r?\n/, '')
|
75
75
|
data.gsub(/^branch(.*)$\r?\n/, '')
|
76
76
|
end
|
77
77
|
|
@@ -11,22 +11,54 @@ module Slather
|
|
11
11
|
ENV['TRAVIS_JOB_ID']
|
12
12
|
end
|
13
13
|
private :travis_job_id
|
14
|
-
|
14
|
+
|
15
15
|
def circleci_job_id
|
16
16
|
ENV['CIRCLE_BUILD_NUM']
|
17
17
|
end
|
18
18
|
private :circleci_job_id
|
19
|
-
|
19
|
+
|
20
20
|
def circleci_pull_request
|
21
|
-
ENV['CI_PULL_REQUEST']
|
21
|
+
ENV['CIRCLE_PR_NUMBER'] || ENV['CI_PULL_REQUEST'] || ""
|
22
22
|
end
|
23
23
|
private :circleci_pull_request
|
24
|
-
|
24
|
+
|
25
|
+
def jenkins_job_id
|
26
|
+
ENV['BUILD_ID']
|
27
|
+
end
|
28
|
+
private :jenkins_job_id
|
29
|
+
|
30
|
+
def jenkins_branch_name
|
31
|
+
branch_name = ENV['GIT_BRANCH']
|
32
|
+
if branch_name.include? 'origin/'
|
33
|
+
branch_name[7...branch_name.length]
|
34
|
+
else
|
35
|
+
branch_name
|
36
|
+
end
|
37
|
+
end
|
38
|
+
private :jenkins_branch_name
|
39
|
+
|
40
|
+
def jenkins_git_info
|
41
|
+
{
|
42
|
+
head: {
|
43
|
+
id: ENV['sha1'],
|
44
|
+
author_name: ENV['ghprbActualCommitAuthor'],
|
45
|
+
message: ENV['ghprbPullTitle']
|
46
|
+
},
|
47
|
+
branch: jenkins_branch_name
|
48
|
+
}
|
49
|
+
end
|
50
|
+
private :jenkins_git_info
|
51
|
+
|
52
|
+
def circleci_build_url
|
53
|
+
"https://circleci.com/gh/" + ENV['CIRCLE_PROJECT_USERNAME'] || "" + "/" + ENV['CIRCLE_PROJECT_REPONAME'] || "" + "/" + ENV['CIRCLE_BUILD_NUM'] || ""
|
54
|
+
end
|
55
|
+
private :circleci_build_url
|
56
|
+
|
25
57
|
def circleci_git_info
|
26
58
|
{
|
27
59
|
:head => {
|
28
60
|
:id => (ENV['CIRCLE_SHA1'] || ""),
|
29
|
-
:author_name => (ENV['CIRCLE_USERNAME'] || ""),
|
61
|
+
:author_name => (ENV['CIRCLE_PR_USERNAME'] || ENV['CIRCLE_USERNAME'] || ""),
|
30
62
|
:message => (`git log --format=%s -n 1 HEAD`.chomp || "")
|
31
63
|
},
|
32
64
|
:branch => (ENV['CIRCLE_BRANCH'] || "")
|
@@ -47,7 +79,7 @@ module Slather
|
|
47
79
|
{
|
48
80
|
:service_job_id => travis_job_id,
|
49
81
|
:service_name => "travis-pro",
|
50
|
-
:repo_token =>
|
82
|
+
:repo_token => coverage_access_token,
|
51
83
|
:source_files => coverage_files.map(&:as_json)
|
52
84
|
}.to_json
|
53
85
|
end
|
@@ -59,19 +91,32 @@ module Slather
|
|
59
91
|
coveralls_hash = {
|
60
92
|
:service_job_id => circleci_job_id,
|
61
93
|
:service_name => "circleci",
|
62
|
-
:repo_token =>
|
94
|
+
:repo_token => coverage_access_token,
|
63
95
|
:source_files => coverage_files.map(&:as_json),
|
64
|
-
:git => circleci_git_info
|
96
|
+
:git => circleci_git_info,
|
97
|
+
:service_build_url => circleci_build_url
|
65
98
|
}
|
66
|
-
|
99
|
+
|
67
100
|
if circleci_pull_request != nil && circleci_pull_request.length > 0
|
68
101
|
coveralls_hash[:service_pull_request] = circleci_pull_request.split("/").last
|
69
102
|
end
|
70
|
-
|
103
|
+
|
71
104
|
coveralls_hash.to_json
|
72
105
|
else
|
73
106
|
raise StandardError, "Environment variable `CIRCLE_BUILD_NUM` not set. Is this running on a circleci build?"
|
74
107
|
end
|
108
|
+
elsif ci_service == :jenkins
|
109
|
+
if jenkins_job_id
|
110
|
+
{
|
111
|
+
service_job_id: jenkins_job_id,
|
112
|
+
service_name: "jenkins",
|
113
|
+
repo_token: coverage_access_token,
|
114
|
+
source_files: coverage_files.map(&:as_json),
|
115
|
+
git: jenkins_git_info
|
116
|
+
}.to_json
|
117
|
+
else
|
118
|
+
raise StandardError, "Environment variable `BUILD_ID` not set. Is this running on a jenkins build?"
|
119
|
+
end
|
75
120
|
else
|
76
121
|
raise StandardError, "No support for ci named #{ci_service}"
|
77
122
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Slather
|
2
|
+
module CoverageService
|
3
|
+
module Hardcover
|
4
|
+
|
5
|
+
def coverage_file_class
|
6
|
+
Slather::CoverallsCoverageFile
|
7
|
+
end
|
8
|
+
private :coverage_file_class
|
9
|
+
|
10
|
+
def jenkins_job_id
|
11
|
+
"#{ENV['JOB_NAME']}/#{ENV['BUILD_NUMBER']}"
|
12
|
+
end
|
13
|
+
private :jenkins_job_id
|
14
|
+
|
15
|
+
def hardcover_coverage_data
|
16
|
+
if ci_service == :jenkins_ci
|
17
|
+
if jenkins_job_id
|
18
|
+
{
|
19
|
+
:service_job_id => jenkins_job_id,
|
20
|
+
:service_name => "jenkins-ci",
|
21
|
+
:repo_token => Project.yml["hardcover_repo_token"],
|
22
|
+
:source_files => coverage_files.map(&:as_json)
|
23
|
+
}.to_json
|
24
|
+
else
|
25
|
+
raise StandardError, "Environment variables `BUILD_NUMBER` and `JOB_NAME` are not set. Is this running on a Jenkins build?"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise StandardError, "No support for ci named #{ci_service}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
private :hardcover_coverage_data
|
32
|
+
|
33
|
+
def post
|
34
|
+
f = File.open('hardcover_json_file', 'w+')
|
35
|
+
begin
|
36
|
+
f.write(hardcover_coverage_data)
|
37
|
+
f.close
|
38
|
+
`curl --form json_file=@#{f.path} #{hardcover_api_jobs_path}`
|
39
|
+
rescue StandardError => e
|
40
|
+
FileUtils.rm(f)
|
41
|
+
raise e
|
42
|
+
end
|
43
|
+
FileUtils.rm(f)
|
44
|
+
end
|
45
|
+
|
46
|
+
def hardcover_api_jobs_path
|
47
|
+
"#{hardcover_base_url}/v1/jobs"
|
48
|
+
end
|
49
|
+
private :hardcover_api_jobs_path
|
50
|
+
|
51
|
+
def hardcover_base_url
|
52
|
+
url = Project.yml["hardcover_base_url"]
|
53
|
+
unless url
|
54
|
+
raise "No `hardcover_base_url` configured. Please add it to your `.slather.yml`"
|
55
|
+
end
|
56
|
+
url
|
57
|
+
end
|
58
|
+
private :hardcover_base_url
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Slather
|
4
|
+
module CoverageService
|
5
|
+
module HtmlOutput
|
6
|
+
|
7
|
+
def coverage_file_class
|
8
|
+
Slather::CoverageFile
|
9
|
+
end
|
10
|
+
private :coverage_file_class
|
11
|
+
|
12
|
+
def directory_path
|
13
|
+
is_path_valid = !output_directory.nil? && !output_directory.strip.eql?("")
|
14
|
+
is_path_valid ? File.expand_path(output_directory) : "html"
|
15
|
+
end
|
16
|
+
private :directory_path
|
17
|
+
|
18
|
+
def post
|
19
|
+
create_html_reports(coverage_files)
|
20
|
+
generate_reports(@docs)
|
21
|
+
|
22
|
+
index_html_path = File.join(directory_path, "index.html")
|
23
|
+
if show_html
|
24
|
+
open_coverage index_html_path
|
25
|
+
else
|
26
|
+
print_path_coverage index_html_path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_path_coverage(index_html)
|
31
|
+
path = File.expand_path index_html
|
32
|
+
puts "\nTo open the html reports, use \n\nopen '#{path}'\n\nor use '--show' flag to open it automatically.\n\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def open_coverage(index_html)
|
36
|
+
path = File.expand_path index_html
|
37
|
+
`open '#{path}'` if File.exist?(path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_html_reports(coverage_files)
|
41
|
+
create_index_html(coverage_files)
|
42
|
+
create_htmls_from_files(coverage_files)
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate_reports(reports)
|
46
|
+
FileUtils.rm_rf(directory_path) if Dir.exist?(directory_path)
|
47
|
+
FileUtils.mkdir_p(directory_path)
|
48
|
+
|
49
|
+
reports.each do |name, doc|
|
50
|
+
html_file = File.join(directory_path, "#{name}.html")
|
51
|
+
File.write(html_file, doc.to_html)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_index_html(coverage_files)
|
56
|
+
project_name = File.basename(self.xcodeproj)
|
57
|
+
template = generate_html_template(project_name, true, false)
|
58
|
+
|
59
|
+
total_relevant_lines = 0
|
60
|
+
total_tested_lines = 0
|
61
|
+
coverage_files.each { |coverage_file|
|
62
|
+
total_tested_lines += coverage_file.num_lines_tested
|
63
|
+
total_relevant_lines += coverage_file.num_lines_testable
|
64
|
+
}
|
65
|
+
|
66
|
+
builder = Nokogiri::HTML::Builder.with(template.at('#reports')) { |cov|
|
67
|
+
cov.h2 "Files for \"#{project_name}\""
|
68
|
+
|
69
|
+
cov.h4 {
|
70
|
+
percentage = (total_tested_lines / total_relevant_lines.to_f) * 100.0
|
71
|
+
cov.span "Total Coverage : "
|
72
|
+
cov.span '%.2f%%' % percentage, :class => class_for_coverage_percentage(percentage), :id => "total_coverage"
|
73
|
+
}
|
74
|
+
|
75
|
+
cov.input(:class => "search", :placeholder => "Search")
|
76
|
+
|
77
|
+
cov.table(:class => "coverage_list", :cellspacing => 0, :cellpadding => 0) {
|
78
|
+
|
79
|
+
cov.thead {
|
80
|
+
cov.tr {
|
81
|
+
cov.th "%", :class => "col_num sort", "data-sort" => "data_percentage"
|
82
|
+
cov.th "File", :class => "sort", "data-sort" => "data_filename"
|
83
|
+
cov.th "Lines", :class => "col_percent sort", "data-sort" => "data_lines"
|
84
|
+
cov.th "Relevant", :class => "col_percent sort", "data-sort" => "data_relevant"
|
85
|
+
cov.th "Covered", :class => "col_percent sort", "data-sort" => "data_covered"
|
86
|
+
cov.th "Missed", :class => "col_percent sort", "data-sort" => "data_missed"
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
cov.tbody(:class => "list") {
|
91
|
+
coverage_files.each { |coverage_file|
|
92
|
+
filename = File.basename(coverage_file.source_file_pathname_relative_to_repo_root)
|
93
|
+
filename_link = "#{filename}.html"
|
94
|
+
|
95
|
+
cov.tr {
|
96
|
+
percentage = coverage_file.percentage_lines_tested
|
97
|
+
|
98
|
+
cov.td { cov.span '%.2f' % percentage, :class => "percentage #{class_for_coverage_percentage(percentage)} data_percentage" }
|
99
|
+
cov.td(:class => "data_filename") {
|
100
|
+
cov.a filename, :href => filename_link
|
101
|
+
}
|
102
|
+
cov.td "#{coverage_file.line_coverage_data.count}", :class => "data_lines"
|
103
|
+
cov.td "#{coverage_file.num_lines_testable}", :class => "data_relevant"
|
104
|
+
cov.td "#{coverage_file.num_lines_tested}", :class => "data_covered"
|
105
|
+
cov.td "#{(coverage_file.num_lines_testable - coverage_file.num_lines_tested)}", :class => "data_missed"
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
@docs = Hash.new
|
113
|
+
@docs[:index] = builder.doc
|
114
|
+
end
|
115
|
+
|
116
|
+
def create_htmls_from_files(coverage_files)
|
117
|
+
coverage_files.map { |file| create_html_from_file file }
|
118
|
+
end
|
119
|
+
|
120
|
+
def create_html_from_file(coverage_file)
|
121
|
+
filepath = coverage_file.source_file_pathname_relative_to_repo_root
|
122
|
+
filename = File.basename(filepath)
|
123
|
+
percentage = coverage_file.percentage_lines_tested
|
124
|
+
|
125
|
+
cleaned_gcov_lines = coverage_file.cleaned_gcov_data.split("\n")
|
126
|
+
is_file_empty = (cleaned_gcov_lines.count <= 0)
|
127
|
+
|
128
|
+
template = generate_html_template(filename, false, is_file_empty)
|
129
|
+
|
130
|
+
builder = Nokogiri::HTML::Builder.with(template.at('#reports')) { |cov|
|
131
|
+
cov.h2(:class => "cov_title") {
|
132
|
+
cov.span("Coverage for \"#{filename}\"" + (!is_file_empty ? " : " : ""))
|
133
|
+
cov.span("#{'%.2f' % percentage}%", :class => class_for_coverage_percentage(percentage)) unless is_file_empty
|
134
|
+
}
|
135
|
+
|
136
|
+
cov.h4("(#{coverage_file.num_lines_tested} of #{coverage_file.num_lines_testable} relevant lines covered)", :class => "cov_subtitle")
|
137
|
+
cov.h4(filepath, :class => "cov_filepath")
|
138
|
+
|
139
|
+
if is_file_empty
|
140
|
+
cov.p "¯\\_(ツ)_/¯"
|
141
|
+
next
|
142
|
+
end
|
143
|
+
|
144
|
+
cov.table(:class => "source_code") {
|
145
|
+
cleaned_gcov_lines.each do |line|
|
146
|
+
data = line.split(':', 3)
|
147
|
+
|
148
|
+
line_number = data[1].to_i
|
149
|
+
next unless line_number > 0
|
150
|
+
|
151
|
+
coverage_data = data[0].strip
|
152
|
+
line_data = [line_number, data[2], hits_for_coverage_data(coverage_data)]
|
153
|
+
classes = ["num", "src", "coverage"]
|
154
|
+
|
155
|
+
cov.tr(:class => class_for_coverage_data(coverage_data)) {
|
156
|
+
line_data.each_with_index { |line, idx|
|
157
|
+
if idx != 1
|
158
|
+
cov.td(line, :class => classes[idx])
|
159
|
+
else
|
160
|
+
cov.td(:class => classes[idx]) {
|
161
|
+
cov.pre { cov.code(line, :class => "objc") }
|
162
|
+
}
|
163
|
+
end
|
164
|
+
}
|
165
|
+
}
|
166
|
+
end
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
@docs[filename] = builder.doc
|
171
|
+
end
|
172
|
+
|
173
|
+
def generate_html_template(title, is_index, is_file_empty)
|
174
|
+
logo_path = File.join(gem_root_path, "docs/logo.jpg")
|
175
|
+
css_path = File.join(gem_root_path, "assets/slather.css")
|
176
|
+
highlight_js_path = File.join(gem_root_path, "assets/highlight.pack.js")
|
177
|
+
list_js_path = File.join(gem_root_path, "assets/list.min.js")
|
178
|
+
|
179
|
+
builder = Nokogiri::HTML::Builder.new do |doc|
|
180
|
+
doc.html {
|
181
|
+
doc.head {
|
182
|
+
doc.title "#{title} - Slather"
|
183
|
+
doc.link :href => css_path, :media => "all", :rel => "stylesheet"
|
184
|
+
}
|
185
|
+
doc.body {
|
186
|
+
doc.header {
|
187
|
+
doc.div(:class => "row") {
|
188
|
+
doc.a(:href => "index.html") { doc.img(:src => logo_path, :alt => "Slather logo") }
|
189
|
+
}
|
190
|
+
}
|
191
|
+
doc.div(:class => "row") { doc.div(:id => "reports") }
|
192
|
+
doc.footer {
|
193
|
+
doc.div(:class => "row") {
|
194
|
+
doc.p { doc.a("Fork me on Github", :href => "https://github.com/venmo/slather") }
|
195
|
+
doc.p("© #{Date.today.year} Slather")
|
196
|
+
}
|
197
|
+
}
|
198
|
+
|
199
|
+
if is_index
|
200
|
+
doc.script :src => list_js_path
|
201
|
+
doc.script "var reports = new List('reports', { valueNames: [ 'data_percentage', 'data_filename', 'data_lines', 'data_relevant', 'data_covered', 'data_missed' ]});"
|
202
|
+
else
|
203
|
+
unless is_file_empty
|
204
|
+
doc.script :src => highlight_js_path
|
205
|
+
doc.script "hljs.initHighlightingOnLoad();"
|
206
|
+
end
|
207
|
+
end
|
208
|
+
}
|
209
|
+
}
|
210
|
+
end
|
211
|
+
builder.doc
|
212
|
+
end
|
213
|
+
|
214
|
+
def gem_root_path
|
215
|
+
File.expand_path File.join(File.dirname(__dir__), "../..")
|
216
|
+
end
|
217
|
+
|
218
|
+
def class_for_coverage_data(coverage_data)
|
219
|
+
case coverage_data
|
220
|
+
when /\d/ then "covered"
|
221
|
+
when /#/ then "missed"
|
222
|
+
else "never"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def hits_for_coverage_data(coverage_data)
|
227
|
+
case coverage_data
|
228
|
+
when /\d/ then (coverage_data.to_i > 0) ? "#{coverage_data}x" : ""
|
229
|
+
when /#/ then "!"
|
230
|
+
else ""
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def class_for_coverage_percentage(percentage)
|
235
|
+
case
|
236
|
+
when percentage > 85 then "cov_high"
|
237
|
+
when percentage > 70 then "cov_medium"
|
238
|
+
else "cov_low"
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
data/lib/slather/project.rb
CHANGED
@@ -19,13 +19,14 @@ end
|
|
19
19
|
module Slather
|
20
20
|
class Project < Xcodeproj::Project
|
21
21
|
|
22
|
-
attr_accessor :build_directory, :ignore_list, :ci_service, :coverage_service, :
|
22
|
+
attr_accessor :build_directory, :ignore_list, :ci_service, :coverage_service, :coverage_access_token, :source_directory, :output_directory, :xcodeproj, :show_html
|
23
23
|
|
24
24
|
alias_method :setup_for_coverage, :slather_setup_for_coverage
|
25
25
|
|
26
26
|
def self.open(xcodeproj)
|
27
27
|
proj = super
|
28
28
|
proj.configure_from_yml
|
29
|
+
proj.xcodeproj = xcodeproj
|
29
30
|
proj
|
30
31
|
end
|
31
32
|
|
@@ -70,7 +71,7 @@ module Slather
|
|
70
71
|
configure_build_directory_from_yml
|
71
72
|
configure_ignore_list_from_yml
|
72
73
|
configure_ci_service_from_yml
|
73
|
-
|
74
|
+
configure_coverage_access_token_from_yml
|
74
75
|
configure_coverage_service_from_yml
|
75
76
|
configure_source_directory_from_yml
|
76
77
|
configure_output_directory_from_yml
|
@@ -104,26 +105,28 @@ module Slather
|
|
104
105
|
self.coverage_service ||= (self.class.yml["coverage_service"] || :terminal)
|
105
106
|
end
|
106
107
|
|
107
|
-
def
|
108
|
-
self.
|
108
|
+
def configure_coverage_access_token_from_yml
|
109
|
+
self.coverage_access_token ||= (ENV["COVERAGE_ACCESS_TOKEN"] || self.class.yml["coverage_access_token"] || "")
|
109
110
|
end
|
110
111
|
|
111
112
|
def coverage_service=(service)
|
112
113
|
service = service && service.to_sym
|
113
114
|
if service == :coveralls
|
114
115
|
extend(Slather::CoverageService::Coveralls)
|
116
|
+
elsif service == :hardcover
|
117
|
+
extend(Slather::CoverageService::Hardcover)
|
115
118
|
elsif service == :terminal
|
116
119
|
extend(Slather::CoverageService::SimpleOutput)
|
117
120
|
elsif service == :gutter_json
|
118
121
|
extend(Slather::CoverageService::GutterJsonOutput)
|
119
122
|
elsif service == :cobertura_xml
|
120
123
|
extend(Slather::CoverageService::CoberturaXmlOutput)
|
124
|
+
elsif service == :html
|
125
|
+
extend(Slather::CoverageService::HtmlOutput)
|
121
126
|
else
|
122
|
-
raise ArgumentError, "`#{coverage_service}` is not a valid coverage service. Try `terminal`, `coveralls`, `gutter_json` or `
|
127
|
+
raise ArgumentError, "`#{coverage_service}` is not a valid coverage service. Try `terminal`, `coveralls`, `gutter_json`, `cobertura_xml` or `html`"
|
123
128
|
end
|
124
129
|
@coverage_service = service
|
125
130
|
end
|
126
|
-
|
127
131
|
end
|
128
132
|
end
|
129
|
-
|