diff --git a/e2e/__tests__/enum.test.ts b/e2e/__tests__/enum.test.ts index e95098f520..1864660690 100644 --- a/e2e/__tests__/enum.test.ts +++ b/e2e/__tests__/enum.test.ts @@ -3,13 +3,13 @@ import { extractSortedSummary } from '../utils' const DIR = 'enum' -test('partial successfully runs the tests inside `enum/` with `isolatedModules: true`', () => { +test('partial successfully runs the tests inside `enum/` with `isolatedModules: false`', () => { const result = runJest(DIR) expect(extractSortedSummary(result.stderr).rest).toMatchSnapshot() }) -test('partial successfully runs the tests inside `enum/` with `isolatedModules: false`', () => { +test('partial successfully runs the tests inside `enum/` with `isolatedModules: true`', () => { const result = runJest(DIR, ['-c=jest-isolated.config.js']) expect(extractSortedSummary(result.stderr).rest).toMatchSnapshot() diff --git a/e2e/__tests__/extend-ts-jest.test.ts b/e2e/__tests__/extend-ts-jest.test.ts new file mode 100644 index 0000000000..4120cebedd --- /dev/null +++ b/e2e/__tests__/extend-ts-jest.test.ts @@ -0,0 +1,15 @@ +import { json as runWithJson, onNodeVersions } from '../run-jest' + +const DIR = 'extend-ts-jest' + +// Only need to test in ESM because ESM makes `this` context become `undefined` +onNodeVersions('>=12.16.0', () => { + test(`successfully runs the tests inside ${DIR}`, () => { + const { json } = runWithJson(DIR, undefined, { + nodeOptions: '--experimental-vm-modules --no-warnings', + }) + + expect(json.success).toBe(true) + expect(json.numTotalTestSuites).toBe(1) + }) +}) diff --git a/e2e/extend-ts-jest/__tests__/foo.spec.ts b/e2e/extend-ts-jest/__tests__/foo.spec.ts new file mode 100644 index 0000000000..a257a9661e --- /dev/null +++ b/e2e/extend-ts-jest/__tests__/foo.spec.ts @@ -0,0 +1,3 @@ +test('should pass', () => { + expect(true).toBe(true) +}) diff --git a/e2e/extend-ts-jest/foo-transformer.js b/e2e/extend-ts-jest/foo-transformer.js new file mode 100644 index 0000000000..ae714ded38 --- /dev/null +++ b/e2e/extend-ts-jest/foo-transformer.js @@ -0,0 +1,10 @@ +const tsJestTransformer = require('../../dist/ts-jest-transformer') + +class FooTransformer extends tsJestTransformer.TsJestTransformer { + async processAsync(sourceText, sourcePath, transformOptions) { + return new Promise((resolve) => resolve(this.process(sourceText, sourcePath, transformOptions))) + } +} +module.exports = { + createTransformer: () => new FooTransformer(), +} diff --git a/e2e/extend-ts-jest/package.json b/e2e/extend-ts-jest/package.json new file mode 100644 index 0000000000..cf79ee3561 --- /dev/null +++ b/e2e/extend-ts-jest/package.json @@ -0,0 +1,12 @@ +{ + "jest": { + "globals": { + "ts-jest": { + "isolatedModules": true + } + }, + "transform": { + "^.+\\.tsx?$": "./foo-transformer.js" + } + } +} diff --git a/src/ts-jest-transformer.spec.ts b/src/ts-jest-transformer.spec.ts index f67c1534db..d7ddd51694 100644 --- a/src/ts-jest-transformer.spec.ts +++ b/src/ts-jest-transformer.spec.ts @@ -1,23 +1,28 @@ import fs from 'fs' -import { join } from 'path' +import path from 'path' -import { Logger, LogLevels } from 'bs-logger' +import { LogLevels } from 'bs-logger' import { removeSync, writeFileSync } from 'fs-extra' import { createConfigSet } from './__helpers__/fakers' import { logTargetMock } from './__helpers__/mocks' import { SOURCE_MAPPING_PREFIX } from './compiler/compiler-utils' -import { TsCompiler } from './compiler/ts-compiler' import { TsJestCompiler } from './compiler/ts-jest-compiler' -import { ConfigSet } from './config/config-set' import { CACHE_KEY_EL_SEPARATOR, TsJestTransformer } from './ts-jest-transformer' -import type { DepGraphInfo, ProjectConfigTsJest, StringMap } from './types' +import type { DepGraphInfo } from './types' import { stringify } from './utils/json' import { sha1 } from './utils/sha1' -import { VersionCheckers } from './utils/version-checkers' const logTarget = logTargetMock() -const cacheDir = join(process.cwd(), 'tmp') +const cacheDir = path.join(process.cwd(), 'tmp') +const baseTransformOptions = { + config: { + testMatch: [], + testRegex: [], + extensionsToTreatAsEsm: [], + }, + cacheFS: new Map(), +} as any // eslint-disable-line @typescript-eslint/no-explicit-any beforeEach(() => { logTarget.clear() @@ -36,16 +41,16 @@ describe('TsJestTransformer', () => { // @ts-expect-error testing purpose expect(Object.keys(TsJestTransformer._cachedConfigSets[0])).toMatchInlineSnapshot(` -Array [ - "jestConfig", - "configSet", - "transformerCfgStr", - "compiler", - "depGraphs", - "tsResolvedModulesCachePath", - "watchMode", -] -`) + Array [ + "jestConfig", + "configSet", + "transformerCfgStr", + "compiler", + "depGraphs", + "tsResolvedModulesCachePath", + "watchMode", + ] + `) }) test( @@ -124,7 +129,7 @@ Array [ fileContent: 'const foo = 1', resolvedModuleNames: [], }) - const resolvedModulesCacheDir = join(tsCacheDir, sha1('ts-jest-resolved-modules', CACHE_KEY_EL_SEPARATOR)) + const resolvedModulesCacheDir = path.join(tsCacheDir, sha1('ts-jest-resolved-modules', CACHE_KEY_EL_SEPARATOR)) fs.mkdirSync(tsCacheDir, { recursive: true }) writeFileSync(resolvedModulesCacheDir, stringify([...depGraphs])) @@ -262,7 +267,7 @@ Array [ test('should be different with non existed imported modules', () => { jest .spyOn(TsJestCompiler.prototype, 'getResolvedModules') - .mockReturnValueOnce([join(process.cwd(), 'src', '__mocks__', 'thing.ts')]) + .mockReturnValueOnce([path.join(process.cwd(), 'src', '__mocks__', 'thing.ts')]) const cacheKey1 = tr.getCacheKey(input.fileContent, input.fileName, transformOptionsWithCache) @@ -280,14 +285,6 @@ Array [ }) describe('process', () => { - const baseTransformOptions = { - config: { - testMatch: [], - testRegex: [], - extensionsToTreatAsEsm: [], - }, - cacheFS: new Map(), - } as any // eslint-disable-line @typescript-eslint/no-explicit-any let tr!: TsJestTransformer beforeEach(() => { @@ -435,63 +432,4 @@ Array [ } }) }) - - describe('subclass extends TsJestTransformer', () => { - class MyTsCompiler extends TsCompiler { - constructor(readonly configSet: ConfigSet, readonly runtimeCacheFS: StringMap) { - super(configSet, runtimeCacheFS) - } - } - - class MyConfigSet extends ConfigSet { - constructor(readonly jestConfig: ProjectConfigTsJest, readonly parentLogger?: Logger) { - super(jestConfig, parentLogger) - } - } - - class MyTransformer extends TsJestTransformer { - protected _createCompiler(configSet: ConfigSet, cacheFS: StringMap): void { - this._compiler = new MyTsCompiler(configSet, cacheFS) - } - - // eslint-disable-next-line class-methods-use-this - protected _createConfigSet(config: ProjectConfigTsJest): MyConfigSet { - return new MyConfigSet(config) - } - } - let tr: MyTransformer - - beforeEach(() => { - tr = new MyTransformer() - }) - - test('should have jest version checking', () => { - VersionCheckers.jest.warn = jest.fn() - - new MyTransformer() - - expect(VersionCheckers.jest.warn).toHaveBeenCalled() - }) - - test('should create MyTsCompiler instance', () => { - // @ts-expect-error testing purpose - tr._createCompiler(createConfigSet(), new Map()) - - // @ts-expect-error testing purpose - expect(tr._compiler).toBeInstanceOf(MyTsCompiler) - }) - - test('should create MyConfigSet instance', () => { - expect( - // @ts-expect-error testing purpose - tr._createConfigSet({ - cwd: process.cwd(), - extensionsToTreatAsEsm: [], - globals: Object.create(null), - testMatch: [], - testRegex: [], - }), - ).toBeInstanceOf(MyConfigSet) - }) - }) }) diff --git a/src/ts-jest-transformer.ts b/src/ts-jest-transformer.ts index fc625e8a71..4994d60d65 100644 --- a/src/ts-jest-transformer.ts +++ b/src/ts-jest-transformer.ts @@ -53,7 +53,9 @@ export class TsJestTransformer implements SyncTransformer { * when running Jest in ESM mode */ this.getCacheKey = this.getCacheKey.bind(this) + this.getCacheKeyAsync = this.getCacheKeyAsync.bind(this) this.process = this.process.bind(this) + this.processAsync = this.processAsync.bind(this) this._logger.debug('created new transformer') process.env.TS_JEST = '1' @@ -183,6 +185,14 @@ export class TsJestTransformer implements SyncTransformer { return result } + async processAsync( + sourceText: string, + sourcePath: Config.Path, + transformOptions: TransformOptionsTsJest, + ): Promise { + return new Promise((resolve) => resolve(this.process(sourceText, sourcePath, transformOptions))) + } + /** * Jest uses this to cache the compiled version of a file * @@ -248,6 +258,14 @@ export class TsJestTransformer implements SyncTransformer { return sha1(...constructingCacheKeyElements) } + async getCacheKeyAsync( + sourceText: string, + sourcePath: string, + transformOptions: TransformOptionsTsJest, + ): Promise { + return new Promise((resolve) => resolve(this.getCacheKey(sourceText, sourcePath, transformOptions))) + } + /** * Subclasses extends `TsJestTransformer` can call this method to get resolved module disk cache */