Skip to content

Commit

Permalink
feat(rule-tester): support multipass fixes (typescript-eslint#8883)
Browse files Browse the repository at this point in the history
* feat(rule-tester): support multipass fixes

* docs: mention multi-pass fixes in rule tester docs

* Update docs/packages/Rule_Tester.mdx

Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>

* Update packages/rule-tester/src/RuleTester.ts

Co-authored-by: Kirk Waiblinger <kirk.waiblinger@gmail.com>

* refactor: break if fixer doesn't change the code

---------

Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
Co-authored-by: Kirk Waiblinger <kirk.waiblinger@gmail.com>
  • Loading branch information
3 people committed May 16, 2024
1 parent 5753fe5 commit 5c80828
Show file tree
Hide file tree
Showing 10 changed files with 603 additions and 124 deletions.
9 changes: 9 additions & 0 deletions docs/packages/Rule_Tester.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ ruleTester.run('my-rule', rule, {
/* ... */
],
},
// Multi-pass fixes can be tested using the array form of output.
// Note: this is unique to typescript-eslint, and doesn't exist in ESLint core.
{
code: 'const d = 1;',
output: ['const e = 1;', 'const f = 1;'],
errors: [
/* ... */
],
},

// suggestions can be tested via errors
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,18 @@ const test = [
},
{
code: wrap`'for (const x of y) {}'`,
output: wrap`\`for (const x of y) {
output: [
wrap`\`for (const x of y) {
}\``,
wrap`\`
for (const x of y) {
}
\``,
wrap`\`
for (const x of y) {
}
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'invalidFormatting',
Expand All @@ -217,8 +227,18 @@ const test = [
{
code: wrap`'for (const x of \`asdf\`) {}'`,
// make sure it escapes the backticks
output: wrap`\`for (const x of \\\`asdf\\\`) {
output: [
wrap`\`for (const x of \\\`asdf\\\`) {
}\``,
wrap`\`
for (const x of \\\`asdf\\\`) {
}
\``,
wrap`\`
for (const x of \\\`asdf\\\`) {
}
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'invalidFormatting',
Expand All @@ -238,7 +258,7 @@ const test = [
},
{
code: wrap`\`const a = '1'\``,
output: wrap`"const a = '1'"`,
output: [wrap`"const a = '1'"`, wrap`"const a = '1';"`],
errors: [
{
messageId: 'singleLineQuotes',
Expand All @@ -247,7 +267,7 @@ const test = [
},
{
code: wrap`\`const a = "1";\``,
output: wrap`'const a = "1";'`,
output: [wrap`'const a = "1";'`, wrap`"const a = '1';"`],
errors: [
{
messageId: 'singleLineQuotes',
Expand All @@ -258,9 +278,14 @@ const test = [
{
code: wrap`\`const a = "1";
${PARENT_INDENT}\``,
output: wrap`\`
output: [
wrap`\`
const a = "1";
${PARENT_INDENT}\``,
wrap`\`
const a = '1';
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'templateLiteralEmptyEnds',
Expand All @@ -270,9 +295,17 @@ ${PARENT_INDENT}\``,
{
code: wrap`\`
${CODE_INDENT}const a = "1";\``,
output: wrap`\`
output: [
wrap`\`
${CODE_INDENT}const a = "1";
\``,
wrap`\`
${CODE_INDENT}const a = "1";
${PARENT_INDENT}\``,
wrap`\`
${CODE_INDENT}const a = '1';
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'templateLiteralEmptyEnds',
Expand All @@ -282,10 +315,20 @@ ${CODE_INDENT}const a = "1";
{
code: wrap`\`const a = "1";
${CODE_INDENT}const b = "2";\``,
output: wrap`\`
output: [
wrap`\`
const a = "1";
${CODE_INDENT}const b = "2";
\``,
wrap`\`
const a = "1";
${CODE_INDENT}const b = "2";
${PARENT_INDENT}\``,
wrap`\`
const a = '1';
const b = '2';
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'templateLiteralEmptyEnds',
Expand All @@ -297,9 +340,14 @@ ${CODE_INDENT}const b = "2";
code: wrap`\`
${CODE_INDENT}const a = "1";
\``,
output: wrap`\`
output: [
wrap`\`
${CODE_INDENT}const a = "1";
${PARENT_INDENT}\``,
wrap`\`
${CODE_INDENT}const a = '1';
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'templateLiteralLastLineIndent',
Expand All @@ -310,9 +358,14 @@ ${PARENT_INDENT}\``,
code: wrap`\`
${CODE_INDENT}const a = "1";
\``,
output: wrap`\`
output: [
wrap`\`
${CODE_INDENT}const a = "1";
${PARENT_INDENT}\``,
wrap`\`
${CODE_INDENT}const a = '1';
${PARENT_INDENT}\``,
],
errors: [
{
messageId: 'templateLiteralLastLineIndent',
Expand Down Expand Up @@ -483,7 +536,8 @@ ruleTester.run({
],
});
`,
output: `
output: [
`
ruleTester.run({
valid: [
{
Expand Down Expand Up @@ -517,6 +571,75 @@ foo
],
});
`,
`
ruleTester.run({
valid: [
{
code: 'foo;',
},
{
code: \`
foo
\`,
},
{
code: \`
foo
\`,
},
],
invalid: [
{
code: 'foo;',
},
{
code: \`
foo
\`,
},
{
code: \`
foo
\`,
},
],
});
`,
`
ruleTester.run({
valid: [
{
code: 'foo;',
},
{
code: \`
foo;
\`,
},
{
code: \`
foo
\`,
},
],
invalid: [
{
code: 'foo;',
},
{
code: \`
foo;
\`,
},
{
code: \`
foo
\`,
},
],
});
`,
],
errors: [
{
messageId: 'singleLineQuotes',
Expand Down
6 changes: 5 additions & 1 deletion packages/eslint-plugin/tests/RuleTester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ export function batchedSingleLineTests<
MessageIds extends string,
Options extends readonly unknown[],
>(
options: InvalidTestCase<MessageIds, Options> | ValidTestCase<Options>,
options:
| (Omit<InvalidTestCase<MessageIds, Options>, 'output'> & {
output?: string | null;
})
| ValidTestCase<Options>,
): (InvalidTestCase<MessageIds, Options> | ValidTestCase<Options>)[] {
// -- eslint counts lines from 1
const lineOffset = options.code.startsWith('\n') ? 2 : 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,16 @@ declare const nested: string, interpolation: string;
\`le\${ \`ss\` }\`
}\`;
`,
output: `
output: [
`
\`use\${
\`less\`
}\`;
`,
`
\`useless\`;
`,
],
errors: [
{
messageId: 'noUselessTemplateLiteral',
Expand Down

0 comments on commit 5c80828

Please sign in to comment.