Skip to content

Commit 22e8422

Browse files
committed
Support SPM coverage
1 parent 295058b commit 22e8422

9 files changed

+59
-45
lines changed

Package.resolved

+3-3
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@
159159
"repositoryURL": "https://github.com/danger/swift.git",
160160
"state": {
161161
"branch": null,
162-
"revision": "ea843a2df3f17c309767dd9725c82dc1c4e60130",
163-
"version": "1.3.1"
162+
"revision": "ece72c9bc2d8b0719d74ba0377063288ca625ba7",
163+
"version": "1.3.2"
164164
}
165165
},
166166
{
@@ -228,7 +228,7 @@
228228
},
229229
{
230230
"package": "Yams",
231-
"repositoryURL": "https://github.com/jpsim/Yams",
231+
"repositoryURL": "https://github.com/jpsim/Yams.git",
232232
"state": {
233233
"branch": null,
234234
"revision": "26ab35f50ea891e8edefcc9d975db2f6b67e1d68",

SPMDangerfile.swift

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import Danger
2+
import DangerSwiftCoverage
3+
4+
let danger = Danger()
5+
Coverage.spmCoverage(minimumCoverage: 50)

Sources/DangerSwiftCoverage/DangerSwiftCoverage.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ public enum Coverage {
1717
}
1818
}
1919

20-
public static func spmCoverage(spmCoverageFilePath: String = ".build/debug/cov", minimumCoverage: Float) {
21-
spmCoverage(spmCoverageFilePath: spmCoverageFilePath, minimumCoverage: minimumCoverage, spmCoverageParser: SPMCoverageParser.self, fileManager: .default, danger: Danger())
20+
public static func spmCoverage(spmCoverageFolder: String = ".build/debug/codecov", minimumCoverage: Float) {
21+
spmCoverage(spmCoverageFolder: spmCoverageFolder, minimumCoverage: minimumCoverage, spmCoverageParser: SPMCoverageParser.self, fileManager: .default, danger: Danger())
2222
}
2323

24-
static func spmCoverage(spmCoverageFilePath: String, minimumCoverage: Float, spmCoverageParser: SPMCoverageParsing.Type, fileManager: FileManager, danger: DangerDSL) {
24+
static func spmCoverage(spmCoverageFolder: String, minimumCoverage: Float, spmCoverageParser: SPMCoverageParsing.Type, fileManager: FileManager, danger: DangerDSL) {
2525
do {
26-
let report = try spmCoverageParser.coverage(spmCoverageFilePath: spmCoverageFilePath, files: modifiedFilesAbsolutePaths(fileManager: fileManager, danger: danger))
26+
let report = try spmCoverageParser.coverage(spmCoverageFolder: spmCoverageFolder, files: modifiedFilesAbsolutePaths(fileManager: fileManager, danger: danger))
2727
sendReport(report, minumumCoverage: minimumCoverage, danger: danger)
2828
} catch {
2929
danger.fail("Failed to get the coverage - Error: \(error.localizedDescription)")

Sources/DangerSwiftCoverage/SPM/SPMCoverageParser.swift

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import Foundation
22

33
protocol SPMCoverageParsing {
4-
static func coverage(spmCoverageFilePath: String, files: [String]) throws -> Report
4+
static func coverage(spmCoverageFolder: String, files: [String]) throws -> Report
55
}
66

77
enum SPMCoverageParser: SPMCoverageParsing {
88
enum Errors: Error {
9-
case buildFolderNotFound
9+
case coverageFileNotFound
1010
}
1111

12-
static func coverage(spmCoverageFilePath: String, files: [String]) throws -> Report {
13-
return try coverage(spmCoverageFilePath: spmCoverageFilePath, files: files, fileManager: .default)
12+
static func coverage(spmCoverageFolder: String, files: [String]) throws -> Report {
13+
return try coverage(spmCoverageFolder: spmCoverageFolder, files: files, fileManager: .default)
1414
}
1515

16-
static func coverage(spmCoverageFilePath: String, files: [String], fileManager: FileManager) throws -> Report {
17-
let url = URL(fileURLWithPath: fileManager.currentDirectoryPath + "/" + spmCoverageFilePath)
16+
static func coverage(spmCoverageFolder: String, files: [String], fileManager: FileManager) throws -> Report {
17+
guard let jsonFileName = try fileManager.contentsOfDirectory(atPath: spmCoverageFolder).first(where: { $0.split(separator: ".").last == "json" }) else {
18+
throw Errors.coverageFileNotFound
19+
}
20+
let url = URL(fileURLWithPath: fileManager.currentDirectoryPath + "/" + spmCoverageFolder + "/" + jsonFileName)
1821
let data = try Data(contentsOf: url)
1922
let coverage = try JSONDecoder().decode(SPMCoverage.self, from: data)
2023
let filteredCoverage = coverage.filteringFiles(notOn: files)

Tests/DangerSwiftCoverageTests/CoverageTests.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ final class CoverageTests: XCTestCase {
2929

3030
func testItSendsAFailMessageIfFailsToParseTheXcodeBuildCoverage() {
3131
dsl = githubFixtureDSL
32-
Coverage.xcodeBuildCoverage(derivedDataFolder: "derived", minimumCoverage: 50, excludedTargets: [], fileManager: FakeCurrentPathProvider(), xcodeBuildCoverageParser: MockXcodeBuildCoverageParser.self, danger: dsl)
32+
Coverage.xcodeBuildCoverage(derivedDataFolder: "derived", minimumCoverage: 50, excludedTargets: [], fileManager: StubbedFileManager(), xcodeBuildCoverageParser: MockXcodeBuildCoverageParser.self, danger: dsl)
3333

3434
XCTAssertEqual(dsl.fails.count, 1)
3535
XCTAssertEqual(dsl.fails[0].message, "Failed to get the coverage - Error: Fake Error")
@@ -38,7 +38,7 @@ final class CoverageTests: XCTestCase {
3838
func testItSendsTheCorrectParametersToTheXcodeBuildCoverageParser() {
3939
dsl = githubWithFilesDSL(created: created, modified: modified)
4040

41-
let currentPathProvider = FakeCurrentPathProvider()
41+
let currentPathProvider = StubbedFileManager()
4242
let excluedTargets = ["TargetA.framework", "TargetB.framework"]
4343

4444
Coverage.xcodeBuildCoverage(derivedDataFolder: "derived", minimumCoverage: 50, excludedTargets: excluedTargets, fileManager: currentPathProvider, xcodeBuildCoverageParser: MockXcodeBuildCoverageParser.self, danger: dsl)
@@ -52,7 +52,7 @@ final class CoverageTests: XCTestCase {
5252
dsl = githubWithFilesDSL()
5353
MockXcodeBuildCoverageParser.shouldSucceed = true
5454

55-
Coverage.xcodeBuildCoverage(derivedDataFolder: "derived", minimumCoverage: 50, excludedTargets: [], fileManager: FakeCurrentPathProvider(), xcodeBuildCoverageParser: MockXcodeBuildCoverageParser.self, danger: dsl)
55+
Coverage.xcodeBuildCoverage(derivedDataFolder: "derived", minimumCoverage: 50, excludedTargets: [], fileManager: StubbedFileManager(), xcodeBuildCoverageParser: MockXcodeBuildCoverageParser.self, danger: dsl)
5656

5757
XCTAssertEqual(dsl.messages.map { $0.message }, ["TestMessage1", "TestMessage2"])
5858

@@ -77,9 +77,9 @@ final class CoverageTests: XCTestCase {
7777
func testItSendsTheCorrectParametersToTheSPMCoverageParser() {
7878
dsl = githubWithFilesDSL(created: created, modified: modified)
7979

80-
let currentPathProvider = FakeCurrentPathProvider()
80+
let currentPathProvider = StubbedFileManager()
8181

82-
Coverage.spmCoverage(spmCoverageFilePath: ".build/debug", minimumCoverage: 50, spmCoverageParser: MockSPMCoverageParser.self, fileManager: currentPathProvider, danger: dsl)
82+
Coverage.spmCoverage(spmCoverageFolder: ".build/debug", minimumCoverage: 50, spmCoverageParser: MockSPMCoverageParser.self, fileManager: currentPathProvider, danger: dsl)
8383

8484
XCTAssertEqual(MockSPMCoverageParser.receivedSPMCoverageFilePath, ".build/debug")
8585
XCTAssertEqual(MockSPMCoverageParser.receivedFiles, (created + modified).map { currentPathProvider.fakePath + "/" + $0 })
@@ -89,7 +89,7 @@ final class CoverageTests: XCTestCase {
8989
dsl = githubWithFilesDSL()
9090
MockSPMCoverageParser.shouldSucceed = true
9191

92-
Coverage.spmCoverage(spmCoverageFilePath: ".build/debug", minimumCoverage: 50, spmCoverageParser: MockSPMCoverageParser.self, fileManager: FakeCurrentPathProvider(), danger: dsl)
92+
Coverage.spmCoverage(spmCoverageFolder: ".build/debug", minimumCoverage: 50, spmCoverageParser: MockSPMCoverageParser.self, fileManager: StubbedFileManager(), danger: dsl)
9393

9494
XCTAssertEqual(dsl.messages.map { $0.message }, [])
9595

@@ -127,7 +127,7 @@ private final class MockSPMCoverageParser: SPMCoverageParsing {
127127
]),
128128
])
129129

130-
static func coverage(spmCoverageFilePath: String, files: [String]) throws -> Report {
130+
static func coverage(spmCoverageFolder spmCoverageFilePath: String, files: [String]) throws -> Report {
131131
receivedSPMCoverageFilePath = spmCoverageFilePath
132132
receivedFiles = files
133133

Tests/DangerSwiftCoverageTests/FakeCurrentPathProvider.swift

-12
This file was deleted.

Tests/DangerSwiftCoverageTests/SPMCoverageParserTests.swift

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ final class SPMCoverageParserTests: XCTestCase {
77

88
try spmCoverageJSON.write(toFile: testPath, atomically: false, encoding: .utf8)
99

10-
let currentPathProvider = FakeCurrentPathProvider()
10+
let fileManager = StubbedFileManager()
1111

1212
var calls = 0
13-
currentPathProvider.currentPathBlock = {
13+
fileManager.currentPathBlock = {
1414
let result: String
1515

1616
if calls == 0 {
@@ -24,7 +24,11 @@ final class SPMCoverageParserTests: XCTestCase {
2424
return result
2525
}
2626

27-
let report = try! SPMCoverageParser.coverage(spmCoverageFilePath: testPath, files: ["/Users/franco/Projects/Logger/Sources/Logger/Logger.swift"], fileManager: currentPathProvider)
27+
fileManager.stubbedContentOfDirectoryBlock = { _ in
28+
[testPath]
29+
}
30+
31+
let report = try! SPMCoverageParser.coverage(spmCoverageFolder: ".", files: ["/Users/franco/Projects/Logger/Sources/Logger/Logger.swift"], fileManager: fileManager)
2832

2933
XCTAssertEqual(report.sections[0].items.count, 1)
3034
XCTAssertEqual(report.sections[0].items[0].fileName, "Sources/Logger/Logger.swift")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Foundation
2+
3+
final class StubbedFileManager: FileManager {
4+
let fakePath = "/usr/franco"
5+
lazy var currentPathBlock: () -> String = { [unowned self] in
6+
self.fakePath
7+
}
8+
9+
var stubbedContentOfDirectoryBlock: ((String) -> [String])?
10+
11+
override var currentDirectoryPath: String {
12+
return currentPathBlock()
13+
}
14+
15+
override func contentsOfDirectory(atPath path: String) throws -> [String] {
16+
if let stubbedContentOfDirectoryBlock = stubbedContentOfDirectoryBlock {
17+
return stubbedContentOfDirectoryBlock(path)
18+
} else {
19+
return try super.contentsOfDirectory(atPath: path)
20+
}
21+
}
22+
}

Tests/DangerSwiftCoverageTests/XcodeCoverageFileFinderTests.swift

+2-10
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final class XcodeCoverageFileFinderTests: XCTestCase {
2121
}
2222

2323
func testItFailsIfTheDirectoryDoesntContainAnXCovFile() {
24-
fileManager.contentResult = { fileName in
24+
fileManager.stubbedContentOfDirectoryBlock = { fileName in
2525
fileName == "derived/Logs/Test/" ? ["test.xcresult"] : []
2626
}
2727

@@ -31,18 +31,10 @@ final class XcodeCoverageFileFinderTests: XCTestCase {
3131
}
3232

3333
func testItReturnsTheCorrectCoverageFile() throws {
34-
fileManager.contentResult = { fileName in
34+
fileManager.stubbedContentOfDirectoryBlock = { fileName in
3535
fileName == "derived/Logs/Test/" ? ["test.xcresult"] : (fileName == "derived/Logs/Test/test.xcresult" ? ["1_test"] : ["action.xccovreport"])
3636
}
3737

3838
XCTAssertEqual(try XcodeCoverageFileFinder.coverageFile(derivedDataFolder: "derived", fileManager: fileManager), "derived/Logs/Test/test.xcresult/1_test/action.xccovreport")
3939
}
4040
}
41-
42-
private final class StubbedFileManager: FileManager {
43-
fileprivate var contentResult: ((String) -> [String])?
44-
45-
override func contentsOfDirectory(atPath path: String) throws -> [String] {
46-
return contentResult?(path) ?? []
47-
}
48-
}

0 commit comments

Comments
 (0)