0001    // This source file is part of the Swift.org open source project
0002    //
0003    // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
0004    // Licensed under Apache License v2.0 with Runtime Library Exception
0005    //
0006    // See http://swift.org/LICENSE.txt for license information
0007    // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
0008    //
0009    //
0010    //  XCTestCase.swift
0011    //  Base protocol (and extension with default methods) for test cases
0012    //
0013    
0014    public protocol XCTestCase
XCTestCase.swift:19
extension XCTestCase {
XCTestMain.swift:47
@noreturn public func XCTMain(testCases: [XCTestCase]) {
: XCTestCaseProvider { 0015 func setUp
XCTestCase.swift:86
                self.setUp()
() 0016 func tearDown
XCTestCase.swift:110
        tearDown()
() 0017 } 0018 0019 extension XCTestCase { 0020 0021 public var continueAfterFailure
XCTestCase.swift:59
                    if !self.continueAfterFailure {
: Bool { 0022 get { 0023 return false 0024 } 0025 set { 0026 // TODO: When using the Objective-C runtime, XCTest is able to throw an exception from an assert and then catch it at the frame above the test method. This enables the framework to effectively stop all execution in the current test. There is no such facility in Swift. Until we figure out how to get a compatible behavior, we have decided to hard-code the value of 'true' for continue after failure. 0027 } 0028 } 0029 0030 public func invokeTest
XCTestMain.swift:62
            testCases[idx].invokeTest()
() { 0031 let tests = self.allTests 0032 guard tests.count > 0 else { 0033 return 0034 } 0035 let state = XCTestCaseState(count: tests.count) 0036 0037 // The tests of this test case are run in a loop within a closure. 0038 // This closure enables the test "loop" to be "continued" from within 0039 // the failure handler closure. Thus enabling a set of tests with in 0040 // a test case to continue after one of them has failed. 0041 // 0042 // Note: The index (idx) is initialized to -1, do to the fact the that 0043 // test runner closure always initially increments the index by one to 0044 // skip the failed test. 0045 0046 var idx = -1 0047 var testRunner: (() -> Void)? 0048 let testRunnerDef = { () in 0049 idx += 1 0050 while idx < tests.count { 0051 let (name, test) = tests[idx] 0052 state.method = "\(self.dynamicType).\(name)" 0053 state.failures = [XCTFailure]() 0054 0055 XCTFailureHandler = { failure in 0056 // Record that the test failed 0057 state.failures.append(failure) 0058 0059 if !self.continueAfterFailure { 0060 0061 // If the test is not suppose to continue after an assertion fails, 0062 // the following code does the following: 0063 // 0064 // 1. Invoke the regular end of test processing 0065 // 2. Invoke the test runner closure to run the rest of the tests in the test case 0066 // 3. Invoke the regular end of test case processing 0067 // 4. Invoke the XCTMainTestLoop closure to run the rest of the test cases 0068 // 5. Invoke the end of all of the test cases processing 0069 0070 self.postTestInvocation(currentTimeIntervalSinceReferenceTime(), state: state) 0071 0072 testRunner!() 0073 0074 self.postTestCase(state) 0075 0076 XCTMainTestLoop!() 0077 0078 postTests() 0079 } else { 0080 // Just keep on running 0081 } 0082 } 0083 0084 print("Test Case '\(state.method)' started.") 0085 0086 self.setUp() 0087 0088 state.start = currentTimeIntervalSinceReferenceTime() 0089 0090 do { 0091 try test() 0092 } catch { 0093 let unexpectedFailure = XCTFailure(message: "", failureDescription: "threw error \"\(error)\"", expected: false, file: "<EXPR>", line: 0) 0094 XCTFailureHandler!(unexpectedFailure) 0095 } 0096 0097 self.postTestInvocation(currentTimeIntervalSinceReferenceTime(), state: state) 0098 0099 idx += 1 0100 } 0101 } 0102 testRunner = testRunnerDef 0103 0104 testRunner!() 0105 0106 postTestCase(state) 0107 } 0108 0109 private func postTestInvocation
XCTestCase.swift:70
                        self.postTestInvocation(currentTimeIntervalSinceReferenceTime(), state: state)
XCTestCase.swift:97
                self.postTestInvocation(currentTimeIntervalSinceReferenceTime(), state: state)
(end: TimeInterval, state: XCTestCaseState) { 0110 tearDown() 0111 0112 let duration = end - state.start 0113 state.totalDuration += duration 0114 0115 for failure in state.failures { 0116 failure.emit(state.method) 0117 state.totalFailures += 1 0118 if !failure.expected { 0119 state.unexpectedFailures += 1 0120 } 0121 } 0122 0123 let result = state.failures.count > 0 ? "failed" : "passed" 0124 0125 print("Test Case '\(state.method)' \(result) (\(printableStringForTimeInterval(duration)) seconds).") 0126 XCTAllRuns.append(XCTRun(duration: duration, method: state.method, passed: state.failures.count == 0, failures: state.failures)) 0127 XCTFailureHandler = nil 0128 } 0129 0130 private func postTestCase
XCTestCase.swift:74
                        self.postTestCase(state)
XCTestCase.swift:106
        postTestCase(state)
(state: XCTestCaseState) { 0131 var testCountSuffix = "s" 0132 if state.count == 1 { 0133 testCountSuffix = "" 0134 } 0135 var failureSuffix = "s" 0136 if state.totalFailures == 1 { 0137 failureSuffix = "" 0138 } 0139 0140 print("Executed \(state.count) test\(testCountSuffix), with \(state.totalFailures) failure\(failureSuffix) (\(state.unexpectedFailures) unexpected) in \(printableStringForTimeInterval(state.totalDuration)) seconds") 0141 } 0142 0143 public func setUp() { 0144 0145 } 0146 0147 public func tearDown() { 0148 0149 } 0150 } 0151 0152 private class XCTestCaseState
XCTestCase.swift:35
        let state = XCTestCaseState(count: tests.count)
XCTestCase.swift:109
    private func postTestInvocation(end: TimeInterval, state: XCTestCaseState) {
XCTestCase.swift:130
    private func postTestCase(state: XCTestCaseState) {
{ 0153 var method
XCTestCase.swift:52
                state.method = "\(self.dynamicType).\(name)"
XCTestCase.swift:84
                print("Test Case '\(state.method)' started.")
XCTestCase.swift:116
            failure.emit(state.method)
XCTestCase.swift:125
        print("Test Case '\(state.method)' \(result) (\(printableStringForTimeInterval(duration)) seconds).")
XCTestCase.swift:126
        XCTAllRuns.append(XCTRun(duration: duration, method: state.method, passed: state.failures.count == 0, failures: state.failures))
: String = "" 0154 var start
XCTestCase.swift:88
                state.start = currentTimeIntervalSinceReferenceTime()
XCTestCase.swift:112
        let duration = end - state.start
: TimeInterval = 0.0 0155 var totalDuration
XCTestCase.swift:113
        state.totalDuration += duration
XCTestCase.swift:140
        print("Executed \(state.count) test\(testCountSuffix), with \(state.totalFailures) failure\(failureSuffix) (\(state.unexpectedFailures) unexpected) in \(printableStringForTimeInterval(state.totalDuration))  seconds")
: TimeInterval = 0.0 0156 var totalFailures
XCTestCase.swift:117
            state.totalFailures += 1
XCTestCase.swift:136
        if state.totalFailures == 1 {
XCTestCase.swift:140
        print("Executed \(state.count) test\(testCountSuffix), with \(state.totalFailures) failure\(failureSuffix) (\(state.unexpectedFailures) unexpected) in \(printableStringForTimeInterval(state.totalDuration))  seconds")
= 0 0157 var unexpectedFailures
XCTestCase.swift:119
                state.unexpectedFailures += 1
XCTestCase.swift:140
        print("Executed \(state.count) test\(testCountSuffix), with \(state.totalFailures) failure\(failureSuffix) (\(state.unexpectedFailures) unexpected) in \(printableStringForTimeInterval(state.totalDuration))  seconds")
= 0 0158 var failures
XCTestCase.swift:53
                state.failures = [XCTFailure]()
XCTestCase.swift:57
                    state.failures.append(failure)
XCTestCase.swift:115
        for failure in state.failures {
XCTestCase.swift:123
        let result = state.failures.count > 0 ? "failed" : "passed"
XCTestCase.swift:126
        XCTAllRuns.append(XCTRun(duration: duration, method: state.method, passed: state.failures.count == 0, failures: state.failures))
XCTestCase.swift:126
        XCTAllRuns.append(XCTRun(duration: duration, method: state.method, passed: state.failures.count == 0, failures: state.failures))
= [XCTFailure]() 0159 let count
XCTestCase.swift:132
        if state.count == 1 {
XCTestCase.swift:140
        print("Executed \(state.count) test\(testCountSuffix), with \(state.totalFailures) failure\(failureSuffix) (\(state.unexpectedFailures) unexpected) in \(printableStringForTimeInterval(state.totalDuration))  seconds")
XCTestCase.swift:162
        self.count = count
: Int 0160 0161 init
XCTestCase.swift:35
        let state = XCTestCaseState(count: tests.count)
(count: Int) { 0162 self.count = count 0163 } 0164 } 0165