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.
@@ -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
- coverage_json_string = llvm_cov_export_output(binary_path)
126
- coverage_json = JSON.parse(coverage_json_string)
127
- pathnames_per_binary = coverage_json["data"].reduce([]) do |result, chunk|
128
- result.concat(chunk["files"].map do |file|
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
- files = profdata_llvm_cov_output(binary_path, pathnames_per_binary).split("\n\n")
129
+ coverage_files
130
+ end
131
+ private :profdata_coverage_files
134
132
 
135
- coverage_files.concat(files.map do |source|
136
- coverage_file = coverage_file_class.new(self, source, line_numbers_first)
137
- # If a single source file is used, the resulting output does not contain the file name.
138
- coverage_file.source_file_pathname = pathnames_per_binary.first if pathnames_per_binary.count == 1
139
- !coverage_file.ignored? ? coverage_file : nil
140
- end.compact)
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 :profdata_coverage_files
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
- raise StandardError, "The specified build directory (#{self.build_directory}) does not exist" unless File.exists?(self.build_directory)
161
- dir = nil
162
- if self.scheme
163
- dir = Dir[File.join(build_directory,"/**/CodeCoverage/#{self.scheme}")].first
164
- else
165
- dir = Dir[File.join(build_directory,"/**/#{first_product_name}")].first
166
- end
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
- if dir == nil
169
- # Xcode 7.3 moved the location of Coverage.profdata
170
- dir = Dir[File.join(build_directory,"/**/CodeCoverage")].first
171
- end
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
- if dir == nil && Slather.xcode_version[0] >= 9
174
- # Xcode 9 moved the location of Coverage.profdata
175
- coverage_files = Dir[File.join(build_directory, "/**/ProfileData/*/Coverage.profdata")]
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
- if coverage_files.count == 0
178
- # Look up one directory
179
- # The ProfileData directory is next to Intermediates.noindex (in previous versions of Xcode the coverage was inside Intermediates)
180
- coverage_files = Dir[File.join(build_directory, "../**/ProfileData/*/Coverage.profdata")]
181
- end
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
- if coverage_files != nil
184
- dir = Pathname.new(coverage_files.first).parent()
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
- raise StandardError, "No coverage directory found." unless dir != nil
189
- dir
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
@@ -1,3 +1,3 @@
1
1
  module Slather
2
- VERSION = '2.4.6' unless defined?(Slather::VERSION)
2
+ VERSION = '2.6.0' unless defined?(Slather::VERSION)
3
3
  end
@@ -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', '~> 1.6'
21
- spec.add_development_dependency 'coveralls'
22
- spec.add_development_dependency 'simplecov'
23
- spec.add_development_dependency 'rake', '~> 10.4'
24
- spec.add_development_dependency 'rspec', '~> 3.4'
25
- spec.add_development_dependency 'pry', '~> 0.9'
26
- spec.add_development_dependency 'cocoapods', '~> 1.2'
27
- spec.add_development_dependency 'json_spec', '~> 1.1.4'
28
- spec.add_development_dependency 'equivalent-xml', '~> 0.5.1'
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', '~> 0.6'
31
- spec.add_dependency 'xcodeproj', '~> 1.4'
32
- spec.add_dependency 'nokogiri', '~> 1.8.2'
33
- spec.add_dependency 'CFPropertyList', '~> 2.2'
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', '>= 4.0.2'
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&#x1F4A3;.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(%q(
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
- allow(fixtures_project).to receive(:profdata_llvm_cov_output).and_return("#{FIXTURES_SWIFT_FILE_PATH}:
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("fixtures.m")
587
- expect(source_files.last.to_s).to include("fixturesTwo.m")
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