Skip to content

Commit

Permalink
Address a few TODO comments in the test suite
Browse files Browse the repository at this point in the history
Category: none
  • Loading branch information
vweevers committed Dec 29, 2024
1 parent 6684039 commit 9c51f71
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 100 deletions.
25 changes: 21 additions & 4 deletions test/iterator-seek-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand All @@ -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()
Expand Down
71 changes: 35 additions & 36 deletions test/self/deferred-iterator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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({
Expand All @@ -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 () {
Expand All @@ -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()
})
}

Expand Down Expand Up @@ -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}()`)
}
}
}
114 changes: 54 additions & 60 deletions test/self/sublevel-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})

Expand Down Expand Up @@ -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!')
Expand Down Expand Up @@ -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 = []
Expand All @@ -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'
})
})

Expand Down

0 comments on commit 9c51f71

Please sign in to comment.