diff --git a/API.md b/API.md index 75af44bf..6ed392d5 100755 --- a/API.md +++ b/API.md @@ -393,3 +393,11 @@ await Hoek.wait(2000); // waits for 2 seconds #### block() A no-op Promise. Does nothing. + + +#### isPromise(promise) + +Determines if an item is a promise where: +- `promise` - the item being tested. + +Returns `true` is the item is a promise, otherwise `false`. diff --git a/lib/index.d.ts b/lib/index.d.ts index b2fa30d6..ae1106ed 100755 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -445,6 +445,16 @@ export function wait(timeout?: number): Promise; export function block(): Promise; +/** + * Determines if an object is a promise. + * + * @param promise - the object tested. + * + * @returns true if the object is a promise, otherwise false. + */ +export function isPromise(promise: any): boolean; + + export namespace ts { /** diff --git a/lib/index.js b/lib/index.js index 77fe3c1b..ea062698 100755 --- a/lib/index.js +++ b/lib/index.js @@ -19,6 +19,7 @@ module.exports = { flatten: require('./flatten'), ignore: require('./ignore'), intersect: require('./intersect'), + isPromise: require('./isPromise'), merge: require('./merge'), once: require('./once'), reach: require('./reach'), diff --git a/lib/isPromise.js b/lib/isPromise.js new file mode 100755 index 00000000..40298040 --- /dev/null +++ b/lib/isPromise.js @@ -0,0 +1,9 @@ +'use strict'; + +const internals = {}; + + +module.exports = function (promise) { + + return !!promise && typeof promise.then === 'function'; +}; diff --git a/test/index.js b/test/index.js index 516eb846..89d15ce1 100755 --- a/test/index.js +++ b/test/index.js @@ -2767,3 +2767,32 @@ describe('stringify()', () => { expect(Hoek.stringify(obj)).to.contain('Cannot display object'); }); }); + +describe('isPromise()', () => { + + it('determines if an object is a promise', async () => { + + expect(Hoek.isPromise({})).to.be.false(); + expect(Hoek.isPromise(null)).to.be.false(); + expect(Hoek.isPromise(false)).to.be.false(); + expect(Hoek.isPromise(0)).to.be.false(); + expect(Hoek.isPromise('')).to.be.false(); + expect(Hoek.isPromise({ then: 1 })).to.be.false(); + expect(Hoek.isPromise([])).to.be.false(); + + const items = [ + Promise.resolve(), + Promise.reject() + ]; + + expect(Hoek.isPromise(items[0])).to.be.true(); + expect(Hoek.isPromise(items[1])).to.be.true(); + expect(Hoek.isPromise(new Promise(Hoek.ignore))).to.be.true(); + expect(Hoek.isPromise({ then: Hoek.ignore })).to.be.true(); + + try { + await Promise.all(items); + } + catch (err) { } + }); +}); diff --git a/test/index.ts b/test/index.ts index 93af87bb..bdaf37e0 100755 --- a/test/index.ts +++ b/test/index.ts @@ -322,6 +322,18 @@ expect.error(Hoek.block(123)); // $lab:types:on$ +// isPromise() + +Hoek.isPromise(1); +Hoek.isPromise({}); +Hoek.isPromise(null); + +expect.type(Hoek.isPromise(1)); + +expect.error(Hoek.isPromise()); +expect.error(Hoek.isPromise(1, 2)); + + // ts interface X { a: number; };