diff --git a/Sources/Overdrive/Task.swift b/Sources/Overdrive/Task.swift index c15db1c..3be754b 100644 --- a/Sources/Overdrive/Task.swift +++ b/Sources/Overdrive/Task.swift @@ -588,8 +588,12 @@ open class Task: TaskBase { case .initialized: return isCancelled case .pending: - guard !isCancelled else { - return true + if isCancelled { + let ready = super.isReady + if ready { + self.state = .ready + } + return ready } if super.isReady { diff --git a/Sources/Overdrive/TaskQueue.swift b/Sources/Overdrive/TaskQueue.swift index f48bcfb..ef3b55c 100644 --- a/Sources/Overdrive/TaskQueue.swift +++ b/Sources/Overdrive/TaskQueue.swift @@ -195,10 +195,9 @@ open class TaskQueue { */ open func add(task: Task) { if !task.contains(observer: FinishBlockObserver.self) { - unowned let observedTask = task - task.add(observer: FinishBlockObserver { [weak self] in + task.add(observer: FinishBlockObserver { [weak self, unowned task] in if let queue = self { - queue.delegate?.didFinish(task: observedTask, inQueue: queue) + queue.delegate?.didFinish(task: task, inQueue: queue) } }) } diff --git a/Tests/OverdriveTests/DependencyTests.swift b/Tests/OverdriveTests/DependencyTests.swift index b85db5c..d7cc614 100644 --- a/Tests/OverdriveTests/DependencyTests.swift +++ b/Tests/OverdriveTests/DependencyTests.swift @@ -107,5 +107,33 @@ class DependencyTests: TestCase { waitForExpectations(timeout: 1, handler: nil) } - + + func testCancellationOfDependentTask() { + let queue = TaskQueue() + let delay: TimeInterval = 1.0 + let delayTask = TestCaseTask(withResult: .value(()), delay: delay) + + let equalExpectation = expectation(description: "value is equal to initial value") + let initialValue = 0 + var value = initialValue + + let modifyTask = InlineTask({ + value = 1 + }) + modifyTask.add(dependency: delayTask) + + let checkTask = InlineTask({ + XCTAssert(value == initialValue) + equalExpectation.fulfill() + }) + checkTask.add(dependency: modifyTask) + + queue.add(task: delayTask) + queue.add(task: modifyTask) + queue.add(task: checkTask) + + modifyTask.cancel() + + waitForExpectations(timeout: delay + 0.5) + } } diff --git a/Tests/OverdriveTests/TestCase.swift b/Tests/OverdriveTests/TestCase.swift index 96b0219..c1f4b99 100644 --- a/Tests/OverdriveTests/TestCase.swift +++ b/Tests/OverdriveTests/TestCase.swift @@ -19,17 +19,21 @@ class TestCaseTask: Task { /// Test result let testResult: Result + let delay: TimeInterval /// Create new instance with specified result /// /// - Parameter result: Any `Result` - init(withResult result: Result) { + init(withResult result: Result, delay: TimeInterval = 0.0) { + self.delay = delay self.testResult = result } override func run() { - finish(with: testResult) + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(self.delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: { + self.finish(with: self.testResult) + }) } }