diff --git a/test/iterator-seek-test.js b/test/iterator-seek-test.js index 2ee3b4b..3bb18cf 100644 --- a/test/iterator-seek-test.js +++ b/test/iterator-seek-test.js @@ -41,11 +41,26 @@ exports.sequence = function (test, testCommon) { exports.seek = function (test, testCommon) { const testData = () => [ + // Note that 'three' sorts before 'two' { type: 'put', key: 'one', value: '1' }, { type: 'put', key: 'two', value: '2' }, { type: 'put', key: 'three', value: '3' } ] + const bufferTestData = () => [ + // Note that 'b9' sorts before 'c0' + { type: 'put', key: Buffer.from('80', 'hex'), value: '1', keyEncoding: 'buffer' }, + { type: 'put', key: Buffer.from('c0', 'hex'), value: '2', keyEncoding: 'buffer' }, + { type: 'put', key: Buffer.from('b9', 'hex'), value: '3', keyEncoding: 'buffer' } + ] + + test('prepare byte-aware tests', function (t) { + const data = bufferTestData() + t.ok(data[0].key.toString() === data[1].key.toString(), 'would be equal when not byte-aware') + t.ok(data[0].key.compare(data[1].key) < 0, 'but less than when byte-aware') + t.end() + }) + for (const mode of ['iterator', 'keys', 'values']) { const mapEntry = mode === 'iterator' ? e => e : mode === 'keys' ? e => e[0] : e => e[1] @@ -63,15 +78,17 @@ exports.seek = function (test, testCommon) { }) if (testCommon.supports.encodings.buffer) { - // TODO: make this test meaningful, with bytes outside the utf8 range test(`${mode}().seek() to buffer target`, async function (t) { + // For this test to be meaningful it must use bytes outside the utf8 range + const data = bufferTestData() const db = testCommon.factory() - await db.batch(testData()) + await db.batch(data) const it = db[mode]({ keyEncoding: 'buffer' }) - it.seek(Buffer.from('two')) + // Seek to second key + it.seek(data[1].key) - t.same(await it.next(), mapEntry([Buffer.from('two'), '2']), 'match') + t.same(await it.next(), mapEntry([data[1].key, '2']), 'match') t.same(await it.next(), undefined, 'end of iterator') return db.close() diff --git a/test/self/deferred-iterator-test.js b/test/self/deferred-iterator-test.js index a578176..2834e51 100644 --- a/test/self/deferred-iterator-test.js +++ b/test/self/deferred-iterator-test.js @@ -55,8 +55,8 @@ for (const mode of ['iterator', 'keys', 'values']) { }) // NOTE: adapted from deferred-leveldown - test(`deferred ${mode}(): non-deferred operations`, function (t) { - t.plan(4) + test(`deferred ${mode}(): non-deferred operations`, async function (t) { + t.plan(3) class MockIterator extends RealCtor { _seek (target) { @@ -74,17 +74,14 @@ for (const mode of ['iterator', 'keys', 'values']) { } }) - // TODO: async/await - db.open().then(function () { - it.seek(123) - it.next().then(function (item) { - t.is(item, nextArg) - it.close().then(t.pass.bind(t, 'closed')) - }) - }) - const it = db[publicMethod]({ gt: 'foo' }) t.ok(it instanceof DeferredCtor) + + await db.open() + it.seek(123) + t.is(await it.next(), nextArg) + + return it.close() }) // NOTE: adapted from deferred-leveldown @@ -127,7 +124,7 @@ for (const mode of ['iterator', 'keys', 'values']) { }) for (const method of ['next', 'nextv', 'all']) { - test(`deferred ${mode}(): closed upon failed open, verified by ${method}()`, function (t) { + test(`deferred ${mode}(): closed upon failed open, verified by ${method}()`, async function (t) { t.plan(5) const db = mockLevel({ @@ -152,11 +149,11 @@ for (const mode of ['iterator', 'keys', 'values']) { return original.call(this, ...args) } - verifyClosed(t, it, method, () => {}) + return verifyClosed(t, it, method) }) - test(`deferred ${mode}(): deferred and real iterators are closed on db.close(), verified by ${method}()`, function (t) { - t.plan(8) + test(`deferred ${mode}(): deferred and real iterators are closed on db.close(), verified by ${method}()`, async function (t) { + t.plan(7) class MockIterator extends RealCtor { async _close () { @@ -179,17 +176,16 @@ for (const mode of ['iterator', 'keys', 'values']) { return original.call(this, ...args) } - // TODO: async/await - db.open().then(() => db.close()).then(function () { - verifyClosed(t, it, method, function () { - db.open().then(function () { - // Should still be closed - verifyClosed(t, it, method, function () { - db.close().then(t.pass.bind(t)) - }) - }) - }) - }) + await db.open() + await db.close() + + await verifyClosed(t, it, method) + await db.open() + + // Should still be closed + await verifyClosed(t, it, method) + + return db.close() }) } @@ -298,18 +294,21 @@ for (const mode of ['iterator', 'keys', 'values']) { }) }) - // TODO: async/await - const verifyClosed = function (t, it, method, cb) { + const verifyClosed = async function (t, it, method) { const requiredArgs = method === 'nextv' ? [10] : [] - it[method](...requiredArgs).then(t.fail.bind(t, 'should not succeed'), function (err) { - t.is(err && err.code, 'LEVEL_ITERATOR_NOT_OPEN', `correct error on first ${method}()`) + try { + await it[method](...requiredArgs) + t.fail('should not succeed') + } catch (err) { + t.is(err.code, 'LEVEL_ITERATOR_NOT_OPEN', `correct error on first ${method}()`) + } - // Should account for userland code that ignores errors - it[method](...requiredArgs).then(t.fail.bind(t, 'should not succeed'), function (err) { - t.is(err && err.code, 'LEVEL_ITERATOR_NOT_OPEN', `correct error on second ${method}()`) - cb() - }) - }) + try { + await it[method](...requiredArgs) + t.fail('should not succeed') + } catch (err) { + t.is(err.code, 'LEVEL_ITERATOR_NOT_OPEN', `correct error on second ${method}()`) + } } } diff --git a/test/self/sublevel-test.js b/test/self/sublevel-test.js index d4f8063..cb82b43 100644 --- a/test/self/sublevel-test.js +++ b/test/self/sublevel-test.js @@ -69,27 +69,25 @@ test('sublevel is extensible', function (t) { }) // NOTE: adapted from subleveldown -test('sublevel prefix and options', function (t) { - // TODO: rename "prefix" to "name" where appropriate. E.g. this test should be - // called 'empty name' rather than 'empty prefix'. - t.test('empty prefix', function (t) { +test('sublevel name and options', function (t) { + t.test('empty name', function (t) { const sub = new NoopLevel().sublevel('') t.is(sub.prefix, '!!') t.same(sub.path(), ['']) t.end() }) - t.test('prefix without options', function (t) { - const sub = new NoopLevel().sublevel('prefix') - t.is(sub.prefix, '!prefix!') - t.same(sub.path(), ['prefix']) + t.test('name without options', function (t) { + const sub = new NoopLevel().sublevel('name') + t.is(sub.prefix, '!name!') + t.same(sub.path(), ['name']) t.end() }) - t.test('prefix and separator option', function (t) { - const sub = new NoopLevel().sublevel('prefix', { separator: '%' }) - t.is(sub.prefix, '%prefix%') - t.same(sub.path(), ['prefix']) + t.test('name and separator option', function (t) { + const sub = new NoopLevel().sublevel('name', { separator: '%' }) + t.is(sub.prefix, '%name%') + t.same(sub.path(), ['name']) t.end() }) @@ -140,22 +138,22 @@ test('sublevel prefix and options', function (t) { t.end() }) - t.test('separator is trimmed from prefix', function (t) { - const sub1 = new NoopLevel().sublevel('!prefix') - t.is(sub1.prefix, '!prefix!') - t.same(sub1.path(), ['prefix']) + t.test('separator is trimmed from name', function (t) { + const sub1 = new NoopLevel().sublevel('!name') + t.is(sub1.prefix, '!name!') + t.same(sub1.path(), ['name']) - const sub2 = new NoopLevel().sublevel('prefix!') - t.is(sub2.prefix, '!prefix!') - t.same(sub2.path(), ['prefix']) + const sub2 = new NoopLevel().sublevel('name!') + t.is(sub2.prefix, '!name!') + t.same(sub2.path(), ['name']) - const sub3 = new NoopLevel().sublevel('!!prefix!!') - t.is(sub3.prefix, '!prefix!') - t.same(sub3.path(), ['prefix']) + const sub3 = new NoopLevel().sublevel('!!name!!') + t.is(sub3.prefix, '!name!') + t.same(sub3.path(), ['name']) - const sub4 = new NoopLevel().sublevel('@prefix@', { separator: '@' }) - t.is(sub4.prefix, '@prefix@') - t.same(sub4.path(), ['prefix']) + const sub4 = new NoopLevel().sublevel('@name@', { separator: '@' }) + t.is(sub4.prefix, '@name@') + t.same(sub4.path(), ['name']) const sub5 = new NoopLevel().sublevel(['!!!a', 'b!!!']) t.is(sub5.prefix, '!a!!b!') @@ -615,7 +613,7 @@ test('sublevel operations are prefixed', function (t) { test('sublevel encodings', function (t) { // NOTE: adapted from subleveldown - t.test('different sublevels can have different encodings', function (t) { + t.test('different sublevels can have different encodings', async function (t) { t.plan(6) const puts = [] @@ -636,41 +634,37 @@ test('sublevel encodings', function (t) { const sub1 = db.sublevel('test1', { valueEncoding: 'json' }) const sub2 = db.sublevel('test2', { keyEncoding: 'buffer', valueEncoding: 'buffer' }) - // TODO: async/await - sub1.put('foo', { some: 'json' }).then(function () { - t.same(puts, [{ - key: '!test1!foo', - value: '{"some":"json"}', - keyEncoding: 'utf8', - valueEncoding: 'utf8' - }]) - - sub1.get('foo').then(function (value) { - t.same(value, { some: 'json' }) - t.same(gets.shift(), { - key: '!test1!foo', - keyEncoding: 'utf8', - valueEncoding: 'utf8' - }) + await sub1.put('foo', { some: 'json' }) - sub2.put(Buffer.from([1, 2]), Buffer.from([3])).then(function () { - t.same(puts, [{ - key: Buffer.from('!test2!\x01\x02'), - value: Buffer.from([3]), - keyEncoding: 'buffer', - valueEncoding: 'buffer' - }]) - - sub2.get(Buffer.from([1, 2])).then(function (value) { - t.same(value, Buffer.from([3])) - t.same(gets.shift(), { - key: Buffer.from('!test2!\x01\x02'), - keyEncoding: 'buffer', - valueEncoding: 'buffer' - }) - }) - }) - }) + t.same(puts, [{ + key: '!test1!foo', + value: '{"some":"json"}', + keyEncoding: 'utf8', + valueEncoding: 'utf8' + }]) + + t.same(await sub1.get('foo'), { some: 'json' }) + t.same(gets.shift(), { + key: '!test1!foo', + keyEncoding: 'utf8', + valueEncoding: 'utf8' + }) + + await sub2.put(Buffer.from([1, 2]), Buffer.from([3])) + + t.same(puts, [{ + key: Buffer.from('!test2!\x01\x02'), + value: Buffer.from([3]), + keyEncoding: 'buffer', + valueEncoding: 'buffer' + }]) + + t.same(await sub2.get(Buffer.from([1, 2])), Buffer.from([3])) + + t.same(gets.shift(), { + key: Buffer.from('!test2!\x01\x02'), + keyEncoding: 'buffer', + valueEncoding: 'buffer' }) })