-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(AsyncOperation): cancel() and isCancelled behavior (#801)
- Loading branch information
Showing
3 changed files
with
134 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
133 changes: 133 additions & 0 deletions
133
Tests/AlgoliaSearchClientTests/Unit/AsyncOperationTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import XCTest | ||
@testable import AlgoliaSearchClient | ||
|
||
final class AsyncOperationTests: XCTestCase { | ||
|
||
class TestOperation: AsyncOperation { | ||
override func main() { | ||
work() | ||
} | ||
|
||
private func work() { | ||
DispatchQueue.global().asyncAfter(deadline: .now() + DispatchTimeInterval.milliseconds(200)) { | ||
self.state = .finished | ||
} | ||
} | ||
} | ||
|
||
func testCancellation_withoutQueue() { | ||
let operation = TestOperation() | ||
XCTAssertTrue(operation.isReady) | ||
operation.cancel() | ||
XCTAssertTrue(operation.isCancelled) | ||
operation.start() | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_updatesIsCancelled_whenCancelledBeforeEnqueuing() { | ||
let operation = TestOperation() | ||
let queue = OperationQueue() | ||
operation.cancel() | ||
queue.addOperation(operation) | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isCancelled) | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_updatesIsCancelled_whenCancelledAfterEnqueuing() { | ||
let operation = TestOperation() | ||
let queue = OperationQueue() | ||
queue.addOperation(operation) | ||
operation.cancel() | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isCancelled) | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_updatesIsCancelled_whenOperationIsRunning() { | ||
let queue = OperationQueue() | ||
let operation = TestOperation() | ||
queue.addOperation(operation) | ||
Thread.sleep(forTimeInterval: 0.1) | ||
XCTAssertTrue(operation.isExecuting) | ||
operation.cancel() | ||
XCTAssertFalse(operation.isFinished) | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isCancelled) | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_ignoresCancellation_whenOperationIsFinished() { | ||
let queue = OperationQueue() | ||
let operation = TestOperation() | ||
queue.addOperation(operation) | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isFinished) | ||
operation.cancel() | ||
XCTAssertFalse(operation.isCancelled) | ||
} | ||
|
||
// Behavior of standard Operation without subclassing. | ||
func testCancellation_ofBlockOperation_withoutQueue() { | ||
let operation = BlockOperation { | ||
Thread.sleep(forTimeInterval: 0.1) | ||
} | ||
XCTAssertTrue(operation.isReady) | ||
operation.cancel() | ||
XCTAssertTrue(operation.isCancelled) | ||
operation.start() | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_ofBlockOperation_updatesIsCancelled_whenCancelledBeforeEnqueuing() { | ||
let operation = BlockOperation { | ||
Thread.sleep(forTimeInterval: 0.1) | ||
} | ||
let queue = OperationQueue() | ||
operation.cancel() | ||
queue.addOperation(operation) | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isCancelled) | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_ofBlockOperation_updatesIsCancelled_whenCancelledAfterEnqueuing() { | ||
let operation = BlockOperation { | ||
Thread.sleep(forTimeInterval: 0.1) | ||
} | ||
let queue = OperationQueue() | ||
queue.addOperation(operation) | ||
operation.cancel() | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isCancelled) | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_ofBlockOperation_updatesIsCancelled_whenOperationIsRunning() { | ||
let queue = OperationQueue() | ||
let operation = BlockOperation { | ||
Thread.sleep(forTimeInterval: 0.2) | ||
} | ||
queue.addOperation(operation) | ||
Thread.sleep(forTimeInterval: 0.1) | ||
XCTAssertTrue(operation.isExecuting) | ||
operation.cancel() | ||
XCTAssertFalse(operation.isFinished) | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isCancelled) | ||
XCTAssertTrue(operation.isFinished) | ||
} | ||
|
||
func testCancellation_ofBlockOperation_ignoresCancellation_whenOperationIsFinished() { | ||
let queue = OperationQueue() | ||
let operation = BlockOperation { | ||
Thread.sleep(forTimeInterval: 0.1) | ||
} | ||
queue.addOperation(operation) | ||
queue.waitUntilAllOperationsAreFinished() | ||
XCTAssertTrue(operation.isFinished) | ||
operation.cancel() | ||
XCTAssertFalse(operation.isCancelled) | ||
} | ||
|
||
} |