Skip to content

Commit 1728b69

Browse files
author
arensman
committed
fix: Flag assert.equal in module hooks
Fixes #531
1 parent fda23d2 commit 1728b69

File tree

6 files changed

+78
-36
lines changed

6 files changed

+78
-36
lines changed

lib/rules/no-assert-equal.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,29 @@ module.exports = {
107107
});
108108
}
109109

110+
function isModuleHookCallback(node) {
111+
return (
112+
node.parent &&
113+
node.parent.type === "Property" &&
114+
utils.isModuleHookPropertyKey(node.parent.key) &&
115+
utils.isInModule(node.parent)
116+
);
117+
}
118+
119+
function pushModuleHookAssert(node) {
120+
if (isModuleHookCallback(node)) {
121+
testStack.push({
122+
assertVar: utils.getAssertContextName(node),
123+
});
124+
}
125+
}
126+
127+
function popModuleHookAssert(node) {
128+
if (isModuleHookCallback(node)) {
129+
testStack.pop();
130+
}
131+
}
132+
110133
return {
111134
CallExpression: function (node) {
112135
/* istanbul ignore else: correctly does nothing */
@@ -136,6 +159,15 @@ module.exports = {
136159
testStack.pop();
137160
}
138161
},
162+
163+
FunctionDeclaration: pushModuleHookAssert,
164+
FunctionExpression: pushModuleHookAssert,
165+
ArrowFunctionExpression: pushModuleHookAssert,
166+
167+
"FunctionDeclaration:exit": popModuleHookAssert,
168+
"FunctionExpression:exit": popModuleHookAssert,
169+
"ArrowFunctionExpression:exit": popModuleHookAssert,
170+
139171
Program: function (node) {
140172
// Gather all calls to global `equal()`.
141173
/* istanbul ignore next: deprecated code paths only followed by old eslint versions */

lib/rules/no-qunit-start-in-tests.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,6 @@ module.exports = {
4646
);
4747
}
4848

49-
function isInModule(propertyNode) {
50-
return (
51-
propertyNode &&
52-
propertyNode.parent && // ObjectExpression
53-
propertyNode.parent.parent && // CallExpression?
54-
propertyNode.parent.parent.type === "CallExpression" &&
55-
utils.isModule(propertyNode.parent.parent.callee)
56-
);
57-
}
58-
5949
//----------------------------------------------------------------------
6050
// Public
6151
//----------------------------------------------------------------------
@@ -84,7 +74,7 @@ module.exports = {
8474
Property: function (node) {
8575
if (
8676
utils.isModuleHookPropertyKey(node.key) &&
87-
isInModule(node)
77+
utils.isInModule(node)
8878
) {
8979
contextStack.push(`${node.key.name} hook`);
9080
}
@@ -99,7 +89,7 @@ module.exports = {
9989
"Property:exit": function (node) {
10090
if (
10191
utils.isModuleHookPropertyKey(node.key) &&
102-
isInModule(node)
92+
utils.isInModule(node)
10393
) {
10494
contextStack.pop();
10595
}

lib/rules/no-setup-teardown.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,11 @@ module.exports = {
5353
}
5454
}
5555

56-
function isInModule(propertyNode) {
57-
return (
58-
propertyNode &&
59-
propertyNode.parent && // ObjectExpression
60-
propertyNode.parent.parent && // CallExpression?
61-
propertyNode.parent.parent.type === "CallExpression" &&
62-
utils.isModule(propertyNode.parent.parent.callee)
63-
);
64-
}
65-
6656
return {
6757
Property: function (node) {
6858
if (
6959
utils.isModuleHookPropertyKey(node.key) &&
70-
isInModule(node)
60+
utils.isInModule(node)
7161
) {
7262
checkModuleHook(node);
7363
}

lib/rules/resolve-async.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,6 @@ module.exports = {
123123
}
124124
}
125125

126-
function isInModule(propertyNode) {
127-
return (
128-
propertyNode &&
129-
propertyNode.parent && // ObjectExpression
130-
propertyNode.parent.parent && // CallExpression?
131-
propertyNode.parent.parent.type === "CallExpression" &&
132-
utils.isModule(propertyNode.parent.parent.callee)
133-
);
134-
}
135-
136126
return {
137127
CallExpression: function (node) {
138128
const callbackVar = getAsyncCallbackVarOrNull(node.callee);
@@ -170,7 +160,7 @@ module.exports = {
170160
Property: function (node) {
171161
if (
172162
utils.isModuleHookPropertyKey(node.key) &&
173-
isInModule(node)
163+
utils.isInModule(node)
174164
) {
175165
const assertContextVar = utils.getAssertContextName(
176166
node.value,
@@ -186,7 +176,7 @@ module.exports = {
186176
"Property:exit": function (node) {
187177
if (
188178
utils.isModuleHookPropertyKey(node.key) &&
189-
isInModule(node)
179+
utils.isInModule(node)
190180
) {
191181
const asyncState = asyncStateStack.pop();
192182
verifyAsyncState(asyncState, node);

lib/utils.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ const assert = require("node:assert");
99
const SUPPORTED_TEST_IDENTIFIERS = new Set(["test", "asyncTest", "only"]);
1010

1111
const OLD_MODULE_HOOK_IDENTIFIERS = ["setup", "teardown"];
12-
const NEW_MODULE_HOOK_IDENTIFIERS = ["beforeEach", "afterEach"];
12+
const NEW_MODULE_HOOK_IDENTIFIERS = [
13+
"before",
14+
"beforeEach",
15+
"afterEach",
16+
"after",
17+
];
1318
const ALL_MODULE_HOOK_IDENTIFIERS = new Set([
1419
...OLD_MODULE_HOOK_IDENTIFIERS,
1520
...NEW_MODULE_HOOK_IDENTIFIERS,
@@ -181,6 +186,16 @@ exports.isModule = function (calleeNode) {
181186
return result;
182187
};
183188

189+
exports.isInModule = function (propertyNode) {
190+
return (
191+
propertyNode &&
192+
propertyNode.parent && // ObjectExpression
193+
propertyNode.parent.parent && // CallExpression?
194+
propertyNode.parent.parent.type === "CallExpression" &&
195+
this.isModule(propertyNode.parent.parent.callee)
196+
);
197+
};
198+
184199
exports.isModuleHookPropertyKey = function (identifierNode) {
185200
return (
186201
identifierNode &&

tests/lib/rules/no-assert-equal.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,30 @@ ruleTester.run("no-assert-equal", rule, {
185185
},
186186
],
187187
},
188+
{
189+
// assert.equal in module hooks
190+
code: "QUnit.module('My module', { before: function (assert) { assert.equal(1, 1); } });",
191+
parser: require.resolve("@typescript-eslint/parser"),
192+
errors: [
193+
{
194+
messageId: "unexpectedAssertEqual",
195+
data: { assertVar: "assert" },
196+
suggestions: [
197+
{
198+
messageId: "switchToDeepEqual",
199+
output: "QUnit.module('My module', { before: function (assert) { assert.deepEqual(1, 1); } });",
200+
},
201+
{
202+
messageId: "switchToPropEqual",
203+
output: "QUnit.module('My module', { before: function (assert) { assert.propEqual(1, 1); } });",
204+
},
205+
{
206+
messageId: "switchToStrictEqual",
207+
output: "QUnit.module('My module', { before: function (assert) { assert.strictEqual(1, 1); } });",
208+
},
209+
],
210+
},
211+
],
212+
},
188213
],
189214
});

0 commit comments

Comments
 (0)