Skip to content

Commit 90e12b1

Browse files
committed
feat: add jsdoc typescript types
1 parent fda23d2 commit 90e12b1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1242
-107
lines changed

lib/rules/assert-args.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,14 @@ module.exports = {
3535
},
3636

3737
create: function (context) {
38+
/** @type {Array<{assertContextVar: string | null}>} */
3839
const testStack = [],
3940
sourceCode = context.getSourceCode();
4041

42+
/**
43+
* @param {import('estree').Node} argNode
44+
* @returns {import('estree').Node}
45+
*/
4146
function isPossibleMessage(argNode) {
4247
// For now, we will allow all nodes. Hoping to allow user-driven
4348
// configuration later.
@@ -48,24 +53,41 @@ module.exports = {
4853
return argNode;
4954
}
5055

56+
/**
57+
* @returns {string | null}
58+
*/
5159
function getAssertContext() {
5260
assert.ok(testStack.length);
5361

5462
return testStack[testStack.length - 1].assertContextVar;
5563
}
5664

65+
/**
66+
* @param {import('estree').Node} callExpressionNode
67+
*/
5768
function checkAssertArity(callExpressionNode) {
69+
if (callExpressionNode.type !== "CallExpression") {
70+
return;
71+
}
72+
73+
const assertContextVar = getAssertContext();
74+
if (!assertContextVar) {
75+
return;
76+
}
77+
5878
const allowedArities = utils.getAllowedArities(
5979
callExpressionNode.callee,
60-
getAssertContext(),
80+
assertContextVar,
6181
),
6282
assertArgs = callExpressionNode.arguments,
6383
lastArg = assertArgs[assertArgs.length - 1],
6484
mayHaveMessage = lastArg && isPossibleMessage(lastArg);
6585

66-
const definitelyTooFewArgs = allowedArities.every(function (arity) {
67-
return assertArgs.length < arity;
68-
});
86+
const definitelyTooFewArgs = allowedArities.every(
87+
function (/** @type {number} */ arity) {
88+
return assertArgs.length < arity;
89+
},
90+
);
6991

7092
if (
7193
mayHaveMessage &&
@@ -84,7 +106,7 @@ module.exports = {
84106
: "unexpectedArgCountNoMessage",
85107
data: {
86108
callee: sourceCode.getText(callExpressionNode.callee),
87-
argCount: assertArgs.length,
109+
argCount: assertArgs.length.toString(),
88110
},
89111
});
90112
}
@@ -99,7 +121,7 @@ module.exports = {
99121
});
100122
} else if (
101123
testStack.length > 0 &&
102-
utils.isAssertion(node.callee, getAssertContext())
124+
utils.isAssertion(node.callee, getAssertContext() ?? "")
103125
) {
104126
checkAssertArity(node);
105127
}

lib/rules/literal-compare-order.js

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ const assert = require("node:assert"),
1515
// Rule Definition
1616
//------------------------------------------------------------------------------
1717

18-
function swapFirstTwoNodesInList(sourceCode, fixer, list) {
19-
const node0Text = sourceCode.getText(list[0]);
20-
const node1Text = sourceCode.getText(list[1]);
21-
return [
22-
fixer.replaceText(list[0], node1Text),
23-
fixer.replaceText(list[1], node0Text),
24-
];
25-
}
26-
2718
/** @type {import('eslint').Rule.RuleModule} */
2819
module.exports = {
2920
meta: {
@@ -45,6 +36,7 @@ module.exports = {
4536
},
4637

4738
create: function (context) {
39+
/** @type {Array<{assertContextVar: string | null}>} */
4840
const testStack = [],
4941
sourceCode = context.getSourceCode();
5042

@@ -54,6 +46,24 @@ module.exports = {
5446
return testStack[testStack.length - 1].assertContextVar;
5547
}
5648

49+
/**
50+
* @param {any} fixer
51+
* @param {import('estree').Node[]} list
52+
* @returns {import('eslint').Rule.Fix[]}
53+
*/
54+
function swapFirstTwoNodesInList(fixer, list) {
55+
const node0Text = sourceCode.getText(list[0]);
56+
const node1Text = sourceCode.getText(list[1]);
57+
return [
58+
fixer.replaceText(list[0], node1Text),
59+
fixer.replaceText(list[1], node0Text),
60+
];
61+
}
62+
63+
/**
64+
* @param {import('estree').Node[]} args
65+
* @param {boolean} compareActualFirst
66+
*/
5767
function checkLiteralCompareOrder(args, compareActualFirst) {
5868
if (args.length < 2) {
5969
return;
@@ -73,7 +83,7 @@ module.exports = {
7383
actual: sourceCode.getText(args[1]),
7484
},
7585
fix(fixer) {
76-
return swapFirstTwoNodesInList(sourceCode, fixer, args);
86+
return swapFirstTwoNodesInList(fixer, args);
7787
},
7888
});
7989
} else if (
@@ -89,13 +99,21 @@ module.exports = {
8999
actual: sourceCode.getText(args[1]),
90100
},
91101
fix(fixer) {
92-
return swapFirstTwoNodesInList(sourceCode, fixer, args);
102+
return swapFirstTwoNodesInList(fixer, args);
93103
},
94104
});
95105
}
96106
}
97107

