diff --git a/packages/typescript-estree/tests/lib/parse.moduleResolver.default-program-error.test.ts b/packages/typescript-estree/tests/lib/parse.moduleResolver.default-program-error.test.ts new file mode 100644 index 000000000000..25557a24ef51 --- /dev/null +++ b/packages/typescript-estree/tests/lib/parse.moduleResolver.default-program-error.test.ts @@ -0,0 +1,32 @@ +import * as parser from '../../src'; +import type { TSESTreeOptions } from '../../src/parser-options'; +import { createAndPrepareParseConfig } from '../../tools/test-utils'; + +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('parseAndGenerateServices', () => { + describe('moduleResolver', () => { + const { code, config } = createAndPrepareParseConfig(); + + const withDefaultProgramConfig: TSESTreeOptions = { + ...config, + project: './tsconfig.defaultProgram.json', + createDefaultProgram: true, + }; + + describe('when file is not in the project and createDefaultProgram=true', () => { + it('returns error because __PLACEHOLDER__ can not be resolved', () => { + expect( + parser + .parseAndGenerateServices(code, withDefaultProgramConfig) + .services.program.getSemanticDiagnostics(), + ).toHaveProperty( + [0, 'messageText'], + "Cannot find module '__PLACEHOLDER__' or its corresponding type declarations.", + ); + }); + }); + }); +}); diff --git a/packages/typescript-estree/tests/lib/parse.moduleResolver.default-program-success.test.ts b/packages/typescript-estree/tests/lib/parse.moduleResolver.default-program-success.test.ts new file mode 100644 index 000000000000..9bebf21de1ae --- /dev/null +++ b/packages/typescript-estree/tests/lib/parse.moduleResolver.default-program-success.test.ts @@ -0,0 +1,34 @@ +import { resolve } from 'path'; + +import * as parser from '../../src'; +import type { TSESTreeOptions } from '../../src/parser-options'; +import { createAndPrepareParseConfig } from '../../tools/test-utils'; + +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('parseAndGenerateServices', () => { + describe('moduleResolver', () => { + const { code, config, projectDirectory } = createAndPrepareParseConfig(); + + const withDefaultProgramConfig: TSESTreeOptions = { + ...config, + project: './tsconfig.defaultProgram.json', + createDefaultProgram: true, + }; + + describe('when file is not in the project and createDefaultProgram=true', () => { + it('resolves __PLACEHOLDER__ correctly', () => { + expect( + parser + .parseAndGenerateServices(code, { + ...withDefaultProgramConfig, + moduleResolver: resolve(projectDirectory, './moduleResolver.js'), + }) + .services.program.getSemanticDiagnostics(), + ).toHaveLength(0); + }); + }); + }); +}); diff --git a/packages/typescript-estree/tests/lib/parse.moduleResolver.placeholder-error.test.ts b/packages/typescript-estree/tests/lib/parse.moduleResolver.placeholder-error.test.ts new file mode 100644 index 000000000000..699c88f0f235 --- /dev/null +++ b/packages/typescript-estree/tests/lib/parse.moduleResolver.placeholder-error.test.ts @@ -0,0 +1,42 @@ +import { resolve } from 'path'; + +import * as parser from '../../src'; +import { createAndPrepareParseConfig } from '../../tools/test-utils'; + +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('parseAndGenerateServices', () => { + describe('moduleResolver', () => { + const { code, config, projectDirectory } = createAndPrepareParseConfig(); + + describe('when file is in the project', () => { + it('returns error if __PLACEHOLDER__ can not be resolved', () => { + expect( + parser + .parseAndGenerateServices(code, config) + .services.program.getSemanticDiagnostics(), + ).toHaveProperty( + [0, 'messageText'], + "Cannot find module '__PLACEHOLDER__' or its corresponding type declarations.", + ); + }); + + it('throws error if moduleResolver can not be found', () => { + expect(() => + parser.parseAndGenerateServices(code, { + ...config, + moduleResolver: resolve( + projectDirectory, + './this_moduleResolver_does_not_exist.js', + ), + }), + ).toThrowErrorMatchingInlineSnapshot(` + "Could not find the provided parserOptions.moduleResolver. + Hint: use an absolute path if you are not in control over where the ESLint instance runs." + `); + }); + }); + }); +}); diff --git a/packages/typescript-estree/tests/lib/parse.moduleResolver.placeholder-success.test.ts b/packages/typescript-estree/tests/lib/parse.moduleResolver.placeholder-success.test.ts new file mode 100644 index 000000000000..eebc01b9369a --- /dev/null +++ b/packages/typescript-estree/tests/lib/parse.moduleResolver.placeholder-success.test.ts @@ -0,0 +1,27 @@ +import { resolve } from 'path'; + +import * as parser from '../../src'; +import { createAndPrepareParseConfig } from '../../tools/test-utils'; + +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('parseAndGenerateServices', () => { + describe('moduleResolver', () => { + const { code, config, projectDirectory } = createAndPrepareParseConfig(); + + describe('when file is in the project', () => { + it('resolves __PLACEHOLDER__ correctly', () => { + expect( + parser + .parseAndGenerateServices(code, { + ...config, + moduleResolver: resolve(projectDirectory, './moduleResolver.js'), + }) + .services.program.getSemanticDiagnostics(), + ).toHaveLength(0); + }); + }); + }); +}); diff --git a/packages/typescript-estree/tests/lib/parse.test.ts b/packages/typescript-estree/tests/lib/parse.test.ts index 76e33bc8e0e0..3e84dd3e069f 100644 --- a/packages/typescript-estree/tests/lib/parse.test.ts +++ b/packages/typescript-estree/tests/lib/parse.test.ts @@ -753,94 +753,4 @@ describe('parseAndGenerateServices', () => { expect(testParse('includeme', ignore)).not.toThrow(); }); }); - - describe('moduleResolver', () => { - beforeEach(() => { - parser.clearCaches(); - }); - - const PROJECT_DIR = resolve(FIXTURES_DIR, '../moduleResolver'); - const code = ` - import { something } from '__PLACEHOLDER__'; - - something(); - `; - const config: TSESTreeOptions = { - comment: true, - tokens: true, - range: true, - loc: true, - project: './tsconfig.json', - tsconfigRootDir: PROJECT_DIR, - filePath: resolve(PROJECT_DIR, 'file.ts'), - }; - const withDefaultProgramConfig: TSESTreeOptions = { - ...config, - project: './tsconfig.defaultProgram.json', - createDefaultProgram: true, - }; - - describe('when file is in the project', () => { - it('returns error if __PLACEHOLDER__ can not be resolved', () => { - expect( - parser - .parseAndGenerateServices(code, config) - .services.program.getSemanticDiagnostics(), - ).toHaveProperty( - [0, 'messageText'], - "Cannot find module '__PLACEHOLDER__' or its corresponding type declarations.", - ); - }); - - it('throws error if moduleResolver can not be found', () => { - expect(() => - parser.parseAndGenerateServices(code, { - ...config, - moduleResolver: resolve( - PROJECT_DIR, - './this_moduleResolver_does_not_exist.js', - ), - }), - ).toThrowErrorMatchingInlineSnapshot(` - "Could not find the provided parserOptions.moduleResolver. - Hint: use an absolute path if you are not in control over where the ESLint instance runs." - `); - }); - - it('resolves __PLACEHOLDER__ correctly', () => { - expect( - parser - .parseAndGenerateServices(code, { - ...config, - moduleResolver: resolve(PROJECT_DIR, './moduleResolver.js'), - }) - .services.program.getSemanticDiagnostics(), - ).toHaveLength(0); - }); - }); - - describe('when file is not in the project and createDefaultProgram=true', () => { - it('returns error because __PLACEHOLDER__ can not be resolved', () => { - expect( - parser - .parseAndGenerateServices(code, withDefaultProgramConfig) - .services.program.getSemanticDiagnostics(), - ).toHaveProperty( - [0, 'messageText'], - "Cannot find module '__PLACEHOLDER__' or its corresponding type declarations.", - ); - }); - - it('resolves __PLACEHOLDER__ correctly', () => { - expect( - parser - .parseAndGenerateServices(code, { - ...withDefaultProgramConfig, - moduleResolver: resolve(PROJECT_DIR, './moduleResolver.js'), - }) - .services.program.getSemanticDiagnostics(), - ).toHaveLength(0); - }); - }); - }); }); diff --git a/packages/typescript-estree/tools/test-utils.ts b/packages/typescript-estree/tools/test-utils.ts index b3b873acc6a4..6f40b597ca73 100644 --- a/packages/typescript-estree/tools/test-utils.ts +++ b/packages/typescript-estree/tools/test-utils.ts @@ -1,9 +1,15 @@ +import { join, resolve } from 'path'; + import type { ParseAndGenerateServicesResult, TSESTree, TSESTreeOptions, } from '../src'; -import { parse as parserParse, parseAndGenerateServices } from '../src'; +import { + clearCaches, + parse as parserParse, + parseAndGenerateServices, +} from '../src'; export function parseCodeAndGenerateServices( code: string, @@ -153,3 +159,41 @@ export function omitDeep( return visit(root as UnknownObject, null); } + +interface CreateAndPrepareParseConfig { + code: string; + config: TSESTreeOptions; + projectDirectory: string; +} + +const FIXTURES_DIR = join(__dirname, '../tests/fixtures/simpleProject'); + +export function createAndPrepareParseConfig(): CreateAndPrepareParseConfig { + beforeEach(() => { + clearCaches(); + }); + + const projectDirectory = resolve(FIXTURES_DIR, '../moduleResolver'); + + const code = ` + import { something } from '__PLACEHOLDER__'; + + something(); + `; + + const config: TSESTreeOptions = { + comment: true, + filePath: resolve(projectDirectory, 'file.ts'), + loc: true, + project: './tsconfig.json', + range: true, + tokens: true, + tsconfigRootDir: projectDirectory, + }; + + return { + code, + config, + projectDirectory, + }; +}