Skip to content

Commit

Permalink
fix(config): use original jest config object instead of stringified c…
Browse files Browse the repository at this point in the history
…onfig (#1511)
  • Loading branch information
ahnpnl committed Apr 8, 2020
1 parent 30aaecd commit 4f0bb33
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 75 deletions.
4 changes: 2 additions & 2 deletions e2e/__tests__/__snapshots__/diagnostics.test.ts.snap
Expand Up @@ -242,7 +242,7 @@ exports[`With diagnostics throw using incremental program with unsupported versi
TypeError: ts.createIncrementalCompilerHost is not a function
at Object.exports.compileUsingProgram (../../__templates__/with-typescript-2-7/node_modules/ts-jest/dist/compiler/program.js:47:19)
at Object.exports.compileUsingProgram (../../__templates__/with-typescript-2-7/node_modules/ts-jest/dist/compiler/program.js:46:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Expand All @@ -264,7 +264,7 @@ exports[`With diagnostics throw using incremental program with unsupported versi
TypeError: ts.createIncrementalCompilerHost is not a function
at Object.exports.compileUsingProgram (../../__templates__/with-unsupported-version/node_modules/ts-jest/dist/compiler/program.js:47:19)
at Object.exports.compileUsingProgram (../../__templates__/with-unsupported-version/node_modules/ts-jest/dist/compiler/program.js:46:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Expand Down
7 changes: 6 additions & 1 deletion src/__helpers__/fakers.ts
Expand Up @@ -69,7 +69,12 @@ export function makeCompiler({
...(tsJestConfig.diagnostics as any),
pretty: false,
}
jestConfig = { ...jestConfig, testMatch: ['^.+\\.tsx?$'], testRegex: ['^.+\\.[tj]sx?$'] }
const testRegex = ['^.+\\.[tj]sx?$']
jestConfig = {
...jestConfig,
testMatch: ['^.+\\.tsx?$'],
testRegex: jestConfig?.testRegex ? testRegex.concat(jestConfig.testRegex) : testRegex,
}
const cs = new ConfigSet(getJestConfig(jestConfig, tsJestConfig), parentConfig)

return createCompiler(cs)
Expand Down
7 changes: 7 additions & 0 deletions src/compiler/compiler-utils.ts
@@ -1,5 +1,6 @@
import { Logger } from 'bs-logger'
import { writeFileSync } from 'fs'
import micromatch = require('micromatch')
import { join, normalize } from 'path'
import * as _ts from 'typescript'

Expand Down Expand Up @@ -51,3 +52,9 @@ export function cacheResolvedModules(
writeFileSync(getResolvedModulesCache(cacheDir), JSON.stringify(memoryCache.resolvedModules))
}
}

export function isTestFile(testMatchPatterns: [string, RegExp], fileName: string) {
return testMatchPatterns.some(pattern =>
typeof pattern === 'string' ? micromatch.isMatch(fileName, pattern) : pattern.test(fileName),
)
}
39 changes: 39 additions & 0 deletions src/compiler/language-service.spec.ts
@@ -1,11 +1,14 @@
import { LogLevels } from 'bs-logger'
import { removeSync, writeFileSync } from 'fs-extra'
import { normalize } from 'path'

import { makeCompiler } from '../__helpers__/fakers'
import { logTargetMock } from '../__helpers__/mocks'
import { tempDir } from '../__helpers__/path'
import ProcessedSource from '../__helpers__/processed-source'

import * as compilerUtils from './compiler-utils'

const logTarget = logTargetMock()

describe('language service', () => {
Expand Down Expand Up @@ -60,6 +63,42 @@ describe('language service', () => {
removeSync(fileName)
})

it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
// tslint:disable-next-line:no-empty
const spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(spec|test)\.[jt]sx?$/] as any[] },
tsJestConfig: { tsConfig: false },
})
const fileName = 'src/__mocks__/main.spec.ts'
const source = JSON.stringify(require('../__mocks__/main.spec'))

compiler.compile(source, fileName)

expect(spy).toHaveBeenCalled()
expect(spy.mock.calls[0][0]).toEqual(normalize(fileName))
expect(spy.mock.calls[0][1]).toEqual(source)

spy.mockRestore()
})

it(`shouldn't cache resolved modules for test file with testMatchPatterns from jest config when not match`, () => {
// tslint:disable-next-line:no-empty
jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(foo|bar)\.[jt]sx?$/] as any[] },
tsJestConfig: { tsConfig: false },
})
const fileName = 'src/__mocks__/main.spec.ts'
const source = JSON.stringify(require('../__mocks__/main.spec'))

compiler.compile(source, fileName)

expect(compilerUtils.cacheResolvedModules).not.toHaveBeenCalled()
})

it('should compile js file for allowJs true with outDir', () => {
const fileName = `test-allow-js-with-outDir.js`
const compiler = makeCompiler({
Expand Down
6 changes: 2 additions & 4 deletions src/compiler/language-service.ts
@@ -1,14 +1,13 @@
import { LogContexts, LogLevels, Logger } from 'bs-logger'
import memoize = require('lodash.memoize')
import micromatch = require('micromatch')
import { basename, normalize, relative } from 'path'
import * as _ts from 'typescript'

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

import { cacheResolvedModules, hasOwn } from './compiler-utils'
import { cacheResolvedModules, hasOwn, isTestFile } from './compiler-utils'

function doTypeChecking(configs: ConfigSet, fileName: string, service: _ts.LanguageService, logger: Logger) {
if (configs.shouldReportDiagnostic(fileName)) {
Expand Down Expand Up @@ -120,9 +119,8 @@ export const compileUsingLanguageService = (
/**
* We don't need the following logic with no cache run because no cache always gives correct typing
*/
/* istanbul ignore next (covered by e2e) */
if (cacheDir) {
if (micromatch.isMatch(normalizedFileName, configs.testMatchPatterns)) {
if (isTestFile(configs.testMatchPatterns, normalizedFileName)) {
cacheResolvedModules(normalizedFileName, code, memoryCache, service.getProgram()!, cacheDir, logger)
} else {
/* istanbul ignore next (covered by e2e) */
Expand Down
79 changes: 79 additions & 0 deletions src/compiler/program.spec.ts
@@ -1,12 +1,15 @@
import { LogLevels } from 'bs-logger'
import { writeFileSync } from 'fs'
import { removeSync } from 'fs-extra'
import { normalize } from 'path'

import { makeCompiler } from '../__helpers__/fakers'
import { logTargetMock } from '../__helpers__/mocks'
import { tempDir } from '../__helpers__/path'
import ProcessedSource from '../__helpers__/processed-source'

import * as compilerUtils from './compiler-utils'

const logTarget = logTargetMock()

const baseTsJestConfig = {
Expand Down Expand Up @@ -107,6 +110,82 @@ describe('cache', () => {
})
})

describe('cache resolved modules for test file', () => {
let spy: jest.SpyInstance
const fileName = 'src/__mocks__/main.spec.ts'
const source = JSON.stringify(require('../__mocks__/main.spec'))

describe('with program', () => {
beforeEach(() => {
// tslint:disable-next-line:no-empty
spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
})

afterEach(() => {
spy.mockRestore()
})

it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(spec|test)\.[jt]sx?$/] as any[] },
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: false },
})
compiler.compile(source, fileName)

expect(spy).toHaveBeenCalled()
expect(spy.mock.calls[0][0]).toEqual(normalize(fileName))
expect(spy.mock.calls[0][1]).toEqual(source)
})

it(`shouldn't cache resolved modules for test file with testMatchPatterns from jest config when not match`, () => {
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(foo|bar)\.[jt]sx?$/] as any[] },
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: false },
})
compiler.compile(source, fileName)

expect(spy).not.toHaveBeenCalled()
})
})

describe('with incremental program', () => {
beforeEach(() => {
// tslint:disable-next-line:no-empty
spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
})

afterEach(() => {
spy.mockRestore()
})

it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(spec|test)\.[jt]sx?$/] as any[] },
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: true },
})
compiler.compile(source, fileName)

expect(spy).toHaveBeenCalled()
expect(spy.mock.calls[0][0]).toEqual(normalize(fileName))
expect(spy.mock.calls[0][1]).toEqual(source)
})

it(`shouldn't cache resolved modules for test file with testMatchPatterns from jest config when not match`, () => {
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp, testRegex: [/.*\.(foo|bar)\.[jt]sx?$/] as any[] },
tsJestConfig: { tsConfig: false, compilerHost: true, incremental: true },
})
compiler.compile(source, fileName)

expect(spy).not.toHaveBeenCalled()
})
})
})

describe('allowJs', () => {
const baseFileName = 'test-allowJs'
const baseFileExt = 'test.js'
Expand Down
6 changes: 2 additions & 4 deletions src/compiler/program.ts
@@ -1,14 +1,13 @@
import { LogContexts, LogLevels, Logger } from 'bs-logger'
import memoize = require('lodash.memoize')
import micromatch = require('micromatch')
import { basename, normalize, relative } from 'path'
import * as _ts from 'typescript'

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

import { cacheResolvedModules, hasOwn } from './compiler-utils'
import { cacheResolvedModules, hasOwn, isTestFile } from './compiler-utils'

function doTypeChecking(configs: ConfigSet, fileName: string, program: _ts.Program, logger: Logger) {
if (configs.shouldReportDiagnostic(fileName)) {
Expand Down Expand Up @@ -166,9 +165,8 @@ export const compileUsingProgram = (configs: ConfigSet, logger: Logger, memoryCa
/**
* We don't need the following logic with no cache run because no cache always gives correct typing
*/
/* istanbul ignore next (covered by e2e) */
if (cacheDir) {
if (micromatch.isMatch(normalizedFileName, configs.testMatchPatterns)) {
if (isTestFile(configs.testMatchPatterns, normalizedFileName)) {
cacheResolvedModules(normalizedFileName, code, memoryCache, program, cacheDir, logger)
} else {
/* istanbul ignore next (covered by e2e) */
Expand Down
52 changes: 26 additions & 26 deletions src/config/config-set.spec.ts
Expand Up @@ -217,9 +217,9 @@ describe('tsJest', () => {
expect(cs.tsJest.babelConfig).toBeUndefined()
expect(cs.babel).toBeUndefined()
expect(logger.target.lines[2]).toMatchInlineSnapshot(`
"[level:20] babel is disabled
"
`)
"[level:20] babel is disabled
"
`)
})

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

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

Expand Down Expand Up @@ -425,15 +425,15 @@ describe('makeDiagnostic', () => {
it('should set category', () => {
expect(cs.makeDiagnostic(4321, 'foo might be bar', { category: ts.DiagnosticCategory.Error }))
.toMatchInlineSnapshot(`
Object {
"category": 1,
"code": 4321,
"file": undefined,
"length": undefined,
"messageText": "foo might be bar",
"start": undefined,
}
`)
Object {
"category": 1,
"code": 4321,
"file": undefined,
"length": undefined,
"messageText": "foo might be bar",
"start": undefined,
}
`)
})
}) // makeDiagnostic

Expand Down Expand Up @@ -494,9 +494,9 @@ describe('typescript', () => {
esModuleInterop: false,
})
expect(target.lines.warn.join()).toMatchInlineSnapshot(`
"[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.
"
`)
"[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.
"
`)
})

it('should not warn neither set synth. default imports if using babel', () => {
Expand Down Expand Up @@ -976,11 +976,11 @@ describe('raiseDiagnostics', () => {
expect(() => raiseDiagnostics([])).not.toThrow()
expect(() => raiseDiagnostics([makeDiagnostic()])).not.toThrow()
expect(logger.target.lines).toMatchInlineSnapshot(`
Array [
"[level:40] [TS9999] foo
",
]
`)
Array [
"[level:40] [TS9999] foo
",
]
`)
})
})

Expand Down
5 changes: 3 additions & 2 deletions src/config/config-set.ts
Expand Up @@ -186,6 +186,7 @@ export class ConfigSet {
...globals['ts-jest'],
}
}

this.logger.debug({ jestConfig: config }, 'normalized jest config')

return config
Expand All @@ -195,8 +196,8 @@ export class ConfigSet {
* @internal
*/
@Memoize()
get testMatchPatterns(): string[] {
return this.jest.testMatch.concat(this.jest.testRegex)
get testMatchPatterns(): [string, RegExp] {
return this.jest.testMatch.concat(this.jest.testRegex) as [string, RegExp]
}

/**
Expand Down

0 comments on commit 4f0bb33

Please sign in to comment.