diff --git a/Tests/AllTestsCommon.swift b/Tests/AllTestsCommon.swift index 3e23fa20..72b0ffb2 100644 --- a/Tests/AllTestsCommon.swift +++ b/Tests/AllTestsCommon.swift @@ -111,6 +111,27 @@ class CustomExecutorTestCase: XCTestCase { final func assertExecutorCalled(atLeast times: Int, file: StaticString = #file, line: UInt = #line) { XCTAssert(_executor.submitCount.withReadLock({ $0 >= times }), "Executor was not called enough times", file: file, line: line) } + + final func expectationThatExecutor(isCalledAtLeast times: Int) -> XCTestExpectation { + return expectation(for: NSPredicate(block: { (sself, _) -> Bool in + guard let sself = sself as? CustomExecutorTestCase else { return false } + return sself._executor.submitCount.withReadLock({ $0 >= times }) + }), evaluatedWith: self) + } + + final let queue = DispatchQueue(label: "com.bignerdranch.DeferredTests") + + final func expectQueueToBeEmpty(description: String? = nil, file: StaticString = #file, line: UInt = #line) -> XCTestExpectation { + let expect = expectation(description: description ?? "queue is empty") + queue.async(flags: .barrier) { +#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS) || !swift(>=4.1) + expect.fulfill() +#else + expect.fulfill(file, line: line) +#endif + } + return expect + } } extension Collection { diff --git a/Tests/TaskTests/TaskTests.swift b/Tests/TaskTests/TaskTests.swift index ac0a0e81..ce27bf07 100755 --- a/Tests/TaskTests/TaskTests.swift +++ b/Tests/TaskTests/TaskTests.swift @@ -25,7 +25,10 @@ class TaskTests: CustomExecutorTestCase { ("testThatRecoverMapsFailures", testThatRecoverMapsFailures), ("testThatMapPassesThroughErrors", testThatMapPassesThroughErrors), ("testThatRecoverPassesThroughValues", testThatRecoverPassesThroughValues), - ("testThatFallbackAlsoProducesANewTask", testThatFallbackAlsoProducesANewTask) + ("testThatFallbackProducesANewTask", testThatFallbackProducesANewTask), + ("testThatFallbackUsingCustomExecutorProducesANewTask", testThatFallbackUsingCustomExecutorProducesANewTask), + ("testThatFallbackReturnsOriginalSuccessValue", testThatFallbackReturnsOriginalSuccessValue), + ("testThatFallbackUsingCustomExecutorReturnsOriginalSuccessValue", testThatFallbackUsingCustomExecutorReturnsOriginalSuccessValue) ] static var allTests: [(String, (TaskTests) -> () throws -> Void)] { @@ -268,16 +271,56 @@ class TaskTests: CustomExecutorTestCase { } #endif - func testThatFallbackAlsoProducesANewTask() { + func testThatFallbackProducesANewTask() { + let task = makeAnyFailedTask().fallback(upon: queue) { _ -> Task in + return self.makeAnyFinishedTask() + } + + shortWait(for: [ + expectation(that: task, succeedsWith: 42), + expectQueueToBeEmpty() + ]) + } + + func testThatFallbackUsingCustomExecutorProducesANewTask() { let task = makeAnyFailedTask().fallback(upon: executor) { _ -> Task in return self.makeAnyFinishedTask() } shortWait(for: [ - expectation(that: task, succeedsWith: 42) + expectation(that: task, succeedsWith: 42), + expectationThatExecutor(isCalledAtLeast: 1) ]) + } - assertExecutorCalled(atLeast: 2) + func testThatFallbackReturnsOriginalSuccessValue() { + let (deferred, task1) = makeAnyUnfinishedTask() + let task2 = task1.fallback(upon: queue) { _ -> Task in + return self.makeAnyFinishedTask() + } + + let expect = expectation(that: task2, succeedsWith: 99) + deferred.succeed(with: 99) + + shortWait(for: [ + expect, + expectQueueToBeEmpty() + ]) + } + + func testThatFallbackUsingCustomExecutorReturnsOriginalSuccessValue() { + let (deferred, task1) = makeAnyUnfinishedTask() + let task2 = task1.fallback(upon: executor) { _ -> Task in + return self.makeAnyFinishedTask() + } + + let expect = expectation(that: task2, succeedsWith: 99) + deferred.succeed(with: 99) + + shortWait(for: [ + expect, + expectationThatExecutor(isCalledAtLeast: 1) + ]) } func testSimpleFutureCanBeUpgradedToTask() {