@@ -2424,4 +2424,243 @@ apiDescribe('Database', persistence => {
24242424 } ) ;
24252425 } ) ;
24262426 } ) ;
2427+
2428+ describe ( 'Sort unicode strings' , ( ) => {
2429+ const expectedDocs = [
2430+ 'b' ,
2431+ 'a' ,
2432+ 'h' ,
2433+ 'i' ,
2434+ 'c' ,
2435+ 'f' ,
2436+ 'e' ,
2437+ 'd' ,
2438+ 'g' ,
2439+ 'k' ,
2440+ 'j'
2441+ ] ;
2442+ it ( 'snapshot listener sorts unicode strings the same as server' , async ( ) => {
2443+ const testDocs = {
2444+ 'a' : { value : 'Łukasiewicz' } ,
2445+ 'b' : { value : 'Sierpiński' } ,
2446+ 'c' : { value : '岩澤' } ,
2447+ 'd' : { value : '🄟' } ,
2448+ 'e' : { value : 'P' } ,
2449+ 'f' : { value : '︒' } ,
2450+ 'g' : { value : '🐵' } ,
2451+ 'h' : { value : '你好' } ,
2452+ 'i' : { value : '你顥' } ,
2453+ 'j' : { value : '😁' } ,
2454+ 'k' : { value : '😀' }
2455+ } ;
2456+
2457+ return withTestCollection ( persistence , testDocs , async collectionRef => {
2458+ const orderedQuery = query ( collectionRef , orderBy ( 'value' ) ) ;
2459+
2460+ const getSnapshot = await getDocsFromServer ( orderedQuery ) ;
2461+ expect ( toIds ( getSnapshot ) ) . to . deep . equal ( expectedDocs ) ;
2462+
2463+ const storeEvent = new EventsAccumulator < QuerySnapshot > ( ) ;
2464+ const unsubscribe = onSnapshot ( orderedQuery , storeEvent . storeEvent ) ;
2465+ const watchSnapshot = await storeEvent . awaitEvent ( ) ;
2466+ expect ( toIds ( watchSnapshot ) ) . to . deep . equal ( toIds ( getSnapshot ) ) ;
2467+
2468+ unsubscribe ( ) ;
2469+
2470+ await checkOnlineAndOfflineResultsMatch ( orderedQuery , ...expectedDocs ) ;
2471+ } ) ;
2472+ } ) ;
2473+
2474+ it ( 'snapshot listener sorts unicode strings in array the same as server' , async ( ) => {
2475+ const testDocs = {
2476+ 'a' : { value : [ 'Łukasiewicz' ] } ,
2477+ 'b' : { value : [ 'Sierpiński' ] } ,
2478+ 'c' : { value : [ '岩澤' ] } ,
2479+ 'd' : { value : [ '🄟' ] } ,
2480+ 'e' : { value : [ 'P' ] } ,
2481+ 'f' : { value : [ '︒' ] } ,
2482+ 'g' : { value : [ '🐵' ] } ,
2483+ 'h' : { value : [ '你好' ] } ,
2484+ 'i' : { value : [ '你顥' ] } ,
2485+ 'j' : { value : [ '😁' ] } ,
2486+ 'k' : { value : [ '😀' ] }
2487+ } ;
2488+
2489+ return withTestCollection ( persistence , testDocs , async collectionRef => {
2490+ const orderedQuery = query ( collectionRef , orderBy ( 'value' ) ) ;
2491+
2492+ const getSnapshot = await getDocsFromServer ( orderedQuery ) ;
2493+ expect ( toIds ( getSnapshot ) ) . to . deep . equal ( expectedDocs ) ;
2494+
2495+ const storeEvent = new EventsAccumulator < QuerySnapshot > ( ) ;
2496+ const unsubscribe = onSnapshot ( orderedQuery , storeEvent . storeEvent ) ;
2497+ const watchSnapshot = await storeEvent . awaitEvent ( ) ;
2498+ expect ( toIds ( watchSnapshot ) ) . to . deep . equal ( toIds ( getSnapshot ) ) ;
2499+
2500+ unsubscribe ( ) ;
2501+
2502+ await checkOnlineAndOfflineResultsMatch ( orderedQuery , ...expectedDocs ) ;
2503+ } ) ;
2504+ } ) ;
2505+
2506+ it ( 'snapshot listener sorts unicode strings in map the same as server' , async ( ) => {
2507+ const testDocs = {
2508+ 'a' : { value : { foo : 'Łukasiewicz' } } ,
2509+ 'b' : { value : { foo : 'Sierpiński' } } ,
2510+ 'c' : { value : { foo : '岩澤' } } ,
2511+ 'd' : { value : { foo : '🄟' } } ,
2512+ 'e' : { value : { foo : 'P' } } ,
2513+ 'f' : { value : { foo : '︒' } } ,
2514+ 'g' : { value : { foo : '🐵' } } ,
2515+ 'h' : { value : { foo : '你好' } } ,
2516+ 'i' : { value : { foo : '你顥' } } ,
2517+ 'j' : { value : { foo : '😁' } } ,
2518+ 'k' : { value : { foo : '😀' } }
2519+ } ;
2520+
2521+ return withTestCollection ( persistence , testDocs , async collectionRef => {
2522+ const orderedQuery = query ( collectionRef , orderBy ( 'value' ) ) ;
2523+
2524+ const getSnapshot = await getDocsFromServer ( orderedQuery ) ;
2525+ expect ( toIds ( getSnapshot ) ) . to . deep . equal ( expectedDocs ) ;
2526+
2527+ const storeEvent = new EventsAccumulator < QuerySnapshot > ( ) ;
2528+ const unsubscribe = onSnapshot ( orderedQuery , storeEvent . storeEvent ) ;
2529+ const watchSnapshot = await storeEvent . awaitEvent ( ) ;
2530+ expect ( toIds ( watchSnapshot ) ) . to . deep . equal ( toIds ( getSnapshot ) ) ;
2531+
2532+ unsubscribe ( ) ;
2533+
2534+ await checkOnlineAndOfflineResultsMatch ( orderedQuery , ...expectedDocs ) ;
2535+ } ) ;
2536+ } ) ;
2537+
2538+ it ( 'snapshot listener sorts unicode strings in map key the same as server' , async ( ) => {
2539+ const testDocs = {
2540+ 'a' : { value : { 'Łukasiewicz' : true } } ,
2541+ 'b' : { value : { 'Sierpiński' : true } } ,
2542+ 'c' : { value : { '岩澤' : true } } ,
2543+ 'd' : { value : { '🄟' : true } } ,
2544+ 'e' : { value : { 'P' : true } } ,
2545+ 'f' : { value : { '︒' : true } } ,
2546+ 'g' : { value : { '🐵' : true } } ,
2547+ 'h' : { value : { '你好' : true } } ,
2548+ 'i' : { value : { '你顥' : true } } ,
2549+ 'j' : { value : { '😁' : true } } ,
2550+ 'k' : { value : { '😀' : true } }
2551+ } ;
2552+
2553+ return withTestCollection ( persistence , testDocs , async collectionRef => {
2554+ const orderedQuery = query ( collectionRef , orderBy ( 'value' ) ) ;
2555+
2556+ const getSnapshot = await getDocsFromServer ( orderedQuery ) ;
2557+ expect ( toIds ( getSnapshot ) ) . to . deep . equal ( expectedDocs ) ;
2558+
2559+ const storeEvent = new EventsAccumulator < QuerySnapshot > ( ) ;
2560+ const unsubscribe = onSnapshot ( orderedQuery , storeEvent . storeEvent ) ;
2561+ const watchSnapshot = await storeEvent . awaitEvent ( ) ;
2562+ expect ( toIds ( watchSnapshot ) ) . to . deep . equal ( toIds ( getSnapshot ) ) ;
2563+
2564+ unsubscribe ( ) ;
2565+
2566+ await checkOnlineAndOfflineResultsMatch ( orderedQuery , ...expectedDocs ) ;
2567+ } ) ;
2568+ } ) ;
2569+
2570+ it ( 'snapshot listener sorts unicode strings in document key the same as server' , async ( ) => {
2571+ const testDocs = {
2572+ 'Łukasiewicz' : { value : true } ,
2573+ 'Sierpiński' : { value : true } ,
2574+ '岩澤' : { value : true } ,
2575+ '🄟' : { value : true } ,
2576+ 'P' : { value : true } ,
2577+ '︒' : { value : true } ,
2578+ '🐵' : { value : true } ,
2579+ '你好' : { value : true } ,
2580+ '你顥' : { value : true } ,
2581+ '😁' : { value : true } ,
2582+ '😀' : { value : true }
2583+ } ;
2584+
2585+ return withTestCollection ( persistence , testDocs , async collectionRef => {
2586+ const orderedQuery = query ( collectionRef , orderBy ( documentId ( ) ) ) ;
2587+
2588+ const getSnapshot = await getDocsFromServer ( orderedQuery ) ;
2589+ const expectedDocs = [
2590+ 'Sierpiński' ,
2591+ 'Łukasiewicz' ,
2592+ '你好' ,
2593+ '你顥' ,
2594+ '岩澤' ,
2595+ '︒' ,
2596+ 'P' ,
2597+ '🄟' ,
2598+ '🐵' ,
2599+ '😀' ,
2600+ '😁'
2601+ ] ;
2602+ expect ( toIds ( getSnapshot ) ) . to . deep . equal ( expectedDocs ) ;
2603+
2604+ const storeEvent = new EventsAccumulator < QuerySnapshot > ( ) ;
2605+ const unsubscribe = onSnapshot ( orderedQuery , storeEvent . storeEvent ) ;
2606+ const watchSnapshot = await storeEvent . awaitEvent ( ) ;
2607+ expect ( toIds ( watchSnapshot ) ) . to . deep . equal ( toIds ( getSnapshot ) ) ;
2608+
2609+ unsubscribe ( ) ;
2610+
2611+ await checkOnlineAndOfflineResultsMatch ( orderedQuery , ...expectedDocs ) ;
2612+ } ) ;
2613+ } ) ;
2614+
2615+ // eslint-disable-next-line no-restricted-properties
2616+ ( persistence . storage === 'indexeddb' ? it . skip : it ) (
2617+ 'snapshot listener sorts unicode strings in document key the same as server with persistence' ,
2618+ async ( ) => {
2619+ const testDocs = {
2620+ 'Łukasiewicz' : { value : true } ,
2621+ 'Sierpiński' : { value : true } ,
2622+ '岩澤' : { value : true } ,
2623+ '🄟' : { value : true } ,
2624+ 'P' : { value : true } ,
2625+ '︒' : { value : true } ,
2626+ '🐵' : { value : true } ,
2627+ '你好' : { value : true } ,
2628+ '你顥' : { value : true } ,
2629+ '😁' : { value : true } ,
2630+ '😀' : { value : true }
2631+ } ;
2632+
2633+ return withTestCollection (
2634+ persistence ,
2635+ testDocs ,
2636+ async collectionRef => {
2637+ const orderedQuery = query ( collectionRef , orderBy ( 'value' ) ) ;
2638+
2639+ const getSnapshot = await getDocsFromServer ( orderedQuery ) ;
2640+ expect ( toIds ( getSnapshot ) ) . to . deep . equal ( [
2641+ 'Sierpiński' ,
2642+ 'Łukasiewicz' ,
2643+ '你好' ,
2644+ '你顥' ,
2645+ '岩澤' ,
2646+ '︒' ,
2647+ 'P' ,
2648+ '🄟' ,
2649+ '🐵' ,
2650+ '😀' ,
2651+ '😁'
2652+ ] ) ;
2653+
2654+ const storeEvent = new EventsAccumulator < QuerySnapshot > ( ) ;
2655+ const unsubscribe = onSnapshot ( orderedQuery , storeEvent . storeEvent ) ;
2656+ const watchSnapshot = await storeEvent . awaitEvent ( ) ;
2657+ // TODO: IndexedDB sorts string lexicographically, and misses the document with ID '🄟','🐵'
2658+ expect ( toIds ( watchSnapshot ) ) . to . deep . equal ( toIds ( getSnapshot ) ) ;
2659+
2660+ unsubscribe ( ) ;
2661+ }
2662+ ) ;
2663+ }
2664+ ) ;
2665+ } ) ;
24272666} ) ;
0 commit comments