mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 09:09:36 +02:00
Merge pull request #17430 from overleaf/dp-callbackify-class
Add callbackifyClass utility GitOrigin-RevId: 762b800ce0eff2f146147908838162f7d32bd855
This commit is contained in:
@@ -8,6 +8,7 @@ module.exports = {
|
||||
promisifyMultiResult,
|
||||
callbackify,
|
||||
callbackifyAll,
|
||||
callbackifyClass,
|
||||
callbackifyMultiResult,
|
||||
expressify,
|
||||
expressifyErrorHandler,
|
||||
@@ -177,6 +178,34 @@ function callbackifyAll(module, opts = {}) {
|
||||
return callbacks
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbackify all methods in a class.
|
||||
*
|
||||
* Options are the same as for callbackifyAll
|
||||
*/
|
||||
function callbackifyClass(cls, opts = {}) {
|
||||
const callbackified = class extends cls {}
|
||||
const { without = [], multiResult = {} } = opts
|
||||
for (const propName of Object.getOwnPropertyNames(cls.prototype)) {
|
||||
if (propName === 'constructor' || without.includes(propName)) {
|
||||
continue
|
||||
}
|
||||
const propValue = cls.prototype[propName]
|
||||
if (typeof propValue !== 'function') {
|
||||
continue
|
||||
}
|
||||
if (multiResult[propName] != null) {
|
||||
callbackified.prototype[propName] = callbackifyMultiResult(
|
||||
propValue,
|
||||
multiResult[propName]
|
||||
)
|
||||
} else {
|
||||
callbackified.prototype[propName] = callbackify(propValue)
|
||||
}
|
||||
}
|
||||
return callbackified
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the effect of `promisifyMultiResult`.
|
||||
*
|
||||
@@ -186,7 +215,7 @@ function callbackifyAll(module, opts = {}) {
|
||||
function callbackifyMultiResult(fn, resultNames) {
|
||||
function callbackified(...args) {
|
||||
const [callback] = args.splice(-1)
|
||||
fn(...args)
|
||||
fn.apply(this, args)
|
||||
.then(result => {
|
||||
const cbResults = resultNames.map(resultName => result[resultName])
|
||||
callback(null, ...cbResults)
|
||||
|
||||
@@ -3,6 +3,7 @@ const {
|
||||
promisifyAll,
|
||||
promisifyClass,
|
||||
callbackifyMultiResult,
|
||||
callbackifyClass,
|
||||
callbackifyAll,
|
||||
expressify,
|
||||
expressifyErrorHandler,
|
||||
@@ -327,6 +328,108 @@ describe('callbackifyAll', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('callbackifyClass', function () {
|
||||
describe('basic functionality', function () {
|
||||
before(function () {
|
||||
this.Class = class {
|
||||
constructor(a) {
|
||||
this.a = a
|
||||
}
|
||||
|
||||
async asyncAdd(b) {
|
||||
return this.a + b
|
||||
}
|
||||
}
|
||||
this.Callbackified = callbackifyClass(this.Class)
|
||||
})
|
||||
|
||||
it('callbackifies the class methods', function (done) {
|
||||
const adder = new this.Callbackified(1)
|
||||
adder.asyncAdd(2, (err, sum) => {
|
||||
expect(err).not.to.exist
|
||||
expect(sum).to.equal(3)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('without option', function () {
|
||||
before(function () {
|
||||
this.Class = class {
|
||||
constructor(a) {
|
||||
this.a = a
|
||||
}
|
||||
|
||||
async asyncAdd(b) {
|
||||
return this.a + b
|
||||
}
|
||||
|
||||
syncAdd(b) {
|
||||
return this.a + b
|
||||
}
|
||||
}
|
||||
this.Callbackified = callbackifyClass(this.Class, {
|
||||
without: ['syncAdd'],
|
||||
})
|
||||
})
|
||||
|
||||
it('does not callbackify excluded functions', function () {
|
||||
const adder = new this.Callbackified(10)
|
||||
const sum = adder.syncAdd(12)
|
||||
expect(sum).to.equal(22)
|
||||
})
|
||||
|
||||
it('callbackifies other functions', function (done) {
|
||||
const adder = new this.Callbackified(1)
|
||||
adder.asyncAdd(2, (err, sum) => {
|
||||
expect(err).not.to.exist
|
||||
expect(sum).to.equal(3)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('multiResult option', function () {
|
||||
before(function () {
|
||||
this.Class = class {
|
||||
constructor(a) {
|
||||
this.a = a
|
||||
}
|
||||
|
||||
async asyncAdd(b) {
|
||||
return this.a + b
|
||||
}
|
||||
|
||||
async asyncArithmetic(b) {
|
||||
return { sum: this.a + b, product: this.a * b }
|
||||
}
|
||||
}
|
||||
this.Callbackified = callbackifyClass(this.Class, {
|
||||
multiResult: { asyncArithmetic: ['sum', 'product'] },
|
||||
})
|
||||
})
|
||||
|
||||
it('callbackifies multi-result functions', function (done) {
|
||||
const adder = new this.Callbackified(3)
|
||||
adder.asyncArithmetic(6, (err, sum, product) => {
|
||||
expect(err).not.to.exist
|
||||
expect(sum).to.equal(9)
|
||||
expect(product).to.equal(18)
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('callbackifies other functions normally', function (done) {
|
||||
const adder = new this.Callbackified(6)
|
||||
adder.asyncAdd(2, (err, sum) => {
|
||||
expect(err).not.to.exist
|
||||
expect(sum).to.equal(8)
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('expressify', function () {
|
||||
it('should propagate any rejection to the "next" callback', function (done) {
|
||||
const fn = () => Promise.reject(new Error('rejected'))
|
||||
|
||||
Reference in New Issue
Block a user