From 1bc65e4b5f2b724b7739b2f5d0f6879df3e812a2 Mon Sep 17 00:00:00 2001 From: Joseph Earl Date: Wed, 15 Apr 2015 22:02:37 +0100 Subject: [PATCH] Fix and add tests for #87 --- Bolts/Common/BFTask.m | 14 +++++----- BoltsTests/TaskTests.m | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/Bolts/Common/BFTask.m b/Bolts/Common/BFTask.m index 681cba77d..ce75f271d 100644 --- a/Bolts/Common/BFTask.m +++ b/Bolts/Common/BFTask.m @@ -82,7 +82,7 @@ + (instancetype)taskForCompletionOfAllTasks:(NSArray *)tasks { if (total == 0) { return [BFTask taskWithResult:nil]; } - + __block int32_t cancelled = 0; NSObject *lock = [[NSObject alloc] init]; NSMutableArray *errors = [NSMutableArray array]; @@ -91,9 +91,7 @@ + (instancetype)taskForCompletionOfAllTasks:(NSArray *)tasks { BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; for (BFTask *task in tasks) { [task continueWithBlock:^id(BFTask *task) { - if (task.cancelled) { - OSAtomicIncrement32(&cancelled); - } else if (task.exception) { + if (task.exception) { @synchronized (lock) { [exceptions addObject:task.exception]; } @@ -101,12 +99,12 @@ + (instancetype)taskForCompletionOfAllTasks:(NSArray *)tasks { @synchronized (lock) { [errors addObject:task.error]; } + } else if (task.cancelled) { + OSAtomicIncrement32(&cancelled); } if (OSAtomicDecrement32(&total) == 0) { - if (cancelled > 0) { - [tcs cancel]; - } else if (exceptions.count > 0) { + if (exceptions.count > 0) { if (exceptions.count == 1) { tcs.exception = [exceptions objectAtIndex:0]; } else { @@ -125,6 +123,8 @@ + (instancetype)taskForCompletionOfAllTasks:(NSArray *)tasks { userInfo:@{ @"errors": errors }]; tcs.error = error; } + } else if (cancelled > 0) { + [tcs cancel]; } else { tcs.result = nil; } diff --git a/BoltsTests/TaskTests.m b/BoltsTests/TaskTests.m index bf0ad5726..76295bf80 100644 --- a/BoltsTests/TaskTests.m +++ b/BoltsTests/TaskTests.m @@ -467,6 +467,69 @@ - (void)testTaskForCompletionOfAllTasksWithResultsSuccess { }] waitUntilFinished]; } +- (void)testTaskForCompletionOfAllTasksErrorCancelledSuccess { + BFTask *errorTask = [BFTask taskWithError:[NSError new]]; + BFTask *cancelledTask = [BFTask cancelledTask]; + BFTask *successfulTask = [BFTask taskWithResult:[NSNumber numberWithInt:2]]; + + BFTask *allTasks = [BFTask taskForCompletionOfAllTasks:@[successfulTask, cancelledTask, errorTask]]; + + XCTAssertTrue(allTasks.faulted, @"Task should be faulted"); +} + +- (void)testTaskForCompletionOfAllTasksExceptionCancelledSuccess { + NSException *exception = [NSException exceptionWithName:@"" reason:@"" userInfo:nil]; + BFTask *exceptionTask = [BFTask taskWithException:exception]; + BFTask *cancelledTask = [BFTask cancelledTask]; + BFTask *successfulTask = [BFTask taskWithResult:[NSNumber numberWithInt:2]]; + + BFTask *allTasks = [BFTask taskForCompletionOfAllTasks:@[successfulTask, cancelledTask, exceptionTask]]; + + XCTAssertTrue(allTasks.faulted, @"Task should be faulted"); + XCTAssertNil(allTasks.error, @"Task shoud not have error"); + XCTAssertNotNil(allTasks.exception, @"Task should have exception"); +} + +- (void)testTaskForCompletionOfAllTasksExceptionErrorCancelledSuccess { + BFTask *errorTask = [BFTask taskWithError:[NSError new]]; + BFTask *exceptionTask = [BFTask taskWithException:[NSException new]]; + BFTask *cancelledTask = [BFTask cancelledTask]; + BFTask *successfulTask = [BFTask taskWithResult:[NSNumber numberWithInt:2]]; + + BFTask *allTasks = [BFTask taskForCompletionOfAllTasks:@[successfulTask, cancelledTask, exceptionTask, errorTask]]; + + XCTAssertTrue(allTasks.faulted, @"Task should be faulted"); + XCTAssertNotNil(allTasks.error, @"Task should have error"); + XCTAssertNil(allTasks.exception, @"Task should not have exception"); +} + +- (void)testTaskForCompletionOfAllTasksErrorCancelled { + BFTask *errorTask = [BFTask taskWithError:[NSError new]]; + BFTask *cancelledTask = [BFTask cancelledTask]; + + BFTask *allTasks = [BFTask taskForCompletionOfAllTasks:@[cancelledTask, errorTask]]; + + XCTAssertTrue(allTasks.faulted, @"Task should be faulted"); +} + +- (void)testTaskForCompletionOfAllTasksSuccessCancelled { + BFTask *cancelledTask = [BFTask cancelledTask]; + BFTask *successfulTask = [BFTask taskWithResult:[NSNumber numberWithInt:2]]; + + BFTask *allTasks = [BFTask taskForCompletionOfAllTasks:@[successfulTask, cancelledTask]]; + + XCTAssertTrue(allTasks.cancelled, @"Task should be cancelled"); +} + +- (void)testTaskForCompletionOfAllTasksSuccessError { + BFTask *errorTask = [BFTask taskWithError:[NSError new]]; + BFTask *successfulTask = [BFTask taskWithResult:[NSNumber numberWithInt:2]]; + + BFTask *allTasks = [BFTask taskForCompletionOfAllTasks:@[successfulTask, errorTask]]; + + XCTAssertTrue(allTasks.faulted, @"Task should be faulted"); +} + - (void)testTaskForCompletionOfAllTasksWithResultsNoTasksImmediateCompletion { NSMutableArray *tasks = [NSMutableArray array];