node-postgres/test/suite.js
Sehrope Sarkuni 0894a3ce07 feat: Add dynamic retrieval for client password (#1926)
* feat: Add dynamic retrieval for client password

Adds option to specify a function for a client password. When the client
is connected, if the value of password is a function then it is invoked
to get the password to use for that connection.

The function must return either a string or a Promise that resolves to
a string. If the function throws or rejects with an error then it will
be bubbled up to the client.

* test: Add testAsync() helper to Suite

Add testAsync() helper function to Suite to simplify running tests that
return a Promise. The test action is executed and if a syncronous error
is thrown then it is immediately considered failed. If the Promise resolves
successfully then the test is considered successful. If the Promise
rejects with an Error then the test is considered failed.

* test: Add tests for dynamic password

* test: Simplify testAsync error handling

* fix: Clean up dynamic password error handling and misc style

* test: Remove extra semicolons

* test: Change testAsync(...) calls to use arrow functions

* fix: Wrap self.password() invocation in an arrow function

* test: Add a comment to testAsync(...)
2019-07-25 12:48:48 -05:00

99 lines
2.0 KiB
JavaScript

'use strict'
const async = require('async')
class Test {
constructor (name, cb) {
this.name = name
this.action = cb
this.timeout = 5000
}
run (cb) {
try {
this._run(cb)
} catch (e) {
cb(e)
}
}
_run (cb) {
if (!this.action) {
console.log(`${this.name} skipped`)
return cb()
}
if (!this.action.length) {
const result = this.action.call(this)
if (!(result || 0).then) {
return cb()
}
result
.then(() => cb())
.catch(err => cb(err || new Error('Unhandled promise rejection')))
} else {
this.action.call(this, cb)
}
}
}
class Suite {
constructor (name) {
console.log('')
this._queue = async.queue(this.run.bind(this), 1)
this._queue.drain = () => { }
}
run (test, cb) {
process.stdout.write(' ' + test.name + ' ')
if (!test.action) {
process.stdout.write('? - SKIPPED\n')
return cb()
}
const tid = setTimeout(() => {
const err = Error(`test: ${test.name} did not complete withint ${test.timeout}ms`)
console.log('\n' + err.stack)
process.exit(-1)
}, test.timeout)
test.run((err) => {
clearTimeout(tid)
if (err) {
process.stdout.write(`FAILED!\n\n${err.stack}\n`)
process.exit(-1)
} else {
process.stdout.write('✔\n')
cb()
}
})
}
test (name, cb) {
const test = new Test(name, cb)
this._queue.push(test)
}
/**
* Run an async test that can return a Promise. If the Promise resolves
* successfully then the test will pass. If the Promise rejects with an
* error then the test will be considered failed.
*/
testAsync (name, action) {
const test = new Test(name, cb => {
Promise.resolve()
.then(action)
.then(() => cb(null), cb)
})
this._queue.push(test)
}
}
process.on('unhandledRejection', (e) => {
setImmediate(() => {
console.error('Unhandled promise rejection')
throw e
})
})
module.exports = Suite