Skip to content

Commit 2d93fc2

Browse files
committed
add more tests
1 parent ca556a2 commit 2d93fc2

File tree

4 files changed

+184
-40
lines changed

4 files changed

+184
-40
lines changed

packages/firestore/src/model/path.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import { Integer } from '@firebase/webchannel-wrapper/bloom-blob';
1919

20+
import { compareUtf8Strings } from '../model/values';
2021
import { debugAssert, fail } from '../util/assert';
2122
import { Code, FirestoreError } from '../util/error';
2223

@@ -201,13 +202,7 @@ abstract class BasePath<B extends BasePath<B>> {
201202
);
202203
} else {
203204
// both non-numeric
204-
if (lhs < rhs) {
205-
return -1;
206-
}
207-
if (lhs > rhs) {
208-
return 1;
209-
}
210-
return 0;
205+
return compareUtf8Strings(lhs, rhs);
211206
}
212207
}
213208

packages/firestore/src/model/values.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,7 @@ export function valueCompare(left: Value, right: Value): number {
251251
getLocalWriteTime(right)
252252
);
253253
case TypeOrder.StringValue:
254-
return compareBlobs(stringValueToUint8Array(left.stringValue!),stringValueToUint8Array(right.stringValue!))
255-
// return compareBlobs(left.stringValue!, right.stringValue!);
254+
return compareUtf8Strings(left.stringValue!, right.stringValue!);
256255
// return primitiveComparator(left.stringValue!, right.stringValue!);
257256
case TypeOrder.BlobValue:
258257
return compareBlobs(left.bytesValue!, right.bytesValue!);
@@ -277,6 +276,12 @@ function stringValueToUint8Array(stringValue: string): Uint8Array {
277276
return encoder.encode(stringValue);
278277
}
279278

279+
export function compareUtf8Strings(left: string, right: string): number {
280+
const leftBytes = stringValueToUint8Array(left);
281+
const rightBytes = stringValueToUint8Array(right);
282+
return compareBlobs(leftBytes, rightBytes);
283+
}
284+
280285
function compareNumbers(left: Value, right: Value): number {
281286
const leftNumber = normalizeNumber(left.integerValue || left.doubleValue);
282287
const rightNumber = normalizeNumber(right.integerValue || right.doubleValue);
@@ -408,7 +413,7 @@ function compareMaps(left: MapValue, right: MapValue): number {
408413
rightKeys.sort();
409414

410415
for (let i = 0; i < leftKeys.length && i < rightKeys.length; ++i) {
411-
const keyCompare = primitiveComparator(leftKeys[i], rightKeys[i]);
416+
const keyCompare = compareUtf8Strings(leftKeys[i], rightKeys[i]);
412417
if (keyCompare !== 0) {
413418
return keyCompare;
414419
}

packages/firestore/test/integration/api/database.test.ts

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,4 +2424,176 @@ apiDescribe('Database', persistence => {
24242424
});
24252425
});
24262426
});
2427+
2428+
describe('Unicode strings', () => {
2429+
it('snapshot listener sorts unicode strings the same as server', async () => {
2430+
const testDocs = {
2431+
'a': { value: 'Łukasiewicz' },
2432+
'b': { value: 'Sierpiński' },
2433+
'c': { value: '岩澤' },
2434+
'd': { value: '🄟' },
2435+
'e': { value: 'P' },
2436+
'f': { value: '︒' },
2437+
'g': { value: '🐵' }
2438+
};
2439+
2440+
return withTestCollection(persistence, testDocs, async collectionRef => {
2441+
const orderedQuery = query(collectionRef, orderBy('value'));
2442+
2443+
const getSnapshot = await getDocsFromServer(orderedQuery);
2444+
expect(toIds(getSnapshot)).to.deep.equal([
2445+
'b',
2446+
'a',
2447+
'c',
2448+
'f',
2449+
'e',
2450+
'd',
2451+
'g'
2452+
]);
2453+
2454+
const storeEvent = new EventsAccumulator<QuerySnapshot>();
2455+
const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent);
2456+
const watchSnapshot = await storeEvent.awaitEvent();
2457+
expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot));
2458+
2459+
unsubscribe();
2460+
});
2461+
});
2462+
2463+
it('snapshot listener sorts unicode strings in array the same as server', async () => {
2464+
const testDocs = {
2465+
'a': { value: ['Łukasiewicz'] },
2466+
'b': { value: ['Sierpiński'] },
2467+
'c': { value: ['岩澤'] },
2468+
'd': { value: ['🄟'] },
2469+
'e': { value: ['P'] },
2470+
'f': { value: ['︒'] },
2471+
'g': { value: ['🐵'] }
2472+
};
2473+
2474+
return withTestCollection(persistence, testDocs, async collectionRef => {
2475+
const orderedQuery = query(collectionRef, orderBy('value'));
2476+
2477+
const getSnapshot = await getDocsFromServer(orderedQuery);
2478+
expect(toIds(getSnapshot)).to.deep.equal([
2479+
'b',
2480+
'a',
2481+
'c',
2482+
'f',
2483+
'e',
2484+
'd',
2485+
'g'
2486+
]);
2487+
2488+
const storeEvent = new EventsAccumulator<QuerySnapshot>();
2489+
const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent);
2490+
const watchSnapshot = await storeEvent.awaitEvent();
2491+
expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot));
2492+
2493+
unsubscribe();
2494+
});
2495+
});
2496+
2497+
it('snapshot listener sorts unicode strings in map the same as server', async () => {
2498+
const testDocs = {
2499+
'a': { value: { foo: 'Łukasiewicz' } },
2500+
'b': { value: { foo: 'Sierpiński' } },
2501+
'c': { value: { foo: '岩澤' } },
2502+
'd': { value: { foo: '🄟' } },
2503+
'e': { value: { foo: 'P' } },
2504+
'f': { value: { foo: '︒' } },
2505+
'g': { value: { foo: '🐵' } }
2506+
};
2507+
2508+
return withTestCollection(persistence, testDocs, async collectionRef => {
2509+
const orderedQuery = query(collectionRef, orderBy('value'));
2510+
2511+
const getSnapshot = await getDocsFromServer(orderedQuery);
2512+
expect(toIds(getSnapshot)).to.deep.equal([
2513+
'b',
2514+
'a',
2515+
'c',
2516+
'f',
2517+
'e',
2518+
'd',
2519+
'g'
2520+
]);
2521+
2522+
const storeEvent = new EventsAccumulator<QuerySnapshot>();
2523+
const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent);
2524+
const watchSnapshot = await storeEvent.awaitEvent();
2525+
expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot));
2526+
2527+
unsubscribe();
2528+
});
2529+
});
2530+
2531+
it('snapshot listener sorts unicode strings in map key the same as server', async () => {
2532+
const testDocs = {
2533+
'a': { value: { 'Łukasiewicz': true } },
2534+
'b': { value: { 'Sierpiński': true } },
2535+
'c': { value: { '岩澤': true } },
2536+
'd': { value: { '🄟': true } },
2537+
'e': { value: { 'P': true } },
2538+
'f': { value: { '︒': true } },
2539+
'g': { value: { '🐵': true } }
2540+
};
2541+
2542+
return withTestCollection(persistence, testDocs, async collectionRef => {
2543+
const orderedQuery = query(collectionRef, orderBy('value'));
2544+
2545+
const getSnapshot = await getDocsFromServer(orderedQuery);
2546+
expect(toIds(getSnapshot)).to.deep.equal([
2547+
'b',
2548+
'a',
2549+
'c',
2550+
'f',
2551+
'e',
2552+
'd',
2553+
'g'
2554+
]);
2555+
2556+
const storeEvent = new EventsAccumulator<QuerySnapshot>();
2557+
const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent);
2558+
const watchSnapshot = await storeEvent.awaitEvent();
2559+
expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot));
2560+
2561+
unsubscribe();
2562+
});
2563+
});
2564+
2565+
// it('snapshot listener sorts unicode strings in document key the same as server', async () => {
2566+
// const testDocs = {
2567+
// 'Łukasiewicz': { value: true },
2568+
// 'Sierpiński': { value: true },
2569+
// '岩澤': { value: true },
2570+
// '🄟': { value: true },
2571+
// 'P': { value: true },
2572+
// '︒': { value: true },
2573+
// '🐵': { value: true }
2574+
// };
2575+
//
2576+
// return withTestCollection(persistence, testDocs, async collectionRef => {
2577+
// const orderedQuery = query(collectionRef, orderBy('value'));
2578+
//
2579+
// const getSnapshot = await getDocsFromServer(orderedQuery);
2580+
// expect(toIds(getSnapshot)).to.deep.equal([
2581+
// 'Sierpiński',
2582+
// 'Łukasiewicz',
2583+
// '岩澤',
2584+
// '︒',
2585+
// 'P',
2586+
// '🄟',
2587+
// '🐵'
2588+
// ]);
2589+
//
2590+
// const storeEvent = new EventsAccumulator<QuerySnapshot>();
2591+
// const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent);
2592+
// const watchSnapshot = await storeEvent.awaitEvent();
2593+
// expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot));
2594+
//
2595+
// unsubscribe();
2596+
// });
2597+
// });
2598+
});
24272599
});

packages/firestore/test/integration/api/query.test.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ import {
5454
writeBatch,
5555
CollectionReference,
5656
WriteBatch,
57-
Firestore,
58-
getDocsFromServer
57+
Firestore
5958
} from '../util/firebase_export';
6059
import {
6160
apiDescribe,
@@ -67,8 +66,7 @@ import {
6766
withRetry,
6867
withTestCollection,
6968
withTestDb,
70-
checkOnlineAndOfflineResultsMatch,
71-
toIds
69+
checkOnlineAndOfflineResultsMatch
7270
} from '../util/helpers';
7371
import { USE_EMULATOR } from '../util/settings';
7472
import { captureExistenceFilterMismatches } from '../util/testing_hooks_util';
@@ -2220,32 +2218,6 @@ apiDescribe('Queries', persistence => {
22202218
}
22212219
).timeout('90s');
22222220

2223-
it('snapshot listener sorts unicode strings the same way as server', async () => {
2224-
const testDocs = {
2225-
'a': { value: 'Łukasiewicz' },
2226-
'b': { value: 'Sierpiński' },
2227-
'c': { value: '岩澤' },
2228-
'd': { value: '🄟' },
2229-
'e': { value: 'P' },
2230-
'f': { value: '︒' },
2231-
'g': { value: '🐵' },
2232-
};
2233-
2234-
return withTestCollection(persistence, testDocs, async collectionRef => {
2235-
const orderedQuery = query(collectionRef, orderBy('value'));
2236-
2237-
const getSnapshot = await getDocsFromServer(orderedQuery);
2238-
expect(toIds(getSnapshot)).to.deep.equal(["b", "a", "c", "f", "e", "d", "g"]);
2239-
2240-
const storeEvent = new EventsAccumulator<QuerySnapshot>();
2241-
const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent);
2242-
const watchSnapshot = await storeEvent.awaitEvent();
2243-
expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot));
2244-
2245-
unsubscribe();
2246-
});
2247-
});
2248-
22492221
it('can query large documents with multi-byte character strings', () => {
22502222
function randomMultiByteCharString(length: number): string {
22512223
const charCodes: number[] = [];

0 commit comments

Comments
 (0)