-
-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: migrate test to eslint-vitest-rule-tester
- Loading branch information
1 parent
ecb384d
commit e87cfe1
Showing
133 changed files
with
10,791 additions
and
10,745 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,42 +18,29 @@ jobs: | |
- "20" | ||
- "latest" | ||
ts_version: | ||
- "next" | ||
# - "next" | ||
- "latest" | ||
- "4.7.4" | ||
# - "4.7.4" | ||
# - "JS" | ||
runs-on: ${{ matrix.os }} | ||
continue-on-error: ${{ matrix.ts_version == 'next' }} | ||
env: | ||
REPORT_COVERAGE: ${{ fromJSON('["false", "true"]')[matrix.node_version == 'latest' && matrix.os == 'ubuntu-latest'] }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: ./.github/actions/prepare | ||
|
||
- name: Build | ||
run: pnpm run build:node | ||
|
||
- name: Compile Tests | ||
run: pnpm run build-tests | ||
|
||
- name: Setup NodeJs ${{ matrix.node_version }} for testing | ||
uses: actions/setup-node@v4 | ||
with: | ||
node-version: ${{ matrix.node_version }} | ||
|
||
- name: Remove Dev TypeScript | ||
run: pnpm remove typescript | ||
|
||
- name: Add TypeScript "${{ matrix.ts_version }}" | ||
if: matrix.ts_version != 'JS' | ||
run: pnpm add -D typescript@"${{ matrix.ts_version }}" | ||
# - name: Add TypeScript "${{ matrix.ts_version }}" for testing | ||
# run: pnpm add -D typescript@"${{ matrix.ts_version }}" | ||
|
||
- name: Run Tests | ||
run: pnpm test-compiled | ||
run: pnpm test:js-run | ||
|
||
- name: Report coverage | ||
uses: codecov/[email protected] | ||
if: env.REPORT_COVERAGE == 'true' | ||
with: | ||
file: coverage/lcov.info | ||
flags: ${{ matrix.ts_version }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,7 +39,6 @@ | |
"files": ["lib/", "package.json", "LICENSE", "README.md"], | ||
"scripts": { | ||
"build": "pnpm run build:node && pnpm run build:docs", | ||
"build-tests": "rimraf tests-compiled && tsc -p tsconfig.tests-compiled.json && tsc-alias -p tsconfig.tests-compiled.json", | ||
"build:docs": "eslint-doc-generator", | ||
"build:node": "rimraf lib && rollup -c rollup.config.ts --configPlugin rollup-plugin-ts", | ||
"lint": "eslint && pnpm run lint:md && pnpm lint:eslint-docs && pnpm run lint:spelling && pnpm run lint:knip && pnpm run lint:packages", | ||
|
@@ -63,11 +62,11 @@ | |
"prepare": "husky", | ||
"release": "semantic-release", | ||
"test": "pnpm run test:js", | ||
"test-compiled": "USE_COMPILED_TESTS=1 vitest run --coverage", | ||
"test-work": "vitest", | ||
"test:js": "vitest --coverage", | ||
"test:js-run": "vitest run --coverage", | ||
"typecheck": "tsc -p tsconfig.build.json --noEmit", | ||
"verify": "pnpm run lint && pnpm run typecheck && pnpm run build-tests && pnpm run test-compiled" | ||
"verify": "pnpm run lint && pnpm run typecheck && pnpm run test:js-run" | ||
}, | ||
"overrides": { | ||
"eslint-plugin-functional": "link:." | ||
|
@@ -91,12 +90,9 @@ | |
"@semantic-release/release-notes-generator": "14.0.1", | ||
"@stylistic/eslint-plugin": "2.6.1", | ||
"@types/dedent": "0.7.2", | ||
"@types/espree": "10.1.0", | ||
"@types/node": "18.18.0", | ||
"@typescript-eslint/eslint-plugin": "8.0.0", | ||
"@typescript-eslint/parser": "8.0.0", | ||
"@typescript-eslint/rule-tester": "8.0.0", | ||
"@vitest/coverage-istanbul": "2.0.5", | ||
"@vitest/coverage-v8": "2.0.5", | ||
"cspell": "8.13.1", | ||
"deassert": "1.0.2", | ||
|
@@ -124,7 +120,7 @@ | |
"eslint-plugin-unicorn": "55.0.0", | ||
"eslint-plugin-vitest": "0.5.4", | ||
"eslint-plugin-yml": "1.14.0", | ||
"espree": "10.1.0", | ||
"eslint-vitest-rule-tester": "0.3.3", | ||
"fast-glob": "3.3.2", | ||
"husky": "9.1.4", | ||
"jsonc-eslint-parser": "2.4.0", | ||
|
@@ -138,7 +134,6 @@ | |
"rollup-plugin-ts": "3.4.5", | ||
"semantic-release": "24.0.0", | ||
"semantic-release-replace-plugin": "1.2.7", | ||
"tsc-alias": "1.8.10", | ||
"tsc-files": "1.1.4", | ||
"tsx": "4.16.5", | ||
"typescript": "5.5.4", | ||
|
@@ -158,5 +153,10 @@ | |
"packageManager": "[email protected]", | ||
"engines": { | ||
"node": ">=v18.18.0" | ||
}, | ||
"pnpm": { | ||
"patchedDependencies": { | ||
"[email protected]": "patches/[email protected]" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
diff --git a/dist/index.d.mts b/dist/index.d.mts | ||
index f982c4d7c06d00d8f1e9f7515951582be0cc1f59..7245940c64de19f60428239bcccca0658bb64a7b 100644 | ||
--- a/dist/index.d.mts | ||
+++ b/dist/index.d.mts | ||
@@ -93,6 +93,12 @@ interface RuleTesterBehaviorOptions { | ||
*/ | ||
verifyFixChanges?: boolean; | ||
} | ||
+interface DefaultFilenames { | ||
+ js: string; | ||
+ jsx: string; | ||
+ ts: string; | ||
+ tsx: string; | ||
+} | ||
interface RuleTesterInitOptions extends CompatConfigOptions, RuleTesterBehaviorOptions { | ||
/** | ||
* The rule to test | ||
@@ -106,6 +112,11 @@ interface RuleTesterInitOptions extends CompatConfigOptions, RuleTesterBehaviorO | ||
* Additional flat configs to be merged with the rule config | ||
*/ | ||
configs?: Linter.FlatConfig | Linter.FlatConfig[]; | ||
+ /** | ||
+ * The default filenames to use for type-aware tests. | ||
+ * @default { js: 'file.js', jsx: 'react.jsx', ts: 'file.ts', tsx: 'react.tsx' } | ||
+ */ | ||
+ defaultFilenames?: Partial<DefaultFilenames>; | ||
} | ||
interface TestCasesOptions { | ||
valid?: (ValidTestCase | string)[]; | ||
@@ -116,8 +127,10 @@ interface TestCasesOptions { | ||
onResult?: (_case: NormalizedTestCase, result: Linter.FixReport) => void | Promise<void>; | ||
} | ||
|
||
-declare function normalizeTestCase(c: TestCase, type?: 'valid' | 'invalid'): NormalizedTestCase; | ||
+declare function normalizeTestCase(c: TestCase, languageOptions: Linter.FlatConfig['languageOptions'], defaultFilenames: DefaultFilenames, type?: 'valid' | 'invalid'): NormalizedTestCase; | ||
declare function normalizeCaseError(error: TestCaseError | string, rule?: RuleModule): Partial<Linter.LintMessage>; | ||
+declare function isUsingTypeScriptParser(languageOptions: Linter.FlatConfig['languageOptions']): boolean; | ||
+declare function isUsingTypeScriptTypings(languageOptions: Linter.FlatConfig['languageOptions']): any; | ||
|
||
declare function createRuleTester(options: RuleTesterInitOptions): RuleTester; | ||
|
||
@@ -132,4 +145,4 @@ declare function runClassic(ruleName: string, rule: RuleModule, cases: TestCases | ||
|
||
declare function pickFlatConfigFromOptions(options: CompatConfigOptions): Linter.FlatConfig | undefined; | ||
|
||
-export { type CompatConfigOptions, type InvalidTestCase, type InvalidTestCaseBase, type NormalizedTestCase, type RuleModule, type RuleTester, type RuleTesterBehaviorOptions, type RuleTesterInitOptions, type TestCase, type TestCaseError, type TestCasesOptions, type TestExecutionResult, type ValidTestCase, type ValidTestCaseBase, createRuleTester, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic }; | ||
+export { type CompatConfigOptions, type DefaultFilenames, type InvalidTestCase, type InvalidTestCaseBase, type NormalizedTestCase, type RuleModule, type RuleTester, type RuleTesterBehaviorOptions, type RuleTesterInitOptions, type TestCase, type TestCaseError, type TestCasesOptions, type TestExecutionResult, type ValidTestCase, type ValidTestCaseBase, createRuleTester, isUsingTypeScriptParser, isUsingTypeScriptTypings, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic }; | ||
diff --git a/dist/index.d.ts b/dist/index.d.ts | ||
index f982c4d7c06d00d8f1e9f7515951582be0cc1f59..7245940c64de19f60428239bcccca0658bb64a7b 100644 | ||
--- a/dist/index.d.ts | ||
+++ b/dist/index.d.ts | ||
@@ -93,6 +93,12 @@ interface RuleTesterBehaviorOptions { | ||
*/ | ||
verifyFixChanges?: boolean; | ||
} | ||
+interface DefaultFilenames { | ||
+ js: string; | ||
+ jsx: string; | ||
+ ts: string; | ||
+ tsx: string; | ||
+} | ||
interface RuleTesterInitOptions extends CompatConfigOptions, RuleTesterBehaviorOptions { | ||
/** | ||
* The rule to test | ||
@@ -106,6 +112,11 @@ interface RuleTesterInitOptions extends CompatConfigOptions, RuleTesterBehaviorO | ||
* Additional flat configs to be merged with the rule config | ||
*/ | ||
configs?: Linter.FlatConfig | Linter.FlatConfig[]; | ||
+ /** | ||
+ * The default filenames to use for type-aware tests. | ||
+ * @default { js: 'file.js', jsx: 'react.jsx', ts: 'file.ts', tsx: 'react.tsx' } | ||
+ */ | ||
+ defaultFilenames?: Partial<DefaultFilenames>; | ||
} | ||
interface TestCasesOptions { | ||
valid?: (ValidTestCase | string)[]; | ||
@@ -116,8 +127,10 @@ interface TestCasesOptions { | ||
onResult?: (_case: NormalizedTestCase, result: Linter.FixReport) => void | Promise<void>; | ||
} | ||
|
||
-declare function normalizeTestCase(c: TestCase, type?: 'valid' | 'invalid'): NormalizedTestCase; | ||
+declare function normalizeTestCase(c: TestCase, languageOptions: Linter.FlatConfig['languageOptions'], defaultFilenames: DefaultFilenames, type?: 'valid' | 'invalid'): NormalizedTestCase; | ||
declare function normalizeCaseError(error: TestCaseError | string, rule?: RuleModule): Partial<Linter.LintMessage>; | ||
+declare function isUsingTypeScriptParser(languageOptions: Linter.FlatConfig['languageOptions']): boolean; | ||
+declare function isUsingTypeScriptTypings(languageOptions: Linter.FlatConfig['languageOptions']): any; | ||
|
||
declare function createRuleTester(options: RuleTesterInitOptions): RuleTester; | ||
|
||
@@ -132,4 +145,4 @@ declare function runClassic(ruleName: string, rule: RuleModule, cases: TestCases | ||
|
||
declare function pickFlatConfigFromOptions(options: CompatConfigOptions): Linter.FlatConfig | undefined; | ||
|
||
-export { type CompatConfigOptions, type InvalidTestCase, type InvalidTestCaseBase, type NormalizedTestCase, type RuleModule, type RuleTester, type RuleTesterBehaviorOptions, type RuleTesterInitOptions, type TestCase, type TestCaseError, type TestCasesOptions, type TestExecutionResult, type ValidTestCase, type ValidTestCaseBase, createRuleTester, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic }; | ||
+export { type CompatConfigOptions, type DefaultFilenames, type InvalidTestCase, type InvalidTestCaseBase, type NormalizedTestCase, type RuleModule, type RuleTester, type RuleTesterBehaviorOptions, type RuleTesterInitOptions, type TestCase, type TestCaseError, type TestCasesOptions, type TestExecutionResult, type ValidTestCase, type ValidTestCaseBase, createRuleTester, isUsingTypeScriptParser, isUsingTypeScriptTypings, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic }; | ||
diff --git a/dist/index.mjs b/dist/index.mjs | ||
index b10c991352ad54b17a05f8e41fe6d4b5e1f77ea1..b426a2540622b4bfd31d70598f971a280fe53ec5 100644 | ||
--- a/dist/index.mjs | ||
+++ b/dist/index.mjs | ||
@@ -1,4 +1,6 @@ | ||
-import { objectPick, toArray } from '@antfu/utils'; | ||
+import path from 'node:path'; | ||
+import process from 'node:process'; | ||
+import { objectPick, deepMerge, toArray } from '@antfu/utils'; | ||
export { unindent as $, unindent } from '@antfu/utils'; | ||
import { Linter } from 'eslint'; | ||
import { expect, describe, it } from 'vitest'; | ||
@@ -17,10 +19,21 @@ function interpolate(text, data) { | ||
); | ||
} | ||
|
||
-function normalizeTestCase(c, type) { | ||
+function normalizeTestCase(c, languageOptions, defaultFilenames, type) { | ||
const obj = typeof c === "string" ? { code: c } : { ...c }; | ||
const normalized = obj; | ||
normalized.type || (normalized.type = type || ("errors" in obj || "output" in obj ? "invalid" : "valid")); | ||
+ if (isUsingTypeScriptParser(languageOptions)) { | ||
+ normalized.filename || (normalized.filename = getDefaultTypeScriptFilename(languageOptions, defaultFilenames)); | ||
+ normalized.parserOptions = { | ||
+ ecmaVersion: "latest", | ||
+ sourceType: "module", | ||
+ disallowAutomaticSingleRunInference: true, | ||
+ ...normalized.parserOptions | ||
+ }; | ||
+ } else { | ||
+ normalized.filename || (normalized.filename = getDefaultJavaScriptFilename(languageOptions, defaultFilenames)); | ||
+ } | ||
return normalized; | ||
} | ||
function normalizeCaseError(error, rule) { | ||
@@ -46,6 +59,20 @@ function normalizeCaseError(error, rule) { | ||
} | ||
return clone; | ||
} | ||
+function getDefaultJavaScriptFilename(languageOptions, defaultFilenames) { | ||
+ return languageOptions?.parserOptions?.ecmaFeatures?.jsx ? defaultFilenames.jsx : defaultFilenames.js; | ||
+} | ||
+function getDefaultTypeScriptFilename(languageOptions, defaultFilenames) { | ||
+ const rootPath = (isUsingTypeScriptTypings(languageOptions) ? languageOptions?.parserOptions?.tsconfigRootDir : void 0) ?? process.cwd(); | ||
+ const filename = languageOptions?.parserOptions?.ecmaFeatures?.jsx ? defaultFilenames.tsx : defaultFilenames.ts; | ||
+ return path.join(rootPath, filename); | ||
+} | ||
+function isUsingTypeScriptParser(languageOptions) { | ||
+ return languageOptions?.parser?.meta?.name === "typescript-eslint/parser"; | ||
+} | ||
+function isUsingTypeScriptTypings(languageOptions) { | ||
+ return languageOptions?.parserOptions?.program || languageOptions?.parserOptions?.project || languageOptions?.parserOptions?.projectService; | ||
+} | ||
|
||
const BOM = "\uFEFF"; | ||
function compareMessagesByFixRange(a, b) { | ||
@@ -139,15 +166,32 @@ function pickFlatConfigFromOptions(options) { | ||
} | ||
|
||
function createRuleTester(options) { | ||
- const linter = new Linter({ configType: "flat" }); | ||
+ const languageOptions = deepMerge( | ||
+ options.languageOptions ?? { | ||
+ parser: options.parser, | ||
+ parserOptions: options.parserOptions | ||
+ }, | ||
+ ...toArray(options.configs).map((c) => c.languageOptions).filter((c) => c !== void 0) | ||
+ ); | ||
+ const linter = new Linter({ | ||
+ configType: "flat", | ||
+ cwd: isUsingTypeScriptParser(options) ? languageOptions?.parserOptions?.tsconfigRootDir : void 0 | ||
+ }); | ||
const defaultConfigs = toArray(options.configs); | ||
{ | ||
const inlineConfig = pickFlatConfigFromOptions(options); | ||
if (inlineConfig) | ||
defaultConfigs.unshift(inlineConfig); | ||
} | ||
+ const defaultFilenames = { | ||
+ js: "file.js", | ||
+ ts: "file.ts", | ||
+ jsx: "react.jsx", | ||
+ tsx: "react.tsx", | ||
+ ...options.defaultFilenames | ||
+ }; | ||
function each(c) { | ||
- const testcase = normalizeTestCase(c); | ||
+ const testcase = normalizeTestCase(c, languageOptions, defaultFilenames); | ||
const { | ||
recursive = 10, | ||
verifyAfterFix = true, | ||
@@ -260,7 +304,7 @@ ${result.output} | ||
if (cases.valid?.length) { | ||
describe("valid", () => { | ||
for (const c of cases.valid) { | ||
- const _case = normalizeTestCase(c, "valid"); | ||
+ const _case = normalizeTestCase(c, languageOptions, defaultFilenames, "valid"); | ||
let run2 = it; | ||
if (_case.only) | ||
run2 = it.only; | ||
@@ -276,7 +320,7 @@ ${result.output} | ||
if (cases.invalid?.length) { | ||
describe("invalid", () => { | ||
for (const c of cases.invalid) { | ||
- const _case = normalizeTestCase(c, "invalid"); | ||
+ const _case = normalizeTestCase(c, languageOptions, defaultFilenames, "invalid"); | ||
let run2 = it; | ||
if (_case.only) | ||
run2 = it.only; | ||
@@ -312,4 +356,4 @@ function runClassic(ruleName, rule, cases, options) { | ||
return tester.run(cases); | ||
} | ||
|
||
-export { createRuleTester, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic }; | ||
+export { createRuleTester, isUsingTypeScriptParser, isUsingTypeScriptTypings, normalizeCaseError, normalizeTestCase, pickFlatConfigFromOptions, run, runClassic }; |
Oops, something went wrong.