diff options
author | 2017-05-15 12:27:07 -0700 | |
---|---|---|
committer | 2017-05-15 12:27:07 -0700 | |
commit | 98ba64449a632518bd2b86fe8d927f4a960d3ddc (patch) | |
tree | 131d9c4272fa6179fcda6c5a33fcb3b1bd57ad2e /Example/Database/Tests/Unit/FSparseSnapshotTests.m | |
parent | 32461366c9e204a527ca05e6e9b9404a2454ac51 (diff) |
Initial
Diffstat (limited to 'Example/Database/Tests/Unit/FSparseSnapshotTests.m')
-rw-r--r-- | Example/Database/Tests/Unit/FSparseSnapshotTests.m | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/Example/Database/Tests/Unit/FSparseSnapshotTests.m b/Example/Database/Tests/Unit/FSparseSnapshotTests.m new file mode 100644 index 0000000..ab22c0d --- /dev/null +++ b/Example/Database/Tests/Unit/FSparseSnapshotTests.m @@ -0,0 +1,207 @@ +/* + * Copyright 2017 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FSparseSnapshotTests.h" +#import "FSparseSnapshotTree.h" +#import "FSnapshotUtilities.h" +#import "FEmptyNode.h" + +@implementation FSparseSnapshotTests + +- (void) testBasicRememberAndFind { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + FPath* path = [[FPath alloc] initWith:@"a/b"]; + id<FNode> node = [FSnapshotUtilities nodeFrom:@"sdfsd"]; + + [st rememberData:node onPath:path]; + id<FNode> found = [st findPath:path]; + XCTAssertFalse([found isEmpty], @"Should find node"); + found = [st findPath:path.parent]; + XCTAssertTrue(found == nil, @"Should not find a node"); +} + +- (void) testFindInsideAnExistingSnapshot { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + FPath* path = [[FPath alloc] initWith:@"t/tt"]; + id<FNode> node = [FSnapshotUtilities nodeFrom:@{@"a": @"sdfsd", @"x": @5, @"999i": @YES}]; + id<FNode> update = [FSnapshotUtilities nodeFrom:@{@"goats": @88}]; + node = [node updateImmediateChild:@"apples" withNewChild:update]; + [st rememberData:node onPath:path]; + + id<FNode> found = [st findPath:path]; + XCTAssertFalse([found isEmpty], @"Should find the node we set"); + found = [st findPath:[path childFromString:@"a"]]; + XCTAssertTrue([[found val] isEqualToString:@"sdfsd"], @"Find works inside data snapshot"); + found = [st findPath:[path childFromString:@"999i"]]; + XCTAssertTrue([[found val] isEqualToNumber:@YES], @"Find works inside data snapshot"); + found = [st findPath:[path childFromString:@"apples"]]; + XCTAssertFalse([found isEmpty], @"Should find the node we set"); + found = [st findPath:[path childFromString:@"apples/goats"]]; + XCTAssertTrue([[found val] isEqualToNumber:@88], @"Find works inside data snapshot"); +} + +- (void) testWriteASnapshotInsideASnapshot { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:[FSnapshotUtilities nodeFrom:@{@"a": @{@"b": @"v"}}] onPath:[[FPath alloc] initWith:@"t"]]; + [st rememberData:[FSnapshotUtilities nodeFrom:@19] onPath:[[FPath alloc] initWith:@"t/a/rr"]]; + id<FNode> found = [st findPath:[[FPath alloc] initWith:@"t/a/b"]]; + XCTAssertTrue([[found val] isEqualToString:@"v"], @"Find inside snap"); + found = [st findPath:[[FPath alloc] initWith:@"t/a/rr"]]; + XCTAssertTrue([[found val] isEqualToNumber:@19], @"Find inside snap"); +} + +- (void) testWriteANullValueAndConfirmItIsRemembered { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:[FSnapshotUtilities nodeFrom:[NSNull null]] onPath:[[FPath alloc] initWith:@"awq/fff"]]; + id<FNode> found = [st findPath:[[FPath alloc] initWith:@"awq/fff"]]; + XCTAssertTrue([found isEmpty], @"Empty node"); + found = [st findPath:[[FPath alloc] initWith:@"awq/sdf"]]; + XCTAssertTrue(found == nil, @"No node here"); + found = [st findPath:[[FPath alloc] initWith:@"awq/fff/jjj"]]; + XCTAssertTrue([found isEmpty], @"Empty node"); + found = [st findPath:[[FPath alloc] initWith:@"awq/sdf/sdj/q"]]; + XCTAssertTrue(found == nil, @"No node here"); +} + +- (void) testOverwriteWithNullAndConfirmItIsRemembered { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:[FSnapshotUtilities nodeFrom:@{@"a": @{@"b": @"v"}}] onPath:[[FPath alloc] initWith:@"t"]]; + id<FNode> found = [st findPath:[[FPath alloc] initWith:@"t"]]; + XCTAssertFalse([found isEmpty], @"non-empty node"); + [st rememberData:[FSnapshotUtilities nodeFrom:[NSNull null]] onPath:[[FPath alloc] initWith:@"t"]]; + found = [st findPath:[[FPath alloc] initWith:@"t"]]; + XCTAssertTrue([found isEmpty], @"Empty node"); +} + +- (void) testSimpleRememberAndForget { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:[FSnapshotUtilities nodeFrom:@{@"a": @{@"b": @"v"}}] onPath:[[FPath alloc] initWith:@"t"]]; + id<FNode> found = [st findPath:[[FPath alloc] initWith:@"t"]]; + XCTAssertFalse([found isEmpty], @"non-empty node"); + [st forgetPath:[[FPath alloc] initWith:@"t"]]; + found = [st findPath:[[FPath alloc] initWith:@"t"]]; + XCTAssertTrue(found == nil, @"node is gone"); +} + +- (void) testForgetTheRoot { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:[FSnapshotUtilities nodeFrom:@{@"a": @{@"b": @"v"}}] onPath:[[FPath alloc] initWith:@"t"]]; + id<FNode> found = [st findPath:[[FPath alloc] initWith:@"t"]]; + XCTAssertFalse([found isEmpty], @"non-empty node"); + found = [st findPath:[[FPath alloc] initWith:@""]]; + XCTAssertTrue(found == nil, @"node is gone"); +} + +- (void) testForgetSnapshotInsideSnapshot { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:[FSnapshotUtilities nodeFrom:@{@"a": @{@"b": @"v", @"c": @9, @"art": @NO}}] onPath:[[FPath alloc] initWith:@"t"]]; + id<FNode> found = [st findPath:[[FPath alloc] initWith:@"t/a/c"]]; + XCTAssertFalse([found isEmpty], @"non-empty node"); + found = [st findPath:[[FPath alloc] initWith:@"t"]]; + XCTAssertFalse([found isEmpty], @"non-empty node"); + [st forgetPath:PATH(@"t/a/c")]; + XCTAssertTrue([st findPath:PATH(@"t")] == nil, @"no more node here"); + XCTAssertTrue([st findPath:PATH(@"t/a")] == nil, @"no more node here"); + XCTAssertTrue([[[st findPath:PATH(@"t/a/b")] val] isEqualToString:@"v"], @"child still exists"); + XCTAssertTrue([st findPath:PATH(@"t/a/c")] == nil, @"no more node here"); + XCTAssertTrue([[[st findPath:PATH(@"t/a/art")] val] isEqualToNumber:@NO], @"child still exists"); +} + +- (void) testPathShallowerThanSnapshots { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:NODE(@NO) onPath:PATH(@"t/x1")]; + [st rememberData:NODE(@YES) onPath:PATH(@"t/x2")]; + + [st forgetPath:PATH(@"t")]; + XCTAssertTrue([st findPath:PATH(@"t")] == nil, @"No more node here"); +} + +- (void) testIterateChildren { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + id<FNode> node = [FSnapshotUtilities nodeFrom:@{@"b": @"v", @"c": @9, @"art": @NO}]; + [st rememberData:node onPath:PATH(@"t")]; + [st rememberData:[FEmptyNode emptyNode] onPath:PATH(@"q")]; + + __block int num = 0; + __block BOOL gotT = NO; + __block BOOL gotQ = NO; + [st forEachChild:^(NSString* key, FSparseSnapshotTree* tree) { + num++; + if ([key isEqualToString:@"t"]) { + gotT = YES; + } else if ([key isEqualToString:@"q"]) { + gotQ = YES; + } else { + XCTFail(@"Unknown child"); + } + }]; + + XCTAssertTrue(gotT, @"Saw t"); + XCTAssertTrue(gotQ, @"Saw q"); + XCTAssertTrue(num == 2, @"Saw two children"); +} + +- (void) testIterateTrees { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + __block int count = 0; + [st forEachTreeAtPath:PATH(@"") do:^(FPath *path, id<FNode> data) { + count++; + }]; + XCTAssertTrue(count == 0, @"No trees to iterate through"); + + [st rememberData:NODE(@1) onPath:PATH(@"t")]; + [st rememberData:NODE(@2) onPath:PATH(@"a/b")]; + [st rememberData:NODE(@3) onPath:PATH(@"a/x/g")]; + [st rememberData:NODE([NSNull null]) onPath:PATH(@"a/x/null")]; + + __block int num = 0; + __block BOOL got1 = NO; + __block BOOL got2 = NO; + __block BOOL got3 = NO; + __block BOOL gotNull = NO; + + [st forEachTreeAtPath:PATH(@"q") do:^(FPath *path, id<FNode> data) { + num++; + NSString* pathString = [path description]; + if ([pathString isEqualToString:@"/q/t"]) { + got1 = YES; + XCTAssertTrue([[data val] isEqualToNumber:@1], @"got 1"); + } else if ([pathString isEqualToString:@"/q/a/b"]) { + got2 = YES; + XCTAssertTrue([[data val] isEqualToNumber:@2], @"got 2"); + } else if ([pathString isEqualToString:@"/q/a/x/g"]) { + got3 = YES; + XCTAssertTrue([[data val] isEqualToNumber:@3], @"got 3"); + } else if ([pathString isEqualToString:@"/q/a/x/null"]) { + gotNull = YES; + XCTAssertTrue([data val] == [NSNull null], @"got null"); + } else { + XCTFail(@"unknown tree"); + } + }]; + + XCTAssertTrue(got1 && got2 && got3 && gotNull, @"saw all the children"); + XCTAssertTrue(num == 4, @"Saw the right number of children"); +} + +- (void) testSetLeafAndForgetDeeperPath { + FSparseSnapshotTree* st = [[FSparseSnapshotTree alloc] init]; + [st rememberData:NODE(@"bar") onPath:PATH(@"foo")]; + BOOL safeToRemove = [st forgetPath:PATH(@"foo/baz")]; + XCTAssertFalse(safeToRemove, @"Should not have deleted anything, nothing to remove"); +} + +@end |