diff options
Diffstat (limited to 'Example/Database/Tests/Helpers/FEventTester.m')
-rw-r--r-- | Example/Database/Tests/Helpers/FEventTester.m | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/Example/Database/Tests/Helpers/FEventTester.m b/Example/Database/Tests/Helpers/FEventTester.m new file mode 100644 index 0000000..fa7c081 --- /dev/null +++ b/Example/Database/Tests/Helpers/FEventTester.m @@ -0,0 +1,172 @@ +/* + * 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 "FEventTester.h" +#import "FIRDatabaseReference.h" +#import "FTupleBoolBlock.h" +#import "FTupleEventTypeString.h" +#import "FTestHelpers.h" +#import "SenTest+FWaiter.h" + +@implementation FEventTester + +@synthesize lookingFor; +@synthesize callbacksCalled; +@synthesize from; +@synthesize errors; +@synthesize seenFirebaseLocations; +@synthesize initializationEvents; +@synthesize actualPathsAndEvents; + +- (id)initFrom:(XCTestCase *)elsewhere +{ + self = [super init]; + if (self) { + self.seenFirebaseLocations = [[NSMutableDictionary alloc] init]; + self.initializationEvents = 0; + self.lookingFor = [[NSMutableArray alloc] init]; + self.actualPathsAndEvents = [[NSMutableArray alloc] init]; + self.from = elsewhere; + self.callbacksCalled = 0; + } + return self; +} + +- (void) addLookingFor:(NSArray *)l { + + // expect them in the order they're given to us + [self.lookingFor addObjectsFromArray:l]; + + + // see notes on ordering of listens in init.spec.js + NSArray* toListen = [l sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { + FTupleEventTypeString* a = obj1; + FTupleEventTypeString* b = obj2; + NSUInteger lenA = [a.firebase description].length; + NSUInteger lenB = [b.firebase description].length; + if (lenA < lenB) { + return NSOrderedAscending; + } else if (lenA == lenB) { + return NSOrderedSame; + } else { + return NSOrderedDescending; + } + }]; + + for(FTupleEventTypeString* fevts in toListen) { + if(! [self.seenFirebaseLocations objectForKey:[fevts.firebase description]]) { + fevts.vvcallback = [self listenOnPath:fevts.firebase]; + fevts.initialized = NO; + [self.seenFirebaseLocations setObject:fevts forKey:[fevts.firebase description]]; + } + } +} + +- (void) unregister { + for(FTupleEventTypeString* fevts in self.lookingFor) { + if (fevts.vvcallback) { + fevts.vvcallback(); + } + } + [self.lookingFor removeAllObjects]; +} + +- (fbt_void_void) listenOnPath:(FIRDatabaseReference *)path { + FIRDatabaseHandle removedHandle = [path observeEventType:FIRDataEventTypeChildRemoved withBlock:[self makeEventCallback:FIRDataEventTypeChildRemoved]]; + FIRDatabaseHandle addedHandle = [path observeEventType:FIRDataEventTypeChildAdded withBlock:[self makeEventCallback:FIRDataEventTypeChildAdded]]; + FIRDatabaseHandle movedHandle = [path observeEventType:FIRDataEventTypeChildMoved withBlock:[self makeEventCallback:FIRDataEventTypeChildMoved]]; + FIRDatabaseHandle changedHandle = [path observeEventType:FIRDataEventTypeChildChanged withBlock:[self makeEventCallback:FIRDataEventTypeChildChanged]]; + FIRDatabaseHandle valueHandle = [path observeEventType:FIRDataEventTypeValue withBlock:[self makeEventCallback:FIRDataEventTypeValue]]; + + fbt_void_void cb = ^() { + [path removeObserverWithHandle:removedHandle]; + [path removeObserverWithHandle:addedHandle]; + [path removeObserverWithHandle:movedHandle]; + [path removeObserverWithHandle:changedHandle]; + [path removeObserverWithHandle:valueHandle]; + }; + return [cb copy]; +} + +- (void) wait { + [self waitUntil:^BOOL{ + return self.actualPathsAndEvents.count >= self.lookingFor.count; + } timeout:kFirebaseTestTimeout]; + + for (int i = 0; i < self.lookingFor.count; ++i) { + FTupleEventTypeString* target = [self.lookingFor objectAtIndex:i]; + FTupleEventTypeString* recvd = [self.actualPathsAndEvents objectAtIndex:i]; + XCTAssertTrue([target isEqualTo:recvd], @"Expected %@ to match %@", target, recvd); + } + + if (self.actualPathsAndEvents.count > self.lookingFor.count) { + NSLog(@"Too many events: %@", self.actualPathsAndEvents); + XCTFail(@"Received too many events"); + } +} + +- (void) waitForInitialization { + [self waitUntil:^BOOL{ + for (FTupleEventTypeString* evt in [self.seenFirebaseLocations allValues]) { + if (!evt.initialized) { + return NO; + } + } + + // splice out all of the initialization events + NSRange theRange; + theRange.location = 0; + theRange.length = self.initializationEvents; + [actualPathsAndEvents removeObjectsInRange:theRange]; + + return YES; + } timeout:kFirebaseTestTimeout]; +} + +- (fbt_void_datasnapshot) makeEventCallback:(FIRDataEventType)type { + + fbt_void_datasnapshot cb = ^(FIRDataSnapshot * snap) { + + FIRDatabaseReference * ref = snap.ref; + NSString* name = nil; + if (type != FIRDataEventTypeValue) { + ref = ref.parent; + name = snap.key; + } + + FTupleEventTypeString* evt = [[FTupleEventTypeString alloc] initWithFirebase:ref withEvent:type withString:name]; + [actualPathsAndEvents addObject:evt]; + + NSLog(@"Adding event: %@ (%@)", evt, [snap value]); + + FTupleEventTypeString* targetEvt = [self.seenFirebaseLocations objectForKey:[ref description]]; + if (targetEvt && !targetEvt.initialized) { + self.initializationEvents++; + if (type == FIRDataEventTypeValue) { + targetEvt.initialized = YES; + } + } + }; + return [cb copy]; +} + + +- (void) failWithException:(NSException *) anException { + //TODO: FIX + @throw anException; +} + +@end |