Skip to content

Commit

Permalink
add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
milaGGL committed Jan 7, 2025
1 parent 22b89e8 commit 24fddb0
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 28 deletions.
8 changes: 4 additions & 4 deletions dev/src/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function compareObjects(left: ApiMapValue, right: ApiMapValue): number {
leftKeys.sort();
rightKeys.sort();
for (let i = 0; i < leftKeys.length && i < rightKeys.length; i++) {
const keyComparison = primitiveComparator(leftKeys[i], rightKeys[i]);
const keyComparison = compareUtf8Strings(leftKeys[i], rightKeys[i]);
if (keyComparison !== 0) {
return keyComparison;
}
Expand Down Expand Up @@ -252,10 +252,10 @@ function stringToUTF8Bytes(str: string): Uint8Array {
return new TextEncoder().encode(str);
}

function compareUTF8bytes(left: string, right: string): number {
export function compareUtf8Strings(left: string, right: string): number {
const leftBytes = stringToUTF8Bytes(left);
const rightBytes = stringToUTF8Bytes(right);
return Buffer.compare(Buffer.from(leftBytes), Buffer.from(rightBytes));
return compareBlobs(Buffer.from(leftBytes), Buffer.from(rightBytes));
}

/*!
Expand All @@ -279,7 +279,7 @@ export function compare(left: api.IValue, right: api.IValue): number {
case TypeOrder.BOOLEAN:
return primitiveComparator(left.booleanValue!, right.booleanValue!);
case TypeOrder.STRING:
return compareUTF8bytes(left.stringValue!, right.stringValue!);
return compareUtf8Strings(left.stringValue!, right.stringValue!);
case TypeOrder.NUMBER:
return compareNumberProtos(left, right);
case TypeOrder.TIMESTAMP:
Expand Down
3 changes: 2 additions & 1 deletion dev/src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import * as firestore from '@google-cloud/firestore';

import {google} from '../protos/firestore_v1_proto_api';
import {compareUtf8Strings} from './order';

import {isObject} from './util';
import {
Expand Down Expand Up @@ -191,7 +192,7 @@ abstract class Path<T> {
);
} else {
// both non-numeric
return this.compareStrings(lhs, rhs);
return compareUtf8Strings(lhs, rhs);
}
}

Expand Down
174 changes: 151 additions & 23 deletions dev/system-test/firestore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4085,34 +4085,162 @@ describe('Query class', () => {
});
});

it('snapshot listener sorts query by unicode strings same way as server', async () => {
const collection = await testCollectionWithDocs({
a: {value: 'Łukasiewicz'},
b: {value: 'Sierpiński'},
c: {value: '岩澤'},
d: {value: '🄟'},
e: {value: 'P'},
f: {value: '︒'},
g: {value: '🐵'},
});
describe('sort unicode strings', () => {
it('snapshot listener sorts query by unicode strings same as server', async () => {
const collection = await testCollectionWithDocs({
a: {value: 'Łukasiewicz'},
b: {value: 'Sierpiński'},
c: {value: '岩澤'},
d: {value: '🄟'},
e: {value: 'P'},
f: {value: '︒'},
g: {value: '🐵'},
});

const query = collection.orderBy("value");
const expectedDocs = ['b', 'a', 'c', 'f', 'e', 'd', 'g'];
const query = collection.orderBy('value');
const expectedDocs = ['b', 'a', 'c', 'f', 'e', 'd', 'g'];

const getSnapshot = await query.get();
expect(getSnapshot.docs.map(d => d.id)).to.deep.equal(expectedDocs);
const getSnapshot = await query.get();
expect(getSnapshot.docs.map(d => d.id)).to.deep.equal(expectedDocs);

const unsubscribe = query.onSnapshot(snapshot =>
currentDeferred.resolve(snapshot)
);
const unsubscribe = query.onSnapshot(snapshot =>
currentDeferred.resolve(snapshot)
);

const watchSnapshot = await waitForSnapshot();
// Compare the snapshot (including sort order) of a snapshot
snapshotsEqual(watchSnapshot, {
docs: getSnapshot.docs,
docChanges: getSnapshot.docChanges(),
const watchSnapshot = await waitForSnapshot();
// Compare the snapshot (including sort order) of a snapshot
snapshotsEqual(watchSnapshot, {
docs: getSnapshot.docs,
docChanges: getSnapshot.docChanges(),
});
unsubscribe();
});

it('snapshot listener sorts query by unicode strings in array same as server', async () => {
const collection = await testCollectionWithDocs({
a: {value: ['Łukasiewicz']},
b: {value: ['Sierpiński']},
c: {value: ['岩澤']},
d: {value: ['🄟']},
e: {value: ['P']},
f: {value: ['︒']},
g: {value: ['🐵']},
});

const query = collection.orderBy('value');
const expectedDocs = ['b', 'a', 'c', 'f', 'e', 'd', 'g'];

const getSnapshot = await query.get();
expect(getSnapshot.docs.map(d => d.id)).to.deep.equal(expectedDocs);

const unsubscribe = query.onSnapshot(snapshot =>
currentDeferred.resolve(snapshot)
);

const watchSnapshot = await waitForSnapshot();
snapshotsEqual(watchSnapshot, {
docs: getSnapshot.docs,
docChanges: getSnapshot.docChanges(),
});
unsubscribe();
});

it('snapshot listener sorts query by unicode strings in map same as server', async () => {
const collection = await testCollectionWithDocs({
a: {value: {foo: 'Łukasiewicz'}},
b: {value: {foo: 'Sierpiński'}},
c: {value: {foo: '岩澤'}},
d: {value: {foo: '🄟'}},
e: {value: {foo: 'P'}},
f: {value: {foo: '︒'}},
g: {value: {foo: '🐵'}},
});

const query = collection.orderBy('value');
const expectedDocs = ['b', 'a', 'c', 'f', 'e', 'd', 'g'];

const getSnapshot = await query.get();
expect(getSnapshot.docs.map(d => d.id)).to.deep.equal(expectedDocs);

const unsubscribe = query.onSnapshot(snapshot =>
currentDeferred.resolve(snapshot)
);

const watchSnapshot = await waitForSnapshot();
// Compare the snapshot (including sort order) of a snapshot
snapshotsEqual(watchSnapshot, {
docs: getSnapshot.docs,
docChanges: getSnapshot.docChanges(),
});
unsubscribe();
});
it('snapshot listener sorts query by unicode strings in map key same as server', async () => {
const collection = await testCollectionWithDocs({
a: {value: {Łukasiewicz: true}},
b: {value: {Sierpiński: true}},
c: {value: {岩澤: true}},
d: {value: {'🄟': true}},
e: {value: {: true}},
f: {value: {'︒': true}},
g: {value: {'🐵': true}},
});

const query = collection.orderBy('value');
const expectedDocs = ['b', 'a', 'c', 'f', 'e', 'd', 'g'];

const getSnapshot = await query.get();
expect(getSnapshot.docs.map(d => d.id)).to.deep.equal(expectedDocs);

const unsubscribe = query.onSnapshot(snapshot =>
currentDeferred.resolve(snapshot)
);

const watchSnapshot = await waitForSnapshot();
// Compare the snapshot (including sort order) of a snapshot
snapshotsEqual(watchSnapshot, {
docs: getSnapshot.docs,
docChanges: getSnapshot.docChanges(),
});
unsubscribe();
});

it('snapshot listener sorts query by unicode strings in document key same as server', async () => {
const collection = await testCollectionWithDocs({
Łukasiewicz: {value: true},
Sierpiński: {value: true},
岩澤: {value: true},
'🄟': {value: true},
: {value: true},
'︒': {value: true},
'🐵': {value: true},
});

const query = collection.orderBy('value');
const expectedDocs = [
'Sierpiński',
'Łukasiewicz',
'岩澤',
'︒',
'P',
'🄟',
'🐵',
];

const getSnapshot = await query.get();
expect(getSnapshot.docs.map(d => d.id)).to.deep.equal(expectedDocs);

const unsubscribe = query.onSnapshot(snapshot =>
currentDeferred.resolve(snapshot)
);

const watchSnapshot = await waitForSnapshot();
// Compare the snapshot (including sort order) of a snapshot
snapshotsEqual(watchSnapshot, {
docs: getSnapshot.docs,
docChanges: getSnapshot.docChanges(),
});
unsubscribe();
});
unsubscribe();
});
});

Expand Down

0 comments on commit 24fddb0

Please sign in to comment.