@@ -2201,16 +2201,43 @@ apiDescribe('Queries', persistence => {
2201
2201
// to send an existence filter.
2202
2202
// eslint-disable-next-line no-restricted-properties
2203
2203
( USE_EMULATOR ? it . skip : it ) (
2204
- 'bloom filter should correctly encode special unicode characters' ,
2204
+ 'bloom filter should correctly encode complex Unicode characters' ,
2205
2205
async ( ) => {
2206
+ // Firestore does not do any Unicode normalization on the document IDs.
2207
+ // Therefore, two document IDs that are canonically-equivalent (i.e. they
2208
+ // visually appear identical) but are represented by a different sequence
2209
+ // of Unicode code points are treated as distinct document IDs.
2206
2210
const testDocIds = [
2207
2211
'DocumentToDelete' ,
2212
+ // The next two strings both end with "e" with an accent: the first uses
2213
+ // the dedicated Unicode code point for this character, while the second
2214
+ // uses the standard lowercase "e" followed by the accent combining
2215
+ // character.
2208
2216
'LowercaseEWithAcuteAccent_\u00E9' ,
2209
2217
'LowercaseEWithAcuteAccent_\u0065\u0301' ,
2218
+ // The next two strings both end with an "e" with two different accents
2219
+ // applied via the following two combining characters. The combining
2220
+ // characters are specified in a different order and Firestore treats
2221
+ // these document IDs as unique, despite the order of the combining
2222
+ // characters being irrelevant.
2210
2223
'LowercaseEWithMultipleAccents_\u0065\u0301\u0327' ,
2211
2224
'LowercaseEWithMultipleAccents_\u0065\u0327\u0301' ,
2225
+ // The next string contains a character outside the BMP (the "basic
2226
+ // multilingual plane"); that is, its code point is greater than 0xFFFF.
2227
+ // In UTF-16 (which JavaScript uses to store Unicode strings) this
2228
+ // requires a surrogate pair, two 16-bit code units, to represent this
2229
+ // character. Make sure that its presence is correctly tested in the
2230
+ // bloom filter, which uses UTF-8 encoding.
2212
2231
'Smiley_\u{1F600}'
2213
2232
] ;
2233
+
2234
+ // Verify assumptions about the equivalence of strings in `testDocIds`.
2235
+ expect ( testDocIds [ 1 ] . normalize ( ) ) . equals ( testDocIds [ 2 ] . normalize ( ) ) ;
2236
+ expect ( testDocIds [ 3 ] . normalize ( ) ) . equals ( testDocIds [ 4 ] . normalize ( ) ) ;
2237
+ expect ( testDocIds [ 5 ] ) . equals ( 'Smiley_\uD83D\uDE00' ) ;
2238
+
2239
+ // Create the mapping from document ID to document data for the document
2240
+ // IDs specified in `testDocIds`.
2214
2241
const testDocs = testDocIds . reduce ( ( map , docId ) => {
2215
2242
map [ docId ] = { foo : 42 } ;
2216
2243
return map ;
0 commit comments