diff --git a/PromisesObjC.podspec b/PromisesObjC.podspec index a0de852..0abd7f1 100644 --- a/PromisesObjC.podspec +++ b/PromisesObjC.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'PromisesObjC' - s.version = '1.0.0' + s.version = '1.0.1' s.authors = 'Google Inc.' s.license = { :type => 'Apache', :file => 'LICENSE' } s.homepage = 'https://github.com/google/promises' @@ -20,8 +20,7 @@ Pod::Spec.new do |s| s.prefix_header_file = false s.header_mappings_dir = "Sources/#{s.module_name}/include/" s.public_header_files = "Sources/#{s.module_name}/include/**/*.h" - s.private_header_files = "Sources/#{s.module_name}/include/FBLPromiseErrorPrivate.h", - "Sources/#{s.module_name}/include/FBLPromisePrivate.h" + s.private_header_files = "Sources/#{s.module_name}/include/FBLPromisePrivate.h" s.source_files = "Sources/#{s.module_name}/**/*.{h,m}" s.xcconfig = { 'HEADER_SEARCH_PATHS' => "\"${PODS_TARGET_SRCROOT}/Sources/#{s.module_name}/include\"" diff --git a/Sources/FBLPromises/FBLPromise+Async.m b/Sources/FBLPromises/FBLPromise+Async.m index 63bb05f..6a64190 100644 --- a/Sources/FBLPromises/FBLPromise+Async.m +++ b/Sources/FBLPromises/FBLPromise+Async.m @@ -29,17 +29,13 @@ + (instancetype)onQueue:(dispatch_queue_t)queue async:(FBLPromiseAsyncWorkBlock) FBLPromise *promise = [[[self class] alloc] initPending]; dispatch_group_async([self class].dispatchGroup, queue, ^{ - @try { - work( - ^(id __nullable value) { - [promise fulfill:value]; - }, - ^(NSError *error) { - [promise reject:error]; - }); - } @catch (id exception) { - [promise reject:exception]; - } + work( + ^(id __nullable value) { + [promise fulfill:value]; + }, + ^(NSError *error) { + [promise reject:error]; + }); }); return promise; } diff --git a/Sources/FBLPromises/FBLPromise+Do.m b/Sources/FBLPromises/FBLPromise+Do.m index 7133c28..2c45924 100644 --- a/Sources/FBLPromises/FBLPromise+Do.m +++ b/Sources/FBLPromises/FBLPromise+Do.m @@ -29,11 +29,7 @@ + (instancetype)onQueue:(dispatch_queue_t)queue do:(FBLPromiseDoWorkBlock)work { FBLPromise *promise = [[[self class] alloc] initPending]; dispatch_group_async([self class].dispatchGroup, queue, ^{ - @try { - [promise fulfill:work()]; - } @catch (id exception) { - [promise reject:exception]; - } + [promise fulfill:work()]; }); return promise; } diff --git a/Sources/FBLPromises/FBLPromise.m b/Sources/FBLPromises/FBLPromise.m index a43a087..7aac9a1 100644 --- a/Sources/FBLPromises/FBLPromise.m +++ b/Sources/FBLPromises/FBLPromise.m @@ -16,8 +16,6 @@ #import "FBLPromisePrivate.h" -#import "FBLPromiseErrorPrivate.h" - /** All states a promise can be in. */ typedef NS_ENUM(NSInteger, FBLPromiseState) { FBLPromiseStatePending = 0, @@ -68,8 +66,6 @@ - (void)fulfill:(nullable id)value { }]; } else if ([value isKindOfClass:[NSError class]]) { [self reject:(NSError *)value]; - } else if ([value isKindOfClass:[NSException class]]) { - [self reject:FBLNSErrorFromNSException((NSException *)value)]; } else { @synchronized(self) { if (_state == FBLPromiseStatePending) { @@ -87,9 +83,6 @@ - (void)fulfill:(nullable id)value { } - (void)reject:(NSError *)error { - if ([error isKindOfClass:[NSException class]]) { - error = FBLNSErrorFromNSException((NSException *)error); - } NSAssert([error isKindOfClass:[NSError class]], @"Invalid error type."); if (![error isKindOfClass:[NSError class]]) { @@ -149,9 +142,6 @@ - (instancetype)initWithResolution:(nullable id)resolution { } else if ([resolution isKindOfClass:[NSError class]]) { _state = FBLPromiseStateRejected; _error = (NSError *)resolution; - } else if ([resolution isKindOfClass:[NSException class]]) { - _state = FBLPromiseStateRejected; - _error = FBLNSErrorFromNSException((NSException *)resolution); } else { _state = FBLPromiseStateFulfilled; _value = resolution; @@ -253,35 +243,13 @@ - (FBLPromise *)chainOnQueue:(dispatch_queue_t)queue chainedFulfill:(FBLPromiseChainedFulfillBlock)chainedFulfill chainedReject:(FBLPromiseChainedRejectBlock)chainedReject { FBLPromise *promise = [[[self class] alloc] initPending]; - FBLPromiseOnFulfillBlock onFulfill; - if (chainedFulfill) { - onFulfill = ^(id __nullable value) { - @try { - [promise fulfill:chainedFulfill(value)]; - } @catch (id exception) { - [promise reject:exception]; - } - }; - } else { - onFulfill = ^(id __nullable value) { - [promise fulfill:value]; - }; - } - FBLPromiseOnRejectBlock onReject; - if (chainedReject) { - onReject = ^(NSError *error) { - @try { - [promise fulfill:chainedReject(error)]; - } @catch (id exception) { - [promise reject:exception]; + [self observeOnQueue:queue + fulfill:^(id __nullable value) { + [promise fulfill:chainedFulfill ? chainedFulfill(value) : value]; } - }; - } else { - onReject = ^(NSError *error) { - [promise reject:error]; - }; - } - [self observeOnQueue:queue fulfill:onFulfill reject:onReject]; + reject:^(NSError *error) { + [promise fulfill:chainedReject ? chainedReject(error) : error]; + }]; return promise; } diff --git a/Sources/FBLPromises/FBLPromiseError.m b/Sources/FBLPromises/FBLPromiseError.m index 7326037..2266b65 100644 --- a/Sources/FBLPromises/FBLPromiseError.m +++ b/Sources/FBLPromises/FBLPromiseError.m @@ -14,23 +14,6 @@ limitations under the License. */ -#import "FBLPromiseErrorPrivate.h" +#import "FBLPromiseError.h" NSString *const FBLPromiseErrorDomain = @"com.google.FBLPromises.Error"; -NSString *const FBLPromiseErrorUserInfoExceptionNameKey = @"NSExceptionName"; -NSString *const FBLPromiseErrorUserInfoExceptionReasonKey = @"NSExceptionReason"; -NSString *const FBLPromiseErrorUserInfoExceptionUserInfoKey = @"NSExceptionUserInfo"; -NSString *const FBLPromiseErrorUserInfoExceptionReturnAddressesKey = @"NSExceptionReturnAddresses"; -NSString *const FBLPromiseErrorUserInfoExceptionCallStackKey = @"NSExceptionCallStack"; - -NSError *FBLNSErrorFromNSException(NSException *exception) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - userInfo[FBLPromiseErrorUserInfoExceptionNameKey] = exception.name; - userInfo[FBLPromiseErrorUserInfoExceptionReasonKey] = exception.reason; - userInfo[FBLPromiseErrorUserInfoExceptionUserInfoKey] = exception.userInfo; - userInfo[FBLPromiseErrorUserInfoExceptionReturnAddressesKey] = exception.callStackReturnAddresses; - userInfo[FBLPromiseErrorUserInfoExceptionCallStackKey] = exception.callStackSymbols; - return [[NSError alloc] initWithDomain:FBLPromiseErrorDomain - code:FBLPromiseErrorCodeException - userInfo:userInfo]; -} diff --git a/Sources/FBLPromises/include/FBLPromiseError.h b/Sources/FBLPromises/include/FBLPromiseError.h index a4f515e..83c0b3f 100644 --- a/Sources/FBLPromises/include/FBLPromiseError.h +++ b/Sources/FBLPromises/include/FBLPromiseError.h @@ -22,19 +22,12 @@ NS_ASSUME_NONNULL_BEGIN Possible error codes in `FBLPromiseErrorDomain`. */ typedef NS_ENUM(NSInteger, FBLPromiseErrorCode) { - /** Objective-C exception was thrown. */ - FBLPromiseErrorCodeException = 1, /** Promise failed to resolve in time. */ - FBLPromiseErrorCodeTimedOut = 2, + FBLPromiseErrorCodeTimedOut = 1, /** Validation predicate returned false. */ - FBLPromiseErrorCodeValidationFailure = 3, + FBLPromiseErrorCodeValidationFailure = 2, } NS_REFINED_FOR_SWIFT; extern NSString* const FBLPromiseErrorDomain NS_REFINED_FOR_SWIFT; -extern NSString* const FBLPromiseErrorUserInfoExceptionNameKey NS_REFINED_FOR_SWIFT; -extern NSString* const FBLPromiseErrorUserInfoExceptionReasonKey NS_REFINED_FOR_SWIFT; -extern NSString* const FBLPromiseErrorUserInfoExceptionUserInfoKey NS_REFINED_FOR_SWIFT; -extern NSString* const FBLPromiseErrorUserInfoExceptionReturnAddressesKey NS_REFINED_FOR_SWIFT; -extern NSString* const FBLPromiseErrorUserInfoExceptionCallStackKey NS_REFINED_FOR_SWIFT; NS_ASSUME_NONNULL_END diff --git a/Sources/FBLPromises/include/FBLPromiseErrorPrivate.h b/Sources/FBLPromises/include/FBLPromiseErrorPrivate.h deleted file mode 100644 index e2e0e82..0000000 --- a/Sources/FBLPromises/include/FBLPromiseErrorPrivate.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - Copyright 2018 Google Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at: - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -#import "FBLPromiseError.h" - -NS_ASSUME_NONNULL_BEGIN - -FOUNDATION_EXPORT NSError *FBLNSErrorFromNSException(NSException *exception) - NS_SWIFT_UNAVAILABLE(""); - -NS_ASSUME_NONNULL_END diff --git a/Sources/FBLPromises/include/module.modulemap b/Sources/FBLPromises/include/module.modulemap index be02a3a..b70ece7 100644 --- a/Sources/FBLPromises/include/module.modulemap +++ b/Sources/FBLPromises/include/module.modulemap @@ -31,6 +31,5 @@ module FBLPromises { header "DotSyntax/FBLPromise+DotSyntax+Validate.h" header "DotSyntax/FBLPromise+DotSyntax+When.h" - exclude header "FBLPromiseErrorPrivate.h" exclude header "FBLPromisePrivate.h" } diff --git a/Sources/FBLPromisesTestHelpers/FBLPromisesTestInteroperability.m b/Sources/FBLPromisesTestHelpers/FBLPromisesTestInteroperability.m index 4ae3186..c5fda8a 100644 --- a/Sources/FBLPromisesTestHelpers/FBLPromisesTestInteroperability.m +++ b/Sources/FBLPromisesTestHelpers/FBLPromisesTestInteroperability.m @@ -37,14 +37,6 @@ + (FBLPromise *)rejectWithError:(NSError *)error delay:(NSTimeInterval)delay { return [self promiseWithValue:nil error:error delay:delay]; } -+ (FBLPromise *)rejectWithException:(NSException *)exception { - return [self rejectWithException:exception delay:0.0]; -} - -+ (FBLPromise *)rejectWithException:(NSException *)exception delay:(NSTimeInterval)delay { - return [self promiseThrowException:exception delay:delay]; -} - #pragma mark - Private /** @@ -65,13 +57,4 @@ + (FBLPromise *)promiseWithValue:(nullable id)value }]; } -+ (FBLPromise *)promiseThrowException:(NSException *__nullable)exception - delay:(NSTimeInterval)delay { - return [FBLPromise async:^(FBLPromiseFulfillBlock __unused _, FBLPromiseRejectBlock __unused __) { - // Can't use asynchronous FBLDelay because the exception will be caught by GCD in that case. - [NSThread sleepForTimeInterval:delay]; - @throw exception; // NOLINT - }]; -} - @end diff --git a/Sources/FBLPromisesTestHelpers/include/FBLPromisesTestInteroperability.h b/Sources/FBLPromisesTestHelpers/include/FBLPromisesTestInteroperability.h index f220733..7eafdf9 100644 --- a/Sources/FBLPromisesTestHelpers/include/FBLPromisesTestInteroperability.h +++ b/Sources/FBLPromisesTestHelpers/include/FBLPromisesTestInteroperability.h @@ -28,9 +28,6 @@ NS_ASSUME_NONNULL_BEGIN + (FBLPromise *)rejectWithError:(NSError *)error NS_SWIFT_UNAVAILABLE(""); + (FBLPromise *)rejectWithError:(NSError *)error delay:(NSTimeInterval)delay NS_SWIFT_NAME(reject(_:delay:)); -+ (FBLPromise *)rejectWithException:(NSException *)exception NS_SWIFT_UNAVAILABLE(""); -+ (FBLPromise *)rejectWithException:(NSException *)exception - delay:(NSTimeInterval)delay NS_SWIFT_NAME(reject(_:delay:)); @end diff --git a/Sources/Promises/PromiseError.swift b/Sources/Promises/PromiseError.swift index 92754ed..37f0d04 100644 --- a/Sources/Promises/PromiseError.swift +++ b/Sources/Promises/PromiseError.swift @@ -18,29 +18,16 @@ import FBLPromises /// Indirectly conforms to `Swift.Error` through conformance to `Swift.CustomNSError` below. /// Not placing it under extension `Promise` for convenience to avoid collisions with `Swift.Error`. public enum PromiseError { - case nsException(NSExceptionName, String?, [AnyHashable: Any]?, [NSNumber], [String]) case timedOut case validationFailure } -/// Downcasting from `Swift.Error` and `NSException`. +/// Downcasting from `Swift.Error`. extension PromiseError { public init?(_ error: Error) { let error = error as NSError if error.domain != __FBLPromiseErrorDomain { return nil } switch error.code { - case __FBLPromiseErrorCode.exception.rawValue: - let errorUserInfo = error.userInfo - guard let name = errorUserInfo[__FBLPromiseErrorUserInfoExceptionNameKey] as? NSExceptionName, - let returnAddresses: [NSNumber] = - errorUserInfo[__FBLPromiseErrorUserInfoExceptionReturnAddressesKey] as? [NSNumber], - let callStack: [String] = - errorUserInfo[__FBLPromiseErrorUserInfoExceptionCallStackKey] as? [String] - else { return nil } - let reason = errorUserInfo[__FBLPromiseErrorUserInfoExceptionReasonKey] as? String - let userInfo = - errorUserInfo[__FBLPromiseErrorUserInfoExceptionUserInfoKey] as? [AnyHashable: Any] - self = .nsException(name, reason, userInfo, returnAddresses, callStack) case __FBLPromiseErrorCode.timedOut.rawValue: self = .timedOut case __FBLPromiseErrorCode.validationFailure.rawValue: @@ -49,14 +36,6 @@ extension PromiseError { return nil } } - - public init?(_ nsException: NSException) { - self = .nsException(nsException.name, - nsException.reason, - nsException.userInfo, - nsException.callStackReturnAddresses, - nsException.callStackSymbols) - } } extension PromiseError: CustomNSError { @@ -66,8 +45,6 @@ extension PromiseError: CustomNSError { public var errorCode: Int { switch self { - case .nsException: - return __FBLPromiseErrorCode.exception.rawValue case .timedOut: return __FBLPromiseErrorCode.timedOut.rawValue case .validationFailure: @@ -76,21 +53,6 @@ extension PromiseError: CustomNSError { } public var errorUserInfo: [String: Any] { - if case let .nsException(name, reason, userInfo, returnAddresses, callStack) = self { - return [ - __FBLPromiseErrorUserInfoExceptionNameKey: name, - __FBLPromiseErrorUserInfoExceptionReasonKey: reason as Any, - __FBLPromiseErrorUserInfoExceptionUserInfoKey: userInfo as Any, - __FBLPromiseErrorUserInfoExceptionReturnAddressesKey: returnAddresses, - __FBLPromiseErrorUserInfoExceptionCallStackKey: callStack - ] - } return [String: Any]() } } - -extension PromiseError: Equatable { - public static func == (lhs: PromiseError, rhs: PromiseError) -> Bool { - return (lhs as NSError).isEqual(rhs as NSError) - } -} diff --git a/Tests/FBLPromisesTests/FBLPromise+AsyncTests.m b/Tests/FBLPromisesTests/FBLPromise+AsyncTests.m index c9ec395..1c30440 100644 --- a/Tests/FBLPromisesTests/FBLPromise+AsyncTests.m +++ b/Tests/FBLPromisesTests/FBLPromise+AsyncTests.m @@ -54,22 +54,6 @@ - (void)testPromiseAsyncReject { XCTAssertNil(promise.value); } -- (void)testPromiseAsyncThrow { - // Arrange & Act. - FBLPromise *promise = - [FBLPromise async:^(FBLPromiseFulfillBlock __unused _, FBLPromiseRejectBlock __unused __) { - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT - }]; - - // Assert. - XCTAssert(FBLWaitForPromisesWithTimeout(10)); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - /** Promise created with `async` should not deallocate until it gets resolved. */ diff --git a/Tests/FBLPromisesTests/FBLPromise+CatchTests.m b/Tests/FBLPromisesTests/FBLPromise+CatchTests.m index 28267c9..4d0bc45 100644 --- a/Tests/FBLPromisesTests/FBLPromise+CatchTests.m +++ b/Tests/FBLPromisesTests/FBLPromise+CatchTests.m @@ -143,68 +143,12 @@ - (void)testPromiseCallsSubsequentCatchAfterAsyncReject { XCTAssertNil(promise.value); } -- (void)testPromiseCatchesThrownException { - // Act. - FBLPromise *promise = [[[[[FBLPromise do:^id { - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT - }] then:^id(id __unused _) { - XCTFail(); - return nil; - }] then:^id(id __unused _) { - XCTFail(); - return nil; - }] then:^id(id __unused _) { - XCTFail(); - return nil; - }] catch:^(NSError *error) { - XCTAssertEqualObjects(error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(error.code, FBLPromiseErrorCodeException); - }]; - - // Assert. - XCTAssert(FBLWaitForPromisesWithTimeout(10)); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - -- (void)testPromiseCatchesThrownExceptionFromAsync { - // Act. - FBLPromise *promise = [ - [[[[FBLPromise async:^(FBLPromiseFulfillBlock __unused _, FBLPromiseRejectBlock __unused __) { - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT - }] then:^id(id __unused _) { - XCTFail(); - return nil; - }] then:^id(id __unused _) { - XCTFail(); - return nil; - }] then:^id(id __unused _) { - XCTFail(); - return nil; - }] catch:^(NSError *error) { - XCTAssertEqualObjects(error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(error.code, FBLPromiseErrorCodeException); - }]; - - // Assert. - XCTAssert(FBLWaitForPromisesWithTimeout(10)); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - - (void)testPromiseNoRejectAfterFulfill { // Act. FBLPromise *promise = [[[[FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { fulfill(@42); reject([NSError errorWithDomain:FBLPromiseErrorDomain code:42 userInfo:nil]); - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT }] then:^id(NSNumber *value) { XCTAssertEqualObjects(value, @42); return value; @@ -227,7 +171,6 @@ - (void)testPromiseNoFulfillAfterReject { [[[[[FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock reject) { reject([NSError errorWithDomain:FBLPromiseErrorDomain code:42 userInfo:nil]); fulfill(@42); - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT }] then:^id(id __unused _) { XCTFail(); return nil; diff --git a/Tests/FBLPromisesTests/FBLPromise+DoTests.m b/Tests/FBLPromisesTests/FBLPromise+DoTests.m index 1002c78..d08737a 100644 --- a/Tests/FBLPromisesTests/FBLPromise+DoTests.m +++ b/Tests/FBLPromisesTests/FBLPromise+DoTests.m @@ -52,21 +52,6 @@ - (void)testPromiseDoReject { XCTAssertNil(promise.value); } -- (void)testPromiseDoThrow { - // Arrange & Act. - FBLPromise *promise = [FBLPromise do:^id { - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT - }]; - - // Assert. - XCTAssert(FBLWaitForPromisesWithTimeout(10)); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - /** Promise created with `do` should not deallocate until it gets resolved. */ diff --git a/Tests/FBLPromisesTests/FBLPromise+RecoverTests.m b/Tests/FBLPromisesTests/FBLPromise+RecoverTests.m index be8cc90..f35af3f 100644 --- a/Tests/FBLPromisesTests/FBLPromise+RecoverTests.m +++ b/Tests/FBLPromisesTests/FBLPromise+RecoverTests.m @@ -95,41 +95,6 @@ - (void)testPromiseValueRecover { XCTAssertNil(promise.error); } -- (void)testPromiseRecoverException { - // Arrange. - NSUInteger __block count = 0; - NSUInteger const expectedCount = 3; - - // Act. - FBLPromise *promise = - [[[[FBLPromise async:^(FBLPromiseFulfillBlock __unused _, FBLPromiseRejectBlock __unused __) { - @throw [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; // NOLINT - }] recover:^id(NSError *error) { - XCTAssertEqualObjects(error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(error.code, FBLPromiseErrorCodeException); - ++count; - return - [FBLPromise async:^(FBLPromiseFulfillBlock fulfill, FBLPromiseRejectBlock __unused _) { - FBLDelay(0.1, ^{ - ++count; - fulfill(@42); - }); - }]; - }] catch:^(NSError __unused *_) { - XCTFail(); - }] then:^id(NSNumber *value) { - XCTAssertEqualObjects(value, @42); - ++count; - return value; - }]; - - // Assert. - XCTAssert(FBLWaitForPromisesWithTimeout(10)); - XCTAssertEqual(count, expectedCount); - XCTAssertEqualObjects(promise.value, @42); - XCTAssertNil(promise.error); -} - - (void)testPromiseRejectRecover { // Arrange. NSUInteger __block count = 0; diff --git a/Tests/FBLPromisesTests/FBLPromiseTests.m b/Tests/FBLPromisesTests/FBLPromiseTests.m index e9f494a..f23a63c 100644 --- a/Tests/FBLPromisesTests/FBLPromiseTests.m +++ b/Tests/FBLPromisesTests/FBLPromiseTests.m @@ -73,28 +73,6 @@ - (void)testPromiseConstructorResolvedWithError { XCTAssertEqual(promise.error.code, 42); } -/** - New promise resolved with an NSException should have corresponding error set and not be pending or - have a value. - */ -- (void)testPromiseConstructorResolvedWithException { - // Arrange & Act. - NSException *exception = [NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]; - FBLPromise *promise = [FBLPromise resolvedWith:exception]; - - // Assert. - XCTAssertFalse(promise.isPending); - XCTAssertFalse(promise.isFulfilled); - XCTAssertTrue(promise.isRejected); - XCTAssertNil(promise.pendingObjects); - XCTAssertNil(promise.value); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - /** New promise resolved with another pending promise should have its value set to nil and not be pending or have an error. @@ -210,29 +188,6 @@ - (void)testPromiseFulfillWithError { XCTAssertEqual(promise.error.code, 42); } -/** - Fulfilling a pending promise with NSException should reject it. - */ -- (void)testPromiseFulfillWithException { - // Arrange. - FBLPromise *promise = [FBLPromise pendingPromise]; - - // Act. - [promise fulfill:[NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]]; - - // Assert. - XCTAssertFalse(promise.isPending); - XCTAssertFalse(promise.isFulfilled); - XCTAssertTrue(promise.isRejected); - XCTAssertNil(promise.pendingObjects); - XCTAssertNil(promise.value); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - /** Rejecting a pending promise should set its error and have no value. */ @@ -253,29 +208,6 @@ - (void)testPromiseReject { XCTAssertEqual(promise.error.code, 42); } -/** - Rejecting a pending promise should with NSException should reject it with a converted error. - */ -- (void)testPromiseRejectWithException { - // Arrange. - FBLPromise *promise = [FBLPromise pendingPromise]; - - // Act. - [promise reject:(id)[NSException exceptionWithName:@"name" reason:@"reason" userInfo:nil]]; - - // Assert. - XCTAssertFalse(promise.isPending); - XCTAssertFalse(promise.isFulfilled); - XCTAssertTrue(promise.isRejected); - XCTAssertNil(promise.pendingObjects); - XCTAssertNil(promise.value); - XCTAssertEqualObjects(promise.error.domain, FBLPromiseErrorDomain); - XCTAssertEqual(promise.error.code, FBLPromiseErrorCodeException); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionNameKey], @"name"); - XCTAssertEqualObjects(promise.error.userInfo[FBLPromiseErrorUserInfoExceptionReasonKey], - @"reason"); -} - /** Subsequent rejecting a pending promise has no effect. */ diff --git a/Tests/PromisesInteroperabilityTests/Promise+CatchInteroperabilityTests.swift b/Tests/PromisesInteroperabilityTests/Promise+CatchInteroperabilityTests.swift index 6a54161..0b33698 100644 --- a/Tests/PromisesInteroperabilityTests/Promise+CatchInteroperabilityTests.swift +++ b/Tests/PromisesInteroperabilityTests/Promise+CatchInteroperabilityTests.swift @@ -33,31 +33,4 @@ class PromiseCatchInteroperabilityTests: XCTestCase { XCTAssertTrue(promise.error == Test.Error.code42) XCTAssertNil(promise.value) } - - func testPromiseRejectNSException() { - // Arrange. - let nsException = NSException(name: .genericException, reason: "", userInfo: nil) - let expectedError = PromiseError(nsException) - - // Act. - let promise = Promise( - FBLPromisesTestInteroperabilityObjC.reject(nsException, delay: 0.1) - ) - promise.catch { error in - guard let error = PromiseError(error), - case let .nsException(name, reason, userInfo, _, _) = error else { XCTFail(); return } - let errorWithoutSpecifics = PromiseError.nsException(name, reason, userInfo, [], []) - XCTAssertEqual(errorWithoutSpecifics, expectedError) - } - - // Assert. - XCTAssert(waitForPromises(timeout: 10)) - XCTAssertTrue(promise.isRejected) - guard let promiseError = promise.error else { XCTFail(); return } - guard let error = PromiseError(promiseError), - case let .nsException(name, reason, userInfo, _, _) = error else { XCTFail(); return } - let errorWithoutSpecifics = PromiseError.nsException(name, reason, userInfo, [], []) - XCTAssertEqual(errorWithoutSpecifics, expectedError) - XCTAssertNil(promise.value) - } } diff --git a/g3doc/index.md b/g3doc/index.md index c62bfd4..604bb89 100644 --- a/g3doc/index.md +++ b/g3doc/index.md @@ -414,7 +414,7 @@ In your `Package.swift` file, add `Promises` dependency to corresponding targets let package = Package( // ... dependencies: [ - .package(url: "https://github.com/google/promises.git", from: "1.0.0"), + .package(url: "https://github.com/google/promises.git", from: "1.0.1"), ], // ... ) @@ -761,7 +761,7 @@ FBLPromise chainedStringPromise = [numberPromise then:^id(NSNumber * return [number stringValue]; }]; -// Return or @throw an error. +// Return an error. FBLPromise chainedStringPromise = [numberPromise then:^id(NSNumber *number) { return [NSError errorWithDomain:@"" code:0 userInfo:nil]; }]; @@ -885,12 +885,6 @@ You can reject a promise in many ways: Or, just [create a resolved promise](#create-a-resolved-promise) with an error. -Note: In Objective-C when `@throw` is invoked in `then` block with `NSException` -argument, the promise is rejected with `NSError` in `FBLPromiseErrorDomain` -domain with code `FBLPromiseErrorCodeException` and additional info about -`NSException` in `userInfo` dict. If `@throw` is invoked with `NSError` -argument, the promise is rejected with that error. - #### Catch `catch` operator expects one argument - a block, which has the error that the