antfu / eslint-vitest-rule-tester

ESLint rule tester with Vitest, with more powerful and friendly APIs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

eslint-vitest-rule-tester

npm version npm downloads bundle JSDocs License

ESLint rule tester with Vitest.

This module requires ESLint v9.0+.

Install

npm i -D eslint-vitest-rule-tester

Usage

Classical Usage

Simliar style to ESLint's RuleTester (test cases with implicit test suites)

import { run, runClassic } from 'eslint-vitest-rule-tester'
import { expect } from 'vitest'

// Classic RuleTester.run style
runClassic('rule-name', rule, {
  valid: [
    // ...
  ],
  invalid: [
    // ...
  ],
}, {
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
  },
})

// Or everyting-in-one-object style
run({
  name: 'rule-name',
  rule,
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
  },

  valid: [
    // test cases
  ],
  invalid: [
    // test cases
  ],
})
Feature Extensions

output

output field can be a function to do custom assertions. This would also be compatible with snapshot testing.

import { run, } from 'eslint-vitest-rule-tester'
import { expect } from 'vitest'

run({
  name: 'rule-name',
  rule,
  invalid: [
    {
      code: 'let foo = 1',
      output(output) {
        expect(output.slice(0, 3)).toBe('let')
        expect(output)
          .toMatchInlineSnapshot(`"const foo = 1;"`)
        // Any custom assertion...
      },
    },
  ],
})

errors

errors field can be a function to do custom assertion, same as output.

import { run } from 'eslint-vitest-rule-tester'
import { expect } from 'vitest'

run({
  name: 'rule-name',
  rule,
  invalid: [
    {
      code: 'let foo = 1',
      errors(errors) {
        expect(errors).toHaveLength(1)
        expect(errors.map(e => e.messageId))
          .toMatchInlineSnapshot(`["error-message-id"]`)
        // Any custom assertion...
      },
    },
  ],
})

onResult hook

onResult field can be a function to do custom assertions with the entire result object.

import { runClassic } from 'eslint-vitest-rule-tester'
import { expect } from 'vitest'

run({
  name: 'rule-name',
  rule,
  invalid: [
    'let foo = 1',
  ],
  onResult(testCase, result) {
    if (testCase.type === 'invalid')
      expect(result).toMatchSnapshot()
    // here you can't use `toMatchInlineSnapshot` because it's not in the test case
  },
})

Explicit Test Suites

import { createRuleTester } from 'eslint-vitest-rule-tester'
import { describe, expect, it } from 'vitest'

describe('rule-name', () => {
  const { valid, invalid } = createRuleTester({
    name: 'rule-name',
    rule,
    configs: {
      // flat config options
      languageOptions: {
        parserOptions: {
          ecmaVersion: 2020,
          sourceType: 'module',
        },
      },
    }
  })

  it('valid case 1', () => {
    valid('const foo = 1')
  })

  it('invalid case 1 with snapshot', () => {
    const result = invalid({
      code: 'const foo = 1',
      errors: ['error-message-id'],
    })

    expect(result.output).toMatchSnapshot()
  })
})

Sponsors

License

MIT License © 2024-PRESENT Anthony Fu

About

ESLint rule tester with Vitest, with more powerful and friendly APIs.

License:MIT License


Languages

Language:TypeScript 99.6%Language:JavaScript 0.4%