Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add deprecation warnings for legacy API in RuleTester #16063

Merged
merged 10 commits into from Jul 28, 2022
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.
snitin315 marked this conversation as resolved.
Show resolved Hide resolved
* @returns {void}
*/
function emitMissingSchemaWarning(ruleName) {
snitin315 marked this conversation as resolved.
Show resolved Hide resolved
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"]
}
];