Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Commit

Permalink
Fix failing to generate coverage if the tests include asyc test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
kishikawakatsumi committed Jun 4, 2015
1 parent f542a93 commit e5b178a
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 1 deletion.
20 changes: 19 additions & 1 deletion Source/SwiftCovFramework/CoverageReporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class CoverageReporter {
let dyldFallbackFrameworkPath = "/Library/Frameworks:/Network/Library/Frameworks:/System/Library/Frameworks:\(xcodePath)/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks:\(xcodePath)/Library/PrivateFrameworks:\(xcodePath)/../OtherFrameworks:\(xcodePath)/../SharedFrameworks:\(xcodePath)/Library/Frameworks:\(xcodePath)/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks"
let dyldFallbackLibraryPath = "\(xcodePath)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib"

let env = [
var env = [
"SWIFTCOV_FILES": join("\n", files ?? []),
"SWIFTCOV_SDK_NAME": sdkName,
"SWIFTCOV_DYLD_FRAMEWORK_PATH": builtProductsDir,
Expand All @@ -71,6 +71,24 @@ public class CoverageReporter {
"SWIFTCOV_DYLD_ROOT_PATH": sdkroot,
"SWIFTCOV_HIT_COUNT": "\(threshold)"
]

if sdkName.hasPrefix("iphone") {
let bootedDevice = SimCtl(verbose: verbose).list()
.flatMap { SimCtl.parseOutput($0) }
.map { (_, _, devices) -> [Device] in
return devices
}
.map { $0.filter { $0.booted }.first }

switch bootedDevice {
case let .Success(bootedDevice):
if let bootedDevice = bootedDevice.value {
env["SWIFTCOV_XPC_SIMULATOR_LAUNCHD_NAME"] = "com.apple.CoreSimulator.SimDevice.\(bootedDevice.UDID).launchd_sim"
}
case .Failure:
break
}
}

return Shell(commandPath: "/usr/bin/python", arguments: [scriptPath, targetPath, srcroot, outputDir], environment: env, verbose: verbose).run()
}
Expand Down
148 changes: 148 additions & 0 deletions Source/SwiftCovFramework/SimCtl.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
//
// SimCtl.swift
// swiftcov
//
// Created by Kishikawa Katsumi on 2015/06/04.
// Copyright (c) 2015 Realm. All rights reserved.
//

import Foundation
import Result

public struct SimCtl {
private let verbose: Bool

public init(verbose: Bool = false) {
self.verbose = verbose
}

public func list() -> Result<String, TerminationStatus> {
let command = Shell(commandPath: "/usr/bin/xcrun", arguments: ["simctl", "list"], verbose: verbose)
return command.output()
}

public static func parseOutput(output: String) -> Result<([DeviceType], [Runtime], [Device]), TerminationStatus> {
let whitespaceAndNewlineCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
let lines: [String] = {
var lines = [String]()
output.enumerateLines { line, _ in
lines.append(line.stringByTrimmingCharactersInSet(whitespaceAndNewlineCharacterSet))
}
return lines.filter { !$0.isEmpty }
}()

enum Mode {
case DeviceType
case Runtime
case Device
}

var deviceTypes = [DeviceType]()
var runtimes = [Runtime]()
var devices = [Device]()

var mode = Mode.DeviceType

var target: String?
var settings = [String: String]()
for line in lines {
switch line {
case "== Device Types ==":
mode = Mode.DeviceType
continue
case "== Runtimes ==":
mode = Mode.Runtime
continue
case "== Devices ==":
mode = Mode.Device
continue
default:
break
}

switch mode {
case .DeviceType:
if let deviceType = DeviceType.parseLine(line) {
deviceTypes.append(deviceType)
}
case .Runtime:
if let runtime = Runtime.parseLine(line) {
runtimes.append(runtime)
}
case .Device:
if let device = Device.parseLine(line) {
devices.append(device)
}
}
}

return Result(value: (deviceTypes, runtimes, devices))
}
}

public struct DeviceType {
public let name: String
public let identifier: String

internal static func parseLine(line: String) -> DeviceType? {
let regex = NSRegularExpression(pattern: "^(.+) \\((.+)\\)$", options: nil, error: nil)!
let matches = regex.matchesInString(line, options: nil, range: NSRange(location: 0, length: (line as NSString).length))
if matches.count == 1 {
for match in matches {
if let match = match as? NSTextCheckingResult {
let name = (line as NSString).substringWithRange(match.rangeAtIndex(1))
let identifier = (line as NSString).substringWithRange(match.rangeAtIndex(2))

return DeviceType(name: name, identifier: identifier)
}
}
}
return nil
}
}

public struct Runtime {
public let name: String
public let build: String
public let identifier: String

internal static func parseLine(line: String) -> Runtime? {
let regex = NSRegularExpression(pattern: "^(.+) \\((.+)\\) \\((.+)\\)$", options: nil, error: nil)!
let matches = regex.matchesInString(line, options: nil, range: NSRange(location: 0, length: (line as NSString).length))
if matches.count == 1 {
for match in matches {
if let match = match as? NSTextCheckingResult {
let name = (line as NSString).substringWithRange(match.rangeAtIndex(1))
let build = (line as NSString).substringWithRange(match.rangeAtIndex(2))
let identifier = (line as NSString).substringWithRange(match.rangeAtIndex(3))

return Runtime(name: name, build: build, identifier: identifier)
}
}
}
return nil
}
}

public struct Device {
public let iOSVersion: String
public let UDID: String
public let booted: Bool

internal static func parseLine(line: String) -> Device? {
let regex = NSRegularExpression(pattern: "^(.+) \\((.+)\\) \\((.+)\\)$", options: nil, error: nil)!
let matches = regex.matchesInString(line, options: nil, range: NSRange(location: 0, length: (line as NSString).length))
if matches.count == 1 {
for match in matches {
if let match = match as? NSTextCheckingResult {
let iOSVersion = (line as NSString).substringWithRange(match.rangeAtIndex(1))
let UDID = (line as NSString).substringWithRange(match.rangeAtIndex(2))
let state = (line as NSString).substringWithRange(match.rangeAtIndex(3))

return Device(iOSVersion: iOSVersion, UDID: UDID, booted: state == "Booted")
}
}
}
return nil
}
}
1 change: 1 addition & 0 deletions Source/SwiftCovFramework/coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ def main():
'DYLD_FALLBACK_FRAMEWORK_PATH=%s' % os.getenv('SWIFTCOV_DYLD_FALLBACK_FRAMEWORK_PATH'),
'DYLD_FALLBACK_LIBRARY_PATH=%s' % os.getenv('SWIFTCOV_DYLD_FALLBACK_LIBRARY_PATH'),
'DYLD_ROOT_PATH=%s' % os.getenv('SWIFTCOV_DYLD_ROOT_PATH'),
'XPC_SIMULATOR_LAUNCHD_NAME=%s' % os.getenv('SWIFTCOV_XPC_SIMULATOR_LAUNCHD_NAME'),
'LC_ALL=en_US.UTF-8']
else:
environment = ['DYLD_FRAMEWORK_PATH=%s' % os.getenv('SWIFTCOV_DYLD_FRAMEWORK_PATH'),
Expand Down
4 changes: 4 additions & 0 deletions swiftcov.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
1401EBDB1B11657C000D8737 /* coverage.py in Resources */ = {isa = PBXBuildFile; fileRef = 1401EBD61B116504000D8737 /* coverage.py */; };
1401EBE81B14AFE2000D8737 /* Xcodebuild.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1401EBE71B14AFE2000D8737 /* Xcodebuild.swift */; };
1401EBEA1B14B009000D8737 /* BuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1401EBE91B14B009000D8737 /* BuildSettings.swift */; };
1499139B1B20C62B0079325B /* SimCtl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1499139A1B20C62B0079325B /* SimCtl.swift */; };
14DE82611B1B0AA900E1BAA4 /* ShellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DE82601B1B0AA900E1BAA4 /* ShellTests.swift */; };
14DE82631B1B210700E1BAA4 /* XcodebuildTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DE82621B1B210700E1BAA4 /* XcodebuildTests.swift */; };
14DE82671B1B4B3D00E1BAA4 /* CoverageReporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14DE82661B1B4B3D00E1BAA4 /* CoverageReporterTests.swift */; };
Expand Down Expand Up @@ -80,6 +81,7 @@
1401EBD61B116504000D8737 /* coverage.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = coverage.py; sourceTree = "<group>"; };
1401EBE71B14AFE2000D8737 /* Xcodebuild.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Xcodebuild.swift; sourceTree = "<group>"; };
1401EBE91B14B009000D8737 /* BuildSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuildSettings.swift; sourceTree = "<group>"; };
1499139A1B20C62B0079325B /* SimCtl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimCtl.swift; sourceTree = "<group>"; };
14DE82601B1B0AA900E1BAA4 /* ShellTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShellTests.swift; sourceTree = "<group>"; };
14DE82621B1B210700E1BAA4 /* XcodebuildTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodebuildTests.swift; sourceTree = "<group>"; };
14DE82661B1B4B3D00E1BAA4 /* CoverageReporterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoverageReporterTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -267,6 +269,7 @@
14DE826A1B1B4DFA00E1BAA4 /* CoverageReporter.swift */,
1401EBE71B14AFE2000D8737 /* Xcodebuild.swift */,
1401EBE91B14B009000D8737 /* BuildSettings.swift */,
1499139A1B20C62B0079325B /* SimCtl.swift */,
1401EBD41B11612C000D8737 /* Shell.swift */,
1401EBD61B116504000D8737 /* coverage.py */,
D0D1216F19E87B05005E4BAA /* Supporting Files */,
Expand Down Expand Up @@ -470,6 +473,7 @@
1401EBE81B14AFE2000D8737 /* Xcodebuild.swift in Sources */,
1401EBD51B11612C000D8737 /* Shell.swift in Sources */,
1401EBEA1B14B009000D8737 /* BuildSettings.swift in Sources */,
1499139B1B20C62B0079325B /* SimCtl.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down

0 comments on commit e5b178a

Please sign in to comment.