Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update: require meta for fixable rules in RuleTester (refs #13349) (#…
…13489)

* Update: require `meta` for fixable rules in RuleTester (refs #13349)

* Fix JSDoc

* Throw for legacy-format fixable rules
  • Loading branch information
mdjermanovic committed Jul 31, 2020
1 parent 6fb4edd commit ecb2b73
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 22 deletions.
10 changes: 10 additions & 0 deletions lib/rule-tester/rule-tester.js
Expand Up @@ -861,6 +861,16 @@ class RuleTester {
);
}

// Rules that produce fixes must have `meta.fixable` property.
if (result.output !== item.code) {
assert.ok(
hasOwnProperty(rule, "meta"),
"Fixable rules should export a `meta.fixable` property."
);

// Linter throws if a rule that produced a fix has `meta` but doesn't have `meta.fixable`.
}

assertASTDidntChange(result.beforeAST, result.afterAST);
}

Expand Down
48 changes: 26 additions & 22 deletions tests/fixtures/testers/rule-tester/no-var.js
Expand Up @@ -7,27 +7,31 @@
// Rule Definition
//------------------------------------------------------------------------------

module.exports = function(context) {

"use strict";


var sourceCode = context.getSourceCode();

return {

"VariableDeclaration": function(node) {
if (node.kind === "var") {
context.report({
node: node,
loc: sourceCode.getFirstToken(node).loc,
message: "Bad var.",
fix: function(fixer) {
return fixer.remove(sourceCode.getFirstToken(node));
}
})
"use strict";

module.exports = {

meta: {
fixable: "code"
},

create(context) {

var sourceCode = context.getSourceCode();

return {
"VariableDeclaration": function(node) {
if (node.kind === "var") {
context.report({
node: node,
loc: sourceCode.getFirstToken(node).loc,
message: "Bad var.",
fix: function(fixer) {
return fixer.remove(sourceCode.getFirstToken(node));
}
})
}
}
}
};

};
}
};
71 changes: 71 additions & 0 deletions tests/lib/rule-tester/rule-tester.js
Expand Up @@ -304,6 +304,10 @@ describe("RuleTester", () => {

it("should use strict equality to compare output", () => {
const replaceProgramWith5Rule = {
meta: {
fixable: "code"
},

create: context => ({
Program(node) {
context.report({ node, message: "bad", fix: fixer => fixer.replaceText(node, "5") });
Expand Down Expand Up @@ -1237,6 +1241,73 @@ describe("RuleTester", () => {
}, "Error must specify 'messageId' if 'data' is used.");
});

// fixable rules with or without `meta` property
it("should not throw an error if a rule that has `meta.fixable` produces fixes", () => {
const replaceProgramWith5Rule = {
meta: {
fixable: "code"
},
create(context) {
return {
Program(node) {
context.report({ node, message: "bad", fix: fixer => fixer.replaceText(node, "5") });
}
};
}
};

ruleTester.run("replaceProgramWith5", replaceProgramWith5Rule, {
valid: [],
invalid: [
{ code: "var foo = bar;", output: "5", errors: 1 }
]
});
});
it("should throw an error if a new-format rule that doesn't have `meta` produces fixes", () => {
const replaceProgramWith5Rule = {
create(context) {
return {
Program(node) {
context.report({ node, message: "bad", fix: fixer => fixer.replaceText(node, "5") });
}
};
}
};

assert.throws(() => {
ruleTester.run("replaceProgramWith5", replaceProgramWith5Rule, {
valid: [],
invalid: [
{ code: "var foo = bar;", output: "5", errors: 1 }
]
});
}, "Fixable rules should export a `meta.fixable` property.");
});
it("should throw an error if a legacy-format rule produces fixes", () => {

/**
* Legacy-format rule (a function instead of an object with `create` method).
* @param {RuleContext} context The ESLint rule context object.
* @returns {Object} Listeners.
*/
function replaceProgramWith5Rule(context) {
return {
Program(node) {
context.report({ node, message: "bad", fix: fixer => fixer.replaceText(node, "5") });
}
};
}

assert.throws(() => {
ruleTester.run("replaceProgramWith5", replaceProgramWith5Rule, {
valid: [],
invalid: [
{ code: "var foo = bar;", output: "5", errors: 1 }
]
});
}, "Fixable rules should export a `meta.fixable` property.");
});

describe("suggestions", () => {
it("should pass with valid suggestions (tested using desc)", () => {
ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
Expand Down

0 comments on commit ecb2b73

Please sign in to comment.