Files
Josh SorefandGitHub b4e60981a5 Spelling (#8280)
Numerous fixes to spelling across the SDK.
2024-07-18 16:53:00 -04:00

352 lines
11 KiB
TypeScript

/**
* @license
* Copyright 2017 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { expect } from 'chai';
import { User } from '../../../src/auth/user';
import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence';
import { Persistence } from '../../../src/local/persistence';
import { documentKeySet } from '../../../src/model/collections';
import { MutationBatch } from '../../../src/model/mutation_batch';
import { addEqualityMatcher } from '../../util/equality_matcher';
import {
expectEqualArrays,
key,
patchMutation,
query,
setMutation
} from '../../util/helpers';
import * as persistenceHelpers from './persistence_test_helpers';
import { TestMutationQueue } from './test_mutation_queue';
let persistence: Persistence;
let mutationQueue: TestMutationQueue;
describe('MemoryMutationQueue', () => {
beforeEach(() => {
return persistenceHelpers.testMemoryEagerPersistence().then(p => {
persistence = p;
});
});
genericMutationQueueTests();
});
describe('IndexedDbMutationQueue', () => {
if (!IndexedDbPersistence.isAvailable()) {
console.warn('No IndexedDB. Skipping IndexedDbMutationQueue tests.');
return;
}
beforeEach(() => {
return persistenceHelpers.testIndexedDbPersistence().then(p => {
persistence = p;
});
});
genericMutationQueueTests();
});
/**
* Defines the set of tests to run against both mutation queue
* implementations.
*/
function genericMutationQueueTests(): void {
addEqualityMatcher();
beforeEach(() => {
mutationQueue = new TestMutationQueue(
persistence,
persistence.getMutationQueue(
new User('user'),
persistence.getIndexManager(new User('user'))
)
);
});
afterEach(async () => {
await persistence.shutdown();
await persistenceHelpers.clearTestPersistence();
});
/**
* Creates a new MutationBatch with the next batch ID and a set of dummy
* mutations.
*/
function addMutationBatch(key?: string): Promise<MutationBatch> {
let keyStr = key;
if (keyStr === undefined) {
keyStr = 'foo/bar';
}
const mutation = setMutation(keyStr, { a: 1 });
return mutationQueue.addMutationBatch([mutation]);
}
/**
* Creates an array of batches containing count dummy MutationBatches. Each
* has a different batchID.
*/
async function createBatches(count: number): Promise<MutationBatch[]> {
const batches: MutationBatch[] = [];
for (let i = 0; i < count; i++) {
const batch = await addMutationBatch();
batches.push(batch);
}
return batches;
}
/**
* Removes the first n entries from the given batches and returns them.
*
* @param n - The number of batches to remove.
* @param batches - The array to mutate, removing entries from it.
* @returns A new array containing all the entries that were removed from
* batches.
*/
async function removeFirstBatches(
n: number,
batches: MutationBatch[]
): Promise<MutationBatch[]> {
const removed: MutationBatch[] = [];
for (let i = 0; i < n; i++) {
const batch = batches[0];
await mutationQueue.removeMutationBatch(batch);
batches.shift();
removed.push(batch);
}
return removed;
}
it('can count batches', async () => {
expect(await mutationQueue.countBatches()).to.equal(0);
expect(await mutationQueue.checkEmpty()).to.equal(true);
const batch1 = await addMutationBatch();
expect(await mutationQueue.countBatches()).to.equal(1);
expect(await mutationQueue.checkEmpty()).to.equal(false);
const batch2 = await addMutationBatch();
expect(await mutationQueue.countBatches()).to.equal(2);
await mutationQueue.removeMutationBatch(batch1);
expect(await mutationQueue.countBatches()).to.equal(1);
await mutationQueue.removeMutationBatch(batch2);
expect(await mutationQueue.countBatches()).to.equal(0);
});
it('can lookup mutation batch', async () => {
// Searching on an empty queue should not find a nonexistent batch
let notFound = await mutationQueue.lookupMutationBatch(42);
expect(notFound).to.be.null;
const batches = await createBatches(10);
const removed = await removeFirstBatches(3, batches);
// After removing, a batch should not be found
for (const batch of removed) {
const notFound = await mutationQueue.lookupMutationBatch(batch.batchId);
expect(notFound).to.be.null;
}
// Remaining entries should still be found
for (const batch of batches) {
const found = await mutationQueue.lookupMutationBatch(batch.batchId);
expect(found!.batchId).to.equal(batch.batchId);
}
// Even on a nonempty queue searching should not find a nonexistent batch
notFound = await mutationQueue.lookupMutationBatch(42);
expect(notFound).to.be.null;
});
it('can getNextMutationBatchAfterBatchId()', async () => {
const batches = await createBatches(10);
const removed = await removeFirstBatches(3, batches);
for (let i = 0; i < batches.length - 1; i++) {
const current = batches[i];
const next = batches[i + 1];
const found = await mutationQueue.getNextMutationBatchAfterBatchId(
current.batchId
);
expect(found!.batchId).to.equal(next.batchId);
}
for (let i = 0; i < removed.length; i++) {
const current = removed[i];
const next = batches[0];
const found = await mutationQueue.getNextMutationBatchAfterBatchId(
current.batchId
);
expect(found!.batchId).to.equal(next.batchId);
}
const first = batches[0];
const found = await mutationQueue.getNextMutationBatchAfterBatchId(
first.batchId - 42
);
expect(found!.batchId).to.equal(first.batchId);
const last = batches[batches.length - 1];
const notFound = await mutationQueue.getNextMutationBatchAfterBatchId(
last.batchId
);
expect(notFound).to.be.null;
});
it('can getAllMutationBatchesAffectingDocumentKey()', async () => {
const mutations = [
setMutation('fob/bar', { a: 1 }),
setMutation('foo/bar', { a: 1 }),
patchMutation('foo/bar', { b: 1 }),
setMutation('foo/bar/suffix/key', { a: 1 }),
setMutation('foo/baz', { a: 1 }),
setMutation('food/bar', { a: 1 })
];
// Store all the mutations.
const batches: MutationBatch[] = [];
for (const mutation of mutations) {
const batch = await mutationQueue.addMutationBatch([mutation]);
batches.push(batch);
}
const expected = [batches[1], batches[2]];
const matches =
await mutationQueue.getAllMutationBatchesAffectingDocumentKey(
key('foo/bar')
);
expectEqualArrays(matches, expected);
});
it('can getAllMutationBatchesAffectingDocumentKeys()', async () => {
const mutations = [
setMutation('fob/bar', { a: 1 }),
setMutation('foo/bar', { a: 1 }),
patchMutation('foo/bar', { b: 1 }),
setMutation('foo/bar/suffix/key', { a: 1 }),
setMutation('foo/baz', { a: 1 }),
setMutation('food/bar', { a: 1 })
];
// Store all the mutations.
const batches: MutationBatch[] = [];
for (const mutation of mutations) {
const batch = await mutationQueue.addMutationBatch([mutation]);
batches.push(batch);
}
const expected = [batches[1], batches[2], batches[4]];
const matches =
await mutationQueue.getAllMutationBatchesAffectingDocumentKeys(
documentKeySet().add(key('foo/bar')).add(key('foo/baz'))
);
expectEqualArrays(matches, expected);
});
it('can getAllMutationBatchesAffectingQuery()', async () => {
const mutations = [
setMutation('fob/bar', { a: 1 }),
setMutation('foo/bar', { a: 1 }),
patchMutation('foo/bar', { b: 1 }),
setMutation('foo/bar/suffix/key', { a: 1 }),
setMutation('foo/baz', { a: 1 }),
setMutation('food/bar', { a: 1 })
];
// Store all the mutations.
const batches: MutationBatch[] = [];
for (const mutation of mutations) {
const batch = await mutationQueue.addMutationBatch([mutation]);
batches.push(batch);
}
const expected = [batches[1], batches[2], batches[4]];
const query1 = query('foo');
const matches = await mutationQueue.getAllMutationBatchesAffectingQuery(
query1
);
expectEqualArrays(matches, expected);
});
it('can getAllMutationBatchesAffectingQuery() with compound batches', async () => {
const value = { a: 1 };
const batch1 = await mutationQueue.addMutationBatch([
setMutation('foo/bar', value),
setMutation('foo/bar/baz/quux', value)
]);
const batch2 = await mutationQueue.addMutationBatch([
setMutation('foo/bar', value),
setMutation('foo/baz', value)
]);
const expected = [batch1, batch2];
const query1 = query('foo');
const matches = await mutationQueue.getAllMutationBatchesAffectingQuery(
query1
);
expectEqualArrays(matches, expected);
});
it('can removeMutationBatch()', async () => {
const batches = await createBatches(10);
await mutationQueue.removeMutationBatch(batches[0]);
batches.splice(0, 1);
expect(await mutationQueue.countBatches()).to.equal(9);
let found;
found = await mutationQueue.getAllMutationBatches();
expectEqualArrays(found, batches);
expect(found.length).to.equal(9);
await mutationQueue.removeMutationBatch(batches[0]);
await mutationQueue.removeMutationBatch(batches[1]);
await mutationQueue.removeMutationBatch(batches[2]);
batches.splice(0, 3);
expect(await mutationQueue.countBatches()).to.equal(6);
found = await mutationQueue.getAllMutationBatches();
expectEqualArrays(found, batches);
expect(found.length).to.equal(6);
await mutationQueue.removeMutationBatch(batches[0]);
batches.shift();
expect(await mutationQueue.countBatches()).to.equal(5);
found = await mutationQueue.getAllMutationBatches();
expectEqualArrays(found, batches);
expect(found.length).to.equal(5);
await mutationQueue.removeMutationBatch(batches[0]);
batches.shift();
expect(await mutationQueue.countBatches()).to.equal(4);
await mutationQueue.removeMutationBatch(batches[0]);
batches.shift();
expect(await mutationQueue.countBatches()).to.equal(3);
found = await mutationQueue.getAllMutationBatches();
expectEqualArrays(found, batches);
expect(found.length).to.equal(3);
expect(await mutationQueue.checkEmpty()).to.equal(false);
for (const batch of batches) {
await mutationQueue.removeMutationBatch(batch);
}
found = await mutationQueue.getAllMutationBatches();
expectEqualArrays(found, []);
expect(found.length).to.equal(0);
expect(await mutationQueue.checkEmpty()).to.equal(true);
});
}