256 lines
8.6 KiB
JavaScript
256 lines
8.6 KiB
JavaScript
|
'use strict'
|
||
|
|
||
|
const { Buffer } = require('buffer')
|
||
|
const textEncoder = new TextEncoder()
|
||
|
|
||
|
exports.all = function (test, testCommon) {
|
||
|
if (!testCommon.supports.encodings.buffer) return
|
||
|
|
||
|
// NOTE: adapted from levelup
|
||
|
test('test put() and get() with buffer value and buffer valueEncoding', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.put('test', testBuffer(), { valueEncoding: 'buffer' })
|
||
|
t.same(await db.get('test', { valueEncoding: 'buffer' }), testBuffer())
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from levelup
|
||
|
test('test put() and get() with buffer value and buffer valueEncoding in factory', async function (t) {
|
||
|
const db = testCommon.factory({ valueEncoding: 'buffer' })
|
||
|
await db.open()
|
||
|
await db.put('test', testBuffer())
|
||
|
t.same(await db.get('test'), testBuffer())
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from levelup
|
||
|
test('test put() and get() with buffer key and buffer keyEncoding', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.put(testBuffer(), 'test', { keyEncoding: 'buffer' })
|
||
|
t.same(await db.get(testBuffer(), { keyEncoding: 'buffer' }), 'test')
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from levelup
|
||
|
test('test put() and get() with buffer key and utf8 keyEncoding', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.put(Buffer.from('foo🐄'), 'test', { keyEncoding: 'utf8' })
|
||
|
t.same(await db.get(Buffer.from('foo🐄'), { keyEncoding: 'utf8' }), 'test')
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from levelup
|
||
|
test('test put() and get() with string value and buffer valueEncoding', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.put('test', 'foo🐄', { valueEncoding: 'buffer' })
|
||
|
t.same(await db.get('test', { valueEncoding: 'buffer' }), Buffer.from('foo🐄'))
|
||
|
t.same(await db.get('test', { valueEncoding: 'utf8' }), 'foo🐄')
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from memdown
|
||
|
test('put() as string, get() as buffer and vice versa', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
const enc = { keyEncoding: 'buffer', valueEncoding: 'buffer' }
|
||
|
const [a, b] = ['🐄', '🐄 says moo']
|
||
|
|
||
|
const promise1 = db.put(a, a).then(async () => {
|
||
|
const value = await db.get(Buffer.from(a), enc)
|
||
|
t.same(value, Buffer.from(a), 'got buffer value')
|
||
|
})
|
||
|
|
||
|
const promise2 = db.put(Buffer.from(b), Buffer.from(b), enc).then(async () => {
|
||
|
const value = await db.get(b)
|
||
|
t.same(value, b, 'got string value')
|
||
|
})
|
||
|
|
||
|
await Promise.all([promise1, promise2])
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from memdown
|
||
|
test('put() stringifies input to buffer', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.put(1, 2)
|
||
|
|
||
|
const it = db.iterator({ keyEncoding: 'buffer', valueEncoding: 'buffer' })
|
||
|
const entries = await it.all()
|
||
|
|
||
|
t.same(entries[0][0], Buffer.from('1'), 'key was stringified')
|
||
|
t.same(entries[0][1], Buffer.from('2'), 'value was stringified')
|
||
|
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from memdown
|
||
|
test('put() as string, iterate as buffer', async function (t) {
|
||
|
const db = testCommon.factory({ keyEncoding: 'utf8', valueEncoding: 'utf8' })
|
||
|
await db.open()
|
||
|
await db.put('🐄', '🐄')
|
||
|
|
||
|
const it = db.iterator({ keyEncoding: 'buffer', valueEncoding: 'buffer' })
|
||
|
const entries = await it.all()
|
||
|
|
||
|
t.same(entries, [[Buffer.from('🐄'), Buffer.from('🐄')]])
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from memdown
|
||
|
test('put() as buffer, iterate as string', async function (t) {
|
||
|
const db = testCommon.factory({ keyEncoding: 'buffer', valueEncoding: 'buffer' })
|
||
|
await db.open()
|
||
|
await db.put(Buffer.from('🐄'), Buffer.from('🐄'))
|
||
|
|
||
|
const it = db.iterator({ keyEncoding: 'utf8', valueEncoding: 'utf8' })
|
||
|
const entries = await it.all()
|
||
|
|
||
|
t.same(entries, [['🐄', '🐄']])
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
test('put() as view, iterate as view', async function (t) {
|
||
|
const db = testCommon.factory({ keyEncoding: 'view', valueEncoding: 'view' })
|
||
|
const cow = textEncoder.encode('🐄')
|
||
|
await db.open()
|
||
|
await db.put(cow, cow)
|
||
|
|
||
|
const it = db.iterator()
|
||
|
const entries = await it.all()
|
||
|
const key = Buffer.isBuffer(entries[0][0]) ? Buffer.from(cow) : cow // Valid, Buffer is a Uint8Array
|
||
|
const value = Buffer.isBuffer(entries[0][1]) ? Buffer.from(cow) : cow
|
||
|
|
||
|
t.same(entries, [[key, value]])
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
test('put() as string, iterate as view', async function (t) {
|
||
|
const db = testCommon.factory({ keyEncoding: 'utf8', valueEncoding: 'utf8' })
|
||
|
const cow = textEncoder.encode('🐄')
|
||
|
await db.open()
|
||
|
await db.put('🐄', '🐄')
|
||
|
|
||
|
const it = db.iterator({ keyEncoding: 'view', valueEncoding: 'view' })
|
||
|
const entries = await it.all()
|
||
|
const key = Buffer.isBuffer(entries[0][0]) ? Buffer.from(cow) : cow // Valid, Buffer is a Uint8Array
|
||
|
const value = Buffer.isBuffer(entries[0][1]) ? Buffer.from(cow) : cow
|
||
|
|
||
|
t.same(entries, [[key, value]])
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
test('put() as view, iterate as string', async function (t) {
|
||
|
const db = testCommon.factory({ keyEncoding: 'view', valueEncoding: 'view' })
|
||
|
const cow = textEncoder.encode('🐄')
|
||
|
await db.open()
|
||
|
await db.put(cow, cow)
|
||
|
|
||
|
const it = db.iterator({ keyEncoding: 'utf8', valueEncoding: 'utf8' })
|
||
|
const entries = await it.all()
|
||
|
|
||
|
t.same(entries, [['🐄', '🐄']])
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from levelup
|
||
|
test('batch() with multiple puts with buffer valueEncoding per batch', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.batch([
|
||
|
{ type: 'put', key: 'foo', value: testBuffer() },
|
||
|
{ type: 'put', key: 'bar', value: testBuffer() },
|
||
|
{ type: 'put', key: 'baz', value: 'abazvalue' }
|
||
|
], { valueEncoding: 'buffer' })
|
||
|
|
||
|
t.same(await db.get('foo', { valueEncoding: 'buffer' }), testBuffer())
|
||
|
t.same(await db.get('bar', { valueEncoding: 'buffer' }), testBuffer())
|
||
|
t.same(await db.get('baz', { valueEncoding: 'buffer' }), Buffer.from('abazvalue'))
|
||
|
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
test('batch() with multiple puts with buffer valueEncoding per operation', async function (t) {
|
||
|
const db = testCommon.factory()
|
||
|
await db.open()
|
||
|
await db.batch([
|
||
|
{ type: 'put', key: 'foo', value: testBuffer(), valueEncoding: 'buffer' },
|
||
|
{ type: 'put', key: 'bar', value: testBuffer(), valueEncoding: 'buffer' },
|
||
|
{ type: 'put', key: 'baz', value: 'abazvalue', valueEncoding: 'buffer' }
|
||
|
])
|
||
|
|
||
|
t.same(await db.get('foo', { valueEncoding: 'buffer' }), testBuffer())
|
||
|
t.same(await db.get('bar', { valueEncoding: 'buffer' }), testBuffer())
|
||
|
t.same(await db.get('baz', { valueEncoding: 'buffer' }), Buffer.from('abazvalue'))
|
||
|
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
// NOTE: adapted from encoding-down
|
||
|
test('batch() with buffer encoding in factory', async function (t) {
|
||
|
const operations = [{
|
||
|
type: 'put',
|
||
|
key: Buffer.from([1, 2, 3]),
|
||
|
value: Buffer.from([4, 5, 6])
|
||
|
}, {
|
||
|
type: 'put',
|
||
|
key: Buffer.from([7, 8, 9]),
|
||
|
value: Buffer.from([10, 11, 12])
|
||
|
}]
|
||
|
|
||
|
const db = testCommon.factory({ keyEncoding: 'buffer', valueEncoding: 'buffer' })
|
||
|
await db.open()
|
||
|
await db.batch(operations)
|
||
|
|
||
|
t.same(await db.get(operations[0].key), operations[0].value)
|
||
|
t.same(await db.get(operations[1].key), operations[1].value)
|
||
|
|
||
|
return db.close()
|
||
|
})
|
||
|
|
||
|
for (const keyEncoding of ['buffer', 'view']) {
|
||
|
// NOTE: adapted from memdown
|
||
|
test(`storage is byte-aware (${keyEncoding} encoding)`, function (t) {
|
||
|
const db = testCommon.factory({ keyEncoding })
|
||
|
|
||
|
db.open(function (err) {
|
||
|
t.ifError(err, 'no open error')
|
||
|
|
||
|
const one = Buffer.from('80', 'hex')
|
||
|
const two = Buffer.from('c0', 'hex')
|
||
|
|
||
|
t.ok(two.toString() === one.toString(), 'would be equal when not byte-aware')
|
||
|
t.ok(two.compare(one) > 0, 'but greater when byte-aware')
|
||
|
|
||
|
db.put(one, 'one', function (err) {
|
||
|
t.ifError(err, 'no put() error')
|
||
|
|
||
|
db.get(one, function (err, value) {
|
||
|
t.ifError(err, 'no get() error')
|
||
|
t.is(value, 'one', 'value one ok')
|
||
|
|
||
|
db.put(two, 'two', function (err) {
|
||
|
t.ifError(err, 'no put() error')
|
||
|
|
||
|
db.get(one, function (err, value) {
|
||
|
t.ifError(err, 'no get() error')
|
||
|
t.is(value, 'one', 'value one did not change')
|
||
|
|
||
|
db.close(t.end.bind(t))
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function testBuffer () {
|
||
|
return Buffer.from('0080c0ff', 'hex')
|
||
|
}
|