deno.land / x / replicache@v10.0.0-beta.0 / sync / patch.test.ts
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194import {LogContext} from '@rocicorp/logger';import {expect} from '@esm-bundle/chai';import * as dag from '../dag/mod';import * as db from '../db/mod';import type {JSONValue} from '../json';import {addGenesis, Chain} from '../db/test-helpers';import {apply} from './patch';import {assertPatchOperations} from '../puller';
test('patch', async () => { const store = new dag.TestStore(); const lc = new LogContext();
type Case = { name: string; patch: JSONValue; expErr?: string; // Note: the test inserts "key" => "value" into the map prior to // calling apply() so we can check if top-level removes work. expMap?: Map<string, string>; }; const cases: Case[] = [ { name: 'put', patch: [{op: 'put', key: 'foo', value: 'bar'}], expErr: undefined, expMap: new Map([ ['key', 'value'], ['foo', 'bar'], ]), }, { name: 'del', patch: [{op: 'del', key: 'key'}], expErr: undefined, expMap: new Map(), }, { name: 'replace', patch: [{op: 'put', key: 'key', value: 'newvalue'}], expErr: undefined, expMap: new Map([['key', 'newvalue']]), }, { name: 'put empty key', patch: [{op: 'put', key: '', value: 'empty'}], expErr: undefined, expMap: new Map([ ['key', 'value'], ['', 'empty'], ]), }, { name: 'put/replace empty key', patch: [ {op: 'put', key: '', value: 'empty'}, {op: 'put', key: '', value: 'changed'}, ], expErr: undefined, expMap: new Map([ ['key', 'value'], ['', 'changed'], ]), }, { name: 'put/remove empty key', patch: [ {op: 'put', key: '', value: 'empty'}, {op: 'del', key: ''}, ], expErr: undefined, expMap: new Map([['key', 'value']]), }, { name: 'top-level clear', patch: [{op: 'clear'}], expErr: undefined, expMap: new Map(), }, { name: 'compound ops', patch: [ {op: 'put', key: 'foo', value: 'bar'}, {op: 'put', key: 'key', value: 'newvalue'}, {op: 'put', key: 'baz', value: 'baz'}, ], expErr: undefined, expMap: new Map([ ['foo', 'bar'], ['key', 'newvalue'], ['baz', 'baz'], ]), }, { name: 'no escaping 1', patch: [{op: 'put', key: '~1', value: 'bar'}], expErr: undefined, expMap: new Map([ ['key', 'value'], ['~1', 'bar'], ]), }, { name: 'no escaping 2', patch: [{op: 'put', key: '~0', value: 'bar'}], expErr: undefined, expMap: new Map([ ['key', 'value'], ['~0', 'bar'], ]), }, { name: 'no escaping 3', patch: [{op: 'put', key: '/', value: 'bar'}], expErr: undefined, expMap: new Map([ ['key', 'value'], ['/', 'bar'], ]), }, { name: 'invalid op', patch: [{op: 'BOOM', key: 'key'}], expErr: 'unknown patch op `BOOM`, expected one of `put`, `del`, `clear`', expMap: undefined, }, { name: 'invalid key', patch: [{op: 'put', key: 42, value: true}], expErr: 'Invalid type: number `42`, expected string', expMap: undefined, }, { name: 'missing value', patch: [{op: 'put', key: 'k'}], // expErr: 'missing field `value`', expErr: 'Invalid type: undefined, expected JSON value', expMap: undefined, }, { name: 'missing key for del', patch: [{op: 'del'}], // expErr: 'missing field `key`', expErr: 'Invalid type: undefined, expected string', expMap: undefined, }, { name: 'make sure we do not apply parts of the patch', patch: [{op: 'put', key: 'k', value: 42}, {op: 'del'}], // expErr: 'missing field `key`', expErr: 'Invalid type: undefined, expected string', expMap: new Map([['key', 'value']]), }, ];
for (const c of cases) { const chain: Chain = []; await addGenesis(chain, store); await store.withWrite(async dagWrite => { const dbWrite = await db.Write.newSnapshot( db.whenceHash(chain[0].chunk.hash), 1, 'cookie', dagWrite, db.readIndexesForWrite(chain[0]), ); await dbWrite.put(lc, 'key', 'value');
const ops = c.patch;
let err; try { assertPatchOperations(ops); await apply(lc, dbWrite, ops); } catch (e) { err = e; } if (c.expErr) { expect(err).to.be.instanceOf(Error); expect((err as Error).message).to.equal(c.expErr); }
if (c.expMap !== undefined) { for (const [k, v] of c.expMap) { expect(v).to.deep.equal(await dbWrite.get(k)); } if (c.expMap.size === 0) { expect(await dbWrite.has('key')).to.be.false; } } }); }});
Version Info