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.
		
		
		
		
		
			
		
			
				
	
	
		
			350 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Objective-C
		
	
			
		
		
	
	
			350 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Objective-C
		
	
| #import "FutureSourceTest.h"
 | |
| #import "TestUtil.h"
 | |
| #import "FutureSource.h"
 | |
| #import "Util.h"
 | |
| 
 | |
| @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
 |