Skip to content

Commit

Permalink
feat!: check for parsing errors in suggestion fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish committed Dec 10, 2022
1 parent 90c9219 commit bb50f15
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
15 changes: 14 additions & 1 deletion lib/rule-tester/flat-rule-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,9 @@ class FlatRuleTester {
messages,
output,
beforeAST,
afterAST: cloneDeeplyExcludesParent(afterAST)
afterAST: cloneDeeplyExcludesParent(afterAST),
configs,
filename
};
}

Expand Down Expand Up @@ -975,6 +977,17 @@ class FlatRuleTester {
if (hasOwnProperty(expectedSuggestion, "output")) {
const codeWithAppliedSuggestion = SourceCodeFixer.applyFixes(item.code, [actualSuggestion]).output;

// Verify if suggestion fix makes a syntax error or not.
const errorMessageInSuggestion =
linter.verify(codeWithAppliedSuggestion, result.configs, result.filename).find(m => m.fatal);

assert(!errorMessageInSuggestion, [
"A fatal parsing error occurred in suggestion fix.",
`Error: ${errorMessageInSuggestion && errorMessageInSuggestion.message}`,
"Suggestion output:",
codeWithAppliedSuggestion
].join("\n"));

assert.strictEqual(codeWithAppliedSuggestion, expectedSuggestion.output, `Expected the applied suggestion fix to match the test suggestion output for suggestion at index: ${index} on error with message: "${message.message}"`);
}
});
Expand Down
15 changes: 14 additions & 1 deletion lib/rule-tester/rule-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,9 @@ class RuleTester {
messages,
output,
beforeAST,
afterAST: cloneDeeplyExcludesParent(afterAST)
afterAST: cloneDeeplyExcludesParent(afterAST),
config,
filename
};
}

Expand Down Expand Up @@ -985,6 +987,17 @@ class RuleTester {
if (hasOwnProperty(expectedSuggestion, "output")) {
const codeWithAppliedSuggestion = SourceCodeFixer.applyFixes(item.code, [actualSuggestion]).output;

// Verify if suggestion fix makes a syntax error or not.
const errorMessageInSuggestion =
linter.verify(codeWithAppliedSuggestion, result.config, result.filename).find(m => m.fatal);

assert(!errorMessageInSuggestion, [
"A fatal parsing error occurred in suggestion fix.",
`Error: ${errorMessageInSuggestion && errorMessageInSuggestion.message}`,
"Suggestion output:",
codeWithAppliedSuggestion
].join("\n"));

assert.strictEqual(codeWithAppliedSuggestion, expectedSuggestion.output, `Expected the applied suggestion fix to match the test suggestion output for suggestion at index: ${index} on error with message: "${message.message}"`);
}
});
Expand Down
41 changes: 41 additions & 0 deletions tests/lib/rule-tester/flat-rule-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -1939,6 +1939,47 @@ describe("FlatRuleTester", () => {
}, "Error should have 2 suggestions. Instead found 1 suggestions");
});

it("should throw if suggestion fix made a syntax error.", () => {
assert.throw(() => {
ruleTester.run(
"foo",
{
meta: { hasSuggestions: true },
create(context) {
return {
Identifier(node) {
context.report({
node,
message: "make a syntax error",
suggest: [
{
desc: "make a syntax error",
fix(fixer) {
return fixer.replaceText(node, "one two");
}
}
]
});
}
};
}
},
{
valid: [""],
invalid: [{
code: "one()",
errors: [{
suggestions: [{
desc: "make a syntax error",
output: "one two()"
}]
}]
}]
}
);
}, /A fatal parsing error occurred in suggestion fix\.\nError: .+\nSuggestion output:\n.+/u);
});

it("should throw if the suggestion description doesn't match", () => {
assert.throws(() => {
ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
Expand Down
41 changes: 41 additions & 0 deletions tests/lib/rule-tester/rule-tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -1923,6 +1923,47 @@ describe("RuleTester", () => {
}, "Error should have 2 suggestions. Instead found 1 suggestions");
});

it("should throw if suggestion fix made a syntax error.", () => {
assert.throw(() => {
ruleTester.run(
"foo",
{
meta: { hasSuggestions: true },
create(context) {
return {
Identifier(node) {
context.report({
node,
message: "make a syntax error",
suggest: [
{
desc: "make a syntax error",
fix(fixer) {
return fixer.replaceText(node, "one two");
}
}
]
});
}
};
}
},
{
valid: [""],
invalid: [{
code: "one()",
errors: [{
suggestions: [{
desc: "make a syntax error",
output: "one two()"
}]
}]
}]
}
);
}, /A fatal parsing error occurred in suggestion fix\.\nError: .+\nSuggestion output:\n.+/u);
});

it("should throw if the suggestion description doesn't match", () => {
assert.throws(() => {
ruleTester.run("suggestions-basic", require("../../fixtures/testers/rule-tester/suggestions").basic, {
Expand Down

0 comments on commit bb50f15

Please sign in to comment.