|
|
@@ -23,6 +23,10 @@
|
|
|
#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
|
|
|
#import "Firestore/Example/Tests/Util/FSTTestingHooks.h"
|
|
|
|
|
|
+// TODO(MIEQ) update these imports with public imports when aggregate types are public
|
|
|
+#import "Firestore/Source/API/FIRAggregateQuerySnapshot+Internal.h"
|
|
|
+#import "Firestore/Source/API/FIRQuery+Internal.h"
|
|
|
+
|
|
|
@interface FIRQueryTests : FSTIntegrationTestCase
|
|
|
@end
|
|
|
|
|
|
@@ -1166,6 +1170,512 @@
|
|
|
matchesResult:@[ @"doc6", @"doc3" ]];
|
|
|
}
|
|
|
|
|
|
+// Multiple Inequality
|
|
|
+- (void)testMultipleInequalityOnDifferentFields {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @0, @"v" : @0},
|
|
|
+ @"doc2" : @{@"key" : @"b", @"sort" : @3, @"v" : @1},
|
|
|
+ @"doc3" : @{@"key" : @"c", @"sort" : @1, @"v" : @3},
|
|
|
+ @"doc4" : @{@"key" : @"d", @"sort" : @2, @"v" : @2}
|
|
|
+ }];
|
|
|
+
|
|
|
+ // Multiple inequality fields
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[collRef queryWhereField:@"key" isNotEqualTo:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2] queryWhereField:@"v" isGreaterThan:@2]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc3" ]));
|
|
|
+
|
|
|
+ // Duplicate inequality fields
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"key" isNotEqualTo:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2] queryWhereField:@"sort"
|
|
|
+ isGreaterThan:@1]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc4" ]));
|
|
|
+
|
|
|
+ // With multiple IN
|
|
|
+ snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThanOrEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]
|
|
|
+ queryWhereField:@"v"
|
|
|
+ in:@[ @2, @3, @4 ]] queryWhereField:@"sort"
|
|
|
+ in:@[ @2, @3 ]]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc4" ]));
|
|
|
+
|
|
|
+ // With NOT-IN
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThanOrEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]
|
|
|
+ queryWhereField:@"v"
|
|
|
+ notIn:@[ @2, @4, @5 ]]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc1", @"doc3" ]));
|
|
|
+
|
|
|
+ // With orderby
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThanOrEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]
|
|
|
+ queryOrderedByField:@"v"
|
|
|
+ descending:YES]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc3", @"doc4", @"doc1" ]));
|
|
|
+
|
|
|
+ // With limit
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThanOrEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]
|
|
|
+ queryOrderedByField:@"v"
|
|
|
+ descending:YES] queryLimitedTo:2]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc3", @"doc4" ]));
|
|
|
+
|
|
|
+ // With limitedToLast
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThanOrEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]
|
|
|
+ queryOrderedByField:@"v"
|
|
|
+ descending:YES] queryLimitedToLast:2]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc4", @"doc1" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityOnSpecialValues {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @0, @"v" : @0},
|
|
|
+ @"doc2" : @{@"key" : @"b", @"sort" : @(NAN), @"v" : @1},
|
|
|
+ @"doc3" : @{@"key" : @"c", @"sort" : [NSNull null], @"v" : @3},
|
|
|
+ @"doc4" : @{@"key" : @"d", @"v" : @0},
|
|
|
+ @"doc5" : @{@"key" : @"e", @"sort" : @1},
|
|
|
+ @"doc6" : @{@"key" : @"f", @"sort" : @1, @"v" : @1}
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot =
|
|
|
+ [self readDocumentSetForRef:[[collRef queryWhereField:@"key"
|
|
|
+ isNotEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc5", @"doc6" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"key" isNotEqualTo:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2] queryWhereField:@"v"
|
|
|
+ isLessThanOrEqualTo:@1]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc6" ]));
|
|
|
+}
|
|
|
+- (void)testMultipleInequalityWithArrayMembership {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @0, @"v" : @[ @0 ]},
|
|
|
+ @"doc2" : @{@"key" : @"b", @"sort" : @1, @"v" : @[ @0, @1, @3 ]},
|
|
|
+ @"doc3" : @{@"key" : @"c", @"sort" : @1, @"v" : @[]},
|
|
|
+ @"doc4" : @{@"key" : @"d", @"sort" : @2, @"v" : @[ @1 ]},
|
|
|
+ @"doc5" : @{@"key" : @"e", @"sort" : @3, @"v" : @[ @2, @4 ]},
|
|
|
+ @"doc6" : @{@"key" : @"f", @"sort" : @4, @"v" : @[ @(NAN) ]},
|
|
|
+ @"doc7" : @{@"key" : @"g", @"sort" : @4, @"v" : @[ [NSNull null] ]}
|
|
|
+
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[collRef queryWhereField:@"key" isNotEqualTo:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1] queryWhereField:@"v" arrayContains:@0]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc2" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"key"
|
|
|
+ isNotEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1]
|
|
|
+ queryWhereField:@"v"
|
|
|
+ arrayContainsAny:@[ @0, @1 ]]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc2", @"doc4" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (NSDictionary<NSString *, id> *)nestedData:(int)number {
|
|
|
+ return @{
|
|
|
+ @"name" : [NSString stringWithFormat:@"room %d", number],
|
|
|
+ @"metadata" : @{@"createdAt" : @(number)},
|
|
|
+ @"field" : [NSString stringWithFormat:@"field %d", number],
|
|
|
+ @"field.dot" : @(number),
|
|
|
+ @"field\\slash" : @(number)
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityWithNestedField {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : [self nestedData:400],
|
|
|
+ @"doc2" : [self nestedData:200],
|
|
|
+ @"doc3" : [self nestedData:100],
|
|
|
+ @"doc4" : [self nestedData:300]
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[[collRef queryWhereField:@"metadata.createdAt"
|
|
|
+ isLessThanOrEqualTo:@500] queryWhereField:@"metadata.createdAt"
|
|
|
+ isGreaterThan:@100]
|
|
|
+ queryWhereField:@"name"
|
|
|
+ isNotEqualTo:@"room 200"] queryOrderedByField:@"name"
|
|
|
+ descending:NO]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc4", @"doc1" ]));
|
|
|
+
|
|
|
+ snapshot =
|
|
|
+ [self readDocumentSetForRef:[[[[collRef queryWhereField:@"field"
|
|
|
+ isGreaterThanOrEqualTo:@"field 100"]
|
|
|
+ queryWhereFieldPath:[[FIRFieldPath alloc]
|
|
|
+ initWithFields:@[ @"field.dot" ]]
|
|
|
+ isNotEqualTo:@300] queryWhereField:@"field\\slash"
|
|
|
+ isLessThan:@400]
|
|
|
+ queryOrderedByField:@"name"
|
|
|
+ descending:YES]];
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc2", @"doc3" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityWithCompositeFilters {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @0, @"v" : @5},
|
|
|
+ @"doc2" : @{@"key" : @"aa", @"sort" : @4, @"v" : @4},
|
|
|
+ @"doc3" : @{@"key" : @"c", @"sort" : @3, @"v" : @3},
|
|
|
+ @"doc4" : @{@"key" : @"b", @"sort" : @2, @"v" : @2},
|
|
|
+ @"doc5" : @{@"key" : @"b", @"sort" : @2, @"v" : @1},
|
|
|
+ @"doc6" : @{@"key" : @"b", @"sort" : @0, @"v" : @0}
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[collRef queryWhereFilter:[FIRFilter orFilterWithFilters:@[
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isEqualTo:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"sort" isLessThanOrEqualTo:@2]
|
|
|
+ ]],
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isNotEqualTo:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"v" isGreaterThan:@4]
|
|
|
+ ]]
|
|
|
+ ]]]];
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, 'v' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc1", @"doc6", @"doc5", @"doc4" ]));
|
|
|
+
|
|
|
+ snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[collRef queryWhereFilter:[FIRFilter orFilterWithFilters:@[
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isEqualTo:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@2]
|
|
|
+ ]],
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isNotEqualTo:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"v" isGreaterThan:@4]
|
|
|
+ ]]
|
|
|
+ ]]] queryOrderedByField:@"sort"
|
|
|
+ descending:YES] queryOrderedByField:@"key"]];
|
|
|
+ // Ordered by: 'sort' desc, 'key' asc, 'v' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc5", @"doc4", @"doc1", @"doc6" ]));
|
|
|
+
|
|
|
+ snapshot = [self
|
|
|
+ readDocumentSetForRef:[collRef
|
|
|
+ queryWhereFilter:[FIRFilter andFilterWithFilters:@[
|
|
|
+
|
|
|
+ [FIRFilter orFilterWithFilters:@[
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isEqualTo:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"sort" isLessThanOrEqualTo:@4]
|
|
|
+ ]],
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isNotEqualTo:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"v" isGreaterThanOrEqualTo:@4]
|
|
|
+ ]]
|
|
|
+ ]],
|
|
|
+
|
|
|
+ [FIRFilter orFilterWithFilters:@[
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isGreaterThan:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"sort" isGreaterThanOrEqualTo:@1]
|
|
|
+ ]],
|
|
|
+ [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"key" isLessThan:@"b"],
|
|
|
+ [FIRFilter filterWhereField:@"v" isGreaterThan:@0]
|
|
|
+ ]]
|
|
|
+ ]]
|
|
|
+
|
|
|
+ ]]]];
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, 'v' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc1", @"doc2" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityFieldsWillBeImplicitlyOrderedLexicographically {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @0, @"v" : @5},
|
|
|
+ @"doc2" : @{@"key" : @"aa", @"sort" : @4, @"v" : @4},
|
|
|
+ @"doc3" : @{@"key" : @"b", @"sort" : @3, @"v" : @3},
|
|
|
+ @"doc4" : @{@"key" : @"b", @"sort" : @2, @"v" : @2},
|
|
|
+ @"doc5" : @{@"key" : @"b", @"sort" : @2, @"v" : @1},
|
|
|
+ @"doc6" : @{@"key" : @"b", @"sort" : @0, @"v" : @0}
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[collRef queryWhereField:@"key" isNotEqualTo:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThan:@1] queryWhereField:@"v" in:@[ @1, @2, @3, @4 ]]];
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc2", @"doc4", @"doc5", @"doc3" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"sort"
|
|
|
+ isGreaterThan:@1] queryWhereField:@"key"
|
|
|
+ isNotEqualTo:@"a"]
|
|
|
+ queryWhereField:@"v"
|
|
|
+ in:@[ @1, @2, @3, @4 ]]];
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc2", @"doc4", @"doc5", @"doc3" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityWithMultipleExplicitOrderBy {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @5, @"v" : @0},
|
|
|
+ @"doc2" : @{@"key" : @"aa", @"sort" : @4, @"v" : @0},
|
|
|
+ @"doc3" : @{@"key" : @"b", @"sort" : @3, @"v" : @1},
|
|
|
+ @"doc4" : @{@"key" : @"b", @"sort" : @2, @"v" : @1},
|
|
|
+ @"doc5" : @{@"key" : @"bb", @"sort" : @1, @"v" : @1},
|
|
|
+ @"doc6" : @{@"key" : @"c", @"sort" : @0, @"v" : @2}
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[collRef queryWhereField:@"key" isGreaterThan:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1] queryOrderedByField:@"v" descending:NO]];
|
|
|
+ // Ordered by: 'v' asc, 'key' asc, 'sort' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc2", @"doc4", @"doc3", @"doc5" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThan:@"a"] queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1]
|
|
|
+ queryOrderedByField:@"v"
|
|
|
+ descending:NO] queryOrderedByField:@"sort"
|
|
|
+ descending:NO]];
|
|
|
+ // Ordered by: 'v asc, 'sort' asc, 'key' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc2", @"doc5", @"doc4", @"doc3" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereField:@"key" isGreaterThan:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1] queryOrderedByField:@"v"
|
|
|
+ descending:YES]];
|
|
|
+ // Implicit order by matches the direction of last explicit order by.
|
|
|
+ // Ordered by: 'v' desc, 'key' desc, 'sort' desc, __name__ desc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc5", @"doc3", @"doc4", @"doc2" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[[collRef queryWhereField:@"key"
|
|
|
+ isGreaterThan:@"a"] queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1]
|
|
|
+ queryOrderedByField:@"v"
|
|
|
+ descending:YES] queryOrderedByField:@"sort"
|
|
|
+ descending:NO]];
|
|
|
+ // Ordered by: 'v desc, 'sort' asc, 'key' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot),
|
|
|
+ (@[ @"doc5", @"doc4", @"doc3", @"doc2" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityInAggregateQuery {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @5, @"v" : @0},
|
|
|
+ @"doc2" : @{@"key" : @"aa", @"sort" : @4, @"v" : @0},
|
|
|
+ @"doc3" : @{@"key" : @"b", @"sort" : @3, @"v" : @1},
|
|
|
+ @"doc4" : @{@"key" : @"b", @"sort" : @2, @"v" : @1},
|
|
|
+ @"doc5" : @{@"key" : @"bb", @"sort" : @1, @"v" : @1},
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRAggregateQuerySnapshot *snapshot =
|
|
|
+ [self readSnapshotForAggregate:[[[[collRef queryWhereField:@"key" isGreaterThan:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1] queryOrderedByField:@"v"
|
|
|
+ descending:NO]
|
|
|
+ aggregate:@[
|
|
|
+ [FIRAggregateField aggregateFieldForCount],
|
|
|
+ [FIRAggregateField aggregateFieldForSumOfField:@"sort"],
|
|
|
+ [FIRAggregateField aggregateFieldForAverageOfField:@"v"]
|
|
|
+ ]]];
|
|
|
+ XCTAssertEqual([snapshot count], [NSNumber numberWithLong:4L]);
|
|
|
+
|
|
|
+ snapshot = [self
|
|
|
+ readSnapshotForAggregate:[[[[collRef queryWhereField:@"key" isGreaterThan:@"a"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThanOrEqualTo:@1] queryWhereField:@"v" isNotEqualTo:@0]
|
|
|
+ aggregate:@[
|
|
|
+ [FIRAggregateField aggregateFieldForCount],
|
|
|
+ [FIRAggregateField aggregateFieldForSumOfField:@"sort"],
|
|
|
+ [FIRAggregateField aggregateFieldForAverageOfField:@"v"],
|
|
|
+ ]]];
|
|
|
+ XCTAssertEqual([snapshot valueForAggregation:[FIRAggregateField aggregateFieldForCount]],
|
|
|
+ [NSNumber numberWithLong:3L]);
|
|
|
+ XCTAssertEqual(
|
|
|
+ [[snapshot valueForAggregation:[FIRAggregateField aggregateFieldForSumOfField:@"sort"]]
|
|
|
+ longValue],
|
|
|
+ 6L);
|
|
|
+ XCTAssertEqual(
|
|
|
+ [snapshot valueForAggregation:[FIRAggregateField aggregateFieldForAverageOfField:@"v"]],
|
|
|
+ [NSNumber numberWithDouble:1.0]);
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityFieldsWithDocumentKey {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @5},
|
|
|
+ @"doc2" : @{@"key" : @"aa", @"sort" : @4},
|
|
|
+ @"doc3" : @{@"key" : @"b", @"sort" : @3},
|
|
|
+ @"doc4" : @{@"key" : @"b", @"sort" : @2},
|
|
|
+ @"doc5" : @{@"key" : @"bb", @"sort" : @1}
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuerySnapshot *snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[collRef queryWhereField:@"sort"
|
|
|
+ isGreaterThan:@1] queryWhereField:@"key" isNotEqualTo:@"a"]
|
|
|
+ queryWhereFieldPath:[FIRFieldPath documentID]
|
|
|
+ isLessThan:@"doc5"]];
|
|
|
+ // Document Key in inequality field will implicitly ordered to the last.
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc2", @"doc4", @"doc3" ]));
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:[[[collRef queryWhereFieldPath:[FIRFieldPath documentID]
|
|
|
+ isLessThan:@"doc5"]
|
|
|
+ queryWhereField:@"sort"
|
|
|
+ isGreaterThan:@1] queryWhereField:@"key"
|
|
|
+ isNotEqualTo:@"a"]];
|
|
|
+ // Changing filters order will not effect implicit order.
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc2", @"doc4", @"doc3" ]));
|
|
|
+
|
|
|
+ snapshot = [self
|
|
|
+ readDocumentSetForRef:[[[[collRef queryWhereFieldPath:[FIRFieldPath documentID]
|
|
|
+ isLessThan:@"doc5"] queryWhereField:@"sort"
|
|
|
+ isGreaterThan:@1]
|
|
|
+ queryWhereField:@"key"
|
|
|
+ isNotEqualTo:@"a"] queryOrderedByField:@"sort" descending:YES]];
|
|
|
+ // Ordered by: 'sort' desc,'key' desc, __name__ desc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc2", @"doc3", @"doc4" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityReadFromCacheWhenOffline {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"key" : @"a", @"sort" : @1},
|
|
|
+ @"doc2" : @{@"key" : @"aa", @"sort" : @4},
|
|
|
+ @"doc3" : @{@"key" : @"b", @"sort" : @3},
|
|
|
+ @"doc4" : @{@"key" : @"b", @"sort" : @2},
|
|
|
+ }];
|
|
|
+
|
|
|
+ FIRQuery *query = [[collRef queryWhereField:@"key" isNotEqualTo:@"a"] queryWhereField:@"sort"
|
|
|
+ isLessThanOrEqualTo:@3];
|
|
|
+
|
|
|
+ // populate the cache.
|
|
|
+ FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:query];
|
|
|
+ XCTAssertEqual(snapshot.count, 2L);
|
|
|
+ XCTAssertEqual(snapshot.metadata.isFromCache, NO);
|
|
|
+
|
|
|
+ [self disableNetwork];
|
|
|
+
|
|
|
+ snapshot = [self readDocumentSetForRef:query];
|
|
|
+ XCTAssertEqual(snapshot.count, 2L);
|
|
|
+ XCTAssertEqual(snapshot.metadata.isFromCache, YES);
|
|
|
+ // Implicitly ordered by: 'key' asc, 'sort' asc, __name__ asc
|
|
|
+ XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(snapshot), (@[ @"doc4", @"doc3" ]));
|
|
|
+}
|
|
|
+
|
|
|
+- (void)testMultipleInequalityFromCacheAndFromServer {
|
|
|
+ // TODO(MIEQ): Enable this test against production when possible.
|
|
|
+ XCTSkipIf(![FSTIntegrationTestCase isRunningAgainstEmulator],
|
|
|
+ "Skip this test if running against production because multiple inequality is "
|
|
|
+ "not supported yet.");
|
|
|
+
|
|
|
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
|
|
|
+ @"doc1" : @{@"a" : @1, @"b" : @0},
|
|
|
+ @"doc2" : @{@"a" : @2, @"b" : @1},
|
|
|
+ @"doc3" : @{@"a" : @3, @"b" : @2},
|
|
|
+ @"doc4" : @{@"a" : @1, @"b" : @3},
|
|
|
+ @"doc5" : @{@"a" : @1, @"b" : @1},
|
|
|
+
|
|
|
+ }];
|
|
|
+
|
|
|
+ // implicit AND: a != 1 && b < 2
|
|
|
+ FIRQuery *query = [[collRef queryWhereField:@"a" isNotEqualTo:@1] queryWhereField:@"b"
|
|
|
+ isLessThan:@2];
|
|
|
+ [self checkOnlineAndOfflineQuery:query matchesResult:@[ @"doc2" ]];
|
|
|
+
|
|
|
+ // explicit AND: a != 1 && b < 2
|
|
|
+ FIRFilter *filter = [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"a" isNotEqualTo:@1], [FIRFilter filterWhereField:@"b"
|
|
|
+ isLessThan:@2]
|
|
|
+ ]];
|
|
|
+ [self checkOnlineAndOfflineQuery:[collRef queryWhereFilter:filter] matchesResult:@[ @"doc2" ]];
|
|
|
+
|
|
|
+ // explicit AND: a < 3 && b not-in [2, 3]
|
|
|
+ // Implicitly ordered by: a asc, b asc, __name__ asc
|
|
|
+ filter = [FIRFilter andFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"a" isLessThan:@3], [FIRFilter filterWhereField:@"b"
|
|
|
+ notIn:@[ @2, @3 ]]
|
|
|
+ ]];
|
|
|
+ [self checkOnlineAndOfflineQuery:[collRef queryWhereFilter:filter]
|
|
|
+ matchesResult:@[ @"doc1", @"doc5", @"doc2" ]];
|
|
|
+
|
|
|
+ // a <3 && b != 0, ordered by: b desc, a desc, __name__ desc
|
|
|
+ query = [[[[collRef queryWhereField:@"a" isLessThan:@3] queryWhereField:@"b" isNotEqualTo:@0]
|
|
|
+ queryOrderedByField:@"b"
|
|
|
+ descending:YES] queryLimitedTo:2];
|
|
|
+ [self checkOnlineAndOfflineQuery:query matchesResult:@[ @"doc4", @"doc2" ]];
|
|
|
+
|
|
|
+ // explicit OR: a>2 || b<1.
|
|
|
+ filter = [FIRFilter orFilterWithFilters:@[
|
|
|
+ [FIRFilter filterWhereField:@"a" isGreaterThan:@2], [FIRFilter filterWhereField:@"b"
|
|
|
+ isLessThan:@1]
|
|
|
+ ]];
|
|
|
+ [self checkOnlineAndOfflineQuery:[collRef queryWhereFilter:filter]
|
|
|
+ matchesResult:@[ @"doc1", @"doc3" ]];
|
|
|
+}
|
|
|
+
|
|
|
- (void)testResumingAQueryShouldUseBloomFilterToAvoidFullRequery {
|
|
|
// TODO(b/291365820): Stop skipping this test when running against the Firestore emulator once
|
|
|
// the emulator is improved to include a bloom filter in the existence filter messages that it
|