diff --git a/lib/chai/assertion.js b/lib/chai/assertion.js index eb53fc6b..33458940 100644 --- a/lib/chai/assertion.js +++ b/lib/chai/assertion.js @@ -5,15 +5,12 @@ * MIT Licensed */ -import {config} from './config.js'; -import {AssertionError} from 'assertion-error'; -import * as util from './utils/index.js'; +import { config } from "./config.js"; +import { AssertionError } from "assertion-error"; +import * as util from "./utils/index.js"; /** - * Assertion Constructor - * * Creates object for chaining. - * * `Assertion` objects contain metadata in the form of flags. Three flags can * be assigned during instantiation by passing arguments to this constructor: * @@ -42,139 +39,161 @@ import * as util from './utils/index.js'; * * - `eql`: This flag contains the deepEqual function to be used by the assertion. * - * @param {unknown} obj target of the assertion - * @param {string} msg (optional) custom error message - * @param {Function} ssfi (optional) starting point for removing stack frames - * @param {boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @param {unknown} ?obj target of the assertion + * @param {string} ?msg (optional) custom error message + * @param {Function} ?ssfi (optional) starting point for removing stack frames + * @param {boolean} ?lockSsfi (optional) whether or not the ssfi flag is locked * @returns {unknown} - * @private */ -export function Assertion(obj, msg, ssfi, lockSsfi) { - util.flag(this, 'ssfi', ssfi || Assertion); - util.flag(this, 'lockSsfi', lockSsfi); - util.flag(this, 'object', obj); - util.flag(this, 'message', msg); - util.flag(this, 'eql', config.deepEqual || util.eql); - - return util.proxify(this); -} +export class Assertion { + constructor(obj, msg, ssfi, lockSsfi) { + util.flag(this, "ssfi", ssfi || Assertion); + util.flag(this, "lockSsfi", lockSsfi); + util.flag(this, "object", obj); + util.flag(this, "message", msg); + util.flag(this, "eql", config.deepEqual || util.eql); + + return util.proxify(this); + } -Object.defineProperty(Assertion, 'includeStack', { - get: function () { + /** @returns {boolean} */ + static get includeStack() { console.warn( - 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.' + "Assertion.includeStack is deprecated, use chai.config.includeStack instead.", ); return config.includeStack; - }, - set: function (value) { + } + + /** @param {boolean} value */ + static set includeStack(value) { console.warn( - 'Assertion.includeStack is deprecated, use chai.config.includeStack instead.' + "Assertion.includeStack is deprecated, use chai.config.includeStack instead.", ); config.includeStack = value; } -}); -Object.defineProperty(Assertion, 'showDiff', { - get: function () { + /** @returns {boolean} */ + static get showDiff() { console.warn( - 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.' + "Assertion.showDiff is deprecated, use chai.config.showDiff instead.", ); return config.showDiff; - }, - set: function (value) { + } + + /** @param {boolean} value */ + static set showDiff(value) { console.warn( - 'Assertion.showDiff is deprecated, use chai.config.showDiff instead.' + "Assertion.showDiff is deprecated, use chai.config.showDiff instead.", ); config.showDiff = value; } -}); - -Assertion.addProperty = function (name, fn) { - util.addProperty(this.prototype, name, fn); -}; -Assertion.addMethod = function (name, fn) { - util.addMethod(this.prototype, name, fn); -}; + /** + * @param {string} name + * @param {Function} fn + */ + static addProperty(name, fn) { + util.addProperty(this.prototype, name, fn); + } -Assertion.addChainableMethod = function (name, fn, chainingBehavior) { - util.addChainableMethod(this.prototype, name, fn, chainingBehavior); -}; + /** + * @param {string} name + * @param {Function} fn + */ + static addMethod(name, fn) { + util.addMethod(this.prototype, name, fn); + } -Assertion.overwriteProperty = function (name, fn) { - util.overwriteProperty(this.prototype, name, fn); -}; + /** + * @param {string} name + * @param {Function} fn + * @param {Function} chainingBehavior + */ + static addChainableMethod(name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + } -Assertion.overwriteMethod = function (name, fn) { - util.overwriteMethod(this.prototype, name, fn); -}; + /** + * @param {string} name + * @param {Function} fn + */ + static overwriteProperty(name, fn) { + util.overwriteProperty(this.prototype, name, fn); + } -Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { - util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); -}; + /** + * @param {string} name + * @param {Function} fn + */ + static overwriteMethod(name, fn) { + util.overwriteMethod(this.prototype, name, fn); + } -/** - * ### .assert(expression, message, negateMessage, expected, actual, showDiff) - * - * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. - * - * @name assert - * @param {unknown} expression to be tested - * @param {string | Function} message or function that returns message to display if expression fails - * @param {string | Function} negatedMessage or function that returns negatedMessage to display if negated expression fails - * @param {unknown} expected value (remember to check for negation) - * @param {unknown} actual (optional) will default to `this.obj` - * @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails - * @private - */ + /** + * @param {string} name + * @param {Function} fn + * @param {Function} chainingBehavior + */ + static overwriteChainableMethod(name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + } -Assertion.prototype.assert = function ( - expr, - msg, - negateMsg, - expected, - _actual, - showDiff -) { - let ok = util.test(this, arguments); - if (false !== showDiff) showDiff = true; - if (undefined === expected && undefined === _actual) showDiff = false; - if (true !== config.showDiff) showDiff = false; - - if (!ok) { - msg = util.getMessage(this, arguments); - let actual = util.getActual(this, arguments); - let assertionErrorObjectProperties = { - actual: actual, - expected: expected, - showDiff: showDiff - }; - - let operator = util.getOperator(this, arguments); - if (operator) { - assertionErrorObjectProperties.operator = operator; + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {unknown} _expr to be tested + * @param {string | Function} msg or function that returns message to display if expression fails + * @param {string | Function} _negateMsg or function that returns negatedMessage to display if negated expression fails + * @param {unknown} expected value (remember to check for negation) + * @param {unknown} _actual (optional) will default to `this.obj` + * @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + */ + assert(_expr, msg, _negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + var actual = util.getActual(this, arguments); + var assertionErrorObjectProperties = { + actual: actual, + expected: expected, + showDiff: showDiff, + }; + + var operator = util.getOperator(this, arguments); + if (operator) { + assertionErrorObjectProperties.operator = operator; + } + + throw new AssertionError( + msg, + assertionErrorObjectProperties, + config.includeStack ? this.assert : util.flag(this, "ssfi"), + ); } + } - throw new AssertionError( - msg, - assertionErrorObjectProperties, - config.includeStack ? this.assert : util.flag(this, 'ssfi') - ); + /** + * Quick reference to stored `actual` value for plugin developers. + * + * @returns {unknown} + */ + get _obj() { + return util.flag(this, "object"); } -}; -/** - * ### ._obj - * - * Quick reference to stored `actual` value for plugin developers. - * - * @private - */ -Object.defineProperty(Assertion.prototype, '_obj', { - get: function () { - return util.flag(this, 'object'); - }, - set: function (val) { - util.flag(this, 'object', val); + /** + * Quick reference to stored `actual` value for plugin developers. + * + * @param {unknown} val + */ + set _obj(val) { + util.flag(this, "object", val); } -}); +} diff --git a/package-lock.json b/package-lock.json index a3b43131..a6319ebf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,8 @@ "eslint": "^8.56.0", "eslint-plugin-jsdoc": "^48.0.4", "mocha": "^10.2.0", - "prettier": "^3.4.2" + "prettier": "^3.4.2", + "typescript": "~5.7.3" }, "engines": { "node": ">=12" @@ -6700,6 +6701,20 @@ "node": ">= 0.6" } }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/typical": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", diff --git a/package.json b/package.json index 79792a3d..cbf9ef25 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "lint": "npm run lint:js && npm run lint:format", "lint:js": "eslint lib/", "lint:format": "prettier --check lib", + "lint:types": "tsc", "clean": "rm -rf chai.js coverage/" }, "engines": { @@ -62,6 +63,7 @@ "eslint": "^8.56.0", "eslint-plugin-jsdoc": "^48.0.4", "mocha": "^10.2.0", - "prettier": "^3.4.2" + "prettier": "^3.4.2", + "typescript": "~5.7.3" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..3d9ba0e4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "nodenext", + "moduleResolution": "nodenext", + "types": [], + "checkJs": true, + "noEmit": true, + "isolatedModules": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true + }, + "include": [ + "lib/**/*.js" + ] +}