Skip to content

Commit 571a880

Browse files
authored
feat: allow subclasses to extend processAsync and getCacheKeyAsync (#3047)
1 parent f51cd62 commit 571a880

File tree

7 files changed

+84
-88
lines changed

7 files changed

+84
-88
lines changed

e2e/__tests__/enum.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import { extractSortedSummary } from '../utils'
33

44
const DIR = 'enum'
55

6-
test('partial successfully runs the tests inside `enum/` with `isolatedModules: true`', () => {
6+
test('partial successfully runs the tests inside `enum/` with `isolatedModules: false`', () => {
77
const result = runJest(DIR)
88

99
expect(extractSortedSummary(result.stderr).rest).toMatchSnapshot()
1010
})
1111

12-
test('partial successfully runs the tests inside `enum/` with `isolatedModules: false`', () => {
12+
test('partial successfully runs the tests inside `enum/` with `isolatedModules: true`', () => {
1313
const result = runJest(DIR, ['-c=jest-isolated.config.js'])
1414

1515
expect(extractSortedSummary(result.stderr).rest).toMatchSnapshot()

e2e/__tests__/extend-ts-jest.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { json as runWithJson, onNodeVersions } from '../run-jest'
2+
3+
const DIR = 'extend-ts-jest'
4+
5+
// Only need to test in ESM because ESM makes `this` context become `undefined`
6+
onNodeVersions('>=12.16.0', () => {
7+
test(`successfully runs the tests inside ${DIR}`, () => {
8+
const { json } = runWithJson(DIR, undefined, {
9+
nodeOptions: '--experimental-vm-modules --no-warnings',
10+
})
11+
12+
expect(json.success).toBe(true)
13+
expect(json.numTotalTestSuites).toBe(1)
14+
})
15+
})
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
test('should pass', () => {
2+
expect(true).toBe(true)
3+
})

e2e/extend-ts-jest/foo-transformer.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const tsJestTransformer = require('../../dist/ts-jest-transformer')
2+
3+
class FooTransformer extends tsJestTransformer.TsJestTransformer {
4+
async processAsync(sourceText, sourcePath, transformOptions) {
5+
return new Promise((resolve) => resolve(this.process(sourceText, sourcePath, transformOptions)))
6+
}
7+
}
8+
module.exports = {
9+
createTransformer: () => new FooTransformer(),
10+
}

e2e/extend-ts-jest/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"jest": {
3+
"globals": {
4+
"ts-jest": {
5+
"isolatedModules": true
6+
}
7+
},
8+
"transform": {
9+
"^.+\\.tsx?$": "./foo-transformer.js"
10+
}
11+
}
12+
}

src/ts-jest-transformer.spec.ts

Lines changed: 24 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
import fs from 'fs'
2-
import { join } from 'path'
2+
import path from 'path'
33

4-
import { Logger, LogLevels } from 'bs-logger'
4+
import { LogLevels } from 'bs-logger'
55
import { removeSync, writeFileSync } from 'fs-extra'
66

77
import { createConfigSet } from './__helpers__/fakers'
88
import { logTargetMock } from './__helpers__/mocks'
99
import { SOURCE_MAPPING_PREFIX } from './compiler/compiler-utils'
10-
import { TsCompiler } from './compiler/ts-compiler'
1110
import { TsJestCompiler } from './compiler/ts-jest-compiler'
12-
import { ConfigSet } from './config/config-set'
1311
import { CACHE_KEY_EL_SEPARATOR, TsJestTransformer } from './ts-jest-transformer'
14-
import type { DepGraphInfo, ProjectConfigTsJest, StringMap } from './types'
12+
import type { DepGraphInfo } from './types'
1513
import { stringify } from './utils/json'
1614
import { sha1 } from './utils/sha1'
17-
import { VersionCheckers } from './utils/version-checkers'
1815

1916
const logTarget = logTargetMock()
20-
const cacheDir = join(process.cwd(), 'tmp')
17+
const cacheDir = path.join(process.cwd(), 'tmp')
18+
const baseTransformOptions = {
19+
config: {
20+
testMatch: [],
21+
testRegex: [],
22+
extensionsToTreatAsEsm: [],
23+
},
24+
cacheFS: new Map(),
25+
} as any // eslint-disable-line @typescript-eslint/no-explicit-any
2126

2227
beforeEach(() => {
2328
logTarget.clear()
@@ -36,16 +41,16 @@ describe('TsJestTransformer', () => {
3641

3742
// @ts-expect-error testing purpose
3843
expect(Object.keys(TsJestTransformer._cachedConfigSets[0])).toMatchInlineSnapshot(`
39-
Array [
40-
"jestConfig",
41-
"configSet",
42-
"transformerCfgStr",
43-
"compiler",
44-
"depGraphs",
45-
"tsResolvedModulesCachePath",
46-
"watchMode",
47-
]
48-
`)
44+
Array [
45+
"jestConfig",
46+
"configSet",
47+
"transformerCfgStr",
48+
"compiler",
49+
"depGraphs",
50+
"tsResolvedModulesCachePath",
51+
"watchMode",
52+
]
53+
`)
4954
})
5055

5156
test(
@@ -124,7 +129,7 @@ Array [
124129
fileContent: 'const foo = 1',
125130
resolvedModuleNames: [],
126131
})
127-
const resolvedModulesCacheDir = join(tsCacheDir, sha1('ts-jest-resolved-modules', CACHE_KEY_EL_SEPARATOR))
132+
const resolvedModulesCacheDir = path.join(tsCacheDir, sha1('ts-jest-resolved-modules', CACHE_KEY_EL_SEPARATOR))
128133
fs.mkdirSync(tsCacheDir, { recursive: true })
129134
writeFileSync(resolvedModulesCacheDir, stringify([...depGraphs]))
130135

@@ -262,7 +267,7 @@ Array [
262267
test('should be different with non existed imported modules', () => {
263268
jest
264269
.spyOn(TsJestCompiler.prototype, 'getResolvedModules')
265-
.mockReturnValueOnce([join(process.cwd(), 'src', '__mocks__', 'thing.ts')])
270+
.mockReturnValueOnce([path.join(process.cwd(), 'src', '__mocks__', 'thing.ts')])
266271

267272
const cacheKey1 = tr.getCacheKey(input.fileContent, input.fileName, transformOptionsWithCache)
268273

@@ -280,14 +285,6 @@ Array [
280285
})
281286

282287
describe('process', () => {
283-
const baseTransformOptions = {
284-
config: {
285-
testMatch: [],
286-
testRegex: [],
287-
extensionsToTreatAsEsm: [],
288-
},
289-
cacheFS: new Map(),
290-
} as any // eslint-disable-line @typescript-eslint/no-explicit-any
291288
let tr!: TsJestTransformer
292289

293290
beforeEach(() => {
@@ -435,63 +432,4 @@ Array [
435432
}
436433
})
437434
})
438-
439-
describe('subclass extends TsJestTransformer', () => {
440-
class MyTsCompiler extends TsCompiler {
441-
constructor(readonly configSet: ConfigSet, readonly runtimeCacheFS: StringMap) {
442-
super(configSet, runtimeCacheFS)
443-
}
444-
}
445-
446-
class MyConfigSet extends ConfigSet {
447-
constructor(readonly jestConfig: ProjectConfigTsJest, readonly parentLogger?: Logger) {
448-
super(jestConfig, parentLogger)
449-
}
450-
}
451-
452-
class MyTransformer extends TsJestTransformer {
453-
protected _createCompiler(configSet: ConfigSet, cacheFS: StringMap): void {
454-
this._compiler = new MyTsCompiler(configSet, cacheFS)
455-
}
456-
457-
// eslint-disable-next-line class-methods-use-this
458-
protected _createConfigSet(config: ProjectConfigTsJest): MyConfigSet {
459-
return new MyConfigSet(config)
460-
}
461-
}
462-
let tr: MyTransformer
463-
464-
beforeEach(() => {
465-
tr = new MyTransformer()
466-
})
467-
468-
test('should have jest version checking', () => {
469-
VersionCheckers.jest.warn = jest.fn()
470-
471-
new MyTransformer()
472-
473-
expect(VersionCheckers.jest.warn).toHaveBeenCalled()
474-
})
475-
476-
test('should create MyTsCompiler instance', () => {
477-
// @ts-expect-error testing purpose
478-
tr._createCompiler(createConfigSet(), new Map())
479-
480-
// @ts-expect-error testing purpose
481-
expect(tr._compiler).toBeInstanceOf(MyTsCompiler)
482-
})
483-
484-
test('should create MyConfigSet instance', () => {
485-
expect(
486-
// @ts-expect-error testing purpose
487-
tr._createConfigSet({
488-
cwd: process.cwd(),
489-
extensionsToTreatAsEsm: [],
490-
globals: Object.create(null),
491-
testMatch: [],
492-
testRegex: [],
493-
}),
494-
).toBeInstanceOf(MyConfigSet)
495-
})
496-
})
497435
})

src/ts-jest-transformer.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@ export class TsJestTransformer implements SyncTransformer {
5353
* when running Jest in ESM mode
5454
*/
5555
this.getCacheKey = this.getCacheKey.bind(this)
56+
this.getCacheKeyAsync = this.getCacheKeyAsync.bind(this)
5657
this.process = this.process.bind(this)
58+
this.processAsync = this.processAsync.bind(this)
5759

5860
this._logger.debug('created new transformer')
5961
process.env.TS_JEST = '1'
@@ -183,6 +185,14 @@ export class TsJestTransformer implements SyncTransformer {
183185
return result
184186
}
185187

188+
async processAsync(
189+
sourceText: string,
190+
sourcePath: Config.Path,
191+
transformOptions: TransformOptionsTsJest,
192+
): Promise<TransformedSource | string> {
193+
return new Promise((resolve) => resolve(this.process(sourceText, sourcePath, transformOptions)))
194+
}
195+
186196
/**
187197
* Jest uses this to cache the compiled version of a file
188198
*
@@ -248,6 +258,14 @@ export class TsJestTransformer implements SyncTransformer {
248258
return sha1(...constructingCacheKeyElements)
249259
}
250260

261+
async getCacheKeyAsync(
262+
sourceText: string,
263+
sourcePath: string,
264+
transformOptions: TransformOptionsTsJest,
265+
): Promise<string> {
266+
return new Promise((resolve) => resolve(this.getCacheKey(sourceText, sourcePath, transformOptions)))
267+
}
268+
251269
/**
252270
* Subclasses extends `TsJestTransformer` can call this method to get resolved module disk cache
253271
*/

0 commit comments

Comments
 (0)