mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
354 lines
9.3 KiB
Objective-C
354 lines
9.3 KiB
Objective-C
#import <XCTest/XCTest.h>
|
|
#import "TestUtil.h"
|
|
#import "FutureSource.h"
|
|
#import "Util.h"
|
|
|
|
@interface FutureSourceTest:XCTestCase
|
|
|
|
@end
|
|
|
|
@implementation FutureSourceTest
|
|
|
|
-(void) testConstructors {
|
|
FutureSource* inc = [FutureSource new];
|
|
test([inc isIncomplete]);
|
|
test(![inc hasSucceeded]);
|
|
test(![inc hasFailed]);
|
|
testThrows([inc forceGetResult]);
|
|
testThrows([inc forceGetFailure]);
|
|
|
|
FutureSource* done = [FutureSource finished:@1];
|
|
test(![done isIncomplete]);
|
|
test([done hasSucceeded]);
|
|
test(![done hasFailed]);
|
|
testDoesNotThrow([done forceGetResult]);
|
|
testThrows([done forceGetFailure]);
|
|
|
|
Future* done2 = [Future finished:@2];
|
|
test(![done2 isIncomplete]);
|
|
test([done2 hasSucceeded]);
|
|
test(![done2 hasFailed]);
|
|
testDoesNotThrow([done2 forceGetResult]);
|
|
testThrows([done2 forceGetFailure]);
|
|
|
|
FutureSource* fail3 = [FutureSource failed:@3];
|
|
test(![fail3 isIncomplete]);
|
|
test(![fail3 hasSucceeded]);
|
|
test([fail3 hasFailed]);
|
|
testThrows([fail3 forceGetResult]);
|
|
testDoesNotThrow([fail3 forceGetFailure]);
|
|
|
|
Future* fail4 = [Future failed:@4];
|
|
test(![fail4 isIncomplete]);
|
|
test(![fail4 hasSucceeded]);
|
|
test([fail4 hasFailed]);
|
|
testThrows([fail4 forceGetResult]);
|
|
testDoesNotThrow([fail4 forceGetFailure]);
|
|
}
|
|
-(void) testAutoUnwrap {
|
|
Future* f = [Future finished:[Future finished:[Future failed:@1]]];
|
|
test([f hasFailed]);
|
|
test([[f forceGetFailure] isEqual:@1]);
|
|
|
|
Future* f2 = [Future finished:[Future finished:[Future finished:@2]]];
|
|
test([f2 hasSucceeded]);
|
|
test([[f2 forceGetResult] isEqual:@2]);
|
|
|
|
test([[[[Future finished:@1] then:^id(id value) {
|
|
return [Future finished:@3];
|
|
}] forceGetResult] isEqual:@3]);
|
|
|
|
test([[[[Future failed:@1] catch:^id(id value) {
|
|
return [Future finished:@3];
|
|
}] forceGetResult] isEqual:@3]);
|
|
}
|
|
-(void) testTrySet {
|
|
FutureSource* setR = [FutureSource new];
|
|
FutureSource* setF = [FutureSource new];
|
|
FutureSource* setWR = [FutureSource new];
|
|
FutureSource* setWF = [FutureSource new];
|
|
FutureSource* wr = [FutureSource new];
|
|
FutureSource* wf = [FutureSource new];
|
|
|
|
// set result
|
|
test([setR trySetResult:@1]);
|
|
test([setR hasSucceeded]);
|
|
test(![setR trySetResult:@0]);
|
|
test(![setR trySetFailure:@0]);
|
|
test(![setR trySetResult:wr]);
|
|
test(![setR trySetResult:wf]);
|
|
test([[setR forceGetResult] isEqual:@1]);
|
|
|
|
// set fail
|
|
test([setF trySetFailure:@2]);
|
|
test([setF hasFailed]);
|
|
test(![setF trySetResult:@0]);
|
|
test(![setF trySetFailure:@0]);
|
|
test(![setF trySetResult:wr]);
|
|
test(![setF trySetResult:wf]);
|
|
test([[setF forceGetFailure] isEqual:@2]);
|
|
|
|
// wire result
|
|
test([setWR trySetResult:wr]);
|
|
test([setWR isIncomplete]);
|
|
test(![setWR trySetResult:@0]);
|
|
test(![setWR trySetFailure:@0]);
|
|
test(![setWR trySetResult:wf]);
|
|
test(![setWR trySetResult:wr]);
|
|
|
|
// wire failure
|
|
test([setWF trySetResult:wf]);
|
|
test([setWF isIncomplete]);
|
|
test(![setWF trySetResult:@0]);
|
|
test(![setWF trySetFailure:@0]);
|
|
test(![setWF trySetResult:wf]);
|
|
test(![setWF trySetResult:wr]);
|
|
|
|
// set result via wire
|
|
test([setWR isIncomplete]);
|
|
[wr trySetResult:@3];
|
|
test([setWR hasSucceeded]);
|
|
test([[setWR forceGetResult] isEqual:@3]);
|
|
|
|
// set failure via wire
|
|
test([setWF isIncomplete]);
|
|
[wf trySetFailure:@4];
|
|
test([setWF hasFailed]);
|
|
test([[setWF forceGetFailure] isEqual:@4]);
|
|
}
|
|
|
|
-(void) testThenDo_OnSuccess {
|
|
FutureSource* f = [FutureSource new];
|
|
__block int ready = 0;
|
|
|
|
// before completed, waits to run
|
|
[f thenDo:^(NSNumber* result) {
|
|
test(ready == 1);
|
|
ready = 2;
|
|
test([result isEqual:@1]);
|
|
}];
|
|
test(ready == 0);
|
|
|
|
ready = 1;
|
|
[f trySetResult:@1];
|
|
test(ready == 2);
|
|
|
|
// after completed, runs inline
|
|
[f thenDo:^(NSNumber* result) {
|
|
test(ready == 2);
|
|
ready = 3;
|
|
test([result isEqual:@1]);
|
|
}];
|
|
test(ready == 3);
|
|
}
|
|
-(void) testThenDo_OnFail {
|
|
FutureSource* f = [FutureSource new];
|
|
[f thenDo:^(NSNumber* result) {
|
|
test(false);
|
|
}];
|
|
[f trySetFailure:@1];
|
|
[f thenDo:^(NSNumber* result) {
|
|
test(false);
|
|
}];
|
|
}
|
|
|
|
-(void) testCatchDo_OnFail {
|
|
FutureSource* f = [FutureSource new];
|
|
__block int ready = 0;
|
|
|
|
// before completed, waits to run
|
|
[f catchDo:^(NSNumber* result) {
|
|
test(ready == 1);
|
|
ready = 2;
|
|
test([result isEqual:@1]);
|
|
}];
|
|
test(ready == 0);
|
|
|
|
ready = 1;
|
|
[f trySetFailure:@1];
|
|
test(ready == 2);
|
|
|
|
// after completed, runs inline
|
|
[f catchDo:^(NSNumber* result) {
|
|
test(ready == 2);
|
|
ready = 3;
|
|
test([result isEqual:@1]);
|
|
}];
|
|
test(ready == 3);
|
|
}
|
|
-(void) testCatchDo_OnSuccess {
|
|
FutureSource* f = [FutureSource new];
|
|
[f catchDo:^(NSNumber* result) {
|
|
test(false);
|
|
}];
|
|
[f trySetResult:@1];
|
|
[f catchDo:^(NSNumber* result) {
|
|
test(false);
|
|
}];
|
|
}
|
|
|
|
-(void) testThenOrCatchDo_OnSuccess {
|
|
FutureSource* f = [FutureSource new];
|
|
__block int ready = 0;
|
|
|
|
// before completed, waits to run
|
|
[f finallyDo:^(Future* completed) {
|
|
test(ready == 1);
|
|
ready = 2;
|
|
test([[completed forceGetResult] isEqual:@1]);
|
|
}];
|
|
test(ready == 0);
|
|
|
|
ready = 1;
|
|
[f trySetResult:@1];
|
|
test(ready == 2);
|
|
|
|
// after completed, runs inline
|
|
[f finallyDo:^(Future* completed) {
|
|
test(ready == 2);
|
|
ready = 3;
|
|
test([[completed forceGetResult] isEqual:@1]);
|
|
}];
|
|
test(ready == 3);
|
|
}
|
|
-(void) testThenOrCatchDo_OnFail {
|
|
FutureSource* f = [FutureSource new];
|
|
__block int ready = 0;
|
|
|
|
// before completed, waits to run
|
|
[f finallyDo:^(Future* completed) {
|
|
test(ready == 1);
|
|
ready = 2;
|
|
test([[completed forceGetResult] isEqual:@1]);
|
|
}];
|
|
test(ready == 0);
|
|
|
|
ready = 1;
|
|
[f trySetResult:@1];
|
|
test(ready == 2);
|
|
|
|
// after completed, runs inline
|
|
[f finallyDo:^(Future* completed) {
|
|
test(ready == 2);
|
|
ready = 3;
|
|
test([[completed forceGetResult] isEqual:@1]);
|
|
}];
|
|
test(ready == 3);
|
|
}
|
|
|
|
-(void) testThen {
|
|
// pre-completed
|
|
bool b = [[[[Future finished:@3] then:^id(id value) {
|
|
test([value isEqual:@3]);
|
|
return @4;
|
|
}] forceGetResult] isEqual:@4];
|
|
test(b);
|
|
|
|
// pre-failed
|
|
bool b2 = [[[[Future failed:@-1] then:^id(id value) {
|
|
test(false);
|
|
return nil;
|
|
}] forceGetFailure] isEqual:@-1];
|
|
test(b2);
|
|
|
|
// post-completed
|
|
FutureSource* f = [FutureSource new];
|
|
Future* f2 = [f then:^id(id value) {
|
|
test([value isEqual:@1]);
|
|
return @2;
|
|
}];
|
|
test([f2 isIncomplete]);
|
|
[f trySetResult:@1];
|
|
test([[f2 forceGetResult] isEqual:@2]);
|
|
|
|
// exceptional
|
|
bool b3 = [[[[Future finished:nil] finally:^id(Future* completed) {
|
|
checkOperation(false);
|
|
return nil;
|
|
}] forceGetFailure] isKindOfClass:[OperationFailed class]];
|
|
test(b3);
|
|
}
|
|
|
|
-(void) testCatch {
|
|
// pre-failed
|
|
bool b = [[[[Future failed:@3] catch:^id(id value) {
|
|
test([value isEqual:@3]);
|
|
return @4;
|
|
}] forceGetResult] isEqual:@4];
|
|
test(b);
|
|
|
|
// pre-completed
|
|
bool b2 = [[[[Future finished:@-1] catch:^id(id value) {
|
|
test(false);
|
|
return nil;
|
|
}] forceGetResult] isEqual:@-1];
|
|
test(b2);
|
|
|
|
// post-failed
|
|
FutureSource* f = [FutureSource new];
|
|
Future* f2 = [f catch:^id(id value) {
|
|
test([value isEqual:@1]);
|
|
return @2;
|
|
}];
|
|
test([f2 isIncomplete]);
|
|
[f trySetFailure:@1];
|
|
test([[f2 forceGetResult] isEqual:@2]);
|
|
|
|
// exceptional
|
|
bool b3 = [[[[Future failed:nil] finally:^id(Future* completed) {
|
|
checkOperation(false);
|
|
return nil;
|
|
}] forceGetFailure] isKindOfClass:[OperationFailed class]];
|
|
test(b3);
|
|
}
|
|
|
|
-(void) testThenOrCatch {
|
|
// pre-completed
|
|
bool b = [[[[Future finished:@3] finally:^id(Future* completed) {
|
|
test([[completed forceGetResult] isEqual:@3]);
|
|
return @4;
|
|
}] forceGetResult] isEqual:@4];
|
|
test(b);
|
|
|
|
// pre-failed
|
|
bool b2 = [[[[Future failed:@-1] finally:^id(Future* completed) {
|
|
test([[completed forceGetFailure] isEqual:@-1]);
|
|
return @5;
|
|
}] forceGetResult] isEqual:@5];
|
|
test(b2);
|
|
|
|
// post-completed
|
|
FutureSource* f = [FutureSource new];
|
|
Future* f2 = [f finally:^id(Future* completed) {
|
|
test([[completed forceGetResult] isEqual:@1]);
|
|
return @2;
|
|
}];
|
|
test([f2 isIncomplete]);
|
|
[f trySetResult:@1];
|
|
test([[f2 forceGetResult] isEqual:@2]);
|
|
|
|
// exceptional
|
|
bool b3 = [[[[Future finished:nil] finally:^id(Future* completed) {
|
|
checkOperation(false);
|
|
return nil;
|
|
}] forceGetFailure] isKindOfClass:[OperationFailed class]];
|
|
test(b3);
|
|
}
|
|
|
|
-(void) completedAsCancelToken_OnSuccess {
|
|
FutureSource* f = [FutureSource new];
|
|
id<CancelToken> c = [f completionAsCancelToken];
|
|
test(![c isAlreadyCancelled]);
|
|
[f trySetResult:nil];
|
|
test([c isAlreadyCancelled]);
|
|
}
|
|
-(void) completedAsCancelToken_OnFailure {
|
|
FutureSource* f = [FutureSource new];
|
|
id<CancelToken> c = [f completionAsCancelToken];
|
|
test(![c isAlreadyCancelled]);
|
|
[f trySetFailure:nil];
|
|
test([c isAlreadyCancelled]);
|
|
}
|
|
|
|
@end
|