Skip to content

Commit

Permalink
Fix: Allow for third parameter in no-hooks-from-ancestor-modules
Browse files Browse the repository at this point in the history
Fixes #230.
  • Loading branch information
Krinkle committed May 13, 2022
1 parent f3878c1 commit e29bf5a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
6 changes: 6 additions & 0 deletions docs/rules/no-hooks-from-ancestor-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ The following patterns are not warnings:
QUnit.module("example module", function(hooks) {
hooks.beforeEach(function() {});
});

QUnit.module("outer module", function() {
QUnit.module("inner module", function(hooks) {
hooks.beforeEach(function() {});
});
});
```

## When Not To Use It
Expand Down
16 changes: 14 additions & 2 deletions lib/rules/no-hooks-from-ancestor-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ module.exports = {
isInModuleCallbackBody(node);
}

function getCallbackArg(args) {
// Callback can be either args[1] or args[2]
// https://api.qunitjs.com/QUnit/module/
if (args[1] && args[1].type === "FunctionExpression") {
return args[1];
}
if (args[2] && args[2].type === "FunctionExpression") {
return args[2];
}
return null;
}

function getHooksIdentifierFromParams(params) {
// In TypeScript, `this` can be passed as the first function parameter to add a type to it,
// and we want to ignore that parameter since we're looking for the `hooks` variable.
Expand All @@ -78,8 +90,8 @@ module.exports = {
description: node.arguments[0].value
};

const callback = node.arguments[1];
const hooksParam = callback && callback.type === "FunctionExpression" ? getHooksIdentifierFromParams(callback.params) : null;
const callback = getCallbackArg(node.arguments);
const hooksParam = callback ? getHooksIdentifierFromParams(callback.params) : null;
moduleStackInfo.hookIdentifierName = hooksParam ? hooksParam.name : null;
moduleStack.push(moduleStackInfo);
} else if (isHookInvocation(node)) {
Expand Down
36 changes: 36 additions & 0 deletions tests/lib/rules/no-hooks-from-ancestor-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ ruleTester.run("no-hooks-from-ancestor-modules", rule, {
QUnit.module("module", function(hooks) { hooks.afterEach(function() {}); });
`,
`
QUnit.module("module", {}, function(hooks) { hooks.beforeEach(function() {}); });
`,
`
QUnit.module("module", makeOptions(), function(hooks) { hooks.beforeEach(function() {}); });
`,
`
QUnit.module("module-a", function() {
QUnit.module("module-b", function(hooks) {
hooks.beforeEach(function() {});
Expand Down Expand Up @@ -140,6 +146,36 @@ ruleTester.run("no-hooks-from-ancestor-modules", rule, {
})
]
},
{
code: `
QUnit.module("module-a", {}, function (hooks) {
QUnit.module("module-b", {}, function () {
hooks.beforeEach(function () {});
});
});
`,
errors: [
createError({
invokedMethodName: "beforeEach",
usedHooksIdentifierName: "hooks"
})
]
},
{
code: `
QUnit.module("module-a", makeOptions(), function (hooks) {
QUnit.module("module-b", makeOptions(), function () {
hooks.beforeEach(function () {});
});
});
`,
errors: [
createError({
invokedMethodName: "beforeEach",
usedHooksIdentifierName: "hooks"
})
]
},
{
code: `
QUnit.module("first", function (firstHooks) {
Expand Down

0 comments on commit e29bf5a

Please sign in to comment.