chai
Version:
BDD/TDD assertion library for node.js and the browser. Test framework agnostic.
74 lines (68 loc) • 2.53 kB
JavaScript
const fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length');
/*!
* Chai - addLengthGuard utility
* Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com>
* MIT Licensed
*/
/**
* ### .addLengthGuard(fn, assertionName, isChainable)
*
* Define `length` as a getter on the given uninvoked method assertion. The
* getter acts as a guard against chaining `length` directly off of an uninvoked
* method assertion, which is a problem because it references `function`'s
* built-in `length` property instead of Chai's `length` assertion. When the
* getter catches the user making this mistake, it throws an error with a
* helpful message.
*
* There are two ways in which this mistake can be made. The first way is by
* chaining the `length` assertion directly off of an uninvoked chainable
* method. In this case, Chai suggests that the user use `lengthOf` instead. The
* second way is by chaining the `length` assertion directly off of an uninvoked
* non-chainable method. Non-chainable methods must be invoked prior to
* chaining. In this case, Chai suggests that the user consult the docs for the
* given assertion.
*
* If the `length` property of functions is unconfigurable, then return `fn`
* without modification.
*
* Note that in ES6, the function's `length` property is configurable, so once
* support for legacy environments is dropped, Chai's `length` property can
* replace the built-in function's `length` property, and this length guard will
* no longer be necessary. In the mean time, maintaining consistency across all
* environments is the priority.
*
* @param {Function} fn
* @param {string} assertionName
* @param {boolean} isChainable
* @returns {unknown}
* @namespace Utils
* @name addLengthGuard
*/
export function addLengthGuard(fn, assertionName, isChainable) {
if (!fnLengthDesc.configurable) return fn;
Object.defineProperty(fn, 'length', {
get: function () {
if (isChainable) {
throw Error(
'Invalid Chai property: ' +
assertionName +
'.length. Due' +
' to a compatibility issue, "length" cannot directly follow "' +
assertionName +
'". Use "' +
assertionName +
'.lengthOf" instead.'
);
}
throw Error(
'Invalid Chai property: ' +
assertionName +
'.length. See' +
' docs for proper usage of "' +
assertionName +
'".'
);
}
});
return fn;
}