diff --git a/src/rx-storage-helper.ts b/src/rx-storage-helper.ts index 79d91a52a5b..a4c9bf883e0 100644 --- a/src/rx-storage-helper.ts +++ b/src/rx-storage-helper.ts @@ -909,6 +909,7 @@ export function randomDelayStorage( storage: RxStorage; delayTimeBefore: () => number; delayTimeAfter: () => number; + longQueryTime?: number; } ): RxStorage { /** @@ -948,8 +949,13 @@ export function randomDelayStorage( return ret; }, async query(a) { - await promiseWait(input.delayTimeBefore()); + if (!input.longQueryTime) { + await promiseWait(input.delayTimeBefore()); + } const ret = await storageInstance.query(a); + if (input.longQueryTime) { + await promiseWait(input.delayTimeBefore() + input.longQueryTime); + } return ret; }, async count(a) { diff --git a/test/unit/config.ts b/test/unit/config.ts index 360a1135f44..6a5b42e26c5 100644 --- a/test/unit/config.ts +++ b/test/unit/config.ts @@ -59,6 +59,9 @@ export function getStorage(storageKey: string): RxTestStorage { return CUSTOM_STORAGE; } + const delayFn = () => randomNumber(10, 50); + // const delayFn = () => 150; + switch (storageKey) { case 'memory': return { @@ -82,9 +85,6 @@ export function getStorage(storageKey: string): RxTestStorage { */ case 'memory-random-delay': - const delayFn = () => randomNumber(10, 50); - // const delayFn = () => 150; - return { name: storageKey, getStorage: () => wrappedValidateAjvStorage({ @@ -112,6 +112,37 @@ export function getStorage(storageKey: string): RxTestStorage { hasReplication: true }; break; + case 'memory-long-query-delay': + + return { + name: storageKey, + getStorage: () => wrappedValidateAjvStorage({ + storage: randomDelayStorage({ + storage: getRxStorageMemory({ + }), + delayTimeBefore: delayFn, + delayTimeAfter: delayFn, + longQueryTime: 2000, + }) + }), + getPerformanceStorage() { + return { + description: 'memory-long-query-delay', + storage: randomDelayStorage({ + storage: getRxStorageMemory({ + }), + delayTimeBefore: delayFn, + delayTimeAfter: delayFn, + longQueryTime: 2000, + }) + }; + }, + hasPersistence: true, + hasMultiInstance: true, + hasAttachments: false, + hasReplication: true + }; + break; case 'localstorage': return { diff --git a/test/unit/reactive-query.test.ts b/test/unit/reactive-query.test.ts index 20e821474ff..aa1f8f07885 100644 --- a/test/unit/reactive-query.test.ts +++ b/test/unit/reactive-query.test.ts @@ -156,21 +156,65 @@ describeParallel('reactive-query.test.js', () => { return; } - const c = await humansCollection.create(1); - let result = []; - c.insert(schemaObjects.humanData()); // do not await here! - c.find().$.subscribe(r => { + if (config.storage.name === 'sqlite-trial') { + // sqlite cannot insert too many rows + return; + } + const c = await humansCollection.create(0); + let docSize = 0; + const genId = () => { + if (typeof crypto === 'object' && 'randomUUID' in crypto) { + return crypto.randomUUID(); + } + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (cc) => { + const r = Math.random() * 16 | 0; + return (cc === 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); + }; + + for (let i = 0; i < 1; i++) { + const len = 3000; + docSize += len; + const docs = Array.from({ length: len }, () => { + const id = genId(); + return schemaObjects.humanData(id); + }); + await c.bulkInsert(docs); + } + + let result: RxDocument<{ + firstName: string; + lastName: string; + passportId: string; + age?: number | undefined; + }, {}>[] = []; + + let done = false; + let insertLen = 0; + + c.find({ sort: [{ age: 'asc', passportId: 'asc', lastName: 'desc', firstName: 'asc' }] }).$.subscribe(r => { + done = true; result = r; }); - await c.insert(schemaObjects.humanData()); - await waitUntil(() => result.length === 3); - // should still have correct results after some time + (async () => { + while (!done) { + await wait(2); + const id = genId(); + c.insert(schemaObjects.humanData(id)); + insertLen++; + } + })(); + + + await waitUntil(() => done); + await waitUntil(() => result.length === insertLen + docSize); await wait(50); - assert.strictEqual(result.length, 3); + assert.strictEqual(result.length, insertLen + docSize); c.database.close(); + }); }); describe('negative', () => {