blob: daa2eeb0cbd1b2599fd307b91c24607539ee1a00 [file] [log] [blame]
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//
// XCTestFiltering.swift
// This provides utilities for executing only a subset of the tests provided to `XCTMain`
//
internal typealias TestFilter = (XCTestCase.Type, String) -> Bool
internal struct TestFiltering {
private let selectedTestName: String?
init(selectedTestName: String?) {
self.selectedTestName = selectedTestName
}
var selectedTestFilter: TestFilter {
guard let selectedTestName = selectedTestName else { return includeAllFilter() }
guard let selectedTest = SelectedTest(selectedTestName: selectedTestName) else { return excludeAllFilter() }
return selectedTest.matches
}
private func excludeAllFilter() -> TestFilter {
return { _,_ in false }
}
private func includeAllFilter() -> TestFilter {
return { _,_ in true }
}
static func filterTests(_ entries: [XCTestCaseEntry], filter: TestFilter) -> [XCTestCaseEntry] {
return entries
.map { testCaseClass, testCaseMethods in
return (testCaseClass, testCaseMethods.filter { filter(testCaseClass, $0.0) } )
}
.filter { _, testCaseMethods in
return !testCaseMethods.isEmpty
}
}
}
/// A selected test can be a single test case, or an entire class of test cases
private struct SelectedTest {
let testCaseClassName: String
let testCaseMethodName: String?
}
private extension SelectedTest {
init?(selectedTestName: String) {
let components = selectedTestName.split(separator: "/").map(String.init)
switch components.count {
case 1:
testCaseClassName = components[0]
testCaseMethodName = nil
case 2:
testCaseClassName = components[0]
testCaseMethodName = components[1]
default:
return nil
}
}
func matches(testCaseClass: XCTestCase.Type, testCaseMethodName: String) -> Bool {
return String(reflecting: testCaseClass) == testCaseClassName && (self.testCaseMethodName == nil || testCaseMethodName == self.testCaseMethodName)
}
}