Skip to content
This repository has been archived by the owner on Dec 1, 2024. It is now read-only.

Commit

Permalink
promisify: tests pass
Browse files Browse the repository at this point in the history
  • Loading branch information
juliangruber committed Aug 25, 2017
1 parent f95eaf8 commit 7790d92
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 91 deletions.
8 changes: 8 additions & 0 deletions lib/batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var util = require('./util')
var WriteError = require('level-errors').WriteError
var getOptions = util.getOptions
var dispatchError = util.dispatchError
var promisify = util.promisify

function Batch (levelup, codec) {
this._levelup = levelup
Expand Down Expand Up @@ -68,6 +69,11 @@ Batch.prototype.clear = function () {
Batch.prototype.write = function (callback) {
var levelup = this._levelup
var ops = this.ops
var promise

if (!callback) {
[ callback, promise ] = promisify()
}

try {
this.batch.write(function (err) {
Expand All @@ -78,6 +84,8 @@ Batch.prototype.write = function (callback) {
} catch (err) {
throw new WriteError(err)
}

return promise
}

module.exports = Batch
75 changes: 55 additions & 20 deletions lib/levelup.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var InitializationError = errors.InitializationError
var getOptions = util.getOptions
var defaultOptions = util.defaultOptions
var dispatchError = util.dispatchError
var promisify = util.promisify

function getCallback (options, callback) {
return typeof options === 'function' ? options : callback
Expand Down Expand Up @@ -77,6 +78,11 @@ inherits(LevelUP, EventEmitter)

LevelUP.prototype.open = function (callback) {
var self = this
var promise

if (!callback) {
[ callback, promise ] = promisify()
}

if (this.isOpen()) {
if (callback) { process.nextTick(function () { callback(null, self) }) }
Expand All @@ -98,10 +104,17 @@ LevelUP.prototype.open = function (callback) {
self.emit('open')
self.emit('ready')
})

return promise
}

LevelUP.prototype.close = function (callback) {
var self = this
var promise

if (!callback) {
[ callback, promise ] = promisify()
}

if (this.isOpen()) {
this.db.close(function () {
Expand All @@ -119,6 +132,8 @@ LevelUP.prototype.close = function (callback) {
self.close(callback)
})
}

return promise
}

LevelUP.prototype.isOpen = function () {
Expand All @@ -140,26 +155,23 @@ function maybeError (db, callback) {
}
}

function writeError (db, message, callback) {
dispatchError(db, new WriteError(message), callback)
}
LevelUP.prototype.get = function (key_, options, callback) {
if (key_ === null || key_ === undefined) {
throw new ReadError('get() requires a key argument')
}

function readError (db, message, callback) {
dispatchError(db, new ReadError(message), callback)
}
callback = getCallback(options, callback)

LevelUP.prototype.get = function (key_, options, callback) {
var self = this
var key
var promise

callback = getCallback(options, callback)
if (!callback) {
[ callback, promise ] = promisify()
}

if (maybeError(this, callback)) { return }

if (key_ === null || key_ === undefined || typeof callback !== 'function') {
return readError(this, 'get() requires key and callback arguments', callback)
}

options = util.getOptions(options)
key = this._codec.encodeKey(key_, options)

Expand All @@ -184,17 +196,24 @@ LevelUP.prototype.get = function (key_, options, callback) {
callback(null, value)
}
})

return promise
}

LevelUP.prototype.put = function (key_, value_, options, callback) {
if (key_ === null || key_ === undefined) throw new WriteError('put() requires a key argument')

var promise
if (!callback) {
[ callback, promise ] = promisify()
}

var self = this
var key
var value

callback = getCallback(options, callback)

if (key_ === null || key_ === undefined) { return writeError(this, 'put() requires a key argument', callback) }

if (maybeError(this, callback)) { return }

options = getOptions(options)
Expand All @@ -208,16 +227,23 @@ LevelUP.prototype.put = function (key_, value_, options, callback) {
self.emit('put', key_, value_)
if (callback) { callback() }
})

return promise
}

LevelUP.prototype.del = function (key_, options, callback) {
if (key_ === null || key_ === undefined) throw new WriteError('del() requires a key argument')

var promise
if (!callback) {
[ callback, promise ] = promisify()
}

var self = this
var key

callback = getCallback(options, callback)

if (key_ === null || key_ === undefined) { return writeError(this, 'del() requires a key argument', callback) }

if (maybeError(this, callback)) { return }

options = getOptions(options)
Expand All @@ -230,17 +256,24 @@ LevelUP.prototype.del = function (key_, options, callback) {
self.emit('del', key_)
if (callback) { callback() }
})

return promise
}

LevelUP.prototype.batch = function (arr_, options, callback) {
var self = this
var arr
if (!arguments.length) return new Batch(this, this._codec)

if (!arguments.length) { return new Batch(this, this._codec) }
if (!Array.isArray(arr_)) throw new WriteError('batch() requires an array argument')

callback = getCallback(options, callback)

if (!Array.isArray(arr_)) { return writeError(this, 'batch() requires an array argument', callback) }
var self = this
var arr
var promise

if (!callback) {
[ callback, promise ] = promisify()
}

if (maybeError(this, callback)) { return }

Expand All @@ -258,6 +291,8 @@ LevelUP.prototype.batch = function (arr_, options, callback) {
self.emit('batch', arr_)
if (callback) { callback() }
})

return promise
}

LevelUP.prototype.readStream =
Expand Down
15 changes: 14 additions & 1 deletion lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,22 @@ function isDefined (v) {
return typeof v !== 'undefined'
}

function promisify () {
var resolve_, reject_
var promise = new Promise(function (resolve, reject) {
[resolve_, reject_] = [resolve, reject]
})
function callback (err, value) {
if (err) reject_(err)
else resolve_(value)
}
return [ callback, promise ]
}

module.exports = {
defaultOptions: defaultOptions,
getOptions: getOptions,
dispatchError: dispatchError,
isDefined: isDefined
isDefined: isDefined,
promisify: promisify
}
15 changes: 1 addition & 14 deletions test/argument-checking-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,9 @@ buster.testCase('Argument checking', {
this.openTestDatabase(function (db) {
assert.exception(
db.get.bind(db),
{ name: 'ReadError', message: 'get() requires key and callback arguments' },
{ name: 'ReadError', message: 'get() requires a key argument' },
'no-arg get() throws'
)

assert.exception(
db.get.bind(db, 'foo'),
{ name: 'ReadError', message: 'get() requires key and callback arguments' },
'callback-less, 1-arg get() throws'
)

assert.exception(
db.get.bind(db, 'foo', {}),
{ name: 'ReadError', message: 'get() requires key and callback arguments' },
'callback-less, 2-arg get() throws'
)

done()
})
},
Expand Down
6 changes: 0 additions & 6 deletions test/batch-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,12 +316,6 @@ buster.testCase('batch()', {
this.verify(function () {
this.batch.clear()
}.bind(this))
},

'test write()': function () {
this.verify(function () {
this.batch.write()
}.bind(this))
}
}
}
Expand Down
15 changes: 1 addition & 14 deletions test/get-put-del-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,22 +88,9 @@ buster.testCase('get() / put() / del()', {
this.openTestDatabase(function (db) {
assert.exception(
db.get.bind(db),
{ name: 'ReadError', message: 'get() requires key and callback arguments' },
{ name: 'ReadError', message: 'get() requires a key argument' },
'no-arg get() throws'
)

assert.exception(
db.get.bind(db, 'foo'),
{ name: 'ReadError', message: 'get() requires key and callback arguments' },
'callback-less, 1-arg get() throws'
)

assert.exception(
db.get.bind(db, 'foo', {}),
{ name: 'ReadError', message: 'get() requires key and callback arguments' },
'callback-less, 2-arg get() throws'
)

done()
})
},
Expand Down
66 changes: 30 additions & 36 deletions test/null-and-undefined-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,57 +27,51 @@ buster.testCase('null & undefined keys & values', {
},

'get() with null key causes error': function (done) {
this.db.get(null, function (err, value) {
refute(value)
assert.isInstanceOf(err, Error)
assert.isInstanceOf(err, errors.LevelUPError)
done()
})
assert.exception(
this.db.get.bind(this.db, null),
{ name: 'ReadError', message: 'get() requires a key argument' }
)
done()
},

'get() with undefined key causes error': function (done) {
this.db.get(undefined, function (err, value) {
refute(value)
assert.isInstanceOf(err, Error)
assert.isInstanceOf(err, errors.LevelUPError)
done()
})
assert.exception(
this.db.get.bind(this.db, undefined),
{ name: 'ReadError', message: 'get() requires a key argument' }
)
done()
},

'del() with null key causes error': function (done) {
this.db.del(null, function (err, value) {
refute(value)
assert.isInstanceOf(err, Error)
assert.isInstanceOf(err, errors.LevelUPError)
done()
})
assert.exception(
this.db.del.bind(this.db, null),
{ name: 'WriteError', message: 'del() requires a key argument' }
)
done()
},

'del() with undefined key causes error': function (done) {
this.db.del(undefined, function (err, value) {
refute(value)
assert.isInstanceOf(err, Error)
assert.isInstanceOf(err, errors.LevelUPError)
done()
})
assert.exception(
this.db.del.bind(this.db, undefined),
{ name: 'WriteError', message: 'del() requires a key argument' }
)
done()
},

'put() with null key causes error': function (done) {
this.db.put(null, 'foo', function (err, value) {
refute(value)
assert.isInstanceOf(err, Error)
assert.isInstanceOf(err, errors.LevelUPError)
done()
})
assert.exception(
this.db.put.bind(this.db, null, 'foo'),
{ name: 'WriteError', message: 'put() requires a key argument' }
)
done()
},

'put() with undefined key causes error': function (done) {
this.db.put(undefined, 'foo', function (err, value) {
refute(value)
assert.isInstanceOf(err, Error)
assert.isInstanceOf(err, errors.LevelUPError)
done()
})
assert.exception(
this.db.put.bind(this.db, undefined, 'foo'),
{ name: 'WriteError', message: 'put() requires a key argument' }
)
done()
},

'put() with null value works': function (done) {
Expand Down

0 comments on commit 7790d92

Please sign in to comment.