From 8cbcd1719f4f327af3b82eba79c772a4d085891e Mon Sep 17 00:00:00 2001 From: Brad Zacher Date: Tue, 23 Jul 2024 21:52:36 +0930 Subject: [PATCH] test: add integration test against @types/eslint v9 --- .../dirname.cjs | 0 .../eslint.config.js | 0 .../package.json | 5 +- .../dirname.cjs | 2 + .../eslint.config.js | 67 ++++++++++ .../package.json | 14 +++ ...nfig-types-@types__eslint-v8.test.ts.snap} | 2 +- ...onfig-types-@types__eslint-v9.test.ts.snap | 119 ++++++++++++++++++ ...at-config-types-@types__eslint-v8.test.ts} | 0 ...lat-config-types-@types__eslint-v9.test.ts | 31 +++++ 10 files changed, 235 insertions(+), 5 deletions(-) rename packages/integration-tests/fixtures/{flat-config-types => flat-config-types-@types__eslint-v8}/dirname.cjs (100%) rename packages/integration-tests/fixtures/{flat-config-types => flat-config-types-@types__eslint-v8}/eslint.config.js (100%) rename packages/integration-tests/fixtures/{flat-config-types => flat-config-types-@types__eslint-v8}/package.json (67%) create mode 100644 packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/dirname.cjs create mode 100644 packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/eslint.config.js create mode 100644 packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/package.json rename packages/integration-tests/tests/__snapshots__/{flat-config-types.test.ts.snap => flat-config-types-@types__eslint-v8.test.ts.snap} (97%) create mode 100644 packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v9.test.ts.snap rename packages/integration-tests/tests/{flat-config-types.test.ts => flat-config-types-@types__eslint-v8.test.ts} (100%) create mode 100644 packages/integration-tests/tests/flat-config-types-@types__eslint-v9.test.ts diff --git a/packages/integration-tests/fixtures/flat-config-types/dirname.cjs b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/dirname.cjs similarity index 100% rename from packages/integration-tests/fixtures/flat-config-types/dirname.cjs rename to packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/dirname.cjs diff --git a/packages/integration-tests/fixtures/flat-config-types/eslint.config.js b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/eslint.config.js similarity index 100% rename from packages/integration-tests/fixtures/flat-config-types/eslint.config.js rename to packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/eslint.config.js diff --git a/packages/integration-tests/fixtures/flat-config-types/package.json b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/package.json similarity index 67% rename from packages/integration-tests/fixtures/flat-config-types/package.json rename to packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/package.json index 4aaf3629d59b..bfad08200499 100644 --- a/packages/integration-tests/fixtures/flat-config-types/package.json +++ b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v8/package.json @@ -1,14 +1,11 @@ { "type": "module", - "scripts": { - "// NOTE: @types/eslint has to be pinned until @stylistic/eslint-plugin latest works with latest": "" - }, "devDependencies": { "@types/eslint__eslintrc": "latest", "@eslint/eslintrc": "latest", "@types/eslint__js": "latest", "@eslint/js": "latest", - "@types/eslint": "^8.56.10", + "@types/eslint": "^8", "eslint": "latest", "@stylistic/eslint-plugin": "latest", "eslint-plugin-deprecation": "latest", diff --git a/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/dirname.cjs b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/dirname.cjs new file mode 100644 index 000000000000..f7cd3060fa96 --- /dev/null +++ b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/dirname.cjs @@ -0,0 +1,2 @@ +// a hacky way to allow __dirname within ESM +module.exports = __dirname; diff --git a/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/eslint.config.js b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/eslint.config.js new file mode 100644 index 000000000000..a7096065b106 --- /dev/null +++ b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/eslint.config.js @@ -0,0 +1,67 @@ +// @ts-check + +import { FlatCompat } from '@eslint/eslintrc'; +import eslint from '@eslint/js'; +import stylisticPlugin from '@stylistic/eslint-plugin'; +import deprecationPlugin from 'eslint-plugin-deprecation'; +import jestPlugin from 'eslint-plugin-jest'; +import tseslint from 'typescript-eslint'; + +import __dirname from './dirname.cjs'; + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: {}, + allConfig: {}, +}); + +// this config is run through eslint as part of the integration test +// so it needs to be a correct config +export default tseslint.config( + { + // config with just ignores is the replacement for `.eslintignore` + ignores: ['**/build/**', '**/dist/**', 'src/some/file/to/ignore.ts'], + }, + { + plugins: { + ['@typescript-eslint']: tseslint.plugin, + ['deprecation']: deprecationPlugin, + ['jest']: jestPlugin, + }, + }, + eslint.configs.recommended, + ...tseslint.configs.recommended, + stylisticPlugin.configs['recommended-flat'], +); + +// wrapped in a function so they aren't executed at lint time +function _otherCases() { + // these are just tests for the types and are not seen by eslint so they can be whatever + tseslint.config({ + plugins: { + ['@stylistic']: stylisticPlugin, + ['@typescript-eslint']: tseslint.plugin, + ['deprecation']: deprecationPlugin, + ['jest']: jestPlugin, + }, + }); + tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + stylisticPlugin.configs['recommended-flat'], + jestPlugin.configs['flat/recommended'], + ); + tseslint.config( + // @ts-expect-error + compat.config(deprecationPlugin.configs.recommended), + ...compat.config(jestPlugin.configs.recommended), + ); + tseslint.config( + // @ts-expect-error + deprecationPlugin.configs.recommended, + // this should error but doesn't because there are no types exported from the jest plugin + jestPlugin.configs.recommended, + // this should error but doesn't because there are no types exported from the jest plugin + ...jestPlugin.configs['flat/recommended'], + ); +} diff --git a/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/package.json b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/package.json new file mode 100644 index 000000000000..0febead2e66c --- /dev/null +++ b/packages/integration-tests/fixtures/flat-config-types-@types__eslint-v9/package.json @@ -0,0 +1,14 @@ +{ + "type": "module", + "devDependencies": { + "@types/eslint__eslintrc": "latest", + "@eslint/eslintrc": "latest", + "@types/eslint__js": "latest", + "@eslint/js": "latest", + "@types/eslint": "^9", + "eslint": "latest", + "@stylistic/eslint-plugin": "latest", + "eslint-plugin-deprecation": "latest", + "eslint-plugin-jest": "latest" + } +} diff --git a/packages/integration-tests/tests/__snapshots__/flat-config-types.test.ts.snap b/packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v8.test.ts.snap similarity index 97% rename from packages/integration-tests/tests/__snapshots__/flat-config-types.test.ts.snap rename to packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v8.test.ts.snap index e6313ebeb826..f21cd613edf1 100644 --- a/packages/integration-tests/tests/__snapshots__/flat-config-types.test.ts.snap +++ b/packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v8.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`flat-config-types eslint should work successfully 1`] = ` +exports[`flat-config-types-@types__eslint-v8 eslint should work successfully 1`] = ` [ { "errorCount": 3, diff --git a/packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v9.test.ts.snap b/packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v9.test.ts.snap new file mode 100644 index 000000000000..a30dfb850fd9 --- /dev/null +++ b/packages/integration-tests/tests/__snapshots__/flat-config-types-@types__eslint-v9.test.ts.snap @@ -0,0 +1,119 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`flat-config-types-@types__eslint-v9 eslint should work successfully 1`] = ` +[ + { + "errorCount": 3, + "fatalErrorCount": 0, + "filePath": "/eslint.config.js", + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "messages": [ + { + "column": 10, + "endColumn": 21, + "endLine": 38, + "line": 38, + "message": "'_otherCases' is defined but never used.", + "messageId": "unusedVar", + "nodeType": null, + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + }, + { + "column": 5, + "endColumn": 24, + "endLine": 55, + "line": 55, + "message": "Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer.", + "messageId": "tsDirectiveCommentRequiresDescription", + "nodeType": "Line", + "ruleId": "@typescript-eslint/ban-ts-comment", + "severity": 2, + }, + { + "column": 5, + "endColumn": 24, + "endLine": 60, + "line": 60, + "message": "Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer.", + "messageId": "tsDirectiveCommentRequiresDescription", + "nodeType": "Line", + "ruleId": "@typescript-eslint/ban-ts-comment", + "severity": 2, + }, + ], + "output": "// @ts-check + +import { FlatCompat } from '@eslint/eslintrc' +import eslint from '@eslint/js' +import stylisticPlugin from '@stylistic/eslint-plugin' +import deprecationPlugin from 'eslint-plugin-deprecation' +import jestPlugin from 'eslint-plugin-jest' +import tseslint from 'typescript-eslint' + +import __dirname from './dirname.cjs' + +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: {}, + allConfig: {}, +}) + +// this config is run through eslint as part of the integration test +// so it needs to be a correct config +export default tseslint.config( + { + // config with just ignores is the replacement for \`.eslintignore\` + ignores: ['**/build/**', '**/dist/**', 'src/some/file/to/ignore.ts'], + }, + { + plugins: { + ['@typescript-eslint']: tseslint.plugin, + ['deprecation']: deprecationPlugin, + ['jest']: jestPlugin, + }, + }, + eslint.configs.recommended, + ...tseslint.configs.recommended, + stylisticPlugin.configs['recommended-flat'], +) + +// wrapped in a function so they aren't executed at lint time +function _otherCases() { + // these are just tests for the types and are not seen by eslint so they can be whatever + tseslint.config({ + plugins: { + ['@stylistic']: stylisticPlugin, + ['@typescript-eslint']: tseslint.plugin, + ['deprecation']: deprecationPlugin, + ['jest']: jestPlugin, + }, + }) + tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + stylisticPlugin.configs['recommended-flat'], + jestPlugin.configs['flat/recommended'], + ) + tseslint.config( + // @ts-expect-error + compat.config(deprecationPlugin.configs.recommended), + ...compat.config(jestPlugin.configs.recommended), + ) + tseslint.config( + // @ts-expect-error + deprecationPlugin.configs.recommended, + // this should error but doesn't because there are no types exported from the jest plugin + jestPlugin.configs.recommended, + // this should error but doesn't because there are no types exported from the jest plugin + ...jestPlugin.configs['flat/recommended'], + ) +} +", + "suppressedMessages": [], + "usedDeprecatedRules": [], + "warningCount": 0, + }, +] +`; diff --git a/packages/integration-tests/tests/flat-config-types.test.ts b/packages/integration-tests/tests/flat-config-types-@types__eslint-v8.test.ts similarity index 100% rename from packages/integration-tests/tests/flat-config-types.test.ts rename to packages/integration-tests/tests/flat-config-types-@types__eslint-v8.test.ts diff --git a/packages/integration-tests/tests/flat-config-types-@types__eslint-v9.test.ts b/packages/integration-tests/tests/flat-config-types-@types__eslint-v9.test.ts new file mode 100644 index 000000000000..7d5faa5e6816 --- /dev/null +++ b/packages/integration-tests/tests/flat-config-types-@types__eslint-v9.test.ts @@ -0,0 +1,31 @@ +import { + eslintIntegrationTest, + typescriptIntegrationTest, +} from '../tools/integration-test-base'; + +for (const additionalFlags of [ + [], + ['--strictNullChecks'], + ['--strictNullChecks', '--exactOptionalPropertyTypes'], +]) { + typescriptIntegrationTest( + `typescript${additionalFlags.length ? ` with ${additionalFlags.join(', ')}` : ''}`, + __filename, + ['--allowJs', '--esModuleInterop', ...additionalFlags, 'eslint.config.js'], + out => { + const lines = out.split('\n').filter( + line => + line && + // error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher. + // this is fine for us to ignore in this context + !line.includes('error TS18028') && + // currently expected errors from @stylistic/eslint-plugin as it doesn't support ESLint v9 types yet + !line.startsWith('node_modules/@stylistic/eslint-plugin/'), + ); + + // The types should not error (e.g. https://github.com/eslint-stylistic/eslint-stylistic/issues/276) + expect(lines).toHaveLength(0); + }, + ); +} +eslintIntegrationTest(__filename, 'eslint.config.js', true);