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.
137 lines
4.5 KiB
Objective-C
137 lines
4.5 KiB
Objective-C
#import <XCTest/XCTest.h>
|
|
#import "ObservableValue.h"
|
|
#import "TestUtil.h"
|
|
#import "CancelTokenSource.h"
|
|
|
|
@interface ObservableTest : XCTestCase
|
|
|
|
@end
|
|
|
|
@implementation ObservableTest
|
|
|
|
-(void) testObservableAddRemove {
|
|
ObservableValueController* s = [ObservableValueController observableValueControllerWithInitialValue:@""];
|
|
ObservableValue* t = s;
|
|
NSMutableArray* a = [NSMutableArray array];
|
|
CancelTokenSource* c = [CancelTokenSource cancelTokenSource];
|
|
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {[a addObject:value];}
|
|
untilCancelled:[c getToken]];
|
|
|
|
test([a isEqualToArray:@[@""]]);
|
|
[s updateValue:@5];
|
|
test([a isEqualToArray:(@[@"", @5])]);
|
|
[s updateValue:@7];
|
|
test([a isEqualToArray:(@[@"", @5, @7])]);
|
|
[c cancel];
|
|
[s updateValue:@11];
|
|
test([a isEqualToArray:(@[@"", @5, @7])]);
|
|
}
|
|
-(void) testObservableAddAdd {
|
|
ObservableValueController* s = [ObservableValueController observableValueControllerWithInitialValue:@""];
|
|
ObservableValue* t = s;
|
|
NSMutableArray* a = [NSMutableArray array];
|
|
CancelTokenSource* c = [CancelTokenSource cancelTokenSource];
|
|
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {[a addObject:value];}
|
|
untilCancelled:[c getToken]];
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {[a addObject:value];}
|
|
untilCancelled:[c getToken]];
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {[a addObject:value];}
|
|
untilCancelled:[c getToken]];
|
|
|
|
test([a isEqualToArray:(@[@"", @"", @""])]);
|
|
[s updateValue:@5];
|
|
test([a isEqualToArray:(@[@"", @"", @"", @5, @5, @5])]);
|
|
}
|
|
-(void) testObservableRedundantSetIgnored {
|
|
id v1 = @"";
|
|
id v2 = nil;
|
|
id v3 = @1;
|
|
|
|
ObservableValueController* s = [ObservableValueController observableValueControllerWithInitialValue:v1];
|
|
ObservableValue* t = s;
|
|
__block id latest = nil;
|
|
__block int count = 0;
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {latest = value;count++;}
|
|
untilCancelled:nil];
|
|
|
|
test(latest == v1);
|
|
test(count == 1);
|
|
|
|
[s updateValue:v1];
|
|
test(latest == v1);
|
|
test(count == 1);
|
|
|
|
[s updateValue:v2];
|
|
test(latest == v2);
|
|
test(count == 2);
|
|
|
|
[s updateValue:v2];
|
|
test(latest == v2);
|
|
test(count == 2);
|
|
|
|
[s updateValue:v1];
|
|
test(latest == v1);
|
|
test(count == 3);
|
|
|
|
[s updateValue:v3];
|
|
test(latest == v3);
|
|
test(count == 4);
|
|
}
|
|
-(void) testObservableReentrantAdd {
|
|
ObservableValueController* s = [ObservableValueController observableValueControllerWithInitialValue:@""];
|
|
ObservableValue* t = s;
|
|
NSMutableArray* a = [NSMutableArray array];
|
|
CancelTokenSource* c = [CancelTokenSource cancelTokenSource];
|
|
|
|
__block void(^registerSelf)() = nil;
|
|
void(^registerSelf_builder)() = ^{
|
|
__block bool first = true;
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {
|
|
if (!first) registerSelf();
|
|
first = false;
|
|
[a addObject:value];
|
|
} untilCancelled:[c getToken]];
|
|
};
|
|
registerSelf = [registerSelf_builder copy];
|
|
registerSelf();
|
|
|
|
// adding during a callback counts as adding after the callback
|
|
// so we should see a doubling each time
|
|
test([a isEqualToArray:@[@""]]);
|
|
[s updateValue:@1];
|
|
test([a isEqualToArray:(@[@"", @1, @1])]);
|
|
[s updateValue:@2];
|
|
test([a isEqualToArray:(@[@"", @1, @1, @2, @2, @2, @2])]);
|
|
[s updateValue:@3];
|
|
test([a isEqualToArray:(@[@"", @1, @1, @2, @2, @2, @2, @3, @3, @3, @3, @3, @3, @3, @3])]);
|
|
}
|
|
-(void) testObservableReentrantRemove {
|
|
ObservableValueController* s = [ObservableValueController observableValueControllerWithInitialValue:@""];
|
|
ObservableValue* t = s;
|
|
NSMutableArray* a = [NSMutableArray array];
|
|
CancelTokenSource* c = [CancelTokenSource cancelTokenSource];
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
__block bool first = true;
|
|
[t watchLatestValueOnArbitraryThread:^(id value) {
|
|
if (!first) {
|
|
[c cancel];
|
|
[a addObject:value];
|
|
}
|
|
first = false;
|
|
} untilCancelled:[c getToken]];
|
|
}
|
|
|
|
// removing during a callback counts as removing after the callback
|
|
// so we should see all the callbacks run, then they're all cancelled
|
|
test([a isEqualToArray:(@[])]);
|
|
[s updateValue:@1];
|
|
test([a isEqualToArray:(@[@1, @1, @1])]);
|
|
[s updateValue:@2];
|
|
test([a isEqualToArray:(@[@1, @1, @1])]);
|
|
}
|
|
|
|
@end
|