108+
/**
109+
* @param {import('eslint').Rule.Node} node
110+
* @param {string | null} assertVar
111+
*/
98112
function processAssertion(node, assertVar) {
113+
if (node.type !== "CallExpression" || !assertVar) {
114+
return;
115+
}
116+
99117
/* istanbul ignore else: correctly does nothing */
100118
if (utils.isComparativeAssertion(node.callee, assertVar)) {
101119
const compareActualFirst = utils.shouldCompareActualFirst(
@@ -109,6 +127,7 @@ module.exports = {
109127
return {
110128
CallExpression: function (node) {
111129
/* istanbul ignore else: correctly does nothing */
130+
const assertVar = getAssertContext();
112131
if (utils.isTest(node.callee)) {
113132
testStack.push({
114133
assertContextVar: utils.getAssertContextNameForTest(
@@ -117,9 +136,10 @@ module.exports = {
117136
});
118137
} else if (
119138
testStack.length > 0 &&
120-
utils.isAssertion(node.callee, getAssertContext())
139+
assertVar &&
140+
utils.isAssertion(node.callee, assertVar)
121141
) {
122-
processAssertion(node, getAssertContext());
142+
processAssertion(node, assertVar);
123143
}
124144
},
125145

lib/rules/no-arrow-tests.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,35 @@ module.exports = {
4242
// Fixer adapted from https://github.com/lo1tuma/eslint-plugin-mocha (MIT)
4343
const sourceCode = context.getSourceCode();
4444

45+
/**
46+
* @param {number} start
47+
* @param {number} end
48+
* @returns {string}
49+
*/
4550
function extractSourceTextByRange(start, end) {
4651
return sourceCode.text.slice(start, end).trim();
4752
}
4853

54+
/**
55+
* @param {import('eslint').Rule.Node} fn
56+
* @returns {string}
57+
*/
4958
function formatFunctionHead(fn) {
59+
if (fn.type !== "FunctionExpression") {
60+
return "";
61+
}
5062
const arrow = sourceCode.getTokenBefore(fn.body);
63+
if (!arrow) {
64+
return "";
65+
}
5166
const beforeArrowToken = sourceCode.getTokenBefore(arrow);
67+
if (!beforeArrowToken) {
68+
return "";
69+
}
5270
let firstToken = sourceCode.getFirstToken(fn);
71+
if (!firstToken) {
72+
return "";
73+
}
5374

5475
let functionKeyword = "function";
5576
let params = extractSourceTextByRange(
@@ -68,6 +89,14 @@ module.exports = {
6889
firstToken = sourceCode.getTokenAfter(firstToken);
6990
}
7091

92+
if (!firstToken) {
93+
return "";
94+
}
95+
96+
if (!fn.body.range) {
97+
return "";
98+
}
99+
71100
const beforeArrowComment = extractSourceTextByRange(
72101
beforeArrowToken.range[1],
73102
arrow.range[0],
@@ -84,7 +113,17 @@ module.exports = {
84113
return `${functionKeyword}${paramsFullText} `;
85114
}
86115

116+
/**
117+
* @param {any} fixer
118+
* @param {import('eslint').Rule.Node} fn
119+
*/
87120
function fixArrowFunction(fixer, fn) {
121+
if (fn.type !== "FunctionExpression") {
122+
return;
123+
}
124+
if (!fn.range || !fn.body.range) {
125+
return;
126+
}
88127
if (fn.body.type === "BlockStatement") {
89128
// When it((...) => { ... }),
90129
// simply replace '(...) => ' with 'function () '
@@ -104,6 +143,9 @@ module.exports = {
104143
);
105144
}
106145

146+
/**
147+
* @param {import('estree').Node} fn
148+
*/
107149
function checkCallback(fn) {
108150
if (fn && fn.type === "ArrowFunctionExpression") {
109151
context.report({
@@ -114,6 +156,10 @@ module.exports = {
114156
}
115157
}
116158

159+
/**
160+
* @param {import('eslint').Rule.Node} propertyNode
161+
* @returns {boolean}
162+
*/
117163
function isPropertyInModule(propertyNode) {
118164
return (
119165
propertyNode &&
@@ -125,8 +171,13 @@ module.exports = {
125171
);
126172
}
127173

174+
/**
175+
* @param {import('eslint').Rule.Node} propertyNode
176+
* @returns {boolean}
177+
*/
128178
function isModuleProperty(propertyNode) {
129179
return (
180+
propertyNode.type === "Property" &&
130181
isPropertyInModule(propertyNode) &&
131182
utils.isModuleHookPropertyKey(propertyNode.key)
132183
);

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

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module.exports = {
3232

3333
create: function (context) {
3434
// Declare a test stack in case of nested test cases (not currently supported by QUnit).
35+
/** @type {Array<{assertVar: string | null}>} */
3536
const testStack = [];
3637

3738
function getCurrentAssertContextVariable() {
@@ -40,7 +41,11 @@ module.exports = {
4041
return testStack[testStack.length - 1].assertVar;
4142
}
4243

43-
// Check for something like `equal(...)` without assert parameter.
44+
/**
45+
* Check for something like `equal(...)` without assert parameter.
46+
* @param {import('eslint').Rule.Node} calleeNode
47+
* @returns {boolean}
48+
*/
4449
function isGlobalEqualityAssertion(calleeNode) {
4550
return (
4651
calleeNode &&
@@ -49,7 +54,11 @@ module.exports = {
4954
);
5055
}
5156

52-
// Check for something like `assert.equal(...)`.
57+
/**
58+
* // Check for something like `assert.equal(...)`.
59+
* @param {import('eslint').Rule.Node} calleeNode
60+
* @returns {boolean}
61+
*/
5362
function isAssertEquality(calleeNode) {
5463
return (
5564
calleeNode &&
@@ -61,37 +70,57 @@ module.exports = {
6170
);
6271
}
6372

64-
// Check for something like `equal(...)` or `assert.equal(...)`.
73+
/**
74+
* Check for something like `equal(...)` or `assert.equal(...)`.
75+
* @param {import('eslint').Rule.Node} calleeNode
76+
* @returns {boolean}
77+
*/
6578
function isEqualityAssertion(calleeNode) {
79+
if (calleeNode.type !== "CallExpression") {
80+
return false;
81+
}
6682
return (
6783
isGlobalEqualityAssertion(calleeNode) ||
6884
isAssertEquality(calleeNode)
6985
);
7086
}
7187

72-
// Finds the first boolean argument of a CallExpression if one exists.
88+
/**
89+
* Finds the first boolean argument of a CallExpression if one exists.
90+
* @param {import('eslint').Rule.Node} node
91+
* @returns {import('eslint').Rule.Node | undefined}
92+
*/
7393
function getBooleanArgument(node) {
74-
return (
75-
node.arguments.length >= 2 &&
76-
[node.arguments[0], node.arguments[1]].find(
77-
(arg) =>
78-
arg.type === "Literal" &&
79-
(arg.value === true || arg.value === false),
80-
)
94+
if (node.type !== "CallExpression" || node.arguments.length < 2) {
95+
return;
96+
}
97+
return [node.arguments[0], node.arguments[1]].find(
98+
(arg) =>
99+
arg.type === "Literal" &&
100+
(arg.value === true || arg.value === false),
81101
);
82102
}
83103

104+
/**
105+
* @param {import('eslint').Rule.Node} node
106+
*/
84107
function reportError(node) {
85108
context.report({
86109
node: node,
87110
messageId: "useAssertTrueOrFalse",
88111
fix(fixer) {
89112
const booleanArgument = getBooleanArgument(node);
113+
if (!booleanArgument) {
114+
return;
115+
}
90116
const newAssertionFunctionName = booleanArgument.value
91117
? "true"
92118
: "false";
93119

94120
const sourceCode = context.getSourceCode();
121+
if (node.type !== "CallExpression") {
122+
return;
123+
}
95124
const newArgsTextArray = node.arguments
96125
.filter((arg) => arg !== booleanArgument)
97126
.map((arg) => sourceCode.getText(arg));

0 commit comments

Comments
 (0)