aboutsummaryrefslogtreecommitdiffhomepage
path: root/Example/Database/Tests/Helpers/FEventTester.m
diff options
context:
space:
mode:
Diffstat (limited to 'Example/Database/Tests/Helpers/FEventTester.m')
-rw-r--r--Example/Database/Tests/Helpers/FEventTester.m172
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