Skip to content

Commit 4f0bb33

Browse files
authored
fix(config): use original jest config object instead of stringified config (#1511)
1 parent 30aaecd commit 4f0bb33

11 files changed

Lines changed: 191 additions & 75 deletions

File tree

e2e/__tests__/__snapshots__/diagnostics.test.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ exports[`With diagnostics throw using incremental program with unsupported versi
242242
243243
TypeError: ts.createIncrementalCompilerHost is not a function
244244
245-
at Object.exports.compileUsingProgram (../../__templates__/with-typescript-2-7/node_modules/ts-jest/dist/compiler/program.js:47:19)
245+
at Object.exports.compileUsingProgram (../../__templates__/with-typescript-2-7/node_modules/ts-jest/dist/compiler/program.js:46:19)
246246
247247
Test Suites: 1 failed, 1 total
248248
Tests: 0 total
@@ -264,7 +264,7 @@ exports[`With diagnostics throw using incremental program with unsupported versi
264264
265265
TypeError: ts.createIncrementalCompilerHost is not a function
266266
267-
at Object.exports.compileUsingProgram (../../__templates__/with-unsupported-version/node_modules/ts-jest/dist/compiler/program.js:47:19)
267+
at Object.exports.compileUsingProgram (../../__templates__/with-unsupported-version/node_modules/ts-jest/dist/compiler/program.js:46:19)
268268
269269
Test Suites: 1 failed, 1 total
270270
Tests: 0 total

src/__helpers__/fakers.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ export function makeCompiler({
6969
...(tsJestConfig.diagnostics as any),
7070
pretty: false,
7171
}
72-
jestConfig = { ...jestConfig, testMatch: ['^.+\\.tsx?$'], testRegex: ['^.+\\.[tj]sx?$'] }
72+
const testRegex = ['^.+\\.[tj]sx?$']
73+
jestConfig = {
74+
...jestConfig,
75+
testMatch: ['^.+\\.tsx?$'],
76+
testRegex: jestConfig?.testRegex ? testRegex.concat(jestConfig.testRegex) : testRegex,
77+
}
7378
const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig)
7479

7580
return createCompiler(cs)

src/compiler/compiler-utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Logger } from 'bs-logger'
22
import { writeFileSync } from 'fs'
3+
import micromatch = require('micromatch')
34
import { join, normalize } from 'path'
45
import * as _ts from 'typescript'
56

@@ -51,3 +52,9 @@ export function cacheResolvedModules(
5152
writeFileSync(getResolvedModulesCache(cacheDir), JSON.stringify(memoryCache.resolvedModules))
5253
}
5354
}
55+
56+
export function isTestFile(testMatchPatterns: [string, RegExp], fileName: string) {
57+
return testMatchPatterns.some(pattern =>
58+
typeof pattern === 'string' ? micromatch.isMatch(fileName, pattern) : pattern.test(fileName),
59+
)
60+
}

src/compiler/language-service.spec.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { LogLevels } from 'bs-logger'
22
import { removeSync, writeFileSync } from 'fs-extra'
3+
import { normalize } from 'path'
34

45
import { makeCompiler } from '../__helpers__/fakers'
56
import { logTargetMock } from '../__helpers__/mocks'
67
import { tempDir } from '../__helpers__/path'
78
import ProcessedSource from '../__helpers__/processed-source'
89

10+
import * as compilerUtils from './compiler-utils'
11+
912
const logTarget = logTargetMock()
1013

1114
describe('language service', () => {
@@ -60,6 +63,42 @@ describe('language service', () => {
6063
removeSync(fileName)
6164
})
6265

66+
it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
67+
// tslint:disable-next-line:no-empty
68+
const spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
69+
const tmp = tempDir('compiler')
70+
const compiler = makeCompiler({
71+
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(spec|test)\.[jt]sx?$/] as any[] },
72+
tsJestConfig: { tsConfig: false },
73+
})
74+
const fileName = 'src/__mocks__/main.spec.ts'
75+
const source = JSON.stringify(require('../__mocks__/main.spec'))
76+
77+
compiler.compile(source, fileName)
78+
79+
expect(spy).toHaveBeenCalled()
80+
expect(spy.mock.calls[0][0]).toEqual(normalize(fileName))
81+
expect(spy.mock.calls[0][1]).toEqual(source)
82+
83+
spy.mockRestore()
84+
})
85+
86+
it(`shouldn't cache resolved modules for test file with testMatchPatterns from jest config when not match`, () => {
87+
// tslint:disable-next-line:no-empty
88+
jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
89+
const tmp = tempDir('compiler')
90+
const compiler = makeCompiler({
91+
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(foo|bar)\.[jt]sx?$/] as any[] },
92+
tsJestConfig: { tsConfig: false },
93+
})
94+
const fileName = 'src/__mocks__/main.spec.ts'
95+
const source = JSON.stringify(require('../__mocks__/main.spec'))
96+
97+
compiler.compile(source, fileName)
98+
99+
expect(compilerUtils.cacheResolvedModules).not.toHaveBeenCalled()
100+
})
101+
63102
it('should compile js file for allowJs true with outDir', () => {
64103
const fileName = `test-allow-js-with-outDir.js`
65104
const compiler = makeCompiler({

src/compiler/language-service.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { LogContexts, LogLevels, Logger } from 'bs-logger'
22
import memoize = require('lodash.memoize')
3-
import micromatch = require('micromatch')
43
import { basename, normalize, relative } from 'path'
54
import * as _ts from 'typescript'
65

76
import { ConfigSet } from '../config/config-set'
87
import { CompilerInstance, MemoryCache, SourceOutput } from '../types'
98
import { Errors, interpolate } from '../util/messages'
109

11-
import { cacheResolvedModules, hasOwn } from './compiler-utils'
10+
import { cacheResolvedModules, hasOwn, isTestFile } from './compiler-utils'
1211

1312
function doTypeChecking(configs: ConfigSet, fileName: string, service: _ts.LanguageService, logger: Logger) {
1413
if (configs.shouldReportDiagnostic(fileName)) {
@@ -120,9 +119,8 @@ export const compileUsingLanguageService = (
120119
/**
121120
* We don't need the following logic with no cache run because no cache always gives correct typing
122121
*/
123-
/* istanbul ignore next (covered by e2e) */
124122
if (cacheDir) {
125-
if (micromatch.isMatch(normalizedFileName, configs.testMatchPatterns)) {
123+
if (isTestFile(configs.testMatchPatterns, normalizedFileName)) {
126124
cacheResolvedModules(normalizedFileName, code, memoryCache, service.getProgram()!, cacheDir, logger)
127125
} else {
128126
/* istanbul ignore next (covered by e2e) */

src/compiler/program.spec.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { LogLevels } from 'bs-logger'
22
import { writeFileSync } from 'fs'
33
import { removeSync } from 'fs-extra'
4+
import { normalize } from 'path'
45

56
import { makeCompiler } from '../__helpers__/fakers'
67
import { logTargetMock } from '../__helpers__/mocks'
78
import { tempDir } from '../__helpers__/path'
89
import ProcessedSource from '../__helpers__/processed-source'
910

11+
import * as compilerUtils from './compiler-utils'
12+
1013
const logTarget = logTargetMock()
1114

1215
const baseTsJestConfig = {
@@ -107,6 +110,82 @@ describe('cache', () => {
107110
})
108111
})
109112

113+
describe('cache resolved modules for test file', () => {
114+
let spy: jest.SpyInstance
115+
const fileName = 'src/__mocks__/main.spec.ts'
116+
const source = JSON.stringify(require('../__mocks__/main.spec'))
117+
118+
describe('with program', () => {
119+
beforeEach(() => {
120+
// tslint:disable-next-line:no-empty
121+
spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
122+
})
123+
124+
afterEach(() => {
125+
spy.mockRestore()
126+
})
127+
128+
it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
129+
const tmp = tempDir('compiler')
130+
const compiler = makeCompiler({
131+
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(spec|test)\.[jt]sx?$/] as any[] },
132+
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: false },
133+
})
134+
compiler.compile(source, fileName)
135+
136+
expect(spy).toHaveBeenCalled()
137+
expect(spy.mock.calls[0][0]).toEqual(normalize(fileName))
138+
expect(spy.mock.calls[0][1]).toEqual(source)
139+
})
140+
141+
it(`shouldn't cache resolved modules for test file with testMatchPatterns from jest config when not match`, () => {
142+
const tmp = tempDir('compiler')
143+
const compiler = makeCompiler({
144+
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(foo|bar)\.[jt]sx?$/] as any[] },
145+
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: false },
146+
})
147+
compiler.compile(source, fileName)
148+
149+
expect(spy).not.toHaveBeenCalled()
150+
})
151+
})
152+
153+
describe('with incremental program', () => {
154+
beforeEach(() => {
155+
// tslint:disable-next-line:no-empty
156+
spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
157+
})
158+
159+
afterEach(() => {
160+
spy.mockRestore()
161+
})
162+
163+
it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
164+
const tmp = tempDir('compiler')
165+
const compiler = makeCompiler({
166+
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(spec|test)\.[jt]sx?$/] as any[] },
167+
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: true },
168+
})
169+
compiler.compile(source, fileName)
170+
171+
expect(spy).toHaveBeenCalled()
172+
expect(spy.mock.calls[0][0]).toEqual(normalize(fileName))
173+
expect(spy.mock.calls[0][1]).toEqual(source)
174+
})
175+
176+
it(`shouldn't cache resolved modules for test file with testMatchPatterns from jest config when not match`, () => {
177+
const tmp = tempDir('compiler')
178+
const compiler = makeCompiler({
179+
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(foo|bar)\.[jt]sx?$/] as any[] },
180+
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: true },
181+
})
182+
compiler.compile(source, fileName)
183+
184+
expect(spy).not.toHaveBeenCalled()
185+
})
186+
})
187+
})
188+
110189
describe('allowJs', () => {
111190
const baseFileName = 'test-allowJs'
112191
const baseFileExt = 'test.js'

src/compiler/program.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { LogContexts, LogLevels, Logger } from 'bs-logger'
22
import memoize = require('lodash.memoize')
3-
import micromatch = require('micromatch')
43
import { basename, normalize, relative } from 'path'
54
import * as _ts from 'typescript'
65

76
import { ConfigSet } from '../config/config-set'
87
import { CompilerInstance, MemoryCache, SourceOutput } from '../types'
98
import { Errors, interpolate } from '../util/messages'
109

11-
import { cacheResolvedModules, hasOwn } from './compiler-utils'
10+
import { cacheResolvedModules, hasOwn, isTestFile } from './compiler-utils'
1211

1312
function doTypeChecking(configs: ConfigSet, fileName: string, program: _ts.Program, logger: Logger) {
1413
if (configs.shouldReportDiagnostic(fileName)) {
@@ -166,9 +165,8 @@ export const compileUsingProgram = (configs: ConfigSet, logger: Logger, memoryCa
166165
/**
167166
* We don't need the following logic with no cache run because no cache always gives correct typing
168167
*/
169-
/* istanbul ignore next (covered by e2e) */
170168
if (cacheDir) {
171-
if (micromatch.isMatch(normalizedFileName, configs.testMatchPatterns)) {
169+
if (isTestFile(configs.testMatchPatterns, normalizedFileName)) {
172170
cacheResolvedModules(normalizedFileName, code, memoryCache, program, cacheDir, logger)
173171
} else {
174172
/* istanbul ignore next (covered by e2e) */

src/config/config-set.spec.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ describe('tsJest', () => {
217217
expect(cs.tsJest.babelConfig).toBeUndefined()
218218
expect(cs.babel).toBeUndefined()
219219
expect(logger.target.lines[2]).toMatchInlineSnapshot(`
220-
"[level:20] babel is disabled
221-
"
222-
`)
220+
"[level:20] babel is disabled
221+
"
222+
`)
223223
})
224224

225225
it('should be correct for true', () => {
@@ -294,9 +294,9 @@ describe('tsJest', () => {
294294
expect(cs.tsJest.babelConfig!.kind).toEqual('inline')
295295
expect(cs.babel).toEqual(expect.objectContaining(babelConfig))
296296
expect(logger.target.lines[2]).toMatchInlineSnapshot(`
297-
"[level:20] normalized babel config via ts-jest option
298-
"
299-
`)
297+
"[level:20] normalized babel config via ts-jest option
298+
"
299+
`)
300300
})
301301

302302
it('should be correct for inline config', () => {
@@ -312,9 +312,9 @@ describe('tsJest', () => {
312312
expect(cs.tsJest.babelConfig!.kind).toEqual('inline')
313313
expect(cs.babel).toEqual(expect.objectContaining(CONFIG))
314314
expect(logger.target.lines[2]).toMatchInlineSnapshot(`
315-
"[level:20] normalized babel config via ts-jest option
316-
"
317-
`)
315+
"[level:20] normalized babel config via ts-jest option
316+
"
317+
`)
318318
})
319319
}) // babelConfig
320320

@@ -425,15 +425,15 @@ describe('makeDiagnostic', () => {
425425
it('should set category', () => {
426426
expect(cs.makeDiagnostic(4321, 'foo might be bar', { category: ts.DiagnosticCategory.Error }))
427427
.toMatchInlineSnapshot(`
428-
Object {
429-
"category": 1,
430-
"code": 4321,
431-
"file": undefined,
432-
"length": undefined,
433-
"messageText": "foo might be bar",
434-
"start": undefined,
435-
}
436-
`)
428+
Object {
429+
"category": 1,
430+
"code": 4321,
431+
"file": undefined,
432+
"length": undefined,
433+
"messageText": "foo might be bar",
434+
"start": undefined,
435+
}
436+
`)
437437
})
438438
}) // makeDiagnostic
439439

@@ -494,9 +494,9 @@ describe('typescript', () => {
494494
esModuleInterop: false,
495495
})
496496
expect(target.lines.warn.join()).toMatchInlineSnapshot(`
497-
"[level:40] message TS151001: If you have issues related to imports, you should consider setting \`esModuleInterop\` to \`true\` in your TypeScript configuration file (usually \`tsconfig.json\`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
498-
"
499-
`)
497+
"[level:40] message TS151001: If you have issues related to imports, you should consider setting \`esModuleInterop\` to \`true\` in your TypeScript configuration file (usually \`tsconfig.json\`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
498+
"
499+
`)
500500
})
501501

502502
it('should not warn neither set synth. default imports if using babel', () => {
@@ -976,11 +976,11 @@ describe('raiseDiagnostics', () => {
976976
expect(() => raiseDiagnostics([])).not.toThrow()
977977
expect(() => raiseDiagnostics([makeDiagnostic()])).not.toThrow()
978978
expect(logger.target.lines).toMatchInlineSnapshot(`
979-
Array [
980-
"[level:40] [TS9999] foo
981-
",
982-
]
983-
`)
979+
Array [
980+
"[level:40] [TS9999] foo
981+
",
982+
]
983+
`)
984984
})
985985
})
986986

src/config/config-set.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ export class ConfigSet {
186186
...globals['ts-jest'],
187187
}
188188
}
189+
189190
this.logger.debug({ jestConfig: config }, 'normalized jest config')
190191

191192
return config
@@ -195,8 +196,8 @@ export class ConfigSet {
195196
* @internal
196197
*/
197198
@Memoize()
198-
get testMatchPatterns(): string[] {
199-
return this.jest.testMatch.concat(this.jest.testRegex)
199+
get testMatchPatterns(): [string, RegExp] {
200+
return this.jest.testMatch.concat(this.jest.testRegex) as [string, RegExp]
200201
}
201202

202203
/**

0 commit comments

Comments
 (0)