10000 Repo: rule-tester: Can I use the output of the snapshot test rules? · Issue #7449 · typescript-eslint/typescript-eslint · GitHub
[go: up one dir, main page]

Skip to content

Repo: rule-tester: Can I use the output of the snapshot test rules? #7449

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

Closed
u3u opened this issue Aug 10, 2023 · 1 comment
Closed

Repo: rule-tester: Can I use the output of the snapshot test rules? #7449

u3u opened this issue Aug 10, 2023 · 1 comment
Labels
question Questions! (i.e. not a bug / enhancment / documentation)

Comments

@u3u
Copy link
u3u commented Aug 10, 2023

Motivation

When a rule contains an auto-fix program, I want to test if the output of the fix meets my expectations. The simplest way is to use snapshot testing and check if the snapshot matches the expected result.

However, now I need to manually maintain strict formatting for indentation, spaces, and other formatting-related outputs.

I also need to use dedent to ensure consistent indentation. This is too troublesome.

If I want to optimize the auto-fixing process, I also need to manually synchronize the output of the tests (sometimes it may be just one extra or missing space, which should not matter because it will eventually be formatted by Prettier).

Example

https://github.com/u3u/eslint-plugin-arrow-return-style/blob/bfa3cc81f15526aa76fe1b043d0a394ffe3be2ba/src/rules/arrow-return-style.test.ts

import { RuleTester } from '@typescript-eslint/rule-tester';
import dedent from 'dedent';
import { afterAll, describe, it } from 'vitest';
import { arrowReturnStyleRule, RULE_NAME } from './arrow-return-style';

RuleTester.afterAll = afterAll;
RuleTester.describe = describe;
RuleTester.it = it;

const ruleTester = new RuleTester({
  parser: '@typescript-eslint/parser',

  parserOptions: {
    ecmaFeatures: { jsx: true },
  },
});

ruleTester.run(RULE_NAME, arrowReturnStyleRule, {
  invalid: [
    {
      code: dedent`
        const delay = () =>
          new Promise((resolve) => {
            setTimeout(resolve, 1000)
          })
      `,

      errors: [{ messageId: 'useExplicitReturn' }],

      output: dedent`
        const delay = () =>
          { return new Promise((resolve) => {
            setTimeout(resolve, 1000)
          }) }
      `,
    },

    {
      code: dedent`
        const foo = () => {
          return 'foo'
        }
      `,

      errors: [{ messageId: 'useImplicitReturn' }],

      output: dedent`
        const foo = () => 
          'foo'\n
      `,
    },

    {
      code: dedent`
        Array.from({ length: 10 }).map((_, i) => {
          return i + 1
        })
      `,

      errors: [{ messageId: 'useImplicitReturn' }],

      output: dedent`
        Array.from({ length: 10 }).map((_, i) => 
          i + 1
        )
      `,
    },

    {
      code: dedent`
        const obj = () => {
          return { name: '' }
        }
      `,

      errors: [{ messageId: 'useImplicitReturn' }],

      output: dedent`
        const obj = () => 
          ({ name: '' })\n
      `,
    },

    {
      code: dedent`
        const data = () => ({
          name: ''
        })
      `,

      errors: [{ messageId: 'useExplicitReturn' }],

      output: dedent`
        const data = () => { return {
          name: ''
        } }
      `,
    },

    {
      code: 'export const defineConfig = <T extends Linter.Config>(config: T) => config',
      errors: [{ messageId: 'useExplicitReturn' }],
      output: 'export const defineConfig = <T extends Linter.Config>(config: T) => { return config }',
    },

    {
      code: 'const Div = () => <><div /></>',
      errors: [{ messageId: 'useExplicitReturn' }],
      options: [{ jsxAlwaysUseExplicitReturn: true }],
      output: 'const Div = () => { return <><div /></> }',
    },

    {
      code: dedent`
        const FC = () =>
          <Foo
          // d=""
          z
          // test={{}}
          data-ignore=""
          bar={[]}
        />
      `,

      errors: [{ messageId: 'useExplicitReturn' }],

      output: dedent`
        const FC = () =>
          { return <Foo
          // d=""
          z
          // test={{}}
          data-ignore=""
          bar={[]}
        /> }
      `,
    },

    {
      code: dedent`
        export const createRule = ESLintUtils.RuleCreator(
          (rule) => \`https://github.com/u3u/eslint-plugin-arrow-return-style/tree/v\${version}/docs/rules/\${rule}.md\`
        )
      `,

      errors: [{ messageId: 'useExplicitReturn' }],

      output: dedent`
        export const createRule = ESLintUtils.RuleCreator(
          (rule) => { return \`https://github.com/u3u/eslint-plugin-arrow-return-style/tree/v\${version}/docs/rules/\${rule}.md\` }
        )
      `,
    },

    {
      code: 'const render = () => (<div />)',
      errors: [{ messageId: 'useExplicitReturn' }],
      options: [{ jsxAlwaysUseExplicitReturn: true }],
      output: 'const render = () => { return <div /> }',
    },

    {
      code: dedent`
        const fn = () =>
          /* block comment */
          1
      `,

      errors: [{ messageId: 'useExplicitReturn' }],

      output: dedent`
        const fn = () => {
          /* block comment */
          return 1
        }
      `,
    },

    {
      code: dedent`
        const test = () =>
          // line comment
          ({ name: 'test' })
      `,

      errors: [{ messageId: 'useExplicitReturn' }],

      output: dedent`
        const test = () => {
          // line comment
          return { name: 'test' }
        }
      `,
    },
  ],

  valid: [
    'const t = () => Date.now()',
    'const fn = () => { return }',

    'Array.from({ length: 10 }).map((_, i) => i + 1)',

    {
      code: 'const Div = () => <><div /></>',
      options: [{ jsxAlwaysUseExplicitReturn: false }],
    },

    dedent`
      const bar = () => {
        // line comment
        return 'bar'
      }
    `,

    dedent`
      const fn = async () => {
        await delay(300)
        return 'fn'
      }
    `,

    dedent`
      export const getUser = async () => {
        return {}
      }
    `,
  ],
});
@u3u u3u added repo maintenance things to do with maintenance of the repo, and not with code/docs triage Waiting for team members to take a look labels Aug 10, 2023
@bradzacher
Copy link
Member
bradzacher commented Aug 10, 2023

No, you currently cannot.
We are investigating this though - see #6499 and pr #6994

@bradzacher bradzacher closed this as not planned Won't fix, can't repro, duplicate, stale Aug 10, 2023
@bradzacher bradzacher added question Questions! (i.e. not a bug / enhancment / documentation) and removed triage Waiting for team members to take a look repo maintenance things to do with maintenance of the repo, and not with code/docs labels Aug 10, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
question Questions! (i.e. not a bug / enhancment / documentation)
Projects
None yet
Development

No branches or pull requests

2 participants
0