18
18
19
19
#import < XCTest/XCTest.h>
20
20
21
+ #import " Firestore/Source/API/FIRFilter+Internal.h"
21
22
#import " Firestore/Source/API/FIRQuery+Internal.h"
22
23
23
24
#import " Firestore/Example/Tests/Util/FSTEventAccumulator.h"
@@ -29,6 +30,25 @@ @interface FIRQueryTests : FSTIntegrationTestCase
29
30
30
31
@implementation FIRQueryTests
31
32
33
+ /* *
34
+ * Checks that running the query while online (against the backend/emulator) results in the same
35
+ * documents as running the query while offline. It also checks that both online and offline
36
+ * query result is equal to the expected documents.
37
+ *
38
+ * @param query The query to check.
39
+ * @param expectedDocs Array of document keys that are expected to match the query.
40
+ */
41
+ - (void )checkOnlineAndOfflineQuery : (FIRQuery *)query matchesResult : (NSArray *)expectedDocs {
42
+ FIRQuerySnapshot *docsFromServer = [self readDocumentSetForRef: query
43
+ source: FIRFirestoreSourceServer];
44
+ FIRQuerySnapshot *docsFromCache = [self readDocumentSetForRef: query
45
+ source: FIRFirestoreSourceCache];
46
+
47
+ XCTAssertEqualObjects (FIRQuerySnapshotGetIDs (docsFromServer),
48
+ FIRQuerySnapshotGetIDs (docsFromCache));
49
+ XCTAssertEqualObjects (FIRQuerySnapshotGetIDs (docsFromCache), expectedDocs);
50
+ }
51
+
32
52
- (void )testLimitQueries {
33
53
FIRCollectionReference *collRef = [self collectionRefWithDocuments: @{
34
54
@" a" : @{@" k" : @" a" },
@@ -804,4 +824,156 @@ - (void)testCollectionGroupQueriesWithWhereFiltersOnArbitraryDocumentIDs {
804
824
XCTAssertEqualObjects (ids, (@[ @" cg-doc2" ]));
805
825
}
806
826
827
+ - (void )testOrQueries {
828
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments: @{
829
+ @" doc1" : @{@" a" : @1 , @" b" : @0 },
830
+ @" doc2" : @{@" a" : @2 , @" b" : @1 },
831
+ @" doc3" : @{@" a" : @3 , @" b" : @2 },
832
+ @" doc4" : @{@" a" : @1 , @" b" : @3 },
833
+ @" doc5" : @{@" a" : @1 , @" b" : @1 }
834
+ }];
835
+
836
+ // Two equalities: a==1 || b==1.
837
+ FIRFilter *filter1 = [FIRFilter orFilterWithFilters: @[
838
+ [FIRFilter filterWhereField: @" a" isEqualTo: @1 ], [FIRFilter filterWhereField: @" b" isEqualTo: @1 ]
839
+ ]];
840
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter1]
841
+ matchesResult: @[ @" doc1" , @" doc2" , @" doc4" , @" doc5" ]];
842
+
843
+ // with one inequality: a>2 || b==1.
844
+ FIRFilter *filter2 = [FIRFilter orFilterWithFilters: @[
845
+ [FIRFilter filterWhereField: @" a" isGreaterThan: @2 ], [FIRFilter filterWhereField: @" b"
846
+ isEqualTo: @1 ]
847
+ ]];
848
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter2]
849
+ matchesResult: @[ @" doc5" , @" doc2" , @" doc3" ]];
850
+
851
+ // (a==1 && b==0) || (a==3 && b==2)
852
+ FIRFilter *filter3 = [FIRFilter orFilterWithFilters: @[
853
+ [FIRFilter andFilterWithFilters: @[
854
+ [FIRFilter filterWhereField: @" a" isEqualTo: @1 ], [FIRFilter filterWhereField: @" b" isEqualTo: @0 ]
855
+ ]],
856
+ [FIRFilter andFilterWithFilters: @[
857
+ [FIRFilter filterWhereField: @" a" isEqualTo: @3 ], [FIRFilter filterWhereField: @" b" isEqualTo: @2 ]
858
+ ]]
859
+ ]];
860
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter3]
861
+ matchesResult: @[ @" doc1" , @" doc3" ]];
862
+
863
+ // a==1 && (b==0 || b==3).
864
+ FIRFilter *filter4 = [FIRFilter andFilterWithFilters: @[
865
+ [FIRFilter filterWhereField: @" a" isEqualTo: @1 ], [FIRFilter orFilterWithFilters: @[
866
+ [FIRFilter filterWhereField: @" b" isEqualTo: @0 ], [FIRFilter filterWhereField: @" b" isEqualTo: @3 ]
867
+ ]]
868
+ ]];
869
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter4]
870
+ matchesResult: @[ @" doc1" , @" doc4" ]];
871
+
872
+ // (a==2 || b==2) && (a==3 || b==3)
873
+ FIRFilter *filter5 = [FIRFilter andFilterWithFilters: @[
874
+ [FIRFilter orFilterWithFilters: @[
875
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b" isEqualTo: @2 ]
876
+ ]],
877
+ [FIRFilter orFilterWithFilters: @[
878
+ [FIRFilter filterWhereField: @" a" isEqualTo: @3 ], [FIRFilter filterWhereField: @" b" isEqualTo: @3 ]
879
+ ]]
880
+ ]];
881
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter5] matchesResult: @[ @" doc3" ]];
882
+
883
+ // Test with limits (implicit order by ASC): (a==1) || (b > 0) LIMIT 2
884
+ FIRFilter *filter6 = [FIRFilter orFilterWithFilters: @[
885
+ [FIRFilter filterWhereField: @" a" isEqualTo: @1 ], [FIRFilter filterWhereField: @" b"
886
+ isGreaterThan: @0 ]
887
+ ]];
888
+ [self checkOnlineAndOfflineQuery: [[collRef queryWhereFilter: filter6] queryLimitedTo: 2 ]
889
+ matchesResult: @[ @" doc1" , @" doc2" ]];
890
+
891
+ // Test with limits (explicit order by): (a==1) || (b > 0) LIMIT_TO_LAST 2
892
+ // Note: The public query API does not allow implicit ordering when limitToLast is used.
893
+ FIRFilter *filter7 = [FIRFilter orFilterWithFilters: @[
894
+ [FIRFilter filterWhereField: @" a" isEqualTo: @1 ], [FIRFilter filterWhereField: @" b"
895
+ isGreaterThan: @0 ]
896
+ ]];
897
+ [self checkOnlineAndOfflineQuery: [[[collRef queryWhereFilter: filter7] queryLimitedToLast: 2 ]
898
+ queryOrderedByField: @" b" ]
899
+ matchesResult: @[ @" doc3" , @" doc4" ]];
900
+
901
+ // Test with limits (explicit order by ASC): (a==2) || (b == 1) ORDER BY a LIMIT 1
902
+ FIRFilter *filter8 = [FIRFilter orFilterWithFilters: @[
903
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b" isEqualTo: @1 ]
904
+ ]];
905
+ [self checkOnlineAndOfflineQuery: [[[collRef queryWhereFilter: filter8] queryLimitedTo: 1 ]
906
+ queryOrderedByField: @" a" ]
907
+ matchesResult: @[ @" doc5" ]];
908
+
909
+ // Test with limits (explicit order by DESC): (a==2) || (b == 1) ORDER BY a LIMIT_TO_LAST 1
910
+ FIRFilter *filter9 = [FIRFilter orFilterWithFilters: @[
911
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b" isEqualTo: @1 ]
912
+ ]];
913
+ [self checkOnlineAndOfflineQuery: [[[collRef queryWhereFilter: filter9] queryLimitedToLast: 1 ]
914
+ queryOrderedByField: @" a" ]
915
+ matchesResult: @[ @" doc2" ]];
916
+
917
+ // Test with limits without orderBy (the __name__ ordering is the tie breaker).
918
+ FIRFilter *filter10 = [FIRFilter orFilterWithFilters: @[
919
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b" isEqualTo: @1 ]
920
+ ]];
921
+ [self checkOnlineAndOfflineQuery: [[collRef queryWhereFilter: filter10] queryLimitedTo: 1 ]
922
+ matchesResult: @[ @" doc2" ]];
923
+ }
924
+
925
+ - (void )testOrQueriesWithInAndNotIn {
926
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments: @{
927
+ @" doc1" : @{@" a" : @1 , @" b" : @0 },
928
+ @" doc2" : @{@" b" : @1 },
929
+ @" doc3" : @{@" a" : @3 , @" b" : @2 },
930
+ @" doc4" : @{@" a" : @1 , @" b" : @3 },
931
+ @" doc5" : @{@" a" : @1 },
932
+ @" doc6" : @{@" a" : @2 }
933
+ }];
934
+
935
+ // a==2 || b in [2,3]
936
+ FIRFilter *filter1 = [FIRFilter orFilterWithFilters: @[
937
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b" in: @[ @2 , @3 ]]
938
+ ]];
939
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter1]
940
+ matchesResult: @[ @" doc3" , @" doc4" , @" doc6" ]];
941
+
942
+ // a==2 || b not-in [2,3]
943
+ // Has implicit orderBy b.
944
+ FIRFilter *filter2 = [FIRFilter orFilterWithFilters: @[
945
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b"
946
+ notIn: @[ @2 , @3 ]]
947
+ ]];
948
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter2]
949
+ matchesResult: @[ @" doc1" , @" doc2" ]];
950
+ }
951
+
952
+ - (void )testOrQueriesWithArrayMembership {
953
+ FIRCollectionReference *collRef = [self collectionRefWithDocuments: @{
954
+ @" doc1" : @{@" a" : @1 , @" b" : @[ @0 ]},
955
+ @" doc2" : @{@" b" : @[ @1 ]},
956
+ @" doc3" : @{@" a" : @3 , @" b" : @[ @2 , @7 ]},
957
+ @" doc4" : @{@" a" : @1 , @" b" : @[ @3 , @7 ]},
958
+ @" doc5" : @{@" a" : @1 },
959
+ @" doc6" : @{@" a" : @2 }
960
+ }];
961
+
962
+ // a==2 || b array-contains 7
963
+ FIRFilter *filter1 = [FIRFilter orFilterWithFilters: @[
964
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b"
965
+ arrayContains: @7 ]
966
+ ]];
967
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter1]
968
+ matchesResult: @[ @" doc3" , @" doc4" , @" doc6" ]];
969
+
970
+ // a==2 || b array-contains-any [0, 3]
971
+ FIRFilter *filter2 = [FIRFilter orFilterWithFilters: @[
972
+ [FIRFilter filterWhereField: @" a" isEqualTo: @2 ], [FIRFilter filterWhereField: @" b"
973
+ arrayContainsAny: @[ @0 , @3 ]]
974
+ ]];
975
+ [self checkOnlineAndOfflineQuery: [collRef queryWhereFilter: filter2]
976
+ matchesResult: @[ @" doc1" , @" doc4" , @" doc6" ]];
977
+ }
978
+
807
979
@end
0 commit comments