Skip to content

Commit 97b218e

Browse files
authored
convert Assertion function to a class (#1677)
1 parent 9d22af3 commit 97b218e

File tree

4 files changed

+168
-114
lines changed

4 files changed

+168
-114
lines changed

lib/chai/assertion.js

Lines changed: 131 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
* MIT Licensed
66
*/
77

8-
import {config} from './config.js';
9-
import {AssertionError} from 'assertion-error';
10-
import * as util from './utils/index.js';
8+
import { config } from "./config.js";
9+
import { AssertionError } from "assertion-error";
10+
import * as util from "./utils/index.js";
1111

1212
/**
13-
* Assertion Constructor
14-
*
1513
* Creates object for chaining.
16-
*
1714
* `Assertion` objects contain metadata in the form of flags. Three flags can
1815
* be assigned during instantiation by passing arguments to this constructor:
1916
*
@@ -42,139 +39,161 @@ import * as util from './utils/index.js';
4239
*
4340
* - `eql`: This flag contains the deepEqual function to be used by the assertion.
4441
*
45-
* @param {unknown} obj target of the assertion
46-
* @param {string} msg (optional) custom error message
47-
* @param {Function} ssfi (optional) starting point for removing stack frames
48-
* @param {boolean} lockSsfi (optional) whether or not the ssfi flag is locked
42+
* @param {unknown} ?obj target of the assertion
43+
* @param {string} ?msg (optional) custom error message
44+
* @param {Function} ?ssfi (optional) starting point for removing stack frames
45+
* @param {boolean} ?lockSsfi (optional) whether or not the ssfi flag is locked
4946
* @returns {unknown}
50-
* @private
5147
*/
52-
export function Assertion(obj, msg, ssfi, lockSsfi) {
53-
util.flag(this, 'ssfi', ssfi || Assertion);
54-
util.flag(this, 'lockSsfi', lockSsfi);
55-
util.flag(this, 'object', obj);
56-
util.flag(this, 'message', msg);
57-
util.flag(this, 'eql', config.deepEqual || util.eql);
58-
59-
return util.proxify(this);
60-
}
48+
export class Assertion {
49+
constructor(obj, msg, ssfi, lockSsfi) {
50+
util.flag(this, "ssfi", ssfi || Assertion);
51+
util.flag(this, "lockSsfi", lockSsfi);
52+
util.flag(this, "object", obj);
53+
util.flag(this, "message", msg);
54+
util.flag(this, "eql", config.deepEqual || util.eql);
55+
56+
return util.proxify(this);
57+
}
6158

62-
Object.defineProperty(Assertion, 'includeStack', {
63-
get: function () {
59+
/** @returns {boolean} */
60+
static get includeStack() {
6461
console.warn(
65-
'Assertion.includeStack is deprecated, use chai.config.includeStack instead.'
62+
"Assertion.includeStack is deprecated, use chai.config.includeStack instead.",
6663
);
6764
return config.includeStack;
68-
},
69-
set: function (value) {
65+
}
66+
67+
/** @param {boolean} value */
68+
static set includeStack(value) {
7069
console.warn(
71-
'Assertion.includeStack is deprecated, use chai.config.includeStack instead.'
70+
"Assertion.includeStack is deprecated, use chai.config.includeStack instead.",
7271
);
7372
config.includeStack = value;
7473
}
75-
});
7674

77-
Object.defineProperty(Assertion, 'showDiff', {
78-
get: function () {
75+
/** @returns {boolean} */
76+
static get showDiff() {
7977
console.warn(
80-
'Assertion.showDiff is deprecated, use chai.config.showDiff instead.'
78+
"Assertion.showDiff is deprecated, use chai.config.showDiff instead.",
8179
);
8280
return config.showDiff;
83-
},
84-
set: function (value) {
81+
}
82+
83+
/** @param {boolean} value */
84+
static set showDiff(value) {
8585
console.warn(
86-
'Assertion.showDiff is deprecated, use chai.config.showDiff instead.'
86+
"Assertion.showDiff is deprecated, use chai.config.showDiff instead.",
8787
);
8888
config.showDiff = value;
8989
}
90-
});
91-
92-
Assertion.addProperty = function (name, fn) {
93-
util.addProperty(this.prototype, name, fn);
94-
};
9590

96-
Assertion.addMethod = function (name, fn) {
97-
util.addMethod(this.prototype, name, fn);
98-
};
91+
/**
92+
* @param {string} name
93+
* @param {Function} fn
94+
*/
95+
static addProperty(name, fn) {
96+
util.addProperty(this.prototype, name, fn);
97+
}
9998

100-
Assertion.addChainableMethod = function (name, fn, chainingBehavior) {
101-
util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
102-
};
99+
/**
100+
* @param {string} name
101+
* @param {Function} fn
102+
*/
103+
static addMethod(name, fn) {
104+
util.addMethod(this.prototype, name, fn);
105+
}
103106

104-
Assertion.overwriteProperty = function (name, fn) {
105-
util.overwriteProperty(this.prototype, name, fn);
106-
};
107+
/**
108+
* @param {string} name
109+
* @param {Function} fn
110+
* @param {Function} chainingBehavior
111+
*/
112+
static addChainableMethod(name, fn, chainingBehavior) {
113+
util.addChainableMethod(this.prototype, name, fn, chainingBehavior);
114+
}
107115

108-
Assertion.overwriteMethod = function (name, fn) {
109-
util.overwriteMethod(this.prototype, name, fn);
110-
};
116+
/**
117+
* @param {string} name
118+
* @param {Function} fn
119+
*/
120+
static overwriteProperty(name, fn) {
121+
util.overwriteProperty(this.prototype, name, fn);
122+
}
111123

112-
Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) {
113-
util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
114-
};
124+
/**
125+
* @param {string} name
126+
* @param {Function} fn
127+
*/
128+
static overwriteMethod(name, fn) {
129+
util.overwriteMethod(this.prototype, name, fn);
130+
}
115131

116-
/**
117-
* ### .assert(expression, message, negateMessage, expected, actual, showDiff)
118-
*
119-
* Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
120-
*
121-
* @name assert
122-
* @param {unknown} expression to be tested
123-
* @param {string | Function} message or function that returns message to display if expression fails
124-
* @param {string | Function} negatedMessage or function that returns negatedMessage to display if negated expression fails
125-
* @param {unknown} expected value (remember to check for negation)
126-
* @param {unknown} actual (optional) will default to `this.obj`
127-
* @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails
128-
* @private
129-
*/
132+
/**
133+
* @param {string} name
134+
* @param {Function} fn
135+
* @param {Function} chainingBehavior
136+
*/
137+
static overwriteChainableMethod(name, fn, chainingBehavior) {
138+
util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior);
139+
}
130140

131-
Assertion.prototype.assert = function (
132-
expr,
133-
msg,
134-
negateMsg,
135-
expected,
136-
_actual,
137-
showDiff
138-
) {
139-
let ok = util.test(this, arguments);
140-
if (false !== showDiff) showDiff = true;
141-
if (undefined === expected && undefined === _actual) showDiff = false;
142-
if (true !== config.showDiff) showDiff = false;
143-
144-
if (!ok) {
145-
msg = util.getMessage(this, arguments);
146-
let actual = util.getActual(this, arguments);
147-
let assertionErrorObjectProperties = {
148-
actual: actual,
149-
expected: expected,
150-
showDiff: showDiff
151-
};
152-
153-
let operator = util.getOperator(this, arguments);
154-
if (operator) {
155-
assertionErrorObjectProperties.operator = operator;
141+
/**
142+
* ### .assert(expression, message, negateMessage, expected, actual, showDiff)
143+
*
144+
* Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass.
145+
*
146+
* @name assert
147+
* @param {unknown} _expr to be tested
148+
* @param {string | Function} msg or function that returns message to display if expression fails
149+
* @param {string | Function} _negateMsg or function that returns negatedMessage to display if negated expression fails
150+
* @param {unknown} expected value (remember to check for negation)
151+
* @param {unknown} _actual (optional) will default to `this.obj`
152+
* @param {boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails
153+
*/
154+
assert(_expr, msg, _negateMsg, expected, _actual, showDiff) {
155+
var ok = util.test(this, arguments);
156+
if (false !== showDiff) showDiff = true;
157+
if (undefined === expected && undefined === _actual) showDiff = false;
158+
if (true !== config.showDiff) showDiff = false;
159+
160+
if (!ok) {
161+
msg = util.getMessage(this, arguments);
162+
var actual = util.getActual(this, arguments);
163+
var assertionErrorObjectProperties = {
164+
actual: actual,
165+
expected: expected,
166+
showDiff: showDiff,
167+
};
168+
169+
var operator = util.getOperator(this, arguments);
170+
if (operator) {
171+
assertionErrorObjectProperties.operator = operator;
172+
}
173+
174+
throw new AssertionError(
175+
msg,
176+
assertionErrorObjectProperties,
177+
config.includeStack ? this.assert : util.flag(this, "ssfi"),
178+
);
156179
}
180+
}
157181

158-
throw new AssertionError(
159-
msg,
160-
assertionErrorObjectProperties,
161-
config.includeStack ? this.assert : util.flag(this, 'ssfi')
162-
);
182+
/**
183+
* Quick reference to stored `actual` value for plugin developers.
184+
*
185+
* @returns {unknown}
186+
*/
187+
get _obj() {
188+
return util.flag(this, "object");
163189
}
164-
};
165190

166-
/**
167-
* ### ._obj
168-
*
169-
* Quick reference to stored `actual` value for plugin developers.
170-
*
171-
* @private
172-
*/
173-
Object.defineProperty(Assertion.prototype, '_obj', {
174-
get: function () {
175-
return util.flag(this, 'object');
176-
},
177-
set: function (val) {
178-
util.flag(this, 'object', val);
191+
/**
192+
* Quick reference to stored `actual` value for plugin developers.
193+
*
194+
* @param {unknown} val
195+
*/
196+
set _obj(val) {
197+
util.flag(this, "object", val);
179198
}
180-
});
199+
}

package-lock.json

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"lint": "npm run lint:js && npm run lint:format",
4040
"lint:js": "eslint lib/",
4141
"lint:format": "prettier --check lib",
42+
"lint:types": "tsc",
4243
"clean": "rm -rf chai.js coverage/"
4344
},
4445
"engines": {
@@ -62,6 +63,7 @@
6263
"eslint": "^8.56.0",
6364
"eslint-plugin-jsdoc": "^48.0.4",
6465
"mocha": "^10.2.0",
65-
"prettier": "^3.4.2"
66+
"prettier": "^3.4.2",
67+
"typescript": "~5.7.3"
6668
}
6769
}

tsconfig.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"target": "esnext",
4+
"module": "nodenext",
5+
"moduleResolution": "nodenext",
6+
"types": [],
7+
"checkJs": true,
8+
"noEmit": true,
9+
"isolatedModules": true,
10+
"forceConsistentCasingInFileNames": true,
11+
"strict": true,
12+
"noUnusedLocals": true,
13+
"noUnusedParameters": true
14+
},
15+
"include": [
16+
"lib/**/*.js"
17+
]
18+
}

0 commit comments

Comments
 (0)