no message

This commit is contained in:
Peter
2016-05-30 18:16:04 +03:00
parent c73133e709
commit 3550e01010
3 changed files with 113 additions and 0 deletions

View File

@@ -4,5 +4,6 @@
- (SSignal *)catch:(SSignal *(^)(id error))f;
- (SSignal *)restart;
- (SSignal *)retryIf:(bool (^)(id error))predicate;
@end

View File

@@ -91,4 +91,57 @@ static dispatch_block_t recursiveBlock(void (^block)(dispatch_block_t recurse))
}];
}
- (SSignal *)retryIf:(bool (^)(id error))predicate {
return [[SSignal alloc] initWithGenerator:^id<SDisposable> (SSubscriber *subscriber)
{
SAtomic *shouldRestart = [[SAtomic alloc] initWithValue:@true];
SMetaDisposable *currentDisposable = [[SMetaDisposable alloc] init];
void (^start)() = recursiveBlock(^(dispatch_block_t recurse)
{
NSNumber *currentShouldRestart = [shouldRestart with:^id(NSNumber *current)
{
return current;
}];
if ([currentShouldRestart boolValue])
{
id<SDisposable> disposable = [self startWithNext:^(id next)
{
[subscriber putNext:next];
} error:^(id error)
{
if (predicate(error)) {
recurse();
} else {
[subscriber putError:error];
}
} completed:^
{
[shouldRestart modify:^id(__unused id current) {
return @false;
}];
[subscriber putCompletion];
}];
[currentDisposable setDisposable:disposable];
} else {
[subscriber putCompletion];
}
});
start();
return [[SBlockDisposable alloc] initWithBlock:^
{
[currentDisposable dispose];
[shouldRestart modify:^id(__unused id current)
{
return @false;
}];
}];
}];
}
@end

View File

@@ -702,4 +702,63 @@
}
}
- (void)testRetryIfNoError {
SSignal *s = [[SSignal single:@1] retryIf:^bool(__unused id error) {
return true;
}];
[s startWithNext:^(id next) {
XCTAssertEqual(next, @1);
}];
}
- (void)testRetryErrorNoMatch {
SSignal *s = [[SSignal fail:@false] retryIf:^bool(id error) {
return false;
}];
}
- (void)testRetryErrorMatch {
__block counter = 1;
SSignal *s = [[[SSignal alloc] initWithGenerator:^id<SDisposable> (SSubscriber *subscriber) {
if (counter == 1) {
counter++;
[subscriber putError:@true];
} else {
[subscriber putNext:@(counter)];
}
return nil;
}] retryIf:^bool(id error) {
return [error boolValue];
}];
__block int value = 0;
[s startWithNext:^(id next) {
value = [next intValue];
}];
XCTAssertEqual(value, 2);
}
- (void)testRetryErrorFailNoMatch {
__block counter = 1;
SSignal *s = [[[SSignal alloc] initWithGenerator:^id<SDisposable> (SSubscriber *subscriber) {
if (counter == 1) {
counter++;
[subscriber putError:@true];
} else {
[subscriber putError:@false];
}
return nil;
}] retryIf:^bool(id error) {
return [error boolValue];
}];
__block bool errorMatches = false;
[s startWithNext:nil error:^(id error) {
errorMatches = ![error boolValue];
} completed:nil];
XCTAssert(errorMatches);
}
@end