From 917a4d85645667ded30026b70bf6fd73ffc957d9 Mon Sep 17 00:00:00 2001 From: Chris Masone Date: Thu, 19 May 2016 15:57:45 -0700 Subject: [PATCH] JS: make sure we call close() on Database most of the time Other than DatasetSpec::value(), this should close all Database instances that we create. I'm not sure how to deal with that one case, though. --- js/src/batch-store-test.js | 2 + js/src/batch-store.js | 4 +- js/src/compare-test.js | 5 +- js/src/database-test.js | 7 ++ js/src/database.js | 4 +- js/src/dataset-test.js | 1 + js/src/decode-test.js | 141 +++++++++++++++-------------------- js/src/encode-test.js | 133 +++++++++++++++------------------ js/src/list-test.js | 62 ++++++++------- js/src/map-test.js | 100 ++++++++++++------------- js/src/meta-sequence-test.js | 22 +++--- js/src/put-cache.js | 2 + js/src/set-test.js | 112 +++++++++++++--------------- js/src/specs-test.js | 20 +++-- js/src/specs.js | 5 +- js/src/struct-test.js | 5 +- js/src/test-util.js | 1 + js/src/type-test.js | 15 ++-- js/src/value-store-test.js | 7 ++ js/src/value-store.js | 4 +- js/src/walk-test.js | 9 ++- js/src/xp-test.js | 1 + 22 files changed, 339 insertions(+), 323 deletions(-) diff --git a/js/src/batch-store-test.js b/js/src/batch-store-test.js index e4520b50db..afc55cb222 100644 --- a/js/src/batch-store-test.js +++ b/js/src/batch-store-test.js @@ -18,6 +18,7 @@ suite('BatchStore', () => { const chunk = await bs.get(c.ref); assert.isTrue(c.ref.equals(chunk.ref)); + await bs.close(); }); test('get after schedulePut works after flush', async () => { @@ -34,5 +35,6 @@ suite('BatchStore', () => { await bs.flush(); chunk = await bs.get(c.ref); assert.isTrue(c.ref.equals(chunk.ref)); + await bs.close(); }); }); diff --git a/js/src/batch-store.js b/js/src/batch-store.js index e01db762f2..d9d726ca6b 100644 --- a/js/src/batch-store.js +++ b/js/src/batch-store.js @@ -140,5 +140,7 @@ export default class BatchStore { // TODO: Should close() call flush() and block until it's done? Maybe closing with outstanding // requests should be an error on both sides. TBD. - close() {} + close(): Promise { + return this._pendingWrites.destroy(); + } } diff --git a/js/src/compare-test.js b/js/src/compare-test.js index d427819c8c..a276c6d285 100644 --- a/js/src/compare-test.js +++ b/js/src/compare-test.js @@ -57,7 +57,7 @@ suite('compare.js', () => { }); test('total ordering', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); // values in increasing order. Some of these are compared by ref so changing the serialization // might change the ordering. @@ -67,7 +67,7 @@ suite('compare.js', () => { 'a', 'b', 'c', // The order of these are done by the hash. - ds.writeValue(10), + db.writeValue(10), await newSet([0, 1, 2, 3]), await newMap([[0, 1], [2, 3]]), boolType, @@ -91,6 +91,7 @@ suite('compare.js', () => { } } } + await db.close(); }); }); diff --git a/js/src/database-test.js b/js/src/database-test.js index 47d480927a..b2c3dace03 100644 --- a/js/src/database-test.js +++ b/js/src/database-test.js @@ -27,6 +27,7 @@ suite('Database', () => { const v2 = await ds.readValue(c.ref); assert.equal('abc', v2); + await ds.close(); }); test('commit', async () => { @@ -101,6 +102,7 @@ suite('Database', () => { const newDs = new Database(bs); assert.strictEqual('d', notNull(await newDs.head(datasetID)).value); assert.strictEqual('a', notNull(await newDs.head('otherDs')).value); + await ds.close(); }); test('concurrency', async () => { @@ -139,6 +141,7 @@ suite('Database', () => { } assert.strictEqual('Merge needed', message); assert.strictEqual('c', notNull(await ds.head(datasetID)).value); + await ds.close(); }); @@ -146,6 +149,7 @@ suite('Database', () => { const ds = new Database(makeTestingBatchStore()); const datasets = await ds.datasets(); assert.strictEqual(0, datasets.size); + await ds.close(); }); test('head', async () => { @@ -166,6 +170,7 @@ suite('Database', () => { assert.isTrue(equals(fooHead, commit)); const barHead = await ds.head('bar'); assert.isNull(barHead); + await ds.close(); }); test('height of refs', async () => { @@ -177,6 +182,7 @@ suite('Database', () => { const r1 = ds.writeValue(v1); assert.strictEqual(2, r1.height); assert.strictEqual(3, ds.writeValue(r1).height); + await ds.close(); }); test('height of collections', async() => { @@ -213,5 +219,6 @@ suite('Database', () => { assert.strictEqual(2, ds.writeValue(l4).height); const l5 = await newList([ds.writeValue(s1), s3]); assert.strictEqual(2, ds.writeValue(l5).height); + await ds.close(); }); }); diff --git a/js/src/database.js b/js/src/database.js index cdc70b0890..ac9db0b970 100644 --- a/js/src/database.js +++ b/js/src/database.js @@ -154,8 +154,8 @@ export default class Database { throw new Error('Optimistic lock failed'); } - close() { - this._vs.close(); + close(): Promise { + return this._vs.close(); } } diff --git a/js/src/dataset-test.js b/js/src/dataset-test.js index 8abce03fa7..d17c713af7 100644 --- a/js/src/dataset-test.js +++ b/js/src/dataset-test.js @@ -57,5 +57,6 @@ suite('Dataset', () => { const newStore = new Database(bs); assert.strictEqual('d', notNull(await newStore.head('ds1')).value); assert.strictEqual('a', notNull(await newStore.head('otherDs')).value); + await newStore.close(); }); }); diff --git a/js/src/decode-test.js b/js/src/decode-test.js index 7a8a32ce54..6c649220a3 100644 --- a/js/src/decode-test.js +++ b/js/src/decode-test.js @@ -31,10 +31,18 @@ import Map, {newMapLeafSequence} from './map.js'; import Blob, {newBlob} from './blob.js'; // Set is already in use in this file. import NomsSet, {newSetLeafSequence} from './set.js'; -import {suite, test} from 'mocha'; +import {suite, setup, teardown, test} from 'mocha'; import {equals} from './compare.js'; suite('Decode', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + function stringToUint8Array(s): Uint8Array { const bytes = new Uint8Array(s.length); for (let i = 0; i < s.length; i++) { @@ -52,9 +60,8 @@ suite('Decode', () => { } test('read', () => { - const ds = new Database(makeTestingBatchStore()); const a = [1, 'hi', true]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); assert.strictEqual(1, r.read()); assert.isFalse(r.atEnd()); @@ -67,9 +74,8 @@ suite('Decode', () => { }); test('read type', () => { - const ds = new Database(makeTestingBatchStore()); function doTest(expected: Type, a: Array) { - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const tr = r.readValue(); assert.isTrue(equals(expected, tr)); } @@ -86,10 +92,8 @@ suite('Decode', () => { }); test('read primitives', () => { - const ds = new Database(makeTestingBatchStore()); - function doTest(expected: any, a: Array): void { - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); assert.deepEqual(expected, v); } @@ -106,22 +110,20 @@ suite('Decode', () => { }); test('read list of number', () => { - const ds = new Database(makeTestingBatchStore()); const a = [Kind.List, Kind.Number, false, [Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: List = r.readValue(); invariant(v instanceof List); - const l = new List(newListLeafSequence(ds, [0, 1, 2, 3])); + const l = new List(newListLeafSequence(db, [0, 1, 2, 3])); assert.isTrue(equals(l, v)); }); test('read list of mixed types', async () => { - const ds = new Database(makeTestingBatchStore()); const a = [Kind.List, Kind.Union, 3, Kind.Bool, Kind.Number, Kind.String, false, [Kind.Number, '1', Kind.String, 'hi', Kind.Bool, true]]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: List = r.readValue(); invariant(v instanceof List); @@ -133,10 +135,9 @@ suite('Decode', () => { }); test('read set of mixed types', async () => { - const ds = new Database(makeTestingBatchStore()); const a = [Kind.Set, Kind.Union, 3, Kind.Bool, Kind.Number, Kind.String, false, [Kind.Bool, true, Kind.Number, '1', Kind.String, 'hi']]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: NomsSet = r.readValue(); invariant(v instanceof NomsSet); @@ -148,7 +149,6 @@ suite('Decode', () => { }); test('read map of mixed types', async () => { - const ds = new Database(makeTestingBatchStore()); const a = [ Kind.Map, Kind.Union, 2, Kind.Bool, Kind.Number, Kind.Union, 2, Kind.Number, Kind.String, false, [ @@ -156,7 +156,7 @@ suite('Decode', () => { Kind.Number, '2', Kind.String, 'hi', ], ]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: Map = r.readValue(); invariant(v instanceof Map); @@ -168,28 +168,26 @@ suite('Decode', () => { }); test('read value list of number', () => { - const ds = new Database(makeTestingBatchStore()); const a = [Kind.Value, Kind.List, Kind.Number, false, [Kind.Number, '0', Kind.Number, '1', Kind.Number, '2']]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); invariant(v instanceof List); - const l = new List(newListLeafSequence(ds, [0, 1, 2])); + const l = new List(newListLeafSequence(db, [0, 1, 2])); assert.isTrue(equals(l, v)); }); test('read compound list', () => { - const ds = new Database(makeTestingBatchStore()); - const r1 = ds.writeValue(new List(newListLeafSequence(ds, [0]))); - const r2 = ds.writeValue(new List(newListLeafSequence(ds, [1, 2]))); - const r3 = ds.writeValue(new List(newListLeafSequence(ds, [3, 4, 5]))); + const r1 = db.writeValue(new List(newListLeafSequence(db, [0]))); + const r2 = db.writeValue(new List(newListLeafSequence(db, [1, 2]))); + const r3 = db.writeValue(new List(newListLeafSequence(db, [3, 4, 5]))); const tuples = [ new MetaTuple(r1, 1, 1), new MetaTuple(r2, 2, 2), new MetaTuple(r3, 3, 3), ]; - const l: List = new List(newListMetaSequence(ds, tuples)); + const l: List = new List(newListMetaSequence(db, tuples)); const a = [ Kind.List, Kind.Number, true, [ @@ -198,76 +196,71 @@ suite('Decode', () => { Kind.Ref, Kind.List, Kind.Number, r3.targetRef.toString(), '1', Kind.Number, '3', '3', ], ]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); invariant(v instanceof List); assert.isTrue(v.ref.equals(l.ref)); }); test('read map of number to number', () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[MapKind, NumberKind, NumberKind, false, [NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: Map = r.readValue(); invariant(v instanceof Map); - const m = new Map(newMapLeafSequence(ds, [[0, 1], [2, 3]])); + const m = new Map(newMapLeafSequence(db, [[0, 1], [2, 3]])); assert.isTrue(equals(v, m)); }); test('read map of ref to number', () => { - const ds = new Database(makeTestingBatchStore()); - const rv1 = ds.writeValue(true); - const rv2 = ds.writeValue('hi'); + const rv1 = db.writeValue(true); + const rv2 = db.writeValue('hi'); const a = [ Kind.Map, Kind.Union, 2, Kind.Ref, Kind.String, Kind.Ref, Kind.Bool, Kind.Number, false, [ Kind.Ref, Kind.Bool, rv1.targetRef.toString(), '1', Kind.Number, '2', Kind.Ref, Kind.String, rv2.targetRef.toString(), '1', Kind.Number, '4', ], ]; - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: Map, number> = r.readValue(); invariant(v instanceof Map); - const m = new Map(newMapLeafSequence(ds, [[rv1, 2], [rv2, 4]])); + const m = new Map(newMapLeafSequence(db, [[rv1, 2], [rv2, 4]])); assert.isTrue(equals(v, m)); }); test('read value map of number to number', () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[ValueKind, MapKind, NumberKind, NumberKind, false, [NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: Map = r.readValue(); invariant(v instanceof Map); - const m = new Map(newMapLeafSequence(ds, [[0, 1], [2, 3]])); + const m = new Map(newMapLeafSequence(db, [[0, 1], [2, 3]])); assert.isTrue(equals(v, m)); }); test('read set of number', () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[SetKind, NumberKind, false, [NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: NomsSet = r.readValue(); invariant(v instanceof NomsSet); - const s = new NomsSet(newSetLeafSequence(ds, [0, 1, 2, 3])); + const s = new NomsSet(newSetLeafSequence(db, [0, 1, 2, 3])); assert.isTrue(equals(v, s)); }); test('read compound set', () => { - const ds = new Database(makeTestingBatchStore()); - const r1 = ds.writeValue(new NomsSet(newSetLeafSequence(ds, [0, 1]))); - const r2 = ds.writeValue(new NomsSet(newSetLeafSequence(ds, [2, 3, 4]))); + const r1 = db.writeValue(new NomsSet(newSetLeafSequence(db, [0, 1]))); + const r2 = db.writeValue(new NomsSet(newSetLeafSequence(db, [2, 3, 4]))); const tuples = [ new MetaTuple(r1, 1, 2), new MetaTuple(r2, 4, 3), ]; - const l: NomsSet = new NomsSet(newSetMetaSequence(ds, tuples)); + const l: NomsSet = new NomsSet(newSetMetaSequence(db, tuples)); const a = parseJson(`[ SetKind, NumberKind, true, [ @@ -275,21 +268,20 @@ suite('Decode', () => { RefKind, SetKind, NumberKind, "%s", "1", NumberKind, "4", "3" ] ]`, r1.targetRef.toString(), r2.targetRef.toString()); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); invariant(v instanceof NomsSet); assert.isTrue(v.ref.equals(l.ref)); }); test('read value set of number', () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[ValueKind, SetKind, NumberKind, false, [NumberKind, "0", NumberKind, "1", NumberKind, "2", NumberKind, "3"]]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: NomsSet = r.readValue(); invariant(v instanceof NomsSet); - const s = new NomsSet(newSetLeafSequence(ds, [0, 1, 2, 3])); + const s = new NomsSet(newSetLeafSequence(db, [0, 1, 2, 3])); assert.isTrue(equals(v, s)); }); @@ -305,7 +297,6 @@ suite('Decode', () => { } test('test read struct', () => { - const ds = new Database(makeTestingBatchStore()); const tr = makeStructType('A1', { 'x': numberType, 's': stringType, @@ -314,7 +305,7 @@ suite('Decode', () => { const a = parseJson(`[StructKind, "A1", ["b", BoolKind, "s", StringKind, "x", NumberKind], BoolKind, true, StringKind, "hi", NumberKind, "42"]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); assertStruct(v, tr.desc, { @@ -325,7 +316,6 @@ suite('Decode', () => { }); test('test read struct with list', () => { - const ds = new Database(makeTestingBatchStore()); const ltr = makeListType(numberType); const tr = makeStructType('A4', { 'b': boolType, @@ -346,18 +336,17 @@ suite('Decode', () => { NumberKind, "2" ], StringKind, "hi"]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); assertStruct(v, tr.desc, { b: true, - l: new List(newListLeafSequence(ds, [0, 1, 2])), + l: new List(newListLeafSequence(db, [0, 1, 2])), s: 'hi', }); }); test('test read value struct', () => { - const ds = new Database(makeTestingBatchStore()); const tr = makeStructType('A1', { 'x': numberType, 's': stringType, @@ -375,7 +364,7 @@ suite('Decode', () => { NumberKind, "42" ]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); assertStruct(v, tr.desc, { @@ -386,7 +375,6 @@ suite('Decode', () => { }); test('test read map of string to struct', async () => { - const ds = new Database(makeTestingBatchStore()); const tr = makeStructType('s', { 'b': boolType, 'i': numberType, @@ -403,7 +391,7 @@ suite('Decode', () => { ] ]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: Map = r.readValue(); invariant(v instanceof Map); @@ -414,21 +402,21 @@ suite('Decode', () => { }); test('decodeNomsValue', () => { - const ds = new Database(makeTestingBatchStore()); const chunk = Chunk.fromString( `t [${Kind.Value},${Kind.Set},${Kind.Number},false,[${Kind.Number},"0",${ Kind.Number},"1",${Kind.Number},"2",${Kind.Number},"3"]]`); - const v = decodeNomsValue(chunk, new Database(makeTestingBatchStore())); + const v = decodeNomsValue(chunk, db); invariant(v instanceof NomsSet); - const s: NomsSet = new NomsSet(newSetLeafSequence(ds, [0, 1, 2, 3])); + const s: NomsSet = new NomsSet(newSetLeafSequence(db, [0, 1, 2, 3])); assert.isTrue(equals(v, s)); }); test('decodeNomsValue: counter with one commit', async () => { + await db.close(); const bs = makeTestingBatchStore(); - const ds = new Database(bs); + db = new Database(bs); const makeChunk = a => Chunk.fromString(`t ${JSON.stringify(a)}`); @@ -469,16 +457,16 @@ suite('Decode', () => { bs.schedulePut(rootChunk, new Set()); await bs.flush(); - const rootMap = await ds.readValue(rootRef); + const rootMap = await db.readValue(rootRef); const counterRef = await rootMap.get('counter'); - const commit = await counterRef.targetValue(ds); + const commit = await counterRef.targetValue(db); assert.strictEqual(1, await commit.value); }); test('out of line blob', async () => { const chunk = Chunk.fromString('b hi'); - const blob = decodeNomsValue(chunk, new Database(makeTestingBatchStore())); + const blob = decodeNomsValue(chunk, db); invariant(blob instanceof Blob); const r = await blob.getReader().read(); assert.isFalse(r.done); @@ -496,7 +484,7 @@ suite('Decode', () => { } const chunk2 = new Chunk(data); - const blob2 = decodeNomsValue(chunk2, new Database(makeTestingBatchStore())); + const blob2 = decodeNomsValue(chunk2, db); invariant(blob2 instanceof Blob); const r2 = await blob2.getReader().read(); assert.isFalse(r2.done); @@ -506,11 +494,10 @@ suite('Decode', () => { }); test('inline blob', async () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[ ListKind, BlobKind, false, [BlobKind, false, "%s", BlobKind, false, "%s"] ]`, encodeBase64(stringToUint8Array('hello')), encodeBase64(stringToUint8Array('world'))); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: List = r.readValue(); invariant(v instanceof List); @@ -523,10 +510,8 @@ suite('Decode', () => { }); test('compound blob', async () => { - const ds = new Database(makeTestingBatchStore()); - - const r1 = ds.writeValue(await newBlob(stringToUint8Array('hi'))); - const r2 = ds.writeValue(await newBlob(stringToUint8Array('world'))); + const r1 = db.writeValue(await newBlob(stringToUint8Array('hi'))); + const r2 = db.writeValue(await newBlob(stringToUint8Array('world'))); const a = parseJson(`[ BlobKind, true, [ @@ -534,7 +519,7 @@ suite('Decode', () => { RefKind, BlobKind, "%s", "1", NumberKind, "5", "5" ] ]`, r1.targetRef, r2.targetRef); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v: Blob = r.readValue(); invariant(v instanceof Blob); @@ -546,8 +531,6 @@ suite('Decode', () => { }); test('recursive struct', () => { - const db = new Database(makeTestingBatchStore()); - // struct A { // b: struct B { // a: List @@ -599,21 +582,19 @@ suite('Decode', () => { }); test('read union list', async () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[ListKind, UnionKind, 2, StringKind, NumberKind, false, [StringKind, "hi", NumberKind, "42"]]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); - const v2 = new List(newListLeafSequence(ds, ['hi', 42])); + const v2 = new List(newListLeafSequence(db, ['hi', 42])); assert.isTrue(equals(v, v2)); }); test('read empty union list', async () => { - const ds = new Database(makeTestingBatchStore()); const a = parseJson(`[ListKind, UnionKind, 0, false, []]`); - const r = new JsonArrayReader(a, ds); + const r = new JsonArrayReader(a, db); const v = r.readValue(); - const v2 = new List(newListLeafSequence(ds, [])); + const v2 = new List(newListLeafSequence(db, [])); assert.isTrue(equals(v, v2)); }); }); diff --git a/js/src/encode-test.js b/js/src/encode-test.js index 1e6129fa13..032e343435 100644 --- a/js/src/encode-test.js +++ b/js/src/encode-test.js @@ -1,7 +1,7 @@ // @flow import {assert} from 'chai'; -import {suite, test} from 'mocha'; +import {suite, setup, teardown, test} from 'mocha'; import {makeTestingBatchStore} from './batch-store-adaptor.js'; import Ref from './ref.js'; @@ -32,10 +32,17 @@ import Database from './database.js'; import type {valueOrPrimitive} from './value.js'; suite('Encode', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + test('write primitives', () => { function f(k: NomsKind, v: valueOrPrimitive, ex: valueOrPrimitive) { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); w.writeValue(v); assert.deepEqual([k, ex], w.array); } @@ -53,28 +60,25 @@ suite('Encode', () => { }); test('write simple blob', async () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); const blob = await newBlob(new Uint8Array([0x00, 0x01])); w.writeValue(blob); assert.deepEqual([Kind.Blob, false, 'AAE='], w.array); }); test('write list', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); - const l = new List(newListLeafSequence(ds, [0, 1, 2, 3])); + const l = new List(newListLeafSequence(db, [0, 1, 2, 3])); w.writeValue(l); assert.deepEqual([Kind.List, Kind.Number, false, [Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']], w.array); }); test('write list of value', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); - const l = new List(newListLeafSequence(ds, ['0', 1, '2', true])); + const l = new List(newListLeafSequence(db, ['0', 1, '2', true])); w.writeValue(l); assert.deepEqual([Kind.List, Kind.Union, 3, Kind.Bool, Kind.Number, Kind.String, false, [ Kind.String, '0', @@ -85,12 +89,11 @@ suite('Encode', () => { }); test('write list of list', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); - const v = new List(newListLeafSequence(ds, [ - new List(newListLeafSequence(ds, [0])), - new List(newListLeafSequence(ds, [1, 2, 3])), + const v = new List(newListLeafSequence(db, [ + new List(newListLeafSequence(db, [0])), + new List(newListLeafSequence(db, [1, 2, 3])), ])); w.writeValue(v); assert.deepEqual([Kind.List, Kind.List, Kind.Number, false, [ @@ -100,27 +103,25 @@ suite('Encode', () => { }); test('write leaf set', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); - const v = new Set(newSetLeafSequence(ds, [0, 1, 2, 3])); + const v = new Set(newSetLeafSequence(db, [0, 1, 2, 3])); w.writeValue(v); assert.deepEqual([Kind.Set, Kind.Number, false, [Kind.Number, '0', Kind.Number, '1', Kind.Number, '2', Kind.Number, '3']], w.array); }); test('write compound set', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); - const r1 = ds.writeValue(new Set(newSetLeafSequence(ds, [0]))); - const r2 = ds.writeValue(new Set(newSetLeafSequence(ds, [1, 2]))); - const r3 = ds.writeValue(new Set(newSetLeafSequence(ds, [3, 4, 5]))); + const w = new JsonArrayWriter(db); + const r1 = db.writeValue(new Set(newSetLeafSequence(db, [0]))); + const r2 = db.writeValue(new Set(newSetLeafSequence(db, [1, 2]))); + const r3 = db.writeValue(new Set(newSetLeafSequence(db, [3, 4, 5]))); const tuples = [ new MetaTuple(r1, 0, 1), new MetaTuple(r2, 2, 2), new MetaTuple(r3, 5, 3), ]; - const l = new Set(newSetMetaSequence(ds, tuples)); + const l = new Set(newSetMetaSequence(db, tuples)); w.writeValue(l); assert.deepEqual([ @@ -133,12 +134,11 @@ suite('Encode', () => { }); test('write set of set', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); - const v = new Set(newSetLeafSequence(ds, [ - new Set(newSetLeafSequence(ds, [0])), - new Set(newSetLeafSequence(ds, [1, 2, 3])), + const v = new Set(newSetLeafSequence(db, [ + new Set(newSetLeafSequence(db, [0])), + new Set(newSetLeafSequence(db, [1, 2, 3])), ])); w.writeValue(v); @@ -149,23 +149,21 @@ suite('Encode', () => { }); test('write map', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); - const v = new Map(newMapLeafSequence(ds, [['a', false], ['b', true]])); + const v = new Map(newMapLeafSequence(db, [['a', false], ['b', true]])); w.writeValue(v); assert.deepEqual([Kind.Map, Kind.String, Kind.Bool, false, [Kind.String, 'a', Kind.Bool, false, Kind.String, 'b', Kind.Bool, true]], w.array); }); test('write map of map', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); // Map, Set>({{'a': 0}: {true}}) - const s = new Set(newSetLeafSequence(ds, [true])); - const m1 = new Map(newMapLeafSequence(ds, [['a', 0]])); - const v = new Map(newMapLeafSequence(ds, [[m1, s]])); + const s = new Set(newSetLeafSequence(db, [true])); + const m1 = new Map(newMapLeafSequence(db, [['a', 0]])); + const v = new Map(newMapLeafSequence(db, [[m1, s]])); w.writeValue(v); assert.deepEqual([Kind.Map, Kind.Map, Kind.String, Kind.Number, @@ -175,8 +173,7 @@ suite('Encode', () => { }); test('write empty struct', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); const v = newStruct('S', {}); @@ -185,8 +182,7 @@ suite('Encode', () => { }); test('write struct', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); const v = newStruct('S', {x: 42, b: true}); w.writeValue(v); @@ -195,24 +191,22 @@ suite('Encode', () => { }); test('write struct with list', () => { - const ds = new Database(makeTestingBatchStore()); - let w = new JsonArrayWriter(ds); + let w = new JsonArrayWriter(db); - let v = newStruct('S', {l: new List(newListLeafSequence(ds, ['a', 'b']))}); + let v = newStruct('S', {l: new List(newListLeafSequence(db, ['a', 'b']))}); w.writeValue(v); assert.deepEqual([Kind.Struct, 'S', ['l', Kind.List, Kind.String], Kind.List, Kind.String, false, [Kind.String, 'a', Kind.String, 'b']], w.array); - v = newStruct('S', {l: new List(newListLeafSequence(ds, []))}); - w = new JsonArrayWriter(ds); + v = newStruct('S', {l: new List(newListLeafSequence(db, []))}); + w = new JsonArrayWriter(db); w.writeValue(v); assert.deepEqual([Kind.Struct, 'S', ['l', Kind.List, Kind.Union, 0], Kind.List, Kind.Union, 0, false, []], w.array); }); test('write struct with struct', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); const v = newStruct('S', {s: newStruct('S2', {x: 42})}); w.writeValue(v); @@ -222,17 +216,16 @@ suite('Encode', () => { }); test('write compound list', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); - const r1 = ds.writeValue(new List(newListLeafSequence(ds, [0]))); - const r2 = ds.writeValue(new List(newListLeafSequence(ds, [1, 2]))); - const r3 = ds.writeValue(new List(newListLeafSequence(ds, [3, 4, 5]))); + const w = new JsonArrayWriter(db); + const r1 = db.writeValue(new List(newListLeafSequence(db, [0]))); + const r2 = db.writeValue(new List(newListLeafSequence(db, [1, 2]))); + const r3 = db.writeValue(new List(newListLeafSequence(db, [3, 4, 5]))); const tuples = [ new MetaTuple(r1, 1, 1), new MetaTuple(r2, 2, 2), new MetaTuple(r3, 3, 3), ]; - const l = new List(newListMetaSequence(ds, tuples)); + const l = new List(newListMetaSequence(db, tuples)); w.writeValue(l); assert.deepEqual([ @@ -245,15 +238,14 @@ suite('Encode', () => { }); test('write compound set with bool', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); - const r1 = ds.writeValue(new Set(newSetLeafSequence(ds, [true]))); - const r2 = ds.writeValue(new Set(newSetLeafSequence(ds, [false]))); + const w = new JsonArrayWriter(db); + const r1 = db.writeValue(new Set(newSetLeafSequence(db, [true]))); + const r2 = db.writeValue(new Set(newSetLeafSequence(db, [false]))); const tuples = [ new MetaTuple(r1, true, 1), new MetaTuple(r2, false, 1), ]; - const l = new Set(newSetMetaSequence(ds, tuples)); + const l = new Set(newSetMetaSequence(db, tuples)); w.writeValue(l); assert.deepEqual([ @@ -265,10 +257,9 @@ suite('Encode', () => { }); test('write type value', () => { - const ds = new Database(makeTestingBatchStore()); const test = (expected: Array, v: Type) => { - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); w.writeValue(v); assert.deepEqual(w.array, expected); }; @@ -313,10 +304,9 @@ suite('Encode', () => { return bytes; } - const ds = new Database(makeTestingBatchStore()); const blob = await newBlob(stringToUint8Array('hi')); - const chunk = encodeNomsValue(blob, ds); + const chunk = encodeNomsValue(blob, db); assert.equal(4, chunk.data.length); assert.deepEqual(stringToUint8Array('b hi'), chunk.data); @@ -330,14 +320,13 @@ suite('Encode', () => { view.setUint8(2 + i, i); } const blob2 = await newBlob(bytes); - const chunk2 = encodeNomsValue(blob2, ds); + const chunk2 = encodeNomsValue(blob2, db); assert.equal(buffer2.byteLength, chunk2.data.buffer.byteLength); assert.deepEqual(buffer2, chunk2.data.buffer); }); test('write ref', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); + const w = new JsonArrayWriter(db); const ref = Ref.parse('sha1-0123456789abcdef0123456789abcdef01234567'); const t = makeRefType(blobType); const v = constructRefValue(t, ref, 1); @@ -347,18 +336,16 @@ suite('Encode', () => { }); test('write union list', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); - const v = new List(newListLeafSequence(ds, ['hi', 42])); + const w = new JsonArrayWriter(db); + const v = new List(newListLeafSequence(db, ['hi', 42])); w.writeValue(v); assert.deepEqual([Kind.List, Kind.Union, 2, Kind.Number, Kind.String, false, [Kind.String, 'hi', Kind.Number, '42']], w.array); }); test('write empty union list', () => { - const ds = new Database(makeTestingBatchStore()); - const w = new JsonArrayWriter(ds); - const v = new List(newListLeafSequence(ds, [])); + const w = new JsonArrayWriter(db); + const v = new List(newListLeafSequence(db, [])); w.writeValue(v); assert.deepEqual([Kind.List, Kind.Union, 0, false, []], w.array); }); diff --git a/js/src/list-test.js b/js/src/list-test.js index 14f3a53fdb..c14d939cbf 100644 --- a/js/src/list-test.js +++ b/js/src/list-test.js @@ -1,7 +1,7 @@ // @flow import {assert} from 'chai'; -import {suite, test} from 'mocha'; +import {suite, setup, teardown, test} from 'mocha'; import Database from './database.js'; import {makeTestingBatchStore} from './batch-store-adaptor.js'; @@ -194,12 +194,12 @@ suite('List', () => { }); test('LONG: write, read, modify, read', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const nums = intSequence(testListSize); const s = await newList(nums); - const r = ds.writeValue(s).targetRef; - const s2 = await ds.readValue(r); + const r = db.writeValue(s).targetRef; + const s2 = await db.readValue(r); const outNums = await s2.toJS(); assert.deepEqual(nums, outNums); @@ -208,21 +208,27 @@ suite('List', () => { const outNums2 = await s3.toJS(); nums.splice(testListSize - 1, 1); assert.deepEqual(nums, outNums2); + await db.close(); }); }); suite('ListLeafSequence', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + test('Empty list isEmpty', () => { - const ds = new Database(makeTestingBatchStore()); - const newList = items => new List(newListLeafSequence(ds, items)); + const newList = items => new List(newListLeafSequence(db, items)); assert.isTrue(newList([]).isEmpty()); }); test('iterator', async () => { - const ds = new Database(makeTestingBatchStore()); - const test = async items => { - const l = new List(newListLeafSequence(ds, items)); + const l = new List(newListLeafSequence(db, items)); assert.deepEqual(items, await flatten(l.iterator())); assert.deepEqual(items, await flattenParallel(l.iterator(), items.length)); }; @@ -233,10 +239,8 @@ suite('ListLeafSequence', () => { }); test('iteratorAt', async () => { - const ds = new Database(makeTestingBatchStore()); - const test = async items => { - const l = new List(newListLeafSequence(ds, items)); + const l = new List(newListLeafSequence(db, items)); for (let i = 0; i <= items.length; i++) { const slice = items.slice(i); assert.deepEqual(slice, await flatten(l.iteratorAt(i))); @@ -251,25 +255,31 @@ suite('ListLeafSequence', () => { }); suite('CompoundList', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); function build(): List { - const ds = new Database(makeTestingBatchStore()); - const l1 = new List(newListLeafSequence(ds, ['a', 'b'])); - const r1 = ds.writeValue(l1); - const l2 = new List(newListLeafSequence(ds, ['e', 'f'])); - const r2 = ds.writeValue(l2); - const l3 = new List(newListLeafSequence(ds, ['h', 'i'])); - const r3 = ds.writeValue(l3); - const l4 = new List(newListLeafSequence(ds, ['m', 'n'])); - const r4 = ds.writeValue(l4); + const l1 = new List(newListLeafSequence(db, ['a', 'b'])); + const r1 = db.writeValue(l1); + const l2 = new List(newListLeafSequence(db, ['e', 'f'])); + const r2 = db.writeValue(l2); + const l3 = new List(newListLeafSequence(db, ['h', 'i'])); + const r3 = db.writeValue(l3); + const l4 = new List(newListLeafSequence(db, ['m', 'n'])); + const r4 = db.writeValue(l4); - const m1 = new List(newListMetaSequence(ds, [new MetaTuple(r1, 2, 2), + const m1 = new List(newListMetaSequence(db, [new MetaTuple(r1, 2, 2), new MetaTuple(r2, 2, 2)])); - const rm1 = ds.writeValue(m1); - const m2 = new List(newListMetaSequence(ds, [new MetaTuple(r3, 2, 2), + const rm1 = db.writeValue(m1); + const m2 = new List(newListMetaSequence(db, [new MetaTuple(r3, 2, 2), new MetaTuple(r4, 2, 2)])); - const rm2 = ds.writeValue(m2); + const rm2 = db.writeValue(m2); - const l = new List(newListMetaSequence(ds, [new MetaTuple(rm1, 4, 4), + const l = new List(newListMetaSequence(db, [new MetaTuple(rm1, 4, 4), new MetaTuple(rm2, 4, 4)])); return l; } diff --git a/js/src/map-test.js b/js/src/map-test.js index ebcd955c1a..ab9abaa372 100644 --- a/js/src/map-test.js +++ b/js/src/map-test.js @@ -1,7 +1,7 @@ // @flow import {assert} from 'chai'; -import {suite, test} from 'mocha'; +import {suite, setup, teardown, test} from 'mocha'; import Database from './database.js'; import MemoryStore from './memory-store.js'; @@ -151,7 +151,7 @@ suite('BuildMap', () => { }); test('LONG: write, read, modify, read', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const kvs = []; for (let i = 0; i < testMapSize; i++) { @@ -160,8 +160,8 @@ suite('BuildMap', () => { const m = await newMap(kvs); - const r = ds.writeValue(m).targetRef; - const m2 = await ds.readValue(r); + const r = db.writeValue(m).targetRef; + const m2 = await db.readValue(r); const outKvs = []; await m2.forEach((v, k) => outKvs.push([k, v])); assert.deepEqual(kvs, outKvs); @@ -174,10 +174,11 @@ suite('BuildMap', () => { kvs.splice(testMapSize * 1 - 1, 1); assert.deepEqual(kvs, outKvs2); assert.strictEqual(testMapSize - 1, m3.size); + await db.close(); }); test('LONG: union write, read, modify, read', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const keys = []; const kvs = []; @@ -214,8 +215,8 @@ suite('BuildMap', () => { assert.isTrue(await m.has(keys[i])); } - const r = ds.writeValue(m).targetRef; - const m2 = await ds.readValue(r); + const r = db.writeValue(m).targetRef; + const m2 = await db.readValue(r); const outVals = []; const outKeys = []; await m2.forEach((v, k) => { @@ -258,14 +259,22 @@ suite('BuildMap', () => { const v = await m3.get(k); assertEqualVal(k, v); } + await db.close(); }); }); suite('MapLeaf', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + test('isEmpty/size', () => { - const ds = new Database(makeTestingBatchStore()); - const newMap = entries => new Map(newMapLeafSequence(ds, entries)); + const newMap = entries => new Map(newMapLeafSequence(db, entries)); let m = newMap([]); assert.isTrue(m.isEmpty()); assert.strictEqual(0, m.size); @@ -275,9 +284,8 @@ suite('MapLeaf', () => { }); test('has', async () => { - const ds = new Database(makeTestingBatchStore()); const m = new Map( - newMapLeafSequence(ds, [['a', false], ['k', true]])); + newMapLeafSequence(db, [['a', false], ['k', true]])); assert.isTrue(await m.has('a')); assert.isFalse(await m.has('b')); assert.isTrue(await m.has('k')); @@ -285,9 +293,7 @@ suite('MapLeaf', () => { }); test('first/last/get', async () => { - const ds = new Database(makeTestingBatchStore()); - const m = new Map( - newMapLeafSequence(ds, [['a', 4], ['k', 8]])); + const m = new Map(newMapLeafSequence(db, [['a', 4], ['k', 8]])); assert.deepEqual(['a', 4], await m.first()); assert.deepEqual(['k', 8], await m.last()); @@ -299,9 +305,7 @@ suite('MapLeaf', () => { }); test('forEach', async () => { - const ds = new Database(makeTestingBatchStore()); - const m = new Map( - newMapLeafSequence(ds, [['a', 4], ['k', 8]])); + const m = new Map(newMapLeafSequence(db, [['a', 4], ['k', 8]])); const kv = []; await m.forEach((v, k) => { kv.push(k, v); }); @@ -309,10 +313,9 @@ suite('MapLeaf', () => { }); test('iterator', async () => { - const ds = new Database(makeTestingBatchStore()); const test = async entries => { - const m = new Map(newMapLeafSequence(ds, entries)); + const m = new Map(newMapLeafSequence(db, entries)); assert.deepEqual(entries, await flatten(m.iterator())); assert.deepEqual(entries, await flattenParallel(m.iterator(), entries.length)); }; @@ -323,8 +326,7 @@ suite('MapLeaf', () => { }); test('LONG: iteratorAt', async () => { - const ds = new Database(makeTestingBatchStore()); - const build = entries => new Map(newMapLeafSequence(ds, entries)); + const build = entries => new Map(newMapLeafSequence(db, entries)); assert.deepEqual([], await flatten(build([]).iteratorAt('a'))); @@ -346,13 +348,12 @@ suite('MapLeaf', () => { }); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); - const r1 = ds.writeValue('x'); - const r2 = ds.writeValue(true); - const r3 = ds.writeValue('b'); - const r4 = ds.writeValue(false); - const m = new Map( - newMapLeafSequence(ds, [[r1, r2], [r3, r4]])); + const r1 = db.writeValue('x'); + const r2 = db.writeValue(true); + const r3 = db.writeValue('b'); + const r4 = db.writeValue(false); + const m = new Map(newMapLeafSequence(db, [[r1, r2], [r3, r4]])); + assert.strictEqual(4, m.chunks.length); assert.isTrue(equals(r1, m.chunks[0])); assert.isTrue(equals(r2, m.chunks[1])); @@ -363,6 +364,14 @@ suite('MapLeaf', () => { }); suite('CompoundMap', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + function build(vwr: ValueReadWriter): Array { const l1 = new Map(newMapLeafSequence(vwr, [['a', false], ['b', false]])); const r1 = vwr.writeValue(l1); @@ -386,15 +395,13 @@ suite('CompoundMap', () => { } test('isEmpty/size', () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); assert.isFalse(c.isEmpty()); assert.strictEqual(8, c.size); }); test('get', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); assert.strictEqual(false, await c.get('a')); assert.strictEqual(false, await c.get('b')); @@ -413,8 +420,7 @@ suite('CompoundMap', () => { }); test('first/last/has', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c, m1, m2] = build(ds); + const [c, m1, m2] = build(db); assert.deepEqual(['a', false], await c.first()); assert.deepEqual(['n', false], await c.last()); @@ -440,8 +446,7 @@ suite('CompoundMap', () => { }); test('forEach', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); const kv = []; await c.forEach((v, k) => { kv.push(k, v); }); @@ -450,8 +455,7 @@ suite('CompoundMap', () => { }); test('iterator', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); const expected = [['a', false], ['b', false], ['e', true], ['f', true], ['h', false], ['i', true], ['m', true], ['n', false]]; assert.deepEqual(expected, await flatten(c.iterator())); @@ -459,8 +463,7 @@ suite('CompoundMap', () => { }); test('LONG: iteratorAt', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); const entries = [['a', false], ['b', false], ['e', true], ['f', true], ['h', false], ['i', true], ['m', true], ['n', false]]; const offsets = { @@ -482,8 +485,7 @@ suite('CompoundMap', () => { }); test('iterator return', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); const iter = c.iterator(); const values = []; for (let res = await iter.next(); !res.done; res = await iter.next()) { @@ -497,8 +499,7 @@ suite('CompoundMap', () => { }); test('iterator return parallel', async () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); const iter = c.iterator(); const values = await Promise.all([iter.next(), iter.next(), iter.return(), iter.next()]); assert.deepEqual([{done: false, value: ['a', false]}, @@ -508,8 +509,7 @@ suite('CompoundMap', () => { }); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); - const [c] = build(ds); + const [c] = build(db); assert.strictEqual(2, c.chunks.length); }); @@ -545,13 +545,14 @@ suite('CompoundMap', () => { } const ms = new CountingMemoryStore(); - const ds = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms))); - [m1, m2] = await Promise.all([m1, m2].map(s => ds.readValue(ds.writeValue(s).targetRef))); + const db = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms))); + [m1, m2] = await Promise.all([m1, m2].map(s => db.readValue(db.writeValue(s).targetRef))); assert.deepEqual([[], [], []], await m1.diff(m1)); assert.deepEqual([[], [], []], await m2.diff(m2)); assert.deepEqual([removed, added, modified], await m1.diff(m2)); assert.deepEqual([added, removed, modified], await m2.diff(m1)); + await db.close(); } async function testSmallRandomDiff(inM1: number, inM2: number, inBoth: number) { @@ -595,8 +596,7 @@ suite('CompoundMap', () => { test('LONG: random map diff 0.1/0.9/0', () => testRandomDiff(randomMapSize, 0.1, 0.9, 0)); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); - const m = build(ds)[1]; + const m = build(db)[1]; const chunks = m.chunks; const sequence = m.sequence; assert.equal(2, chunks.length); diff --git a/js/src/meta-sequence-test.js b/js/src/meta-sequence-test.js index da6a2667ad..ba8ca2e9bf 100644 --- a/js/src/meta-sequence-test.js +++ b/js/src/meta-sequence-test.js @@ -1,7 +1,7 @@ // @flow import {assert} from 'chai'; -import {suite, test} from 'mocha'; +import {suite, setup, teardown, test} from 'mocha'; import {makeTestingBatchStore} from './batch-store-adaptor.js'; import Database from './database.js'; @@ -13,11 +13,17 @@ import Set, {newSetLeafSequence} from './set.js'; import {Kind} from './noms-kind.js'; suite('MetaSequence', () => { - test('calculate ordered sequence MetaTuple height', async () => { - const ds = new Database(makeTestingBatchStore()); + let db; - const set1 = new Set(newSetLeafSequence(ds, ['bar', 'baz'])); - const set2 = new Set(newSetLeafSequence(ds, ['foo', 'qux', 'zoo'])); + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + + test('calculate ordered sequence MetaTuple height', async () => { + const set1 = new Set(newSetLeafSequence(db, ['bar', 'baz'])); + const set2 = new Set(newSetLeafSequence(db, ['foo', 'qux', 'zoo'])); const mt1 = new MetaTuple(new RefValue(set1), 'baz', 2, set1); const mt2 = new MetaTuple(new RefValue(set2), 'zoo', 3, set2); @@ -34,10 +40,8 @@ suite('MetaSequence', () => { }); test('calculate indexed sequence MetaTuple height', async () => { - const ds = new Database(makeTestingBatchStore()); - - const list1 = new List(newListLeafSequence(ds, ['bar', 'baz'])); - const list2 = new List(newListLeafSequence(ds, ['foo', 'qux', 'zoo'])); + const list1 = new List(newListLeafSequence(db, ['bar', 'baz'])); + const list2 = new List(newListLeafSequence(db, ['foo', 'qux', 'zoo'])); const mt1 = new MetaTuple(new RefValue(list1), 2, 2, list1); const mt2 = new MetaTuple(new RefValue(list2), 3, 3, list2); diff --git a/js/src/put-cache.js b/js/src/put-cache.js index e2a891776b..1d38fd4131 100644 --- a/js/src/put-cache.js +++ b/js/src/put-cache.js @@ -38,7 +38,9 @@ export default class OrderedPutCache { } _init(): Promise { + // invariant(false === true); return makeTempDir().then((dir): Promise => { + // console.log('creating', dir); this._folder = dir; const coll = new DbCollection(dir); return coll.ensureIndex({hash: 1}, {unique: true}).then(() => coll); diff --git a/js/src/set-test.js b/js/src/set-test.js index 157badb2f0..84babb6352 100644 --- a/js/src/set-test.js +++ b/js/src/set-test.js @@ -1,7 +1,7 @@ // @flow import {assert} from 'chai'; -import {suite, test} from 'mocha'; +import {suite, setup, teardown, test} from 'mocha'; import Chunk from './chunk.js'; import Database from './database.js'; @@ -128,12 +128,12 @@ suite('BuildSet', () => { }); test('LONG: write, read, modify, read', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const nums = firstNNumbers(testSetSize); const s = await newSet(nums); - const r = ds.writeValue(s).targetRef; - const s2 = await ds.readValue(r); + const r = db.writeValue(s).targetRef; + const s2 = await db.readValue(r); const outNums = []; await s2.forEach(k => outNums.push(k)); assert.deepEqual(nums, outNums); @@ -146,11 +146,12 @@ suite('BuildSet', () => { nums.splice(testSetSize - 1, 1); assert.deepEqual(nums, outNums2); assert.strictEqual(testSetSize - 1, s3.size); + await db.close(); }); test('LONG: union write, read, modify, read', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const tmp = firstNNumbers(testSetSize); const numbers = []; @@ -185,8 +186,8 @@ suite('BuildSet', () => { assert.isTrue(await s.has(vals1[i])); } - const r = ds.writeValue(s).targetRef; - const s2 = await ds.readValue(r); + const r = db.writeValue(s).targetRef; + const s2 = await db.readValue(r); const outVals = []; await s2.forEach(k => outVals.push(k)); assert.equal(testSetSize, s2.size); @@ -203,13 +204,21 @@ suite('BuildSet', () => { for (let i = vals2.length - 1; i >= 0; i -= 5) { assert.isTrue(equals(vals2[i], outVals2[i])); } + await db.close(); }); }); suite('SetLeaf', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + test('isEmpty/size', () => { - const ds = new Database(makeTestingBatchStore()); - const newSet = items => new Set(newSetLeafSequence(ds, items)); + const newSet = items => new Set(newSetLeafSequence(db, items)); let s = newSet([]); assert.isTrue(s.isEmpty()); assert.strictEqual(0, s.size); @@ -219,8 +228,7 @@ suite('SetLeaf', () => { }); test('first/last/has', async () => { - const ds = new Database(makeTestingBatchStore()); - const s = new Set(newSetLeafSequence(ds, ['a', 'k'])); + const s = new Set(newSetLeafSequence(db, ['a', 'k'])); assert.strictEqual('a', await s.first()); assert.strictEqual('k', await s.last()); @@ -232,8 +240,7 @@ suite('SetLeaf', () => { }); test('forEach', async () => { - const ds = new Database(makeTestingBatchStore()); - const m = new Set(newSetLeafSequence(ds, ['a', 'b'])); + const m = new Set(newSetLeafSequence(db, ['a', 'b'])); const values = []; await m.forEach((k) => { values.push(k); }); @@ -241,10 +248,8 @@ suite('SetLeaf', () => { }); test('iterator', async () => { - const ds = new Database(makeTestingBatchStore()); - const test = async items => { - const m = new Set(newSetLeafSequence(ds, items)); + const m = new Set(newSetLeafSequence(db, items)); assert.deepEqual(items, await flatten(m.iterator())); assert.deepEqual(items, await flattenParallel(m.iterator(), items.length)); }; @@ -255,8 +260,7 @@ suite('SetLeaf', () => { }); test('LONG: iteratorAt', async () => { - const ds = new Database(makeTestingBatchStore()); - const build = items => new Set(newSetLeafSequence(ds, items)); + const build = items => new Set(newSetLeafSequence(db, items)); assert.deepEqual([], await flatten(build([]).iteratorAt('a'))); @@ -272,11 +276,10 @@ suite('SetLeaf', () => { }); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); - const r1 = ds.writeValue('x'); - const r2 = ds.writeValue('a'); - const r3 = ds.writeValue('b'); - const l = new Set(newSetLeafSequence(ds, ['z', r1, r2, r3])); + const r1 = db.writeValue('x'); + const r2 = db.writeValue('a'); + const r3 = db.writeValue('b'); + const l = new Set(newSetLeafSequence(db, ['z', r1, r2, r3])); assert.strictEqual(3, l.chunks.length); assert.isTrue(equals(r1, l.chunks[0])); assert.isTrue(equals(r2, l.chunks[1])); @@ -285,6 +288,14 @@ suite('SetLeaf', () => { }); suite('CompoundSet', () => { + let db; + + setup(() => { + db = new Database(makeTestingBatchStore()); + }); + + teardown((): Promise => db.close()); + function build(vwr: ValueReadWriter, values: Array): Set { assert.isTrue(values.length > 1 && Math.log2(values.length) % 1 === 0); @@ -312,15 +323,13 @@ suite('CompoundSet', () => { } test('isEmpty/size', () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); assert.isFalse(c.isEmpty()); assert.strictEqual(8, c.size); }); test('first/last/has', async () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); assert.strictEqual('a', await c.first()); assert.strictEqual('n', await c.last()); assert.isTrue(await c.has('a')); @@ -340,25 +349,22 @@ suite('CompoundSet', () => { }); test('forEach', async () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); const values = []; await c.forEach((k) => { values.push(k); }); assert.deepEqual(['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n'], values); }); test('iterator', async () => { - const ds = new Database(makeTestingBatchStore()); const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']; - const c = build(ds, values); + const c = build(db, values); assert.deepEqual(values, await flatten(c.iterator())); assert.deepEqual(values, await flattenParallel(c.iterator(), values.length)); }); test('LONG: iteratorAt', async () => { - const ds = new Database(makeTestingBatchStore()); const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']; - const c = build(ds, values); + const c = build(db, values); const offsets = { _: 0, a: 0, b: 1, @@ -378,9 +384,8 @@ suite('CompoundSet', () => { }); test('iterator return', async () => { - const ds = new Database(makeTestingBatchStore()); const values = ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']; - const c = build(ds, values); + const c = build(db, values); const iter = c.iterator(); const values2 = []; for (let res = await iter.next(); !res.done; res = await iter.next()) { @@ -393,8 +398,7 @@ suite('CompoundSet', () => { }); test('iterator return parallel', async () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); const iter = c.iterator(); const values = await Promise.all([iter.next(), iter.next(), iter.return(), iter.next()]); assert.deepEqual( @@ -403,21 +407,18 @@ suite('CompoundSet', () => { }); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); assert.strictEqual(2, c.chunks.length); }); test('map', async () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); const values = await c.map((k) => k + '*'); assert.deepEqual(['a*', 'b*', 'e*', 'f*', 'h*', 'i*', 'm*', 'n*'], values); }); test('map async', async () => { - const ds = new Database(makeTestingBatchStore()); - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); const values = await c.map((k) => Promise.resolve(k + '*')); assert.deepEqual(['a*', 'b*', 'e*', 'f*', 'h*', 'i*', 'm*', 'n*'], values); }); @@ -434,9 +435,7 @@ suite('CompoundSet', () => { } test('advanceTo', async () => { - const ds = new Database(makeTestingBatchStore()); - - const c = build(ds, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); + const c = build(db, ['a', 'b', 'e', 'f', 'h', 'i', 'm', 'n']); invariant(c.sequence instanceof OrderedSequence); let cursor = await c.sequence.newCursorAt(null); @@ -476,12 +475,10 @@ suite('CompoundSet', () => { }); async function testIntersect(expect: Array, seqs: Array>) { - const ds = new Database(makeTestingBatchStore()); - - const first = build(ds, seqs[0]); + const first = build(db, seqs[0]); const sets:Array = []; for (let i = 1; i < seqs.length; i++) { - sets.push(build(ds, seqs[i])); + sets.push(build(db, seqs[i])); } const result = await first.intersect(...sets); @@ -505,10 +502,8 @@ suite('CompoundSet', () => { }); test('iterator at 0', async () => { - const ds = new Database(makeTestingBatchStore()); - const test = async (expected, items) => { - const set = new Set(newSetLeafSequence(ds, items)); + const set = new Set(newSetLeafSequence(db, items)); const iter = set.iteratorAt(0); assert.deepEqual(expected, await flatten(iter)); }; @@ -526,9 +521,8 @@ suite('CompoundSet', () => { }); test('LONG: canned set diff', async () => { - const ds = new Database(makeTestingBatchStore()); const s1 = await newSet( - firstNNumbers(testSetSize)).then(s => ds.readValue(ds.writeValue(s).targetRef)); + firstNNumbers(testSetSize)).then(s => db.readValue(db.writeValue(s).targetRef)); { // Insert/remove at start. @@ -578,13 +572,14 @@ suite('CompoundSet', () => { } const ms = new CountingMemoryStore(); - const ds = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms))); - [s1, s2] = await Promise.all([s1, s2].map(s => ds.readValue(ds.writeValue(s).targetRef))); + const db = new Database(new BatchStore(3, new BatchStoreAdaptorDelegate(ms))); + [s1, s2] = await Promise.all([s1, s2].map(s => db.readValue(db.writeValue(s).targetRef))); assert.deepEqual([[], []], await s1.diff(s1)); assert.deepEqual([[], []], await s2.diff(s2)); assert.deepEqual([removed, added], await s1.diff(s2)); assert.deepEqual([added, removed], await s2.diff(s1)); + await db.close(); } function testSmallRandomDiff(inS1: number, inS2: number): Promise { @@ -617,8 +612,7 @@ suite('CompoundSet', () => { test('LONG: random set diff 0.1/0.9', () => testRandomDiff(randomSetSize, 0.1, 0.9)); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); - const s = build(ds, ['a', 'b', 'c', 'd']); + const s = build(db, ['a', 'b', 'c', 'd']); const chunks = s.chunks; const sequence = s.sequence; assert.equal(2, chunks.length); diff --git a/js/src/specs-test.js b/js/src/specs-test.js index c809f72b3f..4e1e66b55a 100644 --- a/js/src/specs-test.js +++ b/js/src/specs-test.js @@ -11,7 +11,7 @@ import {assert} from 'chai'; import {suite, test} from 'mocha'; suite('Specs', () => { - test('DatabaseSpec', () => { + test('DatabaseSpec', async () => { const notAllowed = ['mem:', 'mem:stuff', 'http:', 'https:', 'random:', 'random:random']; notAllowed.forEach(s => assert.isNull(DatabaseSpec.parse(s))); @@ -19,16 +19,20 @@ suite('Specs', () => { invariant(spec); assert.equal(spec.scheme, 'mem'); assert.equal(spec.path, ''); - assert.instanceOf(spec.store(), Database); - assert.instanceOf(spec.store()._vs._bs, BatchStoreAdaptor); + let store = spec.store(); + assert.instanceOf(store, Database); + assert.instanceOf(store._vs._bs, BatchStoreAdaptor); + await store.close(); spec = DatabaseSpec.parse('http://foo'); invariant(spec); assert.isNotNull(spec); assert.equal(spec.scheme, 'http'); assert.equal(spec.path, '//foo'); - assert.instanceOf(spec.store(), Database); - assert.instanceOf(spec.store()._vs._bs, HttpBatchStore); + store = spec.store(); + assert.instanceOf(store, Database); + assert.instanceOf(store._vs._bs, HttpBatchStore); + await store.close(); spec = DatabaseSpec.parse('https://foo'); invariant(spec); @@ -37,7 +41,7 @@ suite('Specs', () => { assert.equal(spec.path, '//foo'); }); - test('DataSetSpec', () => { + test('DataSetSpec', async () => { const invalid = ['mem', 'mem:', 'http', 'http:', 'http://foo', 'monkey', 'monkey:balls']; invalid.forEach(s => assert.isNull(DatasetSpec.parse(s))); @@ -49,6 +53,7 @@ suite('Specs', () => { let ds = spec.set(); assert.instanceOf(ds, Dataset); assert.instanceOf(ds.store._vs._bs, BatchStoreAdaptor); + await ds.store.close(); spec = DatasetSpec.parse('http://localhost:8000/foo:ds'); invariant(spec); @@ -58,9 +63,10 @@ suite('Specs', () => { ds = spec.set(); assert.instanceOf(ds, Dataset); assert.instanceOf(ds.store._vs._bs, HttpBatchStore); + await ds.store.close(); }); - test('RefSpec', () => { + test('RefSpec', async () => { const testRef = new Ref('sha1-0000000000000000000000000000000000000000'); const invalid = [ 'mem', 'mem:', 'http', 'http:', 'http://foo', 'monkey', 'monkey:balls', diff --git a/js/src/specs.js b/js/src/specs.js index d8724ff7b0..a8c5fb3305 100644 --- a/js/src/specs.js +++ b/js/src/specs.js @@ -92,6 +92,8 @@ export class DatasetSpec { // Returns the value at the HEAD of this dataset, if any, or null otherwise. value(): Promise { + // Hm. Calling set() creates a Database that we then toss into the ether, which means we can't + // call close() on it. Ideally, we'd fix that. return this.set().head() .then(commit => commit && commit.value); } @@ -135,7 +137,8 @@ export class RefSpec { // Returns the value for the spec'd reference, if any, or null otherwise. value(): Promise { - return this.store.store().readValue(this.ref); + const store = this.store.store(); + return store.readValue(this.ref).then(v => store.close().then(() => v)); } } diff --git a/js/src/struct-test.js b/js/src/struct-test.js index aeed96444e..1bd4d289b9 100644 --- a/js/src/struct-test.js +++ b/js/src/struct-test.js @@ -34,13 +34,14 @@ suite('Struct', () => { }); test('chunks', () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const b = true; - const r = ds.writeValue(b); + const r = db.writeValue(b); const s1 = newStruct('S1', {r: r}); assert.strictEqual(1, s1.chunks.length); assert.isTrue(equals(r, s1.chunks[0])); + return db.close(); }); test('new', () => { diff --git a/js/src/test-util.js b/js/src/test-util.js index b697c959c9..3b4c3e7961 100644 --- a/js/src/test-util.js +++ b/js/src/test-util.js @@ -60,6 +60,7 @@ export async function testRoundTripAndValidate(v: T, assert.strictEqual(v2, v); } await validateFn(v2); + await ds2.close(); } export function chunkDiffCount(v1: valueOrPrimitive, v2: valueOrPrimitive): number { diff --git a/js/src/type-test.js b/js/src/type-test.js index 30d8f4aae9..e5e398e69f 100644 --- a/js/src/type-test.js +++ b/js/src/type-test.js @@ -19,7 +19,7 @@ import {equals} from './compare.js'; suite('Type', () => { test('types', async () => { - const ds = new Database(makeTestingBatchStore()); + const db = new Database(makeTestingBatchStore()); const mapType = makeMapType(stringType, numberType); const setType = makeSetType(stringType); @@ -28,13 +28,14 @@ suite('Type', () => { 'Field2': boolType, }); - const mapRef = ds.writeValue(mapType).targetRef; - const setRef = ds.writeValue(setType).targetRef; - const mahRef = ds.writeValue(mahType).targetRef; + const mapRef = db.writeValue(mapType).targetRef; + const setRef = db.writeValue(setType).targetRef; + const mahRef = db.writeValue(mahType).targetRef; - assert.isTrue(equals(mapType, await ds.readValue(mapRef))); - assert.isTrue(equals(setType, await ds.readValue(setRef))); - assert.isTrue(equals(mahType, await ds.readValue(mahRef))); + assert.isTrue(equals(mapType, await db.readValue(mapRef))); + assert.isTrue(equals(setType, await db.readValue(setRef))); + assert.isTrue(equals(mahType, await db.readValue(mahRef))); + await db.close(); }); test('type Type', () => { diff --git a/js/src/value-store-test.js b/js/src/value-store-test.js index fec0012281..65a241e569 100644 --- a/js/src/value-store-test.js +++ b/js/src/value-store-test.js @@ -30,6 +30,7 @@ suite('ValueStore', () => { ms.put(c); const v2 = await vs.readValue(c.ref); assert.equal('abc', v2); + await vs.close(); }); test('writeValue primitives', async () => { @@ -45,6 +46,7 @@ suite('ValueStore', () => { assert.equal(false, v2); const v3 = await vs.readValue(r3); assert.equal(2, v3); + await vs.close(); }); test('writeValue rejects invalid', async () => { @@ -62,6 +64,7 @@ suite('ValueStore', () => { ex = e; } assert.instanceOf(ex, Error); + await vs.close(); }); test('write coalescing', async () => { @@ -72,6 +75,7 @@ suite('ValueStore', () => { (bs: any).schedulePut = () => { assert.fail('unreachable'); }; const r2 = vs.writeValue('hello').targetRef; assert.isTrue(r1.equals(r2)); + await vs.close(); }); test('read caching', async () => { @@ -84,6 +88,7 @@ suite('ValueStore', () => { (bs: any).get = () => { throw new Error(); }; const v2 = await vs.readValue(r1); assert.equal(v1, v2); + await vs.close(); }); test('caching eviction', async () => { @@ -108,6 +113,7 @@ suite('ValueStore', () => { ex = e; } assert.instanceOf(ex, Error); + await vs.close(); }); test('hints on cache', async () => { @@ -119,5 +125,6 @@ suite('ValueStore', () => { const v = await vs.readValue(r.targetRef); assert.isTrue(equals(l, v)); + await vs.close(); }); }); diff --git a/js/src/value-store.js b/js/src/value-store.js index bd882d4906..c08797b162 100644 --- a/js/src/value-store.js +++ b/js/src/value-store.js @@ -90,8 +90,8 @@ export default class ValueStore { return this._bs.flush(); } - close() { - this._bs.close(); + close(): Promise { + return this._bs.close(); } } diff --git a/js/src/walk-test.js b/js/src/walk-test.js index e5b85cd614..ba3945e1b2 100644 --- a/js/src/walk-test.js +++ b/js/src/walk-test.js @@ -16,13 +16,18 @@ import {newMap} from './map.js'; import {newSet} from './set.js'; import walk from './walk.js'; -import {suite, test} from 'mocha'; +import {suite, suiteSetup, suiteTeardown, test} from 'mocha'; import {assert} from 'chai'; import type {valueOrPrimitive} from './value.js'; suite('walk', () => { - const ds = new Database(new BatchStoreAdaptor(new MemoryStore())); + let ds; + suiteSetup(() => { + ds = new Database(new BatchStoreAdaptor(new MemoryStore())); + }); + + suiteTeardown((): Promise => ds.close()); test('primitives', async () => { await Promise.all([true, false, 42, 88.8, 'hello!', ''].map(async v => { diff --git a/js/src/xp-test.js b/js/src/xp-test.js index 58aa7fcbd2..89e8396482 100644 --- a/js/src/xp-test.js +++ b/js/src/xp-test.js @@ -29,6 +29,7 @@ suite('cross platform test', () => { assert.strictEqual(v2, t._value, t._description); assert.strictEqual(t._value, v2, t._description); assert.strictEqual(t._expectedRef, r.targetRef.toString(), t._description); + return db.close(); } async function testTypes(testValues: Array): Promise {