-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from IntrepidPursuits/coverage
Coverage
- Loading branch information
Showing
15 changed files
with
447 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// | ||
// CoberturaCoverageTests.swift | ||
// Jenkins | ||
// | ||
// Created by Patrick Butkiewicz on 11/13/16. | ||
// | ||
// | ||
|
||
import Foundation | ||
import XCTest | ||
@testable import Jenkins | ||
|
||
class CoberturaCoverageTests: XCTestCase { | ||
|
||
func testCoberturaCodeCoverageDepth2() { | ||
|
||
guard let path = Bundle(for: type(of: self)).path(forResource: "CoberturaCoverageReportDepth2", ofType: "json") else { | ||
return XCTFail("Missing Coverage Report JSON") | ||
} | ||
|
||
guard | ||
let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped), | ||
let json: JSON = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? JSON | ||
else { | ||
return XCTFail("Failed mapping Coverage Report JSON") | ||
} | ||
|
||
let c = CoberturaCodeCoverageReport(json: json["results"] as! JSON) | ||
|
||
let validChildren = 0 | ||
XCTAssert(c.childReports.count == validChildren, "Report has \(c.childReports.count) children, but should have \(validChildren)") | ||
|
||
let validName = "Cobertura Coverage Report" | ||
XCTAssert(c.name.compare(validName) == ComparisonResult.orderedSame, "Coverage report name is '\(c.name)' but should be \(validName)") | ||
|
||
let validCovElements = 5 | ||
XCTAssert(c.coverageElements.count == validCovElements, "Report has \(c.coverageElements.count) coverage elements but should have \(validCovElements)") | ||
|
||
let validLineRatio = 0.2 | ||
let actualLineRatio = c.ratio(of: CoberturaCodeCoverageElementType.Lines) | ||
XCTAssertEqualWithAccuracy(actualLineRatio, validLineRatio, accuracy: 0.05) | ||
} | ||
|
||
func testCoberturaCodeCoverageDepth3() { | ||
guard let path = Bundle(for: type(of: self)).path(forResource: "CoberturaCoverageReportDepth3", ofType: "json") else { | ||
return XCTFail("Missing Coverage Report JSON") | ||
} | ||
|
||
guard | ||
let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped), | ||
let json: JSON = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? JSON | ||
else { | ||
return XCTFail("Failed mapping Coverage Report JSON") | ||
} | ||
|
||
let c = CoberturaCodeCoverageReport(json: json["results"] as! JSON) | ||
|
||
let validChildren = 27 | ||
XCTAssert(c.childReports.count == validChildren, "Report has \(c.childReports.count) children, but should have \(validChildren)") | ||
|
||
let validName = "Cobertura Coverage Report" | ||
XCTAssert(c.name.compare(validName) == ComparisonResult.orderedSame, "Coverage report name is '\(c.name)' but should be \(validName)") | ||
|
||
let validCovElements = 5 | ||
XCTAssert(c.coverageElements.count == validCovElements, "Report has \(c.coverageElements.count) coverage elements but should have \(validCovElements)") | ||
|
||
let validLineRatio = 0.2 | ||
let actualLineRatio = c.ratio(of: CoberturaCodeCoverageElementType.Lines) | ||
XCTAssertEqualWithAccuracy(actualLineRatio, validLineRatio, accuracy: 0.05) | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>CFBundleDevelopmentRegion</key> | ||
<string>en</string> | ||
<key>CFBundleExecutable</key> | ||
<string>$(EXECUTABLE_NAME)</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>$(PRODUCT_NAME)</string> | ||
<key>CFBundlePackageType</key> | ||
<string>BNDL</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0</string> | ||
<key>CFBundleVersion</key> | ||
<string>1</string> | ||
</dict> | ||
</plist> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"_class":"hudson.plugins.cobertura.targets.CoverageResult","results":{"children":[{"children":[{}],"elements":[{},{},{},{}],"name":"Pods.Crashlytics.iOS.Crashlytics.framework.Headers"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Analytics"},{"children":[{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers"},{"children":[{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.About"},{"children":[{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.CarouselSubControllers"},{"children":[{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.FirmwareUpdate"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.FirmwareUpdate.UpdateSuccessOverlay"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.FullScreenAlert"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.HeartRate"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.Help"},{"children":[{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.MusicShare"},{"children":[{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.NowPlaying"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.PairingMode"},{"children":[{},{},{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.Settings"},{"children":[{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Controllers.VideoPlayer"},{"children":[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Extensions"},{"children":[{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Extensions.CrashlyticsLog"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Mocks"},{"children":[{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Models"},{"children":[{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Models.UserDefaults"},{"children":[{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Utilities"},{"children":[{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.ViewModels"},{"children":[{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.ViewModels.Carousel"},{"children":[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Views"},{"children":[{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Views.CNC"},{"children":[{},{},{},{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Views.HeartRate"},{"children":[{},{}],"elements":[{},{},{},{}],"name":"bose-connect-ios.Views.MusicShareOnboarding"}],"elements":[{"denominator":10.0,"name":"Packages","numerator":2.0,"ratio":20.0},{"denominator":20.0,"name":"Files","numerator":4.0,"ratio":20.0},{"denominator":20.0,"name":"Classes","numerator":5.0,"ratio":25.0},{"denominator":5.0,"name":"Lines","numerator":1.0,"ratio":20.0},{"denominator":0.0,"name":"Conditionals","numerator":0.0,"ratio":100.0}],"name":"Cobertura Coverage Report"}} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"_class":"hudson.plugins.jacoco.report.CoverageReport","branchCoverage":{"covered":731,"missed":454,"percentage":62,"percentageFloat":61.687763,"total":1185},"classCoverage":{"covered":61,"missed":23,"percentage":73,"percentageFloat":72.61904,"total":84},"complexityScore":{"covered":854,"missed":578,"percentage":60,"percentageFloat":59.63687,"total":1432},"instructionCoverage":{"covered":8244,"missed":2896,"percentage":74,"percentageFloat":74.003586,"total":11140},"lineCoverage":{"covered":2107,"missed":764,"percentage":73,"percentageFloat":73.38907,"total":2871},"methodCoverage":{"covered":567,"missed":247,"percentage":70,"percentageFloat":69.65602,"total":814},"previousResult":{"_class":"hudson.plugins.jacoco.report.CoverageReport"}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// | ||
// JacocoCoverageTests.swift | ||
// Jenkins | ||
// | ||
// Created by Patrick Butkiewicz on 11/13/16. | ||
// | ||
// | ||
|
||
import Foundation | ||
import XCTest | ||
@testable import Jenkins | ||
|
||
class JacocoCoverageTests: XCTestCase { | ||
|
||
func testJacocoCodeCoverageDepth2() { | ||
guard let path = Bundle(for: type(of: self)).path(forResource: "JacocoCoverageReportDepth", ofType: "json") else { | ||
return XCTFail("Missing Jacoco Coverage Report JSON") | ||
} | ||
|
||
guard | ||
let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .alwaysMapped), | ||
let json: JSON = try! JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? JSON | ||
else { | ||
return XCTFail("Failed mapping Coverage Report JSON") | ||
} | ||
|
||
let coverage = JacocoCodeCoverageReport(json: json) | ||
|
||
let validBranchRatio = 0.61 | ||
let actualBranchRatio = coverage.ratio(of: JacocoCodeCoverageElementType.BranchCoverage) | ||
XCTAssertEqualWithAccuracy(actualBranchRatio, validBranchRatio, accuracy: 0.05) | ||
|
||
let validClassRatio = 0.72 | ||
let actualClassRatio = coverage.ratio(of: JacocoCodeCoverageElementType.ClassCoverage) | ||
XCTAssertEqualWithAccuracy(actualClassRatio, validClassRatio, accuracy: 0.05) | ||
|
||
let validComplexityRatio = 0.59 | ||
let actualComplexityRatio = coverage.ratio(of: JacocoCodeCoverageElementType.ComplexityCoverage) | ||
XCTAssertEqualWithAccuracy(actualComplexityRatio, validComplexityRatio, accuracy: 0.05) | ||
|
||
let validInstructionRatio = 0.74 | ||
let actualInstructionRatio = coverage.ratio(of: JacocoCodeCoverageElementType.InstructionCoverage) | ||
XCTAssertEqualWithAccuracy(actualInstructionRatio, validInstructionRatio, accuracy: 0.05) | ||
|
||
let validLineRatio = 0.73 | ||
let actualLineRatio = coverage.ratio(of: JacocoCodeCoverageElementType.LineCoverage) | ||
XCTAssertEqualWithAccuracy(actualLineRatio, validLineRatio, accuracy: 0.05) | ||
|
||
let validMethodRatio = 0.69 | ||
let actualMethodRatio = coverage.ratio(of: JacocoCodeCoverageElementType.MethodCoverage) | ||
XCTAssertEqualWithAccuracy(actualMethodRatio, validMethodRatio, accuracy: 0.05) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// | ||
// JenkinsTests.swift | ||
// JenkinsTests | ||
// | ||
// Created by Patrick Butkiewicz on 11/13/16. | ||
// | ||
// | ||
|
||
import XCTest | ||
|
||
class JenkinsTests: XCTestCase { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
// | ||
// Coverage.swift | ||
// Jenkins | ||
// | ||
// Created by Patrick Butkiewicz on 11/13/16. | ||
// | ||
// | ||
|
||
import Foundation | ||
|
||
public enum CoberturaCodeCoverageElementType: String, CoverageElementType { | ||
case Classes = "Classes" | ||
case Conditionals = "Conditionals" | ||
case Files = "Files" | ||
case Lines = "Lines" | ||
case Packages = "Packages" | ||
case Unknown = "Unknown" | ||
|
||
init(_ rawValue: String) { | ||
switch rawValue { | ||
case "Classes": self = .Classes | ||
case "Conditionals": self = .Conditionals | ||
case "Files": self = .Files | ||
case "Lines": self = .Lines | ||
case "Packages": self = .Packages | ||
default: self = .Unknown | ||
} | ||
} | ||
} | ||
|
||
public struct CoberturaCodeCoverageElement: CoverageElement { | ||
public var elementType: CoverageElementType = CoberturaCodeCoverageElementType.Unknown | ||
public var covered: Int = 0 | ||
public var total: Int = 0 | ||
} | ||
|
||
public struct CoberturaCodeCoverageReport: CoverageReport { | ||
private(set) var name: String | ||
private(set) var childReports: [CoberturaCodeCoverageReport] | ||
private(set) var coverageElements: [CoberturaCodeCoverageElement] | ||
|
||
init(json: JSON) { | ||
name = json["name"] as? String ?? "" | ||
|
||
// for each child, init self | ||
let childrenJSON: [JSON] = json["children"] as? [JSON] ?? [] | ||
childReports = childrenJSON | ||
.filter({ child in | ||
let elements = child["elements"] as? [JSON] ?? [] | ||
return elements.filter({ $0.count > 0 }).count > 0 | ||
}) | ||
.map({ | ||
CoberturaCodeCoverageReport(json: $0) | ||
}) | ||
|
||
// for each element, init element | ||
let elementJSON: [JSON] = json["elements"] as? [JSON] ?? [] | ||
coverageElements = elementJSON.map({ json in | ||
let coverageElementName: String = json["name"] as? String ?? "" | ||
let elementType = CoberturaCodeCoverageElementType(coverageElementName) | ||
let covered = json["numerator"] as? Int ?? 0 | ||
let total = json["denominator"] as? Int ?? 0 | ||
return CoberturaCodeCoverageElement(elementType: elementType, covered: covered, total: total) | ||
}) | ||
} | ||
|
||
public func ratio(of element: CoverageElementType) -> Double { | ||
if let e = element as? CoberturaCodeCoverageElementType { | ||
return coverageElements.filter({ | ||
return ($0.elementType as? CoberturaCodeCoverageElementType) == e | ||
}).first?.ratio() ?? 0 | ||
} | ||
return 0 | ||
} | ||
} | ||
|
||
/* | ||
* Jenkins Cobertura Extension | ||
*/ | ||
|
||
extension Jenkins { | ||
public func coberturaCoverage(_ job: String, | ||
build: Int = 0, | ||
depth: Int = 2, | ||
handler: @escaping (_ coverageReport: CoberturaCodeCoverageReport?) -> Void) | ||
{ | ||
let buildPath = (build == 0) ? "lastSuccessfulBuild" : String(build) | ||
|
||
guard let url: URL = URL(string: jobURL)? | ||
.appendingPathComponent(job) | ||
.appendingPathComponent(buildPath) | ||
.appendingPathComponent("cobertura") | ||
.appendingPathComponent("api") | ||
.appendingPathComponent("json") else { | ||
return handler(nil) | ||
} | ||
|
||
let parameters: [String : AnyObject] = ["depth" : depth as AnyObject] | ||
client?.get(path: url, params: parameters) { response, error in | ||
guard let json = response as? JSON, | ||
let results = json["results"] as? JSON else { | ||
return handler(nil) | ||
} | ||
|
||
handler(CoberturaCodeCoverageReport(json: results)) | ||
} | ||
} | ||
|
||
public func coberturaCoverage(_ job: Job, | ||
build: Int = 0, | ||
depth: Int = 2, | ||
handler: @escaping (_ coverageReport: CoberturaCodeCoverageReport?) -> Void) | ||
{ | ||
coberturaCoverage(job.name, build: build, depth: depth, handler: handler) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// | ||
// Coverage.swift | ||
// Jenkins | ||
// | ||
// Created by Patrick Butkiewicz on 11/13/16. | ||
// | ||
// | ||
|
||
import Foundation | ||
|
||
public protocol CoverageReport { | ||
func ratio(of element: CoverageElementType) -> Double | ||
} | ||
|
||
/* | ||
* Coverage Element | ||
*/ | ||
|
||
public protocol CoverageElementType {} | ||
|
||
public protocol CoverageElement { | ||
var elementType: CoverageElementType { get } | ||
var covered: Int { get } | ||
var total: Int { get } | ||
|
||
func missed() -> Int | ||
func ratio() -> Double | ||
} | ||
|
||
extension CoverageElement { | ||
public func missed() -> Int { | ||
return max(0, (total - covered)) | ||
} | ||
|
||
public func ratio() -> Double { | ||
return fmax(0, (Double(covered) / Double(total))) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import Foundation | ||
typealias JSON = [String: AnyObject] |
Oops, something went wrong.