Skip to content

Commit 1cdcbca

Browse files
authored
feat: add deprecation warnings for legacy API in RuleTester (#16063)
* feat: add deprecation warnings for legacy API in `RuleTester` * fix: use unique deprecation code for rules * refactor: avoid using deprecation codes * refactor: use object-style syntax * refactor: use process.emitWarning() * test: add more cases * fix: improve check for missing schema * refactor: update fixtures * test: add test cases when schema is undefined or null * fix: lint
1 parent 0396775 commit 1cdcbca

13 files changed

+498
-214
lines changed

lib/rule-tester/rule-tester.js

+42
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,36 @@ function getCommentsDeprecation() {
305305
);
306306
}
307307

308+
/**
309+
* Emit a deprecation warning if function-style format is being used.
310+
* @param {string} ruleName Name of the rule.
311+
* @returns {void}
312+
*/
313+
function emitLegacyRuleAPIWarning(ruleName) {
314+
if (!emitLegacyRuleAPIWarning[`warned-${ruleName}`]) {
315+
emitLegacyRuleAPIWarning[`warned-${ruleName}`] = true;
316+
process.emitWarning(
317+
`"${ruleName}" rule is using the deprecated function-style format and will stop working in ESLint v9. Please use object-style format: https://eslint.org/docs/developer-guide/working-with-rules`,
318+
"DeprecationWarning"
319+
);
320+
}
321+
}
322+
323+
/**
324+
* Emit a deprecation warning if rule has options but is missing the "meta.schema" property
325+
* @param {string} ruleName Name of the rule.
326+
* @returns {void}
327+
*/
328+
function emitMissingSchemaWarning(ruleName) {
329+
if (!emitMissingSchemaWarning[`warned-${ruleName}`]) {
330+
emitMissingSchemaWarning[`warned-${ruleName}`] = true;
331+
process.emitWarning(
332+
`"${ruleName}" rule has options but is missing the "meta.schema" property and will stop working in ESLint v9. Please add a schema: https://eslint.org/docs/developer-guide/working-with-rules#options-schemas`,
333+
"DeprecationWarning"
334+
);
335+
}
336+
}
337+
308338
//------------------------------------------------------------------------------
309339
// Public Interface
310340
//------------------------------------------------------------------------------
@@ -521,6 +551,9 @@ class RuleTester {
521551
].concat(scenarioErrors).join("\n"));
522552
}
523553

554+
if (typeof rule === "function") {
555+
emitLegacyRuleAPIWarning(ruleName);
556+
}
524557

525558
linter.defineRule(ruleName, Object.assign({}, rule, {
526559

@@ -578,6 +611,15 @@ class RuleTester {
578611

579612
if (hasOwnProperty(item, "options")) {
580613
assert(Array.isArray(item.options), "options must be an array");
614+
if (
615+
item.options.length > 0 &&
616+
typeof rule === "object" &&
617+
(
618+
!rule.meta || (rule.meta && (typeof rule.meta.schema === "undefined" || rule.meta.schema === null))
619+
)
620+
) {
621+
emitMissingSchemaWarning(ruleName);
622+
}
581623
config.rules[ruleName] = [1].concat(item.options);
582624
} else {
583625
config.rules[ruleName] = 1;

tests/fixtures/testers/rule-tester/modify-ast-at-first.js

+29-23
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,36 @@
99
// Rule Definition
1010
//------------------------------------------------------------------------------
1111

12-
module.exports = function(context) {
13-
return {
14-
"Program": function(node) {
15-
node.body.push({
16-
"type": "Identifier",
17-
"name": "modified",
18-
"range": [0, 8],
19-
"loc": {
20-
"start": {
21-
"line": 1,
22-
"column": 0
23-
},
24-
"end": {
25-
"line": 1,
26-
"column": 8
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: []
16+
},
17+
create(context) {
18+
return {
19+
"Program": function(node) {
20+
node.body.push({
21+
"type": "Identifier",
22+
"name": "modified",
23+
"range": [0, 8],
24+
"loc": {
25+
"start": {
26+
"line": 1,
27+
"column": 0
28+
},
29+
"end": {
30+
"line": 1,
31+
"column": 8
32+
}
2733
}
28-
}
29-
});
30-
},
34+
});
35+
},
3136

32-
"Identifier": function(node) {
33-
if (node.name === "bar") {
34-
context.report({message: "error", node: node});
37+
"Identifier": function(node) {
38+
if (node.name === "bar") {
39+
context.report({message: "error", node: node});
40+
}
3541
}
36-
}
37-
};
42+
};
43+
},
3844
};

tests/fixtures/testers/rule-tester/modify-ast-at-last.js

+29-23
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,36 @@
99
// Rule Definition
1010
//------------------------------------------------------------------------------
1111

12-
module.exports = function(context) {
13-
return {
14-
"Program:exit": function(node) {
15-
node.body.push({
16-
"type": "Identifier",
17-
"name": "modified",
18-
"range": [0, 8],
19-
"loc": {
20-
"start": {
21-
"line": 1,
22-
"column": 0
23-
},
24-
"end": {
25-
"line": 1,
26-
"column": 8
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: []
16+
},
17+
create(context) {
18+
return {
19+
"Program:exit": function(node) {
20+
node.body.push({
21+
"type": "Identifier",
22+
"name": "modified",
23+
"range": [0, 8],
24+
"loc": {
25+
"start": {
26+
"line": 1,
27+
"column": 0
28+
},
29+
"end": {
30+
"line": 1,
31+
"column": 8
32+
}
2733
}
28-
}
29-
});
30-
},
34+
});
35+
},
3136

32-
"Identifier": function(node) {
33-
if (node.name === "bar") {
34-
context.report({message: "error", node: node});
37+
"Identifier": function(node) {
38+
if (node.name === "bar") {
39+
context.report({message: "error", node: node});
40+
}
3541
}
36-
}
37-
};
42+
};
43+
},
3844
};

tests/fixtures/testers/rule-tester/modify-ast.js

+14-8
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@
99
// Rule Definition
1010
//------------------------------------------------------------------------------
1111

12-
module.exports = function(context) {
13-
return {
14-
"Identifier": function(node) {
15-
node.name += "!";
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: []
16+
},
17+
create(context) {
18+
return {
19+
"Identifier": function(node) {
20+
node.name += "!";
1621

17-
if (node.name === "bar!") {
18-
context.report({message: "error", node: node});
22+
if (node.name === "bar!") {
23+
context.report({message: "error", node: node});
24+
}
1925
}
20-
}
21-
};
26+
};
27+
},
2228
};

tests/fixtures/testers/rule-tester/no-eval.js

+16-12
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,24 @@
33
* @author Nicholas C. Zakas
44
*/
55

6+
"use strict";
7+
68
//------------------------------------------------------------------------------
79
// Rule Definition
810
//------------------------------------------------------------------------------
911

10-
module.exports = function(context) {
11-
12-
"use strict";
13-
14-
return {
15-
"CallExpression": function(node) {
16-
if (node.callee.name === "eval") {
17-
context.report(node, "eval sucks.");
18-
}
19-
}
20-
};
21-
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: [],
16+
},
17+
create(context) {
18+
return {
19+
CallExpression: function (node) {
20+
if (node.callee.name === "eval") {
21+
context.report(node, "eval sucks.");
22+
}
23+
},
24+
};
25+
},
2226
};

tests/fixtures/testers/rule-tester/no-invalid-args.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,28 @@
33
* @author Mathias Schreck
44
*/
55

6+
"use strict";
7+
68
//------------------------------------------------------------------------------
79
// Rule Definition
810
//------------------------------------------------------------------------------
911

10-
module.exports = function(context) {
11-
"use strict";
12-
13-
var config = context.options[0];
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: [{
16+
type: "boolean"
17+
}]
18+
},
19+
create(context) {
20+
var config = context.options[0];
1421

15-
return {
16-
"Program": function(node) {
17-
if (config === true) {
18-
context.report(node, "Invalid args");
22+
return {
23+
"Program": function(node) {
24+
if (config === true) {
25+
context.report(node, "Invalid args");
26+
}
1927
}
20-
}
21-
};
28+
};
29+
}
2230
};

tests/fixtures/testers/rule-tester/no-invalid-schema.js

+17-17
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@
33
* @author Brandon Mills
44
*/
55

6+
"use strict";
7+
68
//------------------------------------------------------------------------------
79
// Rule Definition
810
//------------------------------------------------------------------------------
911

10-
module.exports = function(context) {
11-
"use strict";
12-
13-
var config = context.options[0];
14-
15-
return {
16-
"Program": function(node) {
17-
if (config) {
18-
context.report(node, "Expected nothing.");
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: [{
16+
"enum": []
17+
}]
18+
},
19+
create(context) {
20+
return {
21+
"Program": function(node) {
22+
if (config) {
23+
context.report(node, "Expected nothing.");
24+
}
1925
}
20-
}
21-
};
26+
};
27+
},
2228
};
23-
24-
module.exports.schema = [
25-
{
26-
"enum": []
27-
}
28-
];

tests/fixtures/testers/rule-tester/no-schema-violation.js

+18-17
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,27 @@
33
* @author Brandon Mills
44
*/
55

6+
"use strict";
7+
68
//------------------------------------------------------------------------------
79
// Rule Definition
810
//------------------------------------------------------------------------------
911

10-
module.exports = function(context) {
11-
"use strict";
12-
13-
var config = context.options[0];
14-
15-
return {
16-
"Program": function(node) {
17-
if (config && config !== "foo") {
18-
context.report(node, "Expected foo.");
12+
module.exports = {
13+
meta: {
14+
type: "problem",
15+
schema: [{
16+
"enum": ["foo"]
17+
}]
18+
},
19+
create(context) {
20+
const config = context.options[0];
21+
return {
22+
"Program": function(node) {
23+
if (config && config !== "foo") {
24+
context.report(node, "Expected foo.");
25+
}
1926
}
20-
}
21-
};
27+
};
28+
},
2229
};
23-
24-
module.exports.schema = [
25-
{
26-
"enum": ["foo"]
27-
}
28-
];

0 commit comments

Comments
 (0)