Skip to content

Commit a34d7ae

Browse files
authored
FIX: sort strings in UTF-8 encoded byte order (#14312)
1 parent 95f8ec8 commit a34d7ae

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

Firestore/Example/Tests/Integration/API/FIRQueryTests.mm

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,142 @@ - (void)testSdkOrdersQueryByDocumentIdTheSameWayOnlineAndOffline {
896896
]];
897897
}
898898

899+
- (void)testSnapshotListenerSortsUnicodeStringsInTheSameOrderAsServer {
900+
FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
901+
@"a" : @{@"value" : @"Łukasiewicz"},
902+
@"b" : @{@"value" : @"Sierpiński"},
903+
@"c" : @{@"value" : @"岩澤"},
904+
@"d" : @{@"value" : @"🄟"},
905+
@"e" : @{@"value" : @""},
906+
@"f" : @{@"value" : @""},
907+
@"g" : @{@"value" : @"🐵"}
908+
909+
}];
910+
911+
FIRQuery *query = [collRef queryOrderedByField:@"value"];
912+
NSArray<NSString *> *expectedDocs = @[ @"b", @"a", @"c", @"f", @"e", @"d", @"g" ];
913+
FIRQuerySnapshot *getSnapshot = [self readDocumentSetForRef:query];
914+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(getSnapshot), expectedDocs);
915+
916+
id<FIRListenerRegistration> registration =
917+
[query addSnapshotListener:self.eventAccumulator.valueEventHandler];
918+
FIRQuerySnapshot *watchSnapshot = [self.eventAccumulator awaitEventWithName:@"Snapshot"];
919+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(watchSnapshot), expectedDocs);
920+
921+
[registration remove];
922+
923+
[self checkOnlineAndOfflineQuery:query matchesResult:expectedDocs];
924+
}
925+
926+
- (void)testSnapshotListenerSortsUnicodeStringsInArrayInTheSameOrderAsServer {
927+
FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
928+
@"a" : @{@"value" : @[ @"Łukasiewicz" ]},
929+
@"b" : @{@"value" : @[ @"Sierpiński" ]},
930+
@"c" : @{@"value" : @[ @"岩澤" ]},
931+
@"d" : @{@"value" : @[ @"🄟" ]},
932+
@"e" : @{@"value" : @[ @"" ]},
933+
@"f" : @{@"value" : @[ @"" ]},
934+
@"g" : @{@"value" : @[ @"🐵" ]}
935+
936+
}];
937+
938+
FIRQuery *query = [collRef queryOrderedByField:@"value"];
939+
NSArray<NSString *> *expectedDocs = @[ @"b", @"a", @"c", @"f", @"e", @"d", @"g" ];
940+
FIRQuerySnapshot *getSnapshot = [self readDocumentSetForRef:query];
941+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(getSnapshot), expectedDocs);
942+
943+
id<FIRListenerRegistration> registration =
944+
[query addSnapshotListener:self.eventAccumulator.valueEventHandler];
945+
FIRQuerySnapshot *watchSnapshot = [self.eventAccumulator awaitEventWithName:@"Snapshot"];
946+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(watchSnapshot), expectedDocs);
947+
948+
[registration remove];
949+
950+
[self checkOnlineAndOfflineQuery:query matchesResult:expectedDocs];
951+
}
952+
953+
- (void)testSnapshotListenerSortsUnicodeStringsInMapInTheSameOrderAsServer {
954+
FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
955+
@"a" : @{@"value" : @{@"foo" : @"Łukasiewicz"}},
956+
@"b" : @{@"value" : @{@"foo" : @"Sierpiński"}},
957+
@"c" : @{@"value" : @{@"foo" : @"岩澤"}},
958+
@"d" : @{@"value" : @{@"foo" : @"🄟"}},
959+
@"e" : @{@"value" : @{@"foo" : @""}},
960+
@"f" : @{@"value" : @{@"foo" : @""}},
961+
@"g" : @{@"value" : @{@"foo" : @"🐵"}}
962+
963+
}];
964+
965+
FIRQuery *query = [collRef queryOrderedByField:@"value"];
966+
NSArray<NSString *> *expectedDocs = @[ @"b", @"a", @"c", @"f", @"e", @"d", @"g" ];
967+
FIRQuerySnapshot *getSnapshot = [self readDocumentSetForRef:query];
968+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(getSnapshot), expectedDocs);
969+
970+
id<FIRListenerRegistration> registration =
971+
[query addSnapshotListener:self.eventAccumulator.valueEventHandler];
972+
FIRQuerySnapshot *watchSnapshot = [self.eventAccumulator awaitEventWithName:@"Snapshot"];
973+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(watchSnapshot), expectedDocs);
974+
975+
[registration remove];
976+
977+
[self checkOnlineAndOfflineQuery:query matchesResult:expectedDocs];
978+
}
979+
980+
- (void)testSnapshotListenerSortsUnicodeStringsInMapKeyInTheSameOrderAsServer {
981+
FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
982+
@"a" : @{@"value" : @{@"Łukasiewicz" : @"foo"}},
983+
@"b" : @{@"value" : @{@"Sierpiński" : @"foo"}},
984+
@"c" : @{@"value" : @{@"岩澤" : @"foo"}},
985+
@"d" : @{@"value" : @{@"🄟" : @"foo"}},
986+
@"e" : @{@"value" : @{@"" : @"foo"}},
987+
@"f" : @{@"value" : @{@"" : @"foo"}},
988+
@"g" : @{@"value" : @{@"🐵" : @"foo"}}
989+
990+
}];
991+
992+
FIRQuery *query = [collRef queryOrderedByField:@"value"];
993+
NSArray<NSString *> *expectedDocs = @[ @"b", @"a", @"c", @"f", @"e", @"d", @"g" ];
994+
FIRQuerySnapshot *getSnapshot = [self readDocumentSetForRef:query];
995+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(getSnapshot), expectedDocs);
996+
997+
id<FIRListenerRegistration> registration =
998+
[query addSnapshotListener:self.eventAccumulator.valueEventHandler];
999+
FIRQuerySnapshot *watchSnapshot = [self.eventAccumulator awaitEventWithName:@"Snapshot"];
1000+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(watchSnapshot), expectedDocs);
1001+
1002+
[registration remove];
1003+
1004+
[self checkOnlineAndOfflineQuery:query matchesResult:expectedDocs];
1005+
}
1006+
1007+
- (void)testSnapshotListenerSortsUnicodeStringsInDocumentKeyInTheSameOrderAsServer {
1008+
FIRCollectionReference *collRef = [self collectionRefWithDocuments:@{
1009+
@"Łukasiewicz" : @{@"value" : @"foo"},
1010+
@"Sierpiński" : @{@"value" : @"foo"},
1011+
@"岩澤" : @{@"value" : @"foo"},
1012+
@"🄟" : @{@"value" : @"foo"},
1013+
@"" : @{@"value" : @"foo"},
1014+
@"" : @{@"value" : @"foo"},
1015+
@"🐵" : @{@"value" : @"foo"}
1016+
1017+
}];
1018+
1019+
FIRQuery *query = [collRef queryOrderedByFieldPath:[FIRFieldPath documentID]];
1020+
NSArray<NSString *> *expectedDocs =
1021+
@[ @"Sierpiński", @"Łukasiewicz", @"岩澤", @"", @"", @"🄟", @"🐵" ];
1022+
FIRQuerySnapshot *getSnapshot = [self readDocumentSetForRef:query];
1023+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(getSnapshot), expectedDocs);
1024+
1025+
id<FIRListenerRegistration> registration =
1026+
[query addSnapshotListener:self.eventAccumulator.valueEventHandler];
1027+
FIRQuerySnapshot *watchSnapshot = [self.eventAccumulator awaitEventWithName:@"Snapshot"];
1028+
XCTAssertEqualObjects(FIRQuerySnapshotGetIDs(watchSnapshot), expectedDocs);
1029+
1030+
[registration remove];
1031+
1032+
[self checkOnlineAndOfflineQuery:query matchesResult:expectedDocs];
1033+
}
1034+
8991035
- (void)testCollectionGroupQueriesWithWhereFiltersOnArbitraryDocumentIDs {
9001036
// Use .document() to get a random collection group name to use but ensure it starts with 'b'
9011037
// for predictable ordering.

0 commit comments

Comments
 (0)