diff --git a/packages/eslint-plugin-internal/tests/rules/no-relative-paths-to-internal-packages.test.ts b/packages/eslint-plugin-internal/tests/rules/no-relative-paths-to-internal-packages.test.ts index 0f48ae9a2c45..3f29b69e50e0 100644 --- a/packages/eslint-plugin-internal/tests/rules/no-relative-paths-to-internal-packages.test.ts +++ b/packages/eslint-plugin-internal/tests/rules/no-relative-paths-to-internal-packages.test.ts @@ -5,7 +5,13 @@ import rule, { PACKAGES_DIR, } from '../../src/rules/no-relative-paths-to-internal-packages'; -const ruleTester = new RuleTester(); +const ruleTester = new RuleTester({ + languageOptions: { + parserOptions: { + tsconfigRootDir: PACKAGES_DIR, + }, + }, +}); ruleTester.run('no-relative-paths-to-internal-packages', rule, { valid: [ diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 4d876425df5b..239e8c1c3cf4 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -80,7 +80,6 @@ "cross-env": "^7.0.3", "cross-fetch": "*", "eslint": "*", - "espree": "^10.0.1", "jest": "29.7.0", "jest-specific-snapshot": "^8.0.0", "json-schema": "*", diff --git a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts index be7cd2ac7730..c1e0f29bbb31 100644 --- a/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts +++ b/packages/eslint-plugin/tests/rules/no-use-before-define.test.ts @@ -722,30 +722,6 @@ function a() {} }, { code: ` -'use strict'; -a(); -{ - function a() {} -} - `, - languageOptions: { - // eslint-disable-next-line @typescript-eslint/no-require-imports - parser: require('espree'), - parserOptions: { - ecmaVersion: 6, - sourceType: 'script', - }, - }, - errors: [ - { - messageId: 'noUseBeforeDefine', - data: { name: 'a' }, - type: AST_NODE_TYPES.Identifier, - }, - ], - }, - { - code: ` a(); try { throw new Error(); diff --git a/packages/rule-tester/src/RuleTester.ts b/packages/rule-tester/src/RuleTester.ts index 07c95b83c23e..ab429606bc8b 100644 --- a/packages/rule-tester/src/RuleTester.ts +++ b/packages/rule-tester/src/RuleTester.ts @@ -167,7 +167,7 @@ function getUnsubstitutedMessagePlaceholders( export class RuleTester extends TestFramework { readonly #testerConfig: TesterConfigWithDefaults; readonly #rules: Record = {}; - readonly #linter: Linter = new Linter({ configType: 'flat' }); + readonly #linter: Linter; /** * Creates a new instance of RuleTester. @@ -183,6 +183,11 @@ export class RuleTester extends TestFramework { rules: { [`${RULE_TESTER_PLUGIN_PREFIX}validate-ast`]: 'error' }, }); + this.#linter = new Linter({ + configType: 'flat', + cwd: this.#testerConfig.languageOptions.parserOptions?.tsconfigRootDir, + }); + // make sure that the parser doesn't hold onto file handles between tests // on linux (i.e. our CI env), there can be very a limited number of watch handles available const constructor = this.constructor as typeof RuleTester; @@ -282,14 +287,19 @@ export class RuleTester extends TestFramework { Hugely helps with the string-based valid test cases as it means they don't need to be made objects! */ - const getFilename = (testOptions?: ParserOptions): string => { + const getFilename = ( + originalFilename: string | undefined, + testOptions: ParserOptions | undefined, + ): string => { const resolvedOptions = deepMerge( this.#testerConfig.languageOptions.parserOptions, testOptions, ) as ParserOptions; - const filename = resolvedOptions.ecmaFeatures?.jsx - ? this.#testerConfig.defaultFilenames.tsx - : this.#testerConfig.defaultFilenames.ts; + const filename = + originalFilename ?? + (resolvedOptions.ecmaFeatures?.jsx + ? this.#testerConfig.defaultFilenames.tsx + : this.#testerConfig.defaultFilenames.ts); if (resolvedOptions.project) { return path.join( resolvedOptions.tsconfigRootDir ?? process.cwd(), @@ -309,22 +319,19 @@ export class RuleTester extends TestFramework { if (languageOptions.parser === parser) { throw new Error(DUPLICATE_PARSER_ERROR_MESSAGE); } - if (!test.filename) { - return { - ...test, - filename: getFilename(languageOptions.parserOptions), - languageOptions: { - ...languageOptions, - parserOptions: { - // Re-running simulates --fix mode, which implies an isolated program - // (i.e. parseAndGenerateServicesCalls[test.filename] > 1). - disallowAutomaticSingleRunInference: true, - ...languageOptions.parserOptions, - }, + return { + ...test, + filename: getFilename(test.filename, languageOptions.parserOptions), + languageOptions: { + ...languageOptions, + parserOptions: { + // Re-running simulates --fix mode, which implies an isolated program + // (i.e. parseAndGenerateServicesCalls[test.filename] > 1). + disallowAutomaticSingleRunInference: true, + ...languageOptions.parserOptions, }, - }; - } - return test; + }, + }; }; const normalizedTests = { @@ -707,16 +714,7 @@ export class RuleTester extends TestFramework { }, }, }); - messages = this.#linter.verify( - code, - // ESLint uses an internal FlatConfigArray that extends @humanwhocodes/config-array. - // Linter uses a typeof getConfig === "function" check. - // We mock out that check here to force it not to use Linter's cwd as basePath. - Object.assign([], { - getConfig: () => actualConfig, - }), - filename, - ); + messages = this.#linter.verify(code, actualConfig, filename); } finally { SourceCode.prototype.applyInlineConfig = applyInlineConfig; SourceCode.prototype.applyLanguageOptions = applyLanguageOptions; @@ -917,6 +915,7 @@ export class RuleTester extends TestFramework { const hasMessageOfThisRule = messages.some(m => m.ruleId === ruleName); + // console.log({ messages }); for (let i = 0, l = item.errors.length; i < l; i++) { const error = item.errors[i]; const message = messages[i]; diff --git a/yarn.lock b/yarn.lock index 2cb664a08646..a0d80f9b5b44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5640,7 +5640,6 @@ __metadata: cross-env: ^7.0.3 cross-fetch: "*" eslint: "*" - espree: ^10.0.1 graphemer: ^1.4.0 ignore: ^5.3.1 jest: 29.7.0