Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions lib/rules/no-assert-equal.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,41 @@ module.exports = {
});
}

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {boolean}
*/
function isModuleHookCallback(propertyNode) {
return (
propertyNode.parent &&
propertyNode.parent.type === "Property" &&
utils.isModuleHookPropertyKey(propertyNode.parent.key) &&
utils.isInModule(propertyNode.parent)
);
}

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {void}
*/
function pushModuleHookAssert(propertyNode) {
if (isModuleHookCallback(propertyNode)) {
testStack.push({
assertVar: utils.getAssertContextName(propertyNode),
});
}
}

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {void}
*/
function popModuleHookAssert(propertyNode) {
if (isModuleHookCallback(propertyNode)) {
testStack.pop();
}
}

return {
CallExpression: function (node) {
/* istanbul ignore else: correctly does nothing */
Expand Down Expand Up @@ -188,6 +223,15 @@ module.exports = {
testStack.pop();
}
},

FunctionDeclaration: pushModuleHookAssert,
FunctionExpression: pushModuleHookAssert,
ArrowFunctionExpression: pushModuleHookAssert,

"FunctionDeclaration:exit": popModuleHookAssert,
"FunctionExpression:exit": popModuleHookAssert,
"ArrowFunctionExpression:exit": popModuleHookAssert,

Program: function (node) {
// Gather all calls to global `equal()`.
/* istanbul ignore next: deprecated code paths only followed by old eslint versions */
Expand Down
18 changes: 2 additions & 16 deletions lib/rules/no-qunit-start-in-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,20 +51,6 @@ module.exports = {
);
}

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {boolean}
*/
function isInModule(propertyNode) {
return (
propertyNode &&
propertyNode.parent && // ObjectExpression
propertyNode.parent.parent && // CallExpression?
propertyNode.parent.parent.type === "CallExpression" &&
utils.isModule(propertyNode.parent.parent.callee)
);
}

//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
Expand Down Expand Up @@ -93,7 +79,7 @@ module.exports = {
Property: function (node) {
if (
utils.isModuleHookPropertyKey(node.key) &&
isInModule(node) &&
utils.isInModule(node) &&
node.key.type === "Identifier"
) {
contextStack.push(`${node.key.name} hook`);
Expand All @@ -109,7 +95,7 @@ module.exports = {
"Property:exit": function (node) {
if (
utils.isModuleHookPropertyKey(node.key) &&
isInModule(node)
utils.isInModule(node)
) {
contextStack.pop();
}
Expand Down
16 changes: 1 addition & 15 deletions lib/rules/no-setup-teardown.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,11 @@ module.exports = {
}
}

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {boolean}
*/
function isInModule(propertyNode) {
return (
propertyNode &&
propertyNode.parent && // ObjectExpression
propertyNode.parent.parent && // CallExpression?
propertyNode.parent.parent.type === "CallExpression" &&
utils.isModule(propertyNode.parent.parent.callee)
);
}

return {
Property: function (node) {
if (
utils.isModuleHookPropertyKey(node.key) &&
isInModule(node)
utils.isInModule(node)
) {
checkModuleHook(node);
}
Expand Down
18 changes: 2 additions & 16 deletions lib/rules/resolve-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,6 @@ module.exports = {
}
}

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {boolean}
*/
function isInModule(propertyNode) {
return (
propertyNode &&
propertyNode.parent && // ObjectExpression
propertyNode.parent.parent && // CallExpression?
propertyNode.parent.parent.type === "CallExpression" &&
utils.isModule(propertyNode.parent.parent.callee)
);
}

return {
CallExpression: function (node) {
const callbackVar = getAsyncCallbackVarOrNull(node.callee);
Expand Down Expand Up @@ -213,7 +199,7 @@ module.exports = {
Property: function (node) {
if (
utils.isModuleHookPropertyKey(node.key) &&
isInModule(node)
utils.isInModule(node)
) {
asyncStateStack.push({
stopSemaphoreCount: 0,
Expand All @@ -228,7 +214,7 @@ module.exports = {
"Property:exit": function (node) {
if (
utils.isModuleHookPropertyKey(node.key) &&
isInModule(node)
utils.isInModule(node)
) {
const asyncState = asyncStateStack.pop();
if (!asyncState) {
Expand Down
21 changes: 20 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ const assert = require("node:assert");
const SUPPORTED_TEST_IDENTIFIERS = new Set(["test", "asyncTest", "only"]);

const OLD_MODULE_HOOK_IDENTIFIERS = ["setup", "teardown"];
const NEW_MODULE_HOOK_IDENTIFIERS = ["beforeEach", "afterEach"];
const NEW_MODULE_HOOK_IDENTIFIERS = [
"before",
"beforeEach",
"afterEach",
"after",
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to split this change into a separate PR? It seems there's a bug fix to no-assert-equal as mentioned in the PR title, but then there's a separate change to the hooks used by separate rules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is somewhat related. Without that change, the fix in no-assert-equal would not apply to the before and after hooks.
However, I can split it up. I’ve created a separate PR (#610) specifically for the changes to the before and after hooks.

const ALL_MODULE_HOOK_IDENTIFIERS = new Set([
...OLD_MODULE_HOOK_IDENTIFIERS,
...NEW_MODULE_HOOK_IDENTIFIERS,
Expand Down Expand Up @@ -216,6 +221,20 @@ exports.isModule = function (calleeNode) {
return result;
};

/**
* @param {import('eslint').Rule.Node} propertyNode
* @returns {boolean}
*/
exports.isInModule = function (propertyNode) {
return (
propertyNode &&
propertyNode.parent && // ObjectExpression
propertyNode.parent.parent && // CallExpression?
propertyNode.parent.parent.type === "CallExpression" &&
exports.isModule(propertyNode.parent.parent.callee)
);
};

/**
* @param {import('estree').Node} identifierNode
* @returns {boolean}
Expand Down
20 changes: 20 additions & 0 deletions tests/lib/rules/no-arrow-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,26 @@ ruleTester.run("no-arrow-tests", rule, {
},
],
},
{
code: "QUnit.module('module', { before: () => {} });",
output: "QUnit.module('module', { before: function() {} });",
errors: [
{
messageId: "noArrowFunction",
type: "ArrowFunctionExpression",
},
],
},
{
code: "QUnit.module('module', { after: () => {} });",
output: "QUnit.module('module', { after: function() {} });",
errors: [
{
messageId: "noArrowFunction",
type: "ArrowFunctionExpression",
},
],
},
{
code: "module('module', { setup: () => {} });",
output: "module('module', { setup: function() {} });",
Expand Down
24 changes: 24 additions & 0 deletions tests/lib/rules/no-assert-equal.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,29 @@ ruleTester.run("no-assert-equal", rule, {
},
],
},
{
// assert.equal in module hooks
code: "QUnit.module('My module', { before: function (assert) { assert.equal(1, 1); } });",
errors: [
{
messageId: "unexpectedAssertEqual",
data: { assertVar: "assert" },
suggestions: [
{
messageId: "switchToDeepEqual",
output: "QUnit.module('My module', { before: function (assert) { assert.deepEqual(1, 1); } });",
},
{
messageId: "switchToPropEqual",
output: "QUnit.module('My module', { before: function (assert) { assert.propEqual(1, 1); } });",
},
{
messageId: "switchToStrictEqual",
output: "QUnit.module('My module', { before: function (assert) { assert.strictEqual(1, 1); } });",
},
],
},
],
},
],
});
8 changes: 8 additions & 0 deletions tests/lib/rules/no-qunit-start-in-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ ruleTester.run("no-qunit-start-in-tests", rule, {
code: 'QUnit.module("module", { afterEach: function() { QUnit.start(); } });',
errors: [createError("afterEach hook")],
},
{
code: 'QUnit.module("module", { before: function() { QUnit.start(); } });',
errors: [createError("before hook")],
},
{
code: 'QUnit.module("module", { after: function() { QUnit.start(); } });',
errors: [createError("after hook")],
},
{
code: 'QUnit.module("module", { setup: function() { QUnit.start(); } });',
errors: [createError("setup hook")],
Expand Down
10 changes: 8 additions & 2 deletions tests/lib/rules/no-setup-teardown.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ ruleTester.run("no-setup-teardown", rule, {
// afterEach
"QUnit.module('Module', { afterEach: function () {} });",

// both
"QUnit.module('Module', { beforeEach: function () {}, afterEach: function () {} });",
// before
"QUnit.module('Module', { before: function () {} });",

// after
"QUnit.module('Module', { after: function () {} });",

// all
"QUnit.module('Module', { before: function () {}, beforeEach: function () {}, afterEach: function () {}, after: function () {} });",

// other property names are not reported
"QUnit.module('Module', { foo: function () {} });",
Expand Down
8 changes: 8 additions & 0 deletions tests/lib/rules/resolve-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ ruleTester.run("resolve-async", rule, {
code: "QUnit.module('name', { teardown: function () { QUnit.stop(); } });",
errors: [createNeedStartCallsMessage("Property")],
},
{
code: "QUnit.module('name', { before: function () { QUnit.stop(); } });",
errors: [createNeedStartCallsMessage("Property")],
},
{
code: "QUnit.module('name', { beforeEach: function () { QUnit.stop(); } });",
errors: [createNeedStartCallsMessage("Property")],
Expand All @@ -203,6 +207,10 @@ ruleTester.run("resolve-async", rule, {
code: "QUnit.module('name', { afterEach: function () { QUnit.stop(); } });",
errors: [createNeedStartCallsMessage("Property")],
},
{
code: "QUnit.module('name', { after: function () { QUnit.stop(); } });",
errors: [createNeedStartCallsMessage("Property")],
},

// Multiple start() calls needed
{
Expand Down