Skip to content

Commit

Permalink
Merge pull request #33 from wileykestner/add_values_to_errors_for_joi…
Browse files Browse the repository at this point in the history
…ned_promises

Add values to errors for joined promises
  • Loading branch information
kseebaldt committed Apr 12, 2015
2 parents 8075cca + 5ddfcdb commit 4d5e124
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
4 changes: 4 additions & 0 deletions Deferred/KSPromise.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ typedef id(^promiseValueCallback)(id value);
typedef id(^promiseErrorCallback)(NSError *error);
typedef void(^deferredCallback)(KSPromise *p);

FOUNDATION_EXPORT NSString *const KSPromiseWhenErrorDomain;
FOUNDATION_EXPORT NSString *const KSPromiseWhenErrorErrorsKey;
FOUNDATION_EXPORT NSString *const KSPromiseWhenErrorValuesKey;

@interface KSPromise : NSObject<KSCancellable>
@property (strong, nonatomic, readonly) id value;
@property (strong, nonatomic, readonly) NSError *error;
Expand Down
16 changes: 15 additions & 1 deletion Deferred/KSPromise.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
# define KS_DISPATCH_RELEASE(q)
#endif


@interface KSPromiseCallbacks : NSObject

@property (copy, nonatomic) promiseValueCallback fulfilledCallback;
@property (copy, nonatomic) promiseErrorCallback errorCallback;

Expand All @@ -24,8 +26,15 @@ @interface KSPromiseCallbacks : NSObject
@property (copy, nonatomic) deferredCallback deprecatedCompleteCallback;

@property (strong, nonatomic) KSPromise *childPromise;

@end


NSString *const KSPromiseWhenErrorDomain = @"KSPromiseJoinError";
NSString *const KSPromiseWhenErrorErrorsKey = @"KSPromiseWhenErrorErrorsKey";
NSString *const KSPromiseWhenErrorValuesKey = @"KSPromiseWhenErrorValuesKey";


@implementation KSPromiseCallbacks

- (id)initWithFulfilledCallback:(promiseValueCallback)fulfilledCallback
Expand Down Expand Up @@ -274,7 +283,12 @@ - (void)joinedPromiseFulfilled:(KSPromise *)promise {
}
if (fulfilled) {
if (errors.count > 0) {
[self rejectWithError:[NSError errorWithDomain:@"KSPromiseJoinError" code:1 userInfo:[NSDictionary dictionaryWithObject:errors forKey:@"errors"]]];
NSDictionary *userInfo = @{KSPromiseWhenErrorErrorsKey: errors,
KSPromiseWhenErrorValuesKey: values};
NSError *whenError = [NSError errorWithDomain:KSPromiseWhenErrorDomain
code:1
userInfo:userInfo];
[self rejectWithError:whenError];
} else {
[self resolveWithValue:values];
}
Expand Down
31 changes: 19 additions & 12 deletions Specs/KSDeferredSpec.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
}];
});

describe(@"when the first promise is resolved", ^{
context(@"when the first promise is resolved", ^{
beforeEach(^{
[deferred resolveWithValue:@"SUCCESS1"];
});
Expand All @@ -59,7 +59,7 @@
rejected should_not be_truthy;
});

describe(@"when both promises are resolved", ^{
context(@"when both promises are resolved", ^{
beforeEach(^{
[deferred2 resolveWithValue:@"SUCCESS2"];
});
Expand All @@ -74,7 +74,7 @@
});
});

describe(@"when both promises are resolved, one without a value", ^{
context(@"when both promises are resolved, one without a value", ^{
beforeEach(^{
[deferred2 resolveWithValue:nil];
});
Expand All @@ -84,7 +84,7 @@
});
});

describe(@"when a promise is rejected and all joined promises have been fulfilled", ^{
context(@"when a promise is rejected and all joined promises have been fulfilled", ^{
beforeEach(^{
[deferred2 rejectWithError:[NSError errorWithDomain:@"MyError" code:123 userInfo:nil]];
});
Expand All @@ -93,21 +93,28 @@
rejected should be_truthy;
});

it(@"should be able to read the resolved values of the joined promises", ^{
joinedPromise.error.domain should equal(@"KSPromiseJoinError");
NSArray *errors = [joinedPromise.error.userInfo objectForKey:@"errors"];
it(@"should be able to read the rejected errors of the joined promises", ^{
joinedPromise.error.domain should equal(KSPromiseWhenErrorDomain);
NSArray *errors = [joinedPromise.error.userInfo objectForKey:KSPromiseWhenErrorErrorsKey];
errors.count should equal(1);
[[errors lastObject] domain] should equal(@"MyError");
});

it(@"should be able to read the resolved values of the joined promises", ^{
joinedPromise.error.domain should equal(KSPromiseWhenErrorDomain);
NSArray *values = [joinedPromise.error.userInfo objectForKey:KSPromiseWhenErrorValuesKey];
values.count should equal(1);
values.lastObject should equal(@"SUCCESS1");
});
});

describe(@"when a promise is rejected without an error and all joined promises have been fulfilled", ^{
context(@"when a promise is rejected without an error and all joined promises have been fulfilled", ^{
beforeEach(^{
[deferred2 rejectWithError:nil];
});

it(@"should insert a null object into the joined promises error list", ^{
NSArray *errors = joinedPromise.error.userInfo[@"errors"];
NSArray *errors = joinedPromise.error.userInfo[KSPromiseWhenErrorErrorsKey];
[errors lastObject] should equal([NSNull null]);
});
});
Expand All @@ -117,7 +124,7 @@
});
});

describe(@"when the first promise is rejected", ^{
context(@"when the first promise is rejected", ^{
beforeEach(^{
[deferred2 rejectWithError:[NSError errorWithDomain:@"MyError" code:123 userInfo:nil]];
});
Expand All @@ -133,7 +140,7 @@
});
});

describe(@"when the first promise is resolved before joined", ^{
context(@"when the first promise is resolved before joined", ^{
beforeEach(^{
[deferred resolveWithValue:@"SUCCESS1"];
joinedPromise = [KSPromise when:[NSArray arrayWithObjects:promise, promise2, nil]];
Expand All @@ -155,7 +162,7 @@
});
});

describe(@"when the first promise is rejected before joined", ^{
context(@"when the first promise is rejected before joined", ^{
beforeEach(^{
[deferred rejectWithError:[NSError errorWithDomain:@"MyError" code:123 userInfo:nil]];
joinedPromise = [KSPromise when:[NSArray arrayWithObjects:promise, promise2, nil]];
Expand Down

0 comments on commit 4d5e124

Please sign in to comment.