Skip to content

Commit

Permalink
feat: add deprecation warnings for legacy API in RuleTester (#16063)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
snitin315 committed Jul 28, 2022
1 parent 0396775 commit 1cdcbca
Show file tree
Hide file tree
Showing 13 changed files with 498 additions and 214 deletions.
42 changes: 42 additions & 0 deletions lib/rule-tester/rule-tester.js
Expand Up @@ -305,6 +305,36 @@ function getCommentsDeprecation() {
);
}

/**
* Emit a deprecation warning if function-style format is being used.
* @param {string} ruleName Name of the rule.
* @returns {void}
*/
function emitLegacyRuleAPIWarning(ruleName) {
if (!emitLegacyRuleAPIWarning[`warned-${ruleName}`]) {
emitLegacyRuleAPIWarning[`warned-${ruleName}`] = true;
process.emitWarning(
`"${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`,
"DeprecationWarning"
);
}
}

/**
* Emit a deprecation warning if rule has options but is missing the "meta.schema" property
* @param {string} ruleName Name of the rule.
* @returns {void}
*/
function emitMissingSchemaWarning(ruleName) {
if (!emitMissingSchemaWarning[`warned-${ruleName}`]) {
emitMissingSchemaWarning[`warned-${ruleName}`] = true;
process.emitWarning(
`"${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`,
"DeprecationWarning"
);
}
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -521,6 +551,9 @@ class RuleTester {
].concat(scenarioErrors).join("\n"));
}

if (typeof rule === "function") {
emitLegacyRuleAPIWarning(ruleName);
}

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

Expand Down Expand Up @@ -578,6 +611,15 @@ class RuleTester {

if (hasOwnProperty(item, "options")) {
assert(Array.isArray(item.options), "options must be an array");
if (
item.options.length > 0 &&
typeof rule === "object" &&
(
!rule.meta || (rule.meta && (typeof rule.meta.schema === "undefined" || rule.meta.schema === null))
)
) {
emitMissingSchemaWarning(ruleName);
}
config.rules[ruleName] = [1].concat(item.options);
} else {
config.rules[ruleName] = 1;
Expand Down
52 changes: 29 additions & 23 deletions tests/fixtures/testers/rule-tester/modify-ast-at-first.js
Expand Up @@ -9,30 +9,36 @@
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {
return {
"Program": function(node) {
node.body.push({
"type": "Identifier",
"name": "modified",
"range": [0, 8],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
module.exports = {
meta: {
type: "problem",
schema: []
},
create(context) {
return {
"Program": function(node) {
node.body.push({
"type": "Identifier",
"name": "modified",
"range": [0, 8],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
}
}
}
});
},
});
},

"Identifier": function(node) {
if (node.name === "bar") {
context.report({message: "error", node: node});
"Identifier": function(node) {
if (node.name === "bar") {
context.report({message: "error", node: node});
}
}
}
};
};
},
};
52 changes: 29 additions & 23 deletions tests/fixtures/testers/rule-tester/modify-ast-at-last.js
Expand Up @@ -9,30 +9,36 @@
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {
return {
"Program:exit": function(node) {
node.body.push({
"type": "Identifier",
"name": "modified",
"range": [0, 8],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
module.exports = {
meta: {
type: "problem",
schema: []
},
create(context) {
return {
"Program:exit": function(node) {
node.body.push({
"type": "Identifier",
"name": "modified",
"range": [0, 8],
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
}
}
}
});
},
});
},

"Identifier": function(node) {
if (node.name === "bar") {
context.report({message: "error", node: node});
"Identifier": function(node) {
if (node.name === "bar") {
context.report({message: "error", node: node});
}
}
}
};
};
},
};
22 changes: 14 additions & 8 deletions tests/fixtures/testers/rule-tester/modify-ast.js
Expand Up @@ -9,14 +9,20 @@
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {
return {
"Identifier": function(node) {
node.name += "!";
module.exports = {
meta: {
type: "problem",
schema: []
},
create(context) {
return {
"Identifier": function(node) {
node.name += "!";

if (node.name === "bar!") {
context.report({message: "error", node: node});
if (node.name === "bar!") {
context.report({message: "error", node: node});
}
}
}
};
};
},
};
28 changes: 16 additions & 12 deletions tests/fixtures/testers/rule-tester/no-eval.js
Expand Up @@ -3,20 +3,24 @@
* @author Nicholas C. Zakas
*/

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {

"use strict";

return {
"CallExpression": function(node) {
if (node.callee.name === "eval") {
context.report(node, "eval sucks.");
}
}
};

module.exports = {
meta: {
type: "problem",
schema: [],
},
create(context) {
return {
CallExpression: function (node) {
if (node.callee.name === "eval") {
context.report(node, "eval sucks.");
}
},
};
},
};
28 changes: 18 additions & 10 deletions tests/fixtures/testers/rule-tester/no-invalid-args.js
Expand Up @@ -3,20 +3,28 @@
* @author Mathias Schreck
*/

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {
"use strict";

var config = context.options[0];
module.exports = {
meta: {
type: "problem",
schema: [{
type: "boolean"
}]
},
create(context) {
var config = context.options[0];

return {
"Program": function(node) {
if (config === true) {
context.report(node, "Invalid args");
return {
"Program": function(node) {
if (config === true) {
context.report(node, "Invalid args");
}
}
}
};
};
}
};
34 changes: 17 additions & 17 deletions tests/fixtures/testers/rule-tester/no-invalid-schema.js
Expand Up @@ -3,26 +3,26 @@
* @author Brandon Mills
*/

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {
"use strict";

var config = context.options[0];

return {
"Program": function(node) {
if (config) {
context.report(node, "Expected nothing.");
module.exports = {
meta: {
type: "problem",
schema: [{
"enum": []
}]
},
create(context) {
return {
"Program": function(node) {
if (config) {
context.report(node, "Expected nothing.");
}
}
}
};
};
},
};

module.exports.schema = [
{
"enum": []
}
];
35 changes: 18 additions & 17 deletions tests/fixtures/testers/rule-tester/no-schema-violation.js
Expand Up @@ -3,26 +3,27 @@
* @author Brandon Mills
*/

"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {
"use strict";

var config = context.options[0];

return {
"Program": function(node) {
if (config && config !== "foo") {
context.report(node, "Expected foo.");
module.exports = {
meta: {
type: "problem",
schema: [{
"enum": ["foo"]
}]
},
create(context) {
const config = context.options[0];
return {
"Program": function(node) {
if (config && config !== "foo") {
context.report(node, "Expected foo.");
}
}
}
};
};
},
};

module.exports.schema = [
{
"enum": ["foo"]
}
];

0 comments on commit 1cdcbca

Please sign in to comment.