Skip to content

Commit

Permalink
Support running test suite on a levelup db (#364)
Browse files Browse the repository at this point in the history
As well as skipping 'start' and 'end' tests (for multileveldown).
  • Loading branch information
vweevers authored Apr 11, 2020
1 parent 9193656 commit 9ca0ff4
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 66 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ This also serves as a signal to users of your implementation. The following opti
- Reads don't operate on a [snapshot](#iterator)
- Snapshots are created asynchronously
- `createIfMissing` and `errorIfExists`: set to `false` if `db._open()` does not support these options.
- `legacyRange`: set to `false` if your iterator does not support the legacy `start` and `end` range options.

This metadata will be moved to manifests (`db.supports`) in the future.

Expand Down
18 changes: 14 additions & 4 deletions test/batch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports.setUp = function (test, testCommon) {
}

exports.args = function (test, testCommon) {
test('test callback-less, 2-arg, batch() throws', function (t) {
testCommon.promises || test('test callback-less, 2-arg, batch() throws', function (t) {
t.throws(
db.batch.bind(db, 'foo', {}),
/Error: batch\(array\) requires a callback argument/,
Expand Down Expand Up @@ -215,7 +215,11 @@ exports.batch = function (test, testCommon) {
db.get('foo', function (err, value) {
t.error(err)
var result
if (isTypedArray(value)) {

if (testCommon.encodings) {
t.is(typeof value, 'string')
result = value
} else if (isTypedArray(value)) {
result = String.fromCharCode.apply(null, new Uint16Array(value))
} else {
t.ok(typeof Buffer !== 'undefined' && value instanceof Buffer)
Expand Down Expand Up @@ -244,7 +248,10 @@ exports.batch = function (test, testCommon) {
db.get('foobatch1', function (err, value) {
t.error(err)
var result
if (isTypedArray(value)) {
if (testCommon.encodings) {
t.is(typeof value, 'string')
result = value
} else if (isTypedArray(value)) {
result = String.fromCharCode.apply(null, new Uint16Array(value))
} else {
t.ok(typeof Buffer !== 'undefined' && value instanceof Buffer)
Expand All @@ -264,7 +271,10 @@ exports.batch = function (test, testCommon) {
db.get('foobatch3', function (err, value) {
t.error(err)
var result
if (isTypedArray(value)) {
if (testCommon.encodings) {
t.is(typeof value, 'string')
result = value
} else if (isTypedArray(value)) {
result = String.fromCharCode.apply(null, new Uint16Array(value))
} else {
t.ok(typeof Buffer !== 'undefined' && value instanceof Buffer)
Expand Down
6 changes: 3 additions & 3 deletions test/chained-batch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test batch#write() with no callback', function (t) {
testCommon.promises || test('test batch#write() with no callback', function (t) {
try {
db.batch().write()
} catch (err) {
Expand Down Expand Up @@ -186,7 +186,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test serialize object', function (t) {
testCommon.serialize && test('test serialize object', function (t) {
var batch = db.batch()
var ops = collectBatchOps(batch)

Expand All @@ -202,7 +202,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test custom _serialize*', function (t) {
testCommon.serialize && test('test custom _serialize*', function (t) {
t.plan(4)

var _db = Object.create(db)
Expand Down
2 changes: 1 addition & 1 deletion test/clear-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ exports.setUp = function (test, testCommon) {
}

exports.args = function (test, testCommon) {
test('test argument-less clear() throws', function (t) {
testCommon.promises || test('test argument-less clear() throws', function (t) {
t.throws(
db.clear.bind(db),
/Error: clear\(\) requires a callback argument/,
Expand Down
4 changes: 2 additions & 2 deletions test/close-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ exports.setUp = function (test, testCommon) {

exports.close = function (test, testCommon) {
test('test close()', function (t) {
t.throws(
testCommon.promises || t.throws(
db.close.bind(db),
/Error: close\(\) requires a callback argument/,
'no-arg close() throws'
)
t.throws(
testCommon.promises || t.throws(
db.close.bind(db, 'foo'),
/Error: close\(\) requires a callback argument/,
'non-callback close() throws'
Expand Down
20 changes: 19 additions & 1 deletion test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,25 @@ function testCommon (options) {
errorIfExists: options.errorIfExists !== false,
snapshots: options.snapshots !== false,
seek: options.seek !== false,
clear: !!options.clear
clear: !!options.clear,

// Allow skipping 'start' and 'end' tests
// TODO (next major): drop legacy range options
legacyRange: options.legacyRange !== false,

// Support running test suite on a levelup db. All options below this line
// are undocumented and should not be used by abstract-leveldown db's (yet).
promises: !!options.promises,
status: options.status !== false,
serialize: options.serialize !== false,

// If true, the test suite assumes a default encoding of utf8 (like levelup)
// and that operations return strings rather than buffers by default.
encodings: !!options.encodings,

// Not yet used, only here for symmetry with levelup's test suite.
deferredOpen: !!options.deferredOpen,
streams: !!options.streams
}
}

Expand Down
8 changes: 4 additions & 4 deletions test/del-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ exports.setUp = function (test, testCommon) {
}

exports.args = function (test, testCommon) {
test('test argument-less del() throws', function (t) {
testCommon.promises || test('test argument-less del() throws', function (t) {
t.throws(
db.del.bind(db),
/Error: del\(\) requires a callback argument/,
Expand All @@ -19,7 +19,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test callback-less, 1-arg, del() throws', function (t) {
testCommon.promises || test('test callback-less, 1-arg, del() throws', function (t) {
t.throws(
db.del.bind(db, 'foo'),
/Error: del\(\) requires a callback argument/,
Expand All @@ -28,7 +28,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test callback-less, 3-arg, del() throws', function (t) {
testCommon.promises || test('test callback-less, 3-arg, del() throws', function (t) {
t.throws(
db.del.bind(db, 'foo', {}),
/Error: del\(\) requires a callback argument/,
Expand All @@ -37,7 +37,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test custom _serialize*', function (t) {
testCommon.serialize && test('test custom _serialize*', function (t) {
t.plan(3)
var db = testCommon.factory()
db._serializeKey = function (data) { return data }
Expand Down
54 changes: 31 additions & 23 deletions test/get-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ exports.setUp = function (test, testCommon) {
}

exports.args = function (test, testCommon) {
test('test argument-less get() throws', function (t) {
testCommon.promises || test('test argument-less get() throws', function (t) {
t.throws(
db.get.bind(db),
/Error: get\(\) requires a callback argument/,
Expand All @@ -20,7 +20,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test callback-less, 1-arg, get() throws', function (t) {
testCommon.promises || test('test callback-less, 1-arg, get() throws', function (t) {
t.throws(
db.get.bind(db, 'foo'),
/Error: get\(\) requires a callback argument/,
Expand All @@ -29,7 +29,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test callback-less, 3-arg, get() throws', function (t) {
testCommon.promises || test('test callback-less, 3-arg, get() throws', function (t) {
t.throws(
db.get.bind(db, 'foo', {}),
/Error: get\(\) requires a callback argument/,
Expand All @@ -38,7 +38,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test custom _serialize*', function (t) {
testCommon.serialize && test('test custom _serialize*', function (t) {
t.plan(3)
var db = testCommon.factory()
db._serializeKey = function (data) { return data }
Expand All @@ -61,29 +61,12 @@ exports.get = function (test, testCommon) {
t.error(err)
db.get('foo', function (err, value) {
t.error(err)
t.ok(typeof value !== 'string', 'should not be string by default')

var result
if (isTypedArray(value)) {
result = String.fromCharCode.apply(null, new Uint16Array(value))
} else {
t.ok(typeof Buffer !== 'undefined' && value instanceof Buffer)
try {
result = value.toString()
} catch (e) {
t.error(e, 'should not throw when converting value to a string')
}
}

t.equal(result, 'bar')

db.get('foo', {}, function (err, value) { // same but with {}
t.error(err)
if (!testCommon.encodings) {
t.ok(typeof value !== 'string', 'should not be string by default')

var result
if (isTypedArray(value)) {
result = String.fromCharCode.apply(null, new Uint16Array(value))
var result = String.fromCharCode.apply(null, new Uint16Array(value))
} else {
t.ok(typeof Buffer !== 'undefined' && value instanceof Buffer)
try {
Expand All @@ -92,6 +75,31 @@ exports.get = function (test, testCommon) {
t.error(e, 'should not throw when converting value to a string')
}
}
} else {
result = value
}

t.equal(result, 'bar')

db.get('foo', {}, function (err, value) { // same but with {}
t.error(err)

if (!testCommon.encodings) {
t.ok(typeof value !== 'string', 'should not be string by default')

if (isTypedArray(value)) {
var result = String.fromCharCode.apply(null, new Uint16Array(value))
} else {
t.ok(typeof Buffer !== 'undefined' && value instanceof Buffer)
try {
result = value.toString()
} catch (e) {
t.error(e, 'should not throw when converting value to a string')
}
}
} else {
result = value
}

t.equal(result, 'bar')

Expand Down
4 changes: 4 additions & 0 deletions test/iterator-range-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ exports.setUp = function (test, testCommon) {

exports.range = function (test, testCommon) {
function rangeTest (name, opts, expected) {
if (!testCommon.legacyRange && ('start' in opts || 'end' in opts)) {
return
}

opts.keyAsBuffer = false
opts.valueAsBuffer = false
test(name, function (t) {
Expand Down
14 changes: 10 additions & 4 deletions test/iterator-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ exports.setUp = function (test, testCommon) {
exports.args = function (test, testCommon) {
test('test iterator has db reference', function (t) {
var iterator = db.iterator()
t.ok(iterator.db === db)
// For levelup compat: may return iterator of an underlying db, that's okay.
t.ok(iterator.db === db || iterator.db)
iterator.end(t.end.bind(t))
})

Expand Down Expand Up @@ -132,14 +133,19 @@ exports.iterator = function (test, testCommon) {
var fn = function (err, key, value) {
t.error(err)
if (key && value) {
t.ok(Buffer.isBuffer(key), 'key argument is a Buffer')
t.ok(Buffer.isBuffer(value), 'value argument is a Buffer')
if (testCommon.encodings) {
t.is(typeof key, 'string', 'key argument is a string')
t.is(typeof value, 'string', 'value argument is a string')
} else {
t.ok(Buffer.isBuffer(key), 'key argument is a Buffer')
t.ok(Buffer.isBuffer(value), 'value argument is a Buffer')
}
t.is(key.toString(), data[idx].key, 'correct key')
t.is(value.toString(), data[idx].value, 'correct value')
process.nextTick(next)
idx++
} else { // end
t.ok(typeof err === 'undefined', 'err argument is undefined')
t.ok(err == null, 'err argument is nullish')
t.ok(typeof key === 'undefined', 'key argument is undefined')
t.ok(typeof value === 'undefined', 'value argument is undefined')
t.is(idx, data.length, 'correct number of entries')
Expand Down
2 changes: 1 addition & 1 deletion test/manifest-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = function (test, testCommon) {

suite(test, testCommon)

test('manifest has status', function (t) {
testCommon.status && test('manifest has status', function (t) {
var db = testCommon.factory()
t.is(db.supports.status, true)

Expand Down
4 changes: 2 additions & 2 deletions test/open-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ exports.setUp = function (test, testCommon) {
}

exports.args = function (test, testCommon) {
test('test database open no-arg throws', function (t) {
testCommon.promises || test('test database open no-arg throws', function (t) {
var db = testCommon.factory()
t.throws(
db.open.bind(db),
Expand All @@ -13,7 +13,7 @@ exports.args = function (test, testCommon) {
t.end()
})

test('test callback-less, 1-arg, open() throws', function (t) {
testCommon.promises || test('test callback-less, 1-arg, open() throws', function (t) {
var db = testCommon.factory()
t.throws(
db.open.bind(db, {}),
Expand Down
Loading

0 comments on commit 9ca0ff4

Please sign in to comment.