Skip to content

Commit

Permalink
fix: always do type check for all files provided to ts-jest transform…
Browse files Browse the repository at this point in the history
…er (#1450)
  • Loading branch information
ahnpnl committed Mar 26, 2020
1 parent 1e34075 commit 107e062
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 92 deletions.
40 changes: 20 additions & 20 deletions e2e/__tests__/__snapshots__/logger.test.ts.snap
Expand Up @@ -12,28 +12,28 @@ Array [
"[level:20] backporting config",
"[level:20] normalized jest config",
"[level:20] normalized ts-jest config",
"[level:20] babel is disabled",
"[level:20] loaded module typescript",
"[level:20] patching typescript",
"[level:20] checking version of typescript: OK",
"[level:20] readTsConfig(): reading <cwd>/tsconfig.json",
"[level:20] normalized typescript config",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] file caching disabled",
"[level:20] compileUsingLanguageService(): create typescript compiler",
"[level:20] compileUsingLanguageService(): creating language service",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] babel is disabled",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
]
`;
Expand All @@ -49,33 +49,33 @@ Array [
"[level:20] backporting config",
"[level:20] normalized jest config",
"[level:20] normalized ts-jest config",
"[level:20] normalized babel config via ts-jest option",
"[level:20] loaded module typescript",
"[level:20] patching typescript",
"[level:20] checking version of typescript: OK",
"[level:20] readTsConfig(): reading <cwd>/tsconfig.json",
"[level:20] normalized typescript config",
"[level:20] file caching disabled",
"[level:20] compileUsingLanguageService(): create typescript compiler",
"[level:20] compileUsingLanguageService(): creating language service",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] normalized babel config via ts-jest option",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] creating babel-jest transformer",
"[level:20] loaded module babel-jest",
"[level:20] patching babel-jest",
"[level:20] checking version of babel-jest: OK",
"[level:20] file caching disabled",
"[level:20] compileUsingLanguageService(): create typescript compiler",
"[level:20] compileUsingLanguageService(): creating language service",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] calling babel-jest processor",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] calling babel-jest processor",
]
`;
Expand All @@ -93,33 +93,33 @@ Array [
"[level:20] normalized jest config",
"[level:20] resolved path from babel.config.js to <cwd>/babel.config.js",
"[level:20] normalized ts-jest config",
"[level:20] normalized babel config via ts-jest option",
"[level:20] loaded module typescript",
"[level:20] patching typescript",
"[level:20] checking version of typescript: OK",
"[level:20] readTsConfig(): reading <cwd>/tsconfig.json",
"[level:20] normalized typescript config",
"[level:20] file caching disabled",
"[level:20] compileUsingLanguageService(): create typescript compiler",
"[level:20] compileUsingLanguageService(): creating language service",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] normalized babel config via ts-jest option",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] creating babel-jest transformer",
"[level:20] loaded module babel-jest",
"[level:20] patching babel-jest",
"[level:20] checking version of babel-jest: OK",
"[level:20] file caching disabled",
"[level:20] compileUsingLanguageService(): create typescript compiler",
"[level:20] compileUsingLanguageService(): creating language service",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] calling babel-jest processor",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] calling babel-jest processor",
]
`;
Expand All @@ -136,28 +136,28 @@ Array [
"[level:20] backporting config",
"[level:20] normalized jest config",
"[level:20] normalized ts-jest config",
"[level:20] babel is disabled",
"[level:20] loaded module typescript",
"[level:20] patching typescript",
"[level:20] checking version of typescript: OK",
"[level:20] readTsConfig(): reading <cwd>/tsconfig.json",
"[level:20] normalized typescript config",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] file caching disabled",
"[level:20] compileUsingLanguageService(): create typescript compiler",
"[level:20] compileUsingLanguageService(): creating language service",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] babel is disabled",
"[level:20] processing <cwd>/Hello.spec.ts",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] computing cache key for <cwd>/Hello.ts",
"[level:20] compileFn(): computing diagnostics for language service",
"[level:20] processing <cwd>/Hello.ts",
"[level:20] readThrough(): no cache",
"[level:20] compileFn(): compiling using language service",
"[level:20] updateMemoryCache(): update memory cache for language service",
"[level:20] visitSourceFileNode(): hoisting",
"[level:20] compileFn(): computing diagnostics for language service",
]
`;
Expand Down
6 changes: 1 addition & 5 deletions src/compiler/__snapshots__/program.spec.ts.snap
Expand Up @@ -146,10 +146,6 @@ exports[`other jsx options should compile tsx file for with program 1`] = `
================================================================================
`;

exports[`typings incremental program should not report diagnostics with pathRegex config does not match file name 1`] = `"test-typings.ts: Emit skipped"`;

exports[`typings incremental program should report diagnostics with pathRegex config matches file name 1`] = `"test-typings.ts: Emit skipped"`;

