slather 2.4.6 → 2.6.0
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 +5 -1
- data/.travis.yml +2 -2
- data/CHANGELOG.md +49 -0
- data/README.md +35 -1
- data/lib/slather.rb +1 -0
- data/lib/slather/command/coverage_command.rb +6 -0
- data/lib/slather/coverage_file.rb +14 -9
- data/lib/slather/coverage_service/coveralls.rb +57 -0
- data/lib/slather/coverage_service/sonarqube_xml_output.rb +61 -0
- data/lib/slather/profdata_coverage_file.rb +24 -10
- data/lib/slather/project.rb +78 -40
- data/lib/slather/version.rb +1 -1
- data/slather.gemspec +14 -14
- data/spec/fixtures/sonarqube-generic-coverage.xml +93 -0
- data/spec/slather/cocoapods_plugin_spec.rb +1 -1
- data/spec/slather/coverage_service/coveralls_spec.rb +20 -0
- data/spec/slather/coverage_service/sonarqube_xml_spec.rb +46 -0
- data/spec/slather/profdata_coverage_spec.rb +21 -0
- data/spec/slather/project_spec.rb +78 -8
- data/spec/spec_helper.rb +1 -0
- metadata +48 -38
data/lib/slather/project.rb
CHANGED
@@ -118,32 +118,66 @@ module Slather
|
|
118
118
|
|
119
119
|
def profdata_coverage_files
|
120
120
|
coverage_files = []
|
121
|
-
line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
|
122
121
|
|
123
122
|
if self.binary_file
|
124
123
|
self.binary_file.each do |binary_path|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
Pathname(file["filename"]).realpath
|
130
|
-
end)
|
131
|
-
end
|
124
|
+
pathnames_per_binary = pathnames_per_binary(binary_path)
|
125
|
+
coverage_files.concat(create_coverage_files_for_binary(binary_path, pathnames_per_binary))
|
126
|
+
end
|
127
|
+
end
|
132
128
|
|
133
|
-
|
129
|
+
coverage_files
|
130
|
+
end
|
131
|
+
private :profdata_coverage_files
|
134
132
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
133
|
+
def pathnames_per_binary(binary_path)
|
134
|
+
coverage_json_string = llvm_cov_export_output(binary_path)
|
135
|
+
coverage_json = JSON.parse(coverage_json_string)
|
136
|
+
coverage_json["data"].reduce([]) do |result, chunk|
|
137
|
+
result.concat(chunk["files"].map do |file|
|
138
|
+
Pathname(file["filename"]).realpath
|
139
|
+
end)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
private :pathnames_per_binary
|
143
|
+
|
144
|
+
def create_coverage_files_for_binary(binary_path, pathnames_per_binary)
|
145
|
+
coverage_files = []
|
146
|
+
|
147
|
+
begin
|
148
|
+
coverage_files.concat(create_coverage_files(binary_path, pathnames_per_binary))
|
149
|
+
rescue Errno::E2BIG => e
|
150
|
+
# pathnames_per_binary is too big for the OS to handle so it's split in two halfs which are processed independently
|
151
|
+
if pathnames_per_binary.count > 1
|
152
|
+
left, right = pathnames_per_binary.each_slice( (pathnames_per_binary.size/2.0).round ).to_a
|
153
|
+
coverage_files.concat(create_coverage_files_for_binary(binary_path, left))
|
154
|
+
coverage_files.concat(create_coverage_files_for_binary(binary_path, right))
|
155
|
+
else
|
156
|
+
# pathnames_per_binary contains one element which is too big for the OS to handle.
|
157
|
+
raise e, "#{e}. A path in your project is close to the E2BIG limit. https://github.com/SlatherOrg/slather/pull/414", e.backtrace
|
141
158
|
end
|
142
159
|
end
|
143
160
|
|
144
161
|
coverage_files
|
145
162
|
end
|
146
|
-
private :
|
163
|
+
private :create_coverage_files_for_binary
|
164
|
+
|
165
|
+
def create_coverage_files(binary_path, pathnames)
|
166
|
+
line_numbers_first = Gem::Version.new(self.llvm_version) >= Gem::Version.new('8.1.0')
|
167
|
+
files = create_profdata(binary_path, pathnames)
|
168
|
+
files.map do |source|
|
169
|
+
coverage_file = coverage_file_class.new(self, source, line_numbers_first)
|
170
|
+
# If a single source file is used, the resulting output does not contain the file name.
|
171
|
+
coverage_file.source_file_pathname = pathnames.first if pathnames.count == 1
|
172
|
+
!coverage_file.ignored? ? coverage_file : nil
|
173
|
+
end.compact
|
174
|
+
end
|
175
|
+
private :create_coverage_files
|
176
|
+
|
177
|
+
def create_profdata(binary_path, pathnames)
|
178
|
+
profdata_llvm_cov_output(binary_path, pathnames).split("\n\n")
|
179
|
+
end
|
180
|
+
private :create_profdata
|
147
181
|
|
148
182
|
def remove_extension(path)
|
149
183
|
path.split(".")[0..-2].join(".")
|
@@ -157,36 +191,38 @@ module Slather
|
|
157
191
|
end
|
158
192
|
|
159
193
|
def profdata_coverage_dir
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
194
|
+
@profdata_coverage_dir ||= begin
|
195
|
+
raise StandardError, "The specified build directory (#{self.build_directory}) does not exist" unless File.exists?(self.build_directory)
|
196
|
+
dir = nil
|
197
|
+
if self.scheme
|
198
|
+
dir = Dir[File.join(build_directory,"/**/CodeCoverage/#{self.scheme}")].first
|
199
|
+
else
|
200
|
+
dir = Dir[File.join(build_directory,"/**/#{first_product_name}")].first
|
201
|
+
end
|
167
202
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
203
|
+
if dir == nil
|
204
|
+
# Xcode 7.3 moved the location of Coverage.profdata
|
205
|
+
dir = Dir[File.join(build_directory,"/**/CodeCoverage")].first
|
206
|
+
end
|
172
207
|
|
173
|
-
|
174
|
-
|
175
|
-
|
208
|
+
if dir == nil && Slather.xcode_version[0] >= 9
|
209
|
+
# Xcode 9 moved the location of Coverage.profdata
|
210
|
+
coverage_files = Dir[File.join(build_directory, "/**/ProfileData/*/Coverage.profdata")]
|
176
211
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
212
|
+
if coverage_files.count == 0
|
213
|
+
# Look up one directory
|
214
|
+
# The ProfileData directory is next to Intermediates.noindex (in previous versions of Xcode the coverage was inside Intermediates)
|
215
|
+
coverage_files = Dir[File.join(build_directory, "../**/ProfileData/*/Coverage.profdata")]
|
216
|
+
end
|
182
217
|
|
183
|
-
|
184
|
-
|
218
|
+
if coverage_files != nil && coverage_files.count != 0
|
219
|
+
dir = Pathname.new(coverage_files.first).parent()
|
220
|
+
end
|
185
221
|
end
|
186
|
-
end
|
187
222
|
|
188
|
-
|
189
|
-
|
223
|
+
raise StandardError, "No coverage directory found." unless dir != nil
|
224
|
+
dir
|
225
|
+
end
|
190
226
|
end
|
191
227
|
|
192
228
|
def profdata_file
|
@@ -388,6 +424,8 @@ module Slather
|
|
388
424
|
extend(Slather::CoverageService::HtmlOutput)
|
389
425
|
when :json
|
390
426
|
extend(Slather::CoverageService::JsonOutput)
|
427
|
+
when :sonarqube_xml
|
428
|
+
extend(Slather::CoverageService::SonarqubeXmlOutput)
|
391
429
|
else
|
392
430
|
raise ArgumentError, "`#{coverage_service}` is not a valid coverage service. Try `terminal`, `coveralls`, `gutter_json`, `cobertura_xml` or `html`"
|
393
431
|
end
|
data/lib/slather/version.rb
CHANGED
data/slather.gemspec
CHANGED
@@ -17,20 +17,20 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ['lib']
|
19
19
|
|
20
|
-
spec.add_development_dependency 'bundler', '~>
|
21
|
-
spec.add_development_dependency 'coveralls'
|
22
|
-
spec.add_development_dependency 'simplecov'
|
23
|
-
spec.add_development_dependency 'rake', '~>
|
24
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
25
|
-
spec.add_development_dependency 'pry', '~> 0.
|
26
|
-
spec.add_development_dependency 'cocoapods', '~> 1.
|
27
|
-
spec.add_development_dependency 'json_spec', '~> 1.1
|
28
|
-
spec.add_development_dependency 'equivalent-xml', '~> 0.
|
20
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
21
|
+
spec.add_development_dependency 'coveralls', '~> 0.8'
|
22
|
+
spec.add_development_dependency 'simplecov', '~> 0'
|
23
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.8'
|
25
|
+
spec.add_development_dependency 'pry', '~> 0.12'
|
26
|
+
spec.add_development_dependency 'cocoapods', '~> 1.10.beta.1'
|
27
|
+
spec.add_development_dependency 'json_spec', '~> 1.1'
|
28
|
+
spec.add_development_dependency 'equivalent-xml', '~> 0.6'
|
29
29
|
|
30
|
-
spec.add_dependency 'clamp', '~>
|
31
|
-
spec.add_dependency 'xcodeproj', '~> 1.
|
32
|
-
spec.add_dependency 'nokogiri', '~> 1.8
|
33
|
-
spec.add_dependency 'CFPropertyList', '
|
30
|
+
spec.add_dependency 'clamp', '~> 1.3'
|
31
|
+
spec.add_dependency 'xcodeproj', '~> 1.7'
|
32
|
+
spec.add_dependency 'nokogiri', '~> 1.8'
|
33
|
+
spec.add_dependency 'CFPropertyList', '>= 2.2', '< 4'
|
34
34
|
|
35
|
-
spec.add_runtime_dependency 'activesupport'
|
35
|
+
spec.add_runtime_dependency 'activesupport'
|
36
36
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<coverage version="1">
|
3
|
+
<file path="spec/fixtures/fixtures/fixtures.m">
|
4
|
+
<lineToCover lineNumber="14" covered="true"/>
|
5
|
+
<lineToCover lineNumber="15" covered="true"/>
|
6
|
+
<lineToCover lineNumber="16" covered="true"/>
|
7
|
+
<lineToCover lineNumber="19" covered="false"/>
|
8
|
+
<lineToCover lineNumber="20" covered="false"/>
|
9
|
+
<lineToCover lineNumber="21" covered="false"/>
|
10
|
+
</file>
|
11
|
+
<file path="spec/fixtures/fixtures/more_files/Branches.m">
|
12
|
+
<lineToCover lineNumber="14" covered="true"/>
|
13
|
+
<lineToCover lineNumber="15" covered="true"/>
|
14
|
+
<lineToCover lineNumber="16" covered="true"/>
|
15
|
+
<lineToCover lineNumber="17" covered="true"/>
|
16
|
+
<lineToCover lineNumber="18" covered="true"/>
|
17
|
+
<lineToCover lineNumber="19" covered="false"/>
|
18
|
+
<lineToCover lineNumber="20" covered="false"/>
|
19
|
+
<lineToCover lineNumber="21" covered="true"/>
|
20
|
+
<lineToCover lineNumber="22" covered="true"/>
|
21
|
+
<lineToCover lineNumber="23" covered="true"/>
|
22
|
+
<lineToCover lineNumber="24" covered="true"/>
|
23
|
+
<lineToCover lineNumber="25" covered="true"/>
|
24
|
+
<lineToCover lineNumber="26" covered="true"/>
|
25
|
+
<lineToCover lineNumber="27" covered="true"/>
|
26
|
+
<lineToCover lineNumber="28" covered="true"/>
|
27
|
+
<lineToCover lineNumber="29" covered="false"/>
|
28
|
+
<lineToCover lineNumber="30" covered="false"/>
|
29
|
+
<lineToCover lineNumber="31" covered="false"/>
|
30
|
+
<lineToCover lineNumber="32" covered="false"/>
|
31
|
+
<lineToCover lineNumber="33" covered="false"/>
|
32
|
+
<lineToCover lineNumber="34" covered="false"/>
|
33
|
+
<lineToCover lineNumber="35" covered="false"/>
|
34
|
+
<lineToCover lineNumber="36" covered="false"/>
|
35
|
+
<lineToCover lineNumber="37" covered="false"/>
|
36
|
+
<lineToCover lineNumber="38" covered="false"/>
|
37
|
+
<lineToCover lineNumber="39" covered="false"/>
|
38
|
+
<lineToCover lineNumber="40" covered="false"/>
|
39
|
+
<lineToCover lineNumber="41" covered="false"/>
|
40
|
+
<lineToCover lineNumber="42" covered="false"/>
|
41
|
+
<lineToCover lineNumber="43" covered="false"/>
|
42
|
+
</file>
|
43
|
+
<file path="spec/fixtures/fixturesTests/BranchesTests.m">
|
44
|
+
<lineToCover lineNumber="18" covered="true"/>
|
45
|
+
<lineToCover lineNumber="19" covered="true"/>
|
46
|
+
<lineToCover lineNumber="20" covered="true"/>
|
47
|
+
<lineToCover lineNumber="21" covered="true"/>
|
48
|
+
<lineToCover lineNumber="23" covered="true"/>
|
49
|
+
<lineToCover lineNumber="24" covered="true"/>
|
50
|
+
<lineToCover lineNumber="25" covered="true"/>
|
51
|
+
<lineToCover lineNumber="26" covered="true"/>
|
52
|
+
<lineToCover lineNumber="28" covered="true"/>
|
53
|
+
<lineToCover lineNumber="29" covered="true"/>
|
54
|
+
<lineToCover lineNumber="30" covered="true"/>
|
55
|
+
<lineToCover lineNumber="31" covered="true"/>
|
56
|
+
<lineToCover lineNumber="33" covered="true"/>
|
57
|
+
<lineToCover lineNumber="34" covered="true"/>
|
58
|
+
<lineToCover lineNumber="35" covered="true"/>
|
59
|
+
<lineToCover lineNumber="36" covered="true"/>
|
60
|
+
</file>
|
61
|
+
<file path="spec/fixtures/fixturesTests/fixturesTests.m">
|
62
|
+
<lineToCover lineNumber="20" covered="true"/>
|
63
|
+
<lineToCover lineNumber="21" covered="true"/>
|
64
|
+
<lineToCover lineNumber="22" covered="true"/>
|
65
|
+
<lineToCover lineNumber="23" covered="true"/>
|
66
|
+
<lineToCover lineNumber="26" covered="true"/>
|
67
|
+
<lineToCover lineNumber="27" covered="true"/>
|
68
|
+
<lineToCover lineNumber="28" covered="true"/>
|
69
|
+
<lineToCover lineNumber="29" covered="true"/>
|
70
|
+
<lineToCover lineNumber="32" covered="true"/>
|
71
|
+
<lineToCover lineNumber="33" covered="true"/>
|
72
|
+
<lineToCover lineNumber="34" covered="true"/>
|
73
|
+
<lineToCover lineNumber="35" covered="true"/>
|
74
|
+
<lineToCover lineNumber="38" covered="true"/>
|
75
|
+
<lineToCover lineNumber="39" covered="true"/>
|
76
|
+
<lineToCover lineNumber="40" covered="true"/>
|
77
|
+
<lineToCover lineNumber="41" covered="true"/>
|
78
|
+
<lineToCover lineNumber="42" covered="true"/>
|
79
|
+
</file>
|
80
|
+
<file path="spec/fixtures/fixturesTests/peekaviewTests💣.m">
|
81
|
+
<lineToCover lineNumber="18" covered="true"/>
|
82
|
+
<lineToCover lineNumber="19" covered="true"/>
|
83
|
+
<lineToCover lineNumber="20" covered="true"/>
|
84
|
+
<lineToCover lineNumber="21" covered="true"/>
|
85
|
+
<lineToCover lineNumber="24" covered="true"/>
|
86
|
+
<lineToCover lineNumber="25" covered="true"/>
|
87
|
+
<lineToCover lineNumber="26" covered="true"/>
|
88
|
+
<lineToCover lineNumber="27" covered="true"/>
|
89
|
+
<lineToCover lineNumber="30" covered="true"/>
|
90
|
+
<lineToCover lineNumber="31" covered="true"/>
|
91
|
+
<lineToCover lineNumber="32" covered="true"/>
|
92
|
+
</file>
|
93
|
+
</coverage>
|
@@ -13,7 +13,7 @@ describe Slather do
|
|
13
13
|
# Execute the post_install hook via CocoaPods
|
14
14
|
sandbox_root = 'Pods'
|
15
15
|
sandbox = Pod::Sandbox.new(sandbox_root)
|
16
|
-
context = Pod::Installer::PostInstallHooksContext.generate(sandbox, [])
|
16
|
+
context = Pod::Installer::PostInstallHooksContext.generate(sandbox, mock_project, [])
|
17
17
|
Pod::HooksManager.run(:post_install, context, {'slather' => nil})
|
18
18
|
end
|
19
19
|
end
|
@@ -151,6 +151,26 @@ describe Slather::CoverageService::Coveralls do
|
|
151
151
|
ENV['GIT_BRANCH'] = git_branch
|
152
152
|
end
|
153
153
|
end
|
154
|
+
|
155
|
+
context "coverage_service is :github" do
|
156
|
+
before(:each) { fixtures_project.ci_service = :github }
|
157
|
+
|
158
|
+
it "should return valid json for coveralls coverage data" do
|
159
|
+
allow(fixtures_project).to receive(:github_job_id).and_return("9182")
|
160
|
+
allow(fixtures_project).to receive(:coverage_access_token).and_return("abc123")
|
161
|
+
allow(fixtures_project).to receive(:github_pull_request).and_return("1")
|
162
|
+
allow(fixtures_project).to receive(:github_build_url).and_return("https://github.com/Bruce/Wayne/actions/runs/1")
|
163
|
+
allow(fixtures_project).to receive(:github_git_info).and_return({ :head => { :id => "ababa123", :author_name => "bwayne", :message => "hello" }, :branch => "master" })
|
164
|
+
expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql("{\"service_job_id\":\"9182\",\"service_name\":\"github\",\"repo_name\":\"\",\"repo_token\":\"abc123\",\"service_pull_request\":\"1\",\"service_build_url\":\"https://github.com/Bruce/Wayne/actions/runs/1\",\"git\":{\"head\":{\"id\":\"ababa123\",\"author_name\":\"bwayne\",\"message\":\"hello\"},\"branch\":\"master\"}}").excluding("source_files")
|
165
|
+
expect(fixtures_project.send(:coveralls_coverage_data)).to be_json_eql(fixtures_project.coverage_files.map(&:as_json).to_json).at_path("source_files")
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should raise an error if there is no GITHUB_RUN_ID" do
|
169
|
+
allow(fixtures_project).to receive(:github_job_id).and_return(nil)
|
170
|
+
expect { fixtures_project.send(:coveralls_coverage_data) }.to raise_error(StandardError)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
154
174
|
end
|
155
175
|
|
156
176
|
describe '#coveralls_coverage_data' do
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper')
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
describe Slather::CoverageService::SonarqubeXmlOutput do
|
5
|
+
|
6
|
+
let(:fixtures_project) do
|
7
|
+
proj = Slather::Project.open(FIXTURES_PROJECT_PATH)
|
8
|
+
proj.build_directory = TEMP_DERIVED_DATA_PATH
|
9
|
+
proj.input_format = "profdata"
|
10
|
+
proj.coverage_service = "sonarqube_xml"
|
11
|
+
proj.configure
|
12
|
+
proj
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#coverage_file_class' do
|
16
|
+
it "should return CoverageFile" do
|
17
|
+
expect(fixtures_project.send(:coverage_file_class)).to eq(Slather::ProfdataCoverageFile)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#post' do
|
22
|
+
it "should create an XML report spanning all coverage files" do
|
23
|
+
fixtures_project.post
|
24
|
+
|
25
|
+
file = File.open(FIXTURES_SONARQUBE_XML_PATH)
|
26
|
+
fixture_xml_doc = Nokogiri::XML(file)
|
27
|
+
file.close
|
28
|
+
|
29
|
+
file = File.open('sonarqube-generic-coverage.xml')
|
30
|
+
current_xml_doc = Nokogiri::XML(file)
|
31
|
+
file.close
|
32
|
+
|
33
|
+
expect(EquivalentXml.equivalent?(current_xml_doc, fixture_xml_doc)).to be_truthy
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should create an XML report in the given output directory" do
|
37
|
+
fixtures_project.output_directory = "./output"
|
38
|
+
fixtures_project.post
|
39
|
+
|
40
|
+
filepath = "#{fixtures_project.output_directory}/sonarqube-generic-coverage.xml"
|
41
|
+
expect(File.exists?(filepath)).to be_truthy
|
42
|
+
|
43
|
+
FileUtils.rm_rf(fixtures_project.output_directory)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -90,6 +90,23 @@ describe Slather::ProfdataCoverageFile do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
describe '#ignore_error_lines' do
|
94
|
+
it 'should ignore lines starting with - when line_numbers_first is true' do
|
95
|
+
expect(profdata_coverage_file.ignore_error_lines(['--------'], true)).to eq([])
|
96
|
+
expect(profdata_coverage_file.ignore_error_lines(['--------', 'not ignored'], true)).to eq(['not ignored'])
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should ignore lines starting with | when line_numbers_first is true' do
|
100
|
+
expect(profdata_coverage_file.ignore_error_lines(['| Unexecuted instantiation'], true)).to eq([])
|
101
|
+
expect(profdata_coverage_file.ignore_error_lines(['| Unexecuted instantiation', 'not ignored'], true)).to eq(['not ignored'])
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should not ignore any lines when line_numbers_first is false' do
|
105
|
+
lines = ['| Unexecuted instantiation', '------']
|
106
|
+
expect(profdata_coverage_file.ignore_error_lines(lines, false)).to eq(lines)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
93
110
|
describe "#coverage_for_line" do
|
94
111
|
it "should return the number of hits for the line" do
|
95
112
|
expect(profdata_coverage_file.coverage_for_line(" 10| 40| func applicationWillTerminate(application: UIApplication) {", false)).to eq(10)
|
@@ -116,6 +133,10 @@ describe Slather::ProfdataCoverageFile do
|
|
116
133
|
expect(profdata_coverage_file.coverage_for_line(" 18| 11.8k| return a + b;", true)).to eq(11800)
|
117
134
|
expect(profdata_coverage_file.coverage_for_line(" 18| 2.58M| return a + b;", true)).to eq(2580000)
|
118
135
|
end
|
136
|
+
|
137
|
+
it 'should ignore errors in profdata' do
|
138
|
+
expect(profdata_coverage_file.coverage_for_line('------------------', true)).to eq(nil)
|
139
|
+
end
|
119
140
|
end
|
120
141
|
|
121
142
|
describe "#num_lines_tested" do
|
@@ -64,15 +64,78 @@ describe Slather::Project do
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
-
describe "#profdata_coverage_files" do
|
67
|
+
describe "#profdata_coverage_files with large file lists" do
|
68
68
|
class SpecXcode7CoverageFile < Slather::ProfdataCoverageFile
|
69
69
|
end
|
70
70
|
|
71
|
+
llvm_cov_export_output = %q(
|
72
|
+
{
|
73
|
+
"data":[
|
74
|
+
{
|
75
|
+
"files":[
|
76
|
+
{
|
77
|
+
"filename":"spec/fixtures/fixtures/Fixtures.swift"
|
78
|
+
}
|
79
|
+
]
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"files":[
|
83
|
+
{
|
84
|
+
"filename":"spec/fixtures/fixtures/Fixtures.swift"
|
85
|
+
}
|
86
|
+
]
|
87
|
+
}
|
88
|
+
]
|
89
|
+
})
|
90
|
+
|
91
|
+
profdata_llvm_cov_output = "#{FIXTURES_SWIFT_FILE_PATH}:
|
92
|
+
| 0|
|
93
|
+
| 1|import UIKit
|
94
|
+
| 2|
|
95
|
+
| 3|@UIApplicationMain
|
96
|
+
| 4|class AppDelegate: UIResponder, UIApplicationDelegate {
|
97
|
+
| 5|
|
98
|
+
| 6| var window: UIWindow?
|
99
|
+
| 7|
|
100
|
+
1| 8| func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
|
101
|
+
1| 9| return true
|
102
|
+
1| 10| }
|
103
|
+
| 11|
|
104
|
+
0| 12| func applicationWillResignActive(application: UIApplication) {
|
105
|
+
0| 13| }
|
106
|
+
0| 14|}"
|
107
|
+
|
71
108
|
before(:each) do
|
72
109
|
allow(Dir).to receive(:[]).and_call_original
|
73
110
|
allow(Dir).to receive(:[]).with("#{fixtures_project.build_directory}/**/Coverage.profdata").and_return(["/some/path/Coverage.profdata"])
|
74
111
|
allow(fixtures_project).to receive(:binary_file).and_return(["Fixtures"])
|
75
|
-
allow(fixtures_project).to receive(:llvm_cov_export_output).and_return(
|
112
|
+
allow(fixtures_project).to receive(:llvm_cov_export_output).and_return(llvm_cov_export_output)
|
113
|
+
allow(fixtures_project).to receive(:coverage_file_class).and_return(SpecXcode7CoverageFile)
|
114
|
+
allow(fixtures_project).to receive(:ignore_list).and_return([])
|
115
|
+
end
|
116
|
+
|
117
|
+
it "Should catch Errno::E2BIG and re-raise if the input is too large to split into multiple chunks" do
|
118
|
+
allow(fixtures_project).to receive(:unsafe_profdata_llvm_cov_output).and_raise(Errno::E2BIG)
|
119
|
+
expect { fixtures_project.send(:profdata_coverage_files) }.to raise_error(Errno::E2BIG, "Argument list too long. A path in your project is close to the E2BIG limit. https://github.com/SlatherOrg/slather/pull/414")
|
120
|
+
end
|
121
|
+
|
122
|
+
it "Should catch Errno::E2BIG and return Coverage.profdata file objects when the work can be split into two" do
|
123
|
+
allow(fixtures_project).to receive(:unsafe_profdata_llvm_cov_output).once {
|
124
|
+
# raise once and then insert the stub
|
125
|
+
allow(fixtures_project).to receive(:profdata_llvm_cov_output).and_return(profdata_llvm_cov_output)
|
126
|
+
raise Errno::E2BIG
|
127
|
+
}
|
128
|
+
profdata_coverage_files = fixtures_project.send(:profdata_coverage_files)
|
129
|
+
profdata_coverage_files.each { |cf| expect(cf.kind_of?(SpecXcode7CoverageFile)).to be_truthy }
|
130
|
+
expect(profdata_coverage_files.map { |cf| cf.source_file_pathname.basename.to_s }).to eq(["Fixtures.swift", "Fixtures.swift"])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#profdata_coverage_files" do
|
135
|
+
class SpecXcode7CoverageFile < Slather::ProfdataCoverageFile
|
136
|
+
end
|
137
|
+
|
138
|
+
llvm_cov_export_output = %q(
|
76
139
|
{
|
77
140
|
"data":[
|
78
141
|
{
|
@@ -83,9 +146,9 @@ describe Slather::Project do
|
|
83
146
|
]
|
84
147
|
}
|
85
148
|
]
|
86
|
-
}
|
87
|
-
|
88
|
-
|
149
|
+
})
|
150
|
+
|
151
|
+
profdata_llvm_cov_output = "#{FIXTURES_SWIFT_FILE_PATH}:
|
89
152
|
| 0|
|
90
153
|
| 1|import UIKit
|
91
154
|
| 2|
|
@@ -100,7 +163,14 @@ describe Slather::Project do
|
|
100
163
|
| 11|
|
101
164
|
0| 12| func applicationWillResignActive(application: UIApplication) {
|
102
165
|
0| 13| }
|
103
|
-
0| 14|}"
|
166
|
+
0| 14|}"
|
167
|
+
|
168
|
+
before(:each) do
|
169
|
+
allow(Dir).to receive(:[]).and_call_original
|
170
|
+
allow(Dir).to receive(:[]).with("#{fixtures_project.build_directory}/**/Coverage.profdata").and_return(["/some/path/Coverage.profdata"])
|
171
|
+
allow(fixtures_project).to receive(:binary_file).and_return(["Fixtures"])
|
172
|
+
allow(fixtures_project).to receive(:llvm_cov_export_output).and_return(llvm_cov_export_output)
|
173
|
+
allow(fixtures_project).to receive(:profdata_llvm_cov_output).and_return(profdata_llvm_cov_output)
|
104
174
|
allow(fixtures_project).to receive(:coverage_file_class).and_return(SpecXcode7CoverageFile)
|
105
175
|
allow(fixtures_project).to receive(:ignore_list).and_return([])
|
106
176
|
end
|
@@ -583,8 +653,8 @@ describe Slather::Project do
|
|
583
653
|
it "should find relevant source files" do
|
584
654
|
source_files = fixtures_project.find_source_files
|
585
655
|
expect(source_files.count).to eq(2)
|
586
|
-
expect(source_files.first.to_s).to include("
|
587
|
-
expect(source_files.last.to_s).to include("
|
656
|
+
expect(source_files.first.to_s).to include("fixturesTwo.m")
|
657
|
+
expect(source_files.last.to_s).to include("fixtures.m")
|
588
658
|
end
|
589
659
|
|
590
660
|
it "should print out the coverage for each file, and then total coverage" do
|