diff --git a/src/__mocks__/thing.ts b/src/__mocks__/thing.ts index 1d4cc258f1..1606338dcd 100644 --- a/src/__mocks__/thing.ts +++ b/src/__mocks__/thing.ts @@ -1,3 +1,5 @@ +// @ts-expect-error testing purpose +import babelFooCfg from './babel-foo.config' import { getFoo } from './thing1' import { getFooBar } from './thing1' import { getBar } from './thing2' @@ -5,3 +7,4 @@ import { getBar } from './thing2' getFoo('foo') getBar('bar') getFooBar('foobar') +getFoo(JSON.stringify(babelFooCfg.presets)) diff --git a/src/compiler/__snapshots__/ts-compiler.spec.ts.snap b/src/compiler/__snapshots__/ts-compiler.spec.ts.snap index 6ed799cb5b..828025107b 100644 --- a/src/compiler/__snapshots__/ts-compiler.spec.ts.snap +++ b/src/compiler/__snapshots__/ts-compiler.spec.ts.snap @@ -36,12 +36,33 @@ const App = () => { `; exports[`TsCompiler isolatedModule false should compile codes with useESM true 1`] = ` -"import { getFoo } from './thing1'; +"// @ts-expect-error testing purpose +import babelFooCfg from './babel-foo.config'; +import { getFoo } from './thing1'; import { getFooBar } from './thing1'; import { getBar } from './thing2'; getFoo('foo'); getBar('bar'); getFooBar('foobar'); +getFoo(JSON.stringify(babelFooCfg.presets)); +//# " +`; + +exports[`TsCompiler isolatedModule false should compile ts file which has an existing js file 1`] = ` +"\\"use strict\\"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { \\"default\\": mod }; +}; +Object.defineProperty(exports, \\"__esModule\\", { value: true }); +// @ts-expect-error testing purpose +const babel_foo_config_1 = __importDefault(require(\\"./babel-foo.config\\")); +const thing1_1 = require(\\"./thing1\\"); +const thing1_2 = require(\\"./thing1\\"); +const thing2_1 = require(\\"./thing2\\"); +thing1_1.getFoo('foo'); +thing2_1.getBar('bar'); +thing1_2.getFooBar('foobar'); +thing1_1.getFoo(JSON.stringify(babel_foo_config_1.default.presets)); //# " `; @@ -73,11 +94,14 @@ exports.default = 42; `; exports[`TsCompiler isolatedModule true should transpile code with useESM true 1`] = ` -"import { getFoo } from './thing1'; +"// @ts-expect-error testing purpose +import babelFooCfg from './babel-foo.config'; +import { getFoo } from './thing1'; import { getFooBar } from './thing1'; import { getBar } from './thing2'; getFoo('foo'); getBar('bar'); getFooBar('foobar'); +getFoo(JSON.stringify(babelFooCfg.presets)); //# " `; diff --git a/src/compiler/ts-compiler.spec.ts b/src/compiler/ts-compiler.spec.ts index 2a833fb3b4..170a3d885b 100644 --- a/src/compiler/ts-compiler.spec.ts +++ b/src/compiler/ts-compiler.spec.ts @@ -1,11 +1,13 @@ import { readFileSync } from 'fs' import { join, normalize } from 'path' -import { makeCompiler } from '../__helpers__/fakers' +import { createConfigSet, makeCompiler } from '../__helpers__/fakers' import { logTargetMock } from '../__helpers__/mocks' import { mockFolder } from '../__helpers__/path' import ProcessedSource from '../__helpers__/processed-source' +import { TsCompiler } from './ts-compiler' + const logTarget = logTargetMock() describe('TsCompiler', () => { @@ -236,6 +238,20 @@ const t: string = f(5) expect(compiler._initialCompilerOptions.allowSyntheticDefaultImports).not.toEqual(true) }) + test('should compile ts file which has an existing js file', () => { + const configSet = createConfigSet({ + tsJestConfig: baseTsJestConfig, + }) + const fileName = join(mockFolder, 'thing.ts') + const fileContent = readFileSync(fileName, 'utf-8') + configSet.parsedTsConfig.fileNames.push(...[fileName.replace('.ts', '.js'), fileName]) + const compiler = new TsCompiler(configSet, new Map()) + + const compiledOutput = compiler.getCompiledOutput(fileContent, fileName, false) + + expect(new ProcessedSource(compiledOutput, fileName).outputCodeWithoutMaps).toMatchSnapshot() + }) + describe('allowJs option', () => { const fileName = 'test-allow-js.js' const source = 'export default 42' @@ -407,6 +423,7 @@ const t: string = f(5) const jestCacheFS = new Map() const importedModule1 = join(mockFolder, 'thing1.ts') const importedModule2 = join(mockFolder, 'thing2.ts') + const importedModule3 = join(mockFolder, 'babel-foo.config.js') const fileContentWithModules = readFileSync(fileName, 'utf-8') jestCacheFS.set(importedModule1, readFileSync(importedModule1, 'utf-8')) const compiler = makeCompiler( @@ -420,7 +437,7 @@ const t: string = f(5) compiler .getResolvedModules(fileContentWithModules, fileName, new Map()) .map((resolvedFileName) => normalize(resolvedFileName)), - ).toEqual([importedModule1, importedModule2]) + ).toEqual([importedModule3, importedModule1, importedModule2]) }) }) diff --git a/src/compiler/ts-compiler.ts b/src/compiler/ts-compiler.ts index 87dc043a3f..b252beede4 100644 --- a/src/compiler/ts-compiler.ts +++ b/src/compiler/ts-compiler.ts @@ -21,8 +21,8 @@ import type { ResolvedModuleWithFailedLookupLocations, } from 'typescript' -import { ConfigSet, TS_JEST_OUT_DIR } from '../config/config-set' -import { LINE_FEED } from '../constants' +import type { ConfigSet } from '../config/config-set' +import { LINE_FEED, TS_TSX_REGEX } from '../constants' import type { StringMap, TsCompilerInstance, TsJestAstTransformer, TTypeScript } from '../types' import { rootLogger } from '../utils/logger' import { Errors, interpolate } from '../utils/messages' @@ -116,12 +116,7 @@ export class TsCompiler implements TsCompilerInstance { private _createLanguageService(): void { // Initialize memory cache for typescript compiler this._parsedTsConfig.fileNames - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - .filter( - (fileName) => - !this.configSet.isTestFile(fileName) && - !fileName.includes(this._parsedTsConfig.options.outDir ?? TS_JEST_OUT_DIR), - ) + .filter((fileName) => TS_TSX_REGEX.test(fileName) && !this.configSet.isTestFile(fileName)) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion .forEach((fileName) => this._fileVersionCache!.set(fileName, 0)) /* istanbul ignore next */