BoltsTests/CancellationTests.m (118 lines of code) (raw):

/* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ @import XCTest; #import <Bolts/Bolts.h> @interface CancellationTests : XCTestCase @end @implementation CancellationTests - (void)testCancel { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; XCTAssertFalse(cts.cancellationRequested, @"Source should not be cancelled"); XCTAssertFalse(cts.token.cancellationRequested, @"Token should not be cancelled"); [cts cancel]; XCTAssertTrue(cts.cancellationRequested, @"Source should be cancelled"); XCTAssertTrue(cts.token.cancellationRequested, @"Token should be cancelled"); } - (void)testCancelMultipleTimes { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; XCTAssertFalse(cts.cancellationRequested); XCTAssertFalse(cts.token.cancellationRequested); [cts cancel]; XCTAssertTrue(cts.cancellationRequested); XCTAssertTrue(cts.token.cancellationRequested); [cts cancel]; XCTAssertTrue(cts.cancellationRequested); XCTAssertTrue(cts.token.cancellationRequested); } - (void)testCancellationBlock { __block BOOL cancelled = NO; BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; [cts.token registerCancellationObserverWithBlock:^{ cancelled = YES; }]; XCTAssertFalse(cts.cancellationRequested, @"Source should not be cancelled"); XCTAssertFalse(cts.token.cancellationRequested, @"Token should not be cancelled"); [cts cancel]; XCTAssertTrue(cancelled, @"Source should be cancelled"); } - (void)testCancellationAfterDelay { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; XCTAssertFalse(cts.cancellationRequested, @"Source should not be cancelled"); XCTAssertFalse(cts.token.cancellationRequested, @"Token should not be cancelled"); [cts cancelAfterDelay:200]; XCTAssertFalse(cts.cancellationRequested, @"Source should be cancelled"); XCTAssertFalse(cts.token.cancellationRequested, @"Token should be cancelled"); // Spin the run loop for half a second, since `delay` is in milliseconds, not seconds. [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]]; XCTAssertTrue(cts.cancellationRequested, @"Source should be cancelled"); XCTAssertTrue(cts.token.cancellationRequested, @"Token should be cancelled"); } - (void)testCancellationAfterDelayValidation { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; XCTAssertFalse(cts.cancellationRequested); XCTAssertFalse(cts.token.cancellationRequested); XCTAssertThrowsSpecificNamed([cts cancelAfterDelay:-2], NSException, NSInvalidArgumentException); } - (void)testCancellationAfterZeroDelay { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; XCTAssertFalse(cts.cancellationRequested); XCTAssertFalse(cts.token.cancellationRequested); [cts cancelAfterDelay:0]; XCTAssertTrue(cts.cancellationRequested); XCTAssertTrue(cts.token.cancellationRequested); } - (void)testCancellationAfterDelayOnCancelled { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; [cts cancel]; XCTAssertTrue(cts.cancellationRequested); XCTAssertTrue(cts.token.cancellationRequested); [cts cancelAfterDelay:1]; XCTAssertTrue(cts.cancellationRequested); XCTAssertTrue(cts.token.cancellationRequested); } - (void)testDispose { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; [cts dispose]; XCTAssertThrowsSpecificNamed([cts cancel], NSException, NSInternalInconsistencyException); XCTAssertThrowsSpecificNamed(cts.cancellationRequested, NSException, NSInternalInconsistencyException); XCTAssertThrowsSpecificNamed(cts.token.cancellationRequested, NSException, NSInternalInconsistencyException); cts = [BFCancellationTokenSource cancellationTokenSource]; [cts cancel]; XCTAssertTrue(cts.cancellationRequested, @"Source should be cancelled"); XCTAssertTrue(cts.token.cancellationRequested, @"Token should be cancelled"); [cts dispose]; XCTAssertThrowsSpecificNamed(cts.cancellationRequested, NSException, NSInternalInconsistencyException); XCTAssertThrowsSpecificNamed(cts.token.cancellationRequested, NSException, NSInternalInconsistencyException); } - (void)testDisposeMultipleTimes { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; [cts dispose]; XCTAssertNoThrow([cts dispose]); } - (void)testDisposeRegistration { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; BFCancellationTokenRegistration *registration = [cts.token registerCancellationObserverWithBlock:^{ XCTFail(); }]; XCTAssertNoThrow([registration dispose]); [cts cancel]; } - (void)testDisposeRegistrationMultipleTimes { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; BFCancellationTokenRegistration *registration = [cts.token registerCancellationObserverWithBlock:^{ XCTFail(); }]; XCTAssertNoThrow([registration dispose]); XCTAssertNoThrow([registration dispose]); [cts cancel]; } - (void)testDisposeRegistrationAfterCancellationToken { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; BFCancellationTokenRegistration *registration = [cts.token registerCancellationObserverWithBlock:^{ }]; [registration dispose]; [cts dispose]; } - (void)testDisposeRegistrationBeforeCancellationToken { BFCancellationTokenSource *cts = [BFCancellationTokenSource cancellationTokenSource]; BFCancellationTokenRegistration *registration = [cts.token registerCancellationObserverWithBlock:^{ }]; [cts dispose]; XCTAssertNoThrow([registration dispose]); } @end