Skip to content

Commit

Permalink
feat: allow subclasses to extend processAsync and getCacheKeyAsync (
Browse files Browse the repository at this point in the history
  • Loading branch information
ahnpnl authored Nov 9, 2021
1 parent f51cd62 commit 571a880
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 88 deletions.
4 changes: 2 additions & 2 deletions e2e/__tests__/enum.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
15 changes: 15 additions & 0 deletions e2e/__tests__/extend-ts-jest.test.ts
Original file line number Diff line number Diff line change
@@ -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)
})
})
3 changes: 3 additions & 0 deletions e2e/extend-ts-jest/__tests__/foo.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
test('should pass', () => {
expect(true).toBe(true)
})
10 changes: 10 additions & 0 deletions e2e/extend-ts-jest/foo-transformer.js
Original file line number Diff line number Diff line change
@@ -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(),
}
12 changes: 12 additions & 0 deletions e2e/extend-ts-jest/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"jest": {
"globals": {
"ts-jest": {
"isolatedModules": true
}
},
"transform": {
"^.+\\.tsx?$": "./foo-transformer.js"
}
}
}
110 changes: 24 additions & 86 deletions src/ts-jest-transformer.spec.ts
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -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(
Expand Down Expand Up @@ -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]))

Expand Down Expand Up @@ -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)

Expand All @@ -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(() => {
Expand Down Expand Up @@ -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)
})
})
})
18 changes: 18 additions & 0 deletions src/ts-jest-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -183,6 +185,14 @@ export class TsJestTransformer implements SyncTransformer {
return result
}

async processAsync(
sourceText: string,
sourcePath: Config.Path,
transformOptions: TransformOptionsTsJest,
): Promise<TransformedSource | string> {
return new Promise((resolve) => resolve(this.process(sourceText, sourcePath, transformOptions)))
}

/**
* Jest uses this to cache the compiled version of a file
*
Expand Down Expand Up @@ -248,6 +258,14 @@ export class TsJestTransformer implements SyncTransformer {
return sha1(...constructingCacheKeyElements)
}

async getCacheKeyAsync(
sourceText: string,
sourcePath: string,
transformOptions: TransformOptionsTsJest,
): Promise<string> {
return new Promise((resolve) => resolve(this.getCacheKey(sourceText, sourcePath, transformOptions)))
}

/**
* Subclasses extends `TsJestTransformer` can call this method to get resolved module disk cache
*/
Expand Down

0 comments on commit 571a880

Please sign in to comment.