exports[`typings normal program should not report diagnostics with pathRegex config matches file name 1`] = `"test-typings.ts: Emit skipped"`;
exports[`typings incremental program should report diagnostics with pathRegex config matches file name 1`] = `"test-typings.ts(3,7): error TS2322: Type 'number' is not assignable to type 'string'."`;

exports[`typings normal program should report diagnostics with pathRegex config matches file name 1`] = `"test-typings.ts(3,7): error TS2322: Type 'number' is not assignable to type 'string'."`;
27 changes: 14 additions & 13 deletions src/compiler/instance.ts
Expand Up @@ -35,7 +35,7 @@ import mkdirp = require('mkdirp')
import { basename, extname, join, normalize } from 'path'

import { ConfigSet } from '../config/config-set'
import { CompileFn, CompileResult, MemoryCache, TsCompiler } from '../types'
import { CompileFn, CompilerInstance, MemoryCache, TsCompiler } from '../types'
import { sha1 } from '../util/sha1'

import { compileUsingLanguageService } from './language-service'
Expand Down Expand Up @@ -113,11 +113,10 @@ const readThrough = (
mkdirp.sync(cachedir)

return (code: string, fileName: string, lineOffset?: number) => {
const normalizedFileName = normalize(fileName)
const cachePath = join(cachedir, getCacheName(code, normalizedFileName))
const extension = getExtension(normalizedFileName)
const outputPath = `${cachePath}${extension}`

const normalizedFileName = normalize(fileName),
cachePath = join(cachedir, getCacheName(code, normalizedFileName)),
extension = getExtension(normalizedFileName),
outputPath = `${cachePath}${extension}`
try {
const output = readFileSync(outputPath, 'utf8')
if (isValidCacheContent(output)) {
Expand All @@ -129,10 +128,12 @@ const readThrough = (
} catch (err) {}

logger.debug({ fileName }, 'readThrough(): cache miss')
const [value, sourceMap] = compileFn(code, normalizedFileName, lineOffset)
const output = updateOutput(value, normalizedFileName, sourceMap, getExtension)

const [value, sourceMap] = compileFn(code, normalizedFileName, lineOffset),
output = updateOutput(value, normalizedFileName, sourceMap, getExtension)

logger.debug({ normalizedFileName, outputPath }, 'readThrough(): writing caches')

memoryCache.outputs[normalizedFileName] = output
writeFileSync(outputPath, output)

Expand Down Expand Up @@ -172,16 +173,16 @@ export const createCompiler = (configs: ConfigSet): TsCompiler => {
compilerOptions.jsx === ts.JsxEmit.Preserve
? (path: string) => (/\.[tj]sx$/.test(path) ? '.jsx' : '.js')
: (_: string) => '.js'
let compileResult: CompileResult
let compilerInstance: CompilerInstance
if (!tsJest.isolatedModules) {
// Use language services by default
compileResult = !tsJest.compilerHost
compilerInstance = !tsJest.compilerHost
? compileUsingLanguageService(configs, logger, memoryCache)
: compileUsingProgram(configs, logger, memoryCache)
} else {
compileResult = compileUsingTranspileModule(configs, logger)
compilerInstance = compileUsingTranspileModule(configs, logger)
}
const compile = readThrough(cachedir, memoryCache, compileResult.compileFn, getExtension, logger)
const compile = readThrough(cachedir, memoryCache, compilerInstance.compileFn, getExtension, logger)

return { cwd: configs.cwd, compile, program: compileResult.program }
return { cwd: configs.cwd, compile, program: compilerInstance.program, diagnose: compilerInstance.diagnoseFn }
}
8 changes: 4 additions & 4 deletions src/compiler/language-service.spec.ts
Expand Up @@ -36,8 +36,6 @@ describe('language service', () => {
"[level:20] updateMemoryCache(): update memory cache for language service
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics for language service
",
"[level:20] readThrough(): writing caches
",
Expand Down Expand Up @@ -146,8 +144,9 @@ const x: string = g(5)
tsJestConfig: { tsConfig: false, diagnostics: { pathRegex: fileName } },
})
writeFileSync(fileName, source, 'utf8')
compiler.compile(source, fileName)

expect(() => compiler.compile(source, fileName)).toThrowErrorMatchingSnapshot()
expect(() => compiler.diagnose!(fileName)).toThrowErrorMatchingSnapshot()

removeSync(fileName)
})
Expand All @@ -162,8 +161,9 @@ const t: string = f(5)
tsJestConfig: { tsConfig: false, diagnostics: { pathRegex: 'bar.ts' } },
})
writeFileSync(fileName, source, 'utf8')
compiler.compile(source, fileName)

expect(() => compiler.compile(source, fileName)).not.toThrowError()
expect(() => compiler.diagnose!(fileName)).not.toThrowError()

removeSync(fileName)
})
Expand Down
32 changes: 19 additions & 13 deletions src/compiler/language-service.ts
Expand Up @@ -4,7 +4,7 @@ import { basename, normalize, relative } from 'path'
import * as _ts from 'typescript'

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

const hasOwn = Object.prototype.hasOwnProperty
Expand All @@ -16,7 +16,7 @@ export const compileUsingLanguageService = (
configs: ConfigSet,
logger: Logger,
memoryCache: MemoryCache,
): CompileResult => {
): CompilerInstance => {
logger.debug('compileUsingLanguageService(): create typescript compiler')

const ts = configs.compilerModule,
Expand Down Expand Up @@ -95,17 +95,6 @@ export const compileUsingLanguageService = (
// Must set memory cache before attempting to read file.
updateMemoryCache(code, normalizedFileName)
const output: _ts.EmitOutput = service.getEmitOutput(normalizedFileName)
if (configs.shouldReportDiagnostic(normalizedFileName)) {
logger.debug({ normalizedFileName }, 'compileFn(): computing diagnostics for language service')

// Get the relevant diagnostics - this is 3x faster than `getPreEmitDiagnostics`.
const diagnostics = service
.getCompilerOptionsDiagnostics()
.concat(service.getSyntacticDiagnostics(normalizedFileName))
.concat(service.getSemanticDiagnostics(normalizedFileName))
// will raise or just warn diagnostics depending on config
configs.raiseDiagnostics(diagnostics, normalizedFileName, logger)
}

/* istanbul ignore next (this should never happen but is kept for security) */
if (output.emitSkipped) {
Expand All @@ -123,6 +112,23 @@ export const compileUsingLanguageService = (

return [output.outputFiles[1].text, output.outputFiles[0].text]
},
diagnoseFn: (filePath: string) => {
const normalizedFileName = normalize(filePath)
if (configs.shouldReportDiagnostic(normalizedFileName)) {
logger.debug({ normalizedFileName }, 'compileFn(): computing diagnostics for language service')

// Not sure why e2e tests not working without this if. In reality, this if is not needed
if (service.getProgram()!.getSourceFile(filePath)) {
// Get the relevant diagnostics - this is 3x faster than `getPreEmitDiagnostics`.
const diagnostics = service
.getCompilerOptionsDiagnostics()
.concat(service.getSyntacticDiagnostics(normalizedFileName))
.concat(service.getSemanticDiagnostics(normalizedFileName))
// will raise or just warn diagnostics depending on config
configs.raiseDiagnostics(diagnostics, normalizedFileName, logger)
}
}
},
program: service.getProgram(),
}
}
30 changes: 21 additions & 9 deletions src/compiler/program.spec.ts
Expand Up @@ -38,7 +38,11 @@ const t: string = f(5)
},
})

expect(() => compiler.compile(source, fileName)).toThrowErrorMatchingSnapshot()
try {
compiler.compile(source, fileName)
} catch (e) {}

expect(() => compiler.diagnose!(fileName)).toThrowErrorMatchingSnapshot()
})

it('should not report diagnostics with pathRegex config matches file name', () => {
Expand All @@ -50,7 +54,11 @@ const t: string = f(5)
},
})

expect(() => compiler.compile(source, fileName)).toThrowErrorMatchingSnapshot()
try {
compiler.compile(source, fileName)
} catch (e) {}

expect(() => compiler.diagnose!(fileName)).not.toThrowError()
})
})

Expand All @@ -60,11 +68,15 @@ const t: string = f(5)
tsJestConfig: {
...baseTsJestConfig,
incremental: true,
diagnostics: { pathRegex: 'typings-error.ts' },
diagnostics: { pathRegex: fileName },
},
})

expect(() => compiler.compile(source, fileName)).toThrowErrorMatchingSnapshot()
try {
compiler.compile(source, fileName)
} catch (e) {}

expect(() => compiler.diagnose!(fileName)).toThrowErrorMatchingSnapshot()
})

it('should not report diagnostics with pathRegex config does not match file name', () => {
Expand All @@ -76,7 +88,11 @@ const t: string = f(5)
},
})

expect(() => compiler.compile(source, fileName)).toThrowErrorMatchingSnapshot()
try {
compiler.compile(source, fileName)
} catch (e) {}

expect(() => compiler.diagnose!(fileName)).not.toThrowError()
})
})
})
Expand Down Expand Up @@ -161,8 +177,6 @@ describe('cache', () => {
"[level:20] updateMemoryCache(): update memory cache for program
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics for program
",
"[level:20] readThrough(): writing caches
",
Expand Down Expand Up @@ -202,8 +216,6 @@ Array [
"[level:20] updateMemoryCache(): update memory cache for incremental program
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] compileFn(): computing diagnostics for incremental program
",
"[level:20] readThrough(): writing caches
",
Expand Down

0 comments on commit 107e062

Please sign in to comment.