Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/** @type {import('@jest/types').Config.InitialOptions} */
/** @typedef {import('ts-jest')} */

module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
Expand All @@ -7,6 +10,7 @@ module.exports = {
globals: {
'ts-jest': {
isolatedModules: true,
tsConfig: 'tsconfig-tests.json'
},
},
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"private": true,
"scripts": {
"build": "yarn tsc -b -f tsconfig.json",
"test": "yarn build && jest"
"test": "jest"
},
"devDependencies": {
"@types/jest": "^25.2.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"packages/*"
],
"scripts": {
"test": "yarn tsc -b packages/my-app/tsconfig.json && jest --no-cache"
"test": "jest --no-cache"
},
"devDependencies": {
"@types/jest": "^25.2.1",
Expand Down
154 changes: 2 additions & 152 deletions src/compiler/compiler-utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { Logger } from 'bs-logger'
import { writeFileSync } from 'fs'
import micromatch = require('micromatch')
import { dirname, join, normalize, relative, resolve } from 'path'
import { join, normalize } from 'path'
import * as _ts from 'typescript'

import { ConfigSet } from '../config/config-set'
import { EXTENSION_REGEX, JSON_REGEX, TS_TSX_REGEX } from '../constants'
import { MemoryCache, SourceOutput, TSFiles } from '../types'
import { MemoryCache } from '../types'
import { sha1 } from '../util/sha1'

/**
Expand Down Expand Up @@ -60,151 +58,3 @@ export function isTestFile(testMatchPatterns: (string | RegExp)[], fileName: str
typeof pattern === 'string' ? micromatch.isMatch(fileName, pattern) : pattern.test(fileName),
)
}

/* istanbul ignore next (we leave this for e2e) */
function isUsingProjectReferences(
program: _ts.Program,
projectReferences: readonly _ts.ProjectReference[] | undefined,
) {
if (projectReferences && !!program.getProjectReferences) {
return Boolean(program && program.getProjectReferences())
}

return false
}

/* istanbul ignore next (we leave this for e2e) */
function getResolvedProjectReferences(
program: _ts.Program,
): readonly (_ts.ResolvedProjectReference | undefined)[] | undefined {
const getProjectReferences = program.getResolvedProjectReferences ?? program.getProjectReferences
if (getProjectReferences) {
return getProjectReferences()
}

return
}

/* istanbul ignore next (we leave this for e2e) */
function getProjectReferenceForFile(
filePath: string,
program: _ts.Program,
projectReferences: readonly _ts.ProjectReference[] | undefined,
) {
if (isUsingProjectReferences(program, projectReferences)) {
return (
program &&
getResolvedProjectReferences(program)!.find(
ref => (ref && ref.commandLine.fileNames.some(file => normalize(file) === filePath)) || false,
)
)
}

return
}

/**
* @internal
*/
/* istanbul ignore next (we leave this for e2e) */
export function getAndCacheProjectReference(
filePath: string,
program: _ts.Program,
files: TSFiles,
projectReferences: readonly _ts.ProjectReference[] | undefined,
) {
const file = files.get(filePath)
if (file?.projectReference) {
return file.projectReference.project
}

const projectReference = getProjectReferenceForFile(filePath, program, projectReferences)
if (file !== undefined) {
file.projectReference = { project: projectReference }
}

return projectReference
}

// Adapted from https://github.com/Microsoft/TypeScript/blob/45101491c0b077c509b25830ef0ee5f85b293754/src/compiler/tsbuild.ts#L305
/* istanbul ignore next (we leave this for e2e) */
function getOutputJavaScriptFileName(inputFileName: string, projectReference: _ts.ResolvedProjectReference) {
const { options } = projectReference.commandLine
const projectDirectory = options.rootDir || dirname(projectReference.sourceFile.fileName)
const relativePath = relative(projectDirectory, inputFileName)
const outputPath = resolve(options.outDir || projectDirectory, relativePath)
const newExtension = JSON_REGEX.test(inputFileName)
? '.json'
: TS_TSX_REGEX.test(inputFileName) && options.jsx === _ts.JsxEmit.Preserve
? '.jsx'
: '.js'

return outputPath.replace(EXTENSION_REGEX, newExtension)
}

/**
* Gets the output JS file path for an input file governed by a composite project.
* Pulls from the cache if it exists; computes and caches the result otherwise.
*/
/* istanbul ignore next (we leave this for e2e) */
function getAndCacheOutputJSFileName(
inputFileName: string,
projectReference: _ts.ResolvedProjectReference,
files: TSFiles,
) {
const file = files.get(inputFileName)
if (file?.projectReference?.outputFileName) {
return file.projectReference.outputFileName
}

const outputFileName = getOutputJavaScriptFileName(inputFileName, projectReference)
if (file !== undefined) {
file.projectReference = file.projectReference ?? {
project: projectReference,
}
file.projectReference.outputFileName = outputFileName
}

return outputFileName
}

/**
* @internal
*/
/* istanbul ignore next (we leave this for e2e) */
export function getCompileResultFromReferencedProject(
fileName: string,
configs: ConfigSet,
files: TSFiles,
referencedProject: _ts.ResolvedProjectReference,
): SourceOutput {
const [relativeProjectConfigPath, relativeFilePath] = [
configs.resolvePath(referencedProject.sourceFile.fileName),
configs.resolvePath(fileName),
]
if (referencedProject.commandLine.options.outFile !== undefined) {
throw new Error(
`The referenced project at ${relativeProjectConfigPath} is using ` +
"the outFile' option, which is not supported with ts-jest.",
)
}

const jsFileName = getAndCacheOutputJSFileName(fileName, referencedProject, files)
const relativeJSFileName = configs.resolvePath(jsFileName)
if (!configs.compilerModule.sys.fileExists(jsFileName)) {
throw new Error(
'Could not find output JavaScript file for input ' +
`${relativeFilePath} (looked at ${relativeJSFileName}).\n` +
'The input file is part of a project reference located at ' +
`${relativeProjectConfigPath}, so ts-jest is looking for the ` +
'project’s pre-built output on disk. Try running `tsc --build` ' +
'to build project references.',
)
}

const mapFileName = `${jsFileName}.map`
const outputText = configs.compilerModule.sys.readFile(jsFileName)
const sourceMapText = configs.compilerModule.sys.readFile(mapFileName)

return [outputText!, sourceMapText!]
}
51 changes: 0 additions & 51 deletions src/compiler/language-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,57 +17,6 @@ describe('Language service', () => {
logTarget.clear()
})

it('should get compile result from referenced project when there is a built reference project', () => {
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp },
tsJestConfig: { tsConfig: false },
})
const source = 'console.log("hello")'
const fileName = 'test-reference-project.ts'
const getAndCacheProjectReferenceSpy = jest
.spyOn(compilerUtils, 'getAndCacheProjectReference')
.mockReturnValueOnce({} as any)
jest
.spyOn(compilerUtils, 'getCompileResultFromReferencedProject')
.mockImplementationOnce(() => [
source,
'{"version":3,"file":"test-reference-project.js","sourceRoot":"","sources":["test-reference-project.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA","sourcesContent":["console.log(\\"hello\\")"]}',
])
writeFileSync(fileName, source, 'utf8')

compiler.compile(source, fileName)

expect(getAndCacheProjectReferenceSpy).toHaveBeenCalled()
expect(compilerUtils.getCompileResultFromReferencedProject).toHaveBeenCalled()

jest.restoreAllMocks()
removeSync(fileName)
})

it('should get compile result from language service when there is no referenced project', () => {
const tmp = tempDir('compiler')
const compiler = makeCompiler({
jestConfig: { cache: true, cacheDirectory: tmp },
tsJestConfig: { tsConfig: false },
})
const source = 'console.log("hello")'
const fileName = 'test-no-reference-project.ts'
const getAndCacheProjectReferenceSpy = jest
.spyOn(compilerUtils, 'getAndCacheProjectReference')
.mockReturnValueOnce(undefined)
jest.spyOn(compilerUtils, 'getCompileResultFromReferencedProject')
writeFileSync(fileName, source, 'utf8')

compiler.compile(source, fileName)

expect(getAndCacheProjectReferenceSpy).toHaveBeenCalled()
expect(compilerUtils.getCompileResultFromReferencedProject).not.toHaveBeenCalled()

jest.restoreAllMocks()
removeSync(fileName)
})

it('should cache resolved modules for test file with testMatchPatterns from jest config when match', () => {
const spy = jest.spyOn(compilerUtils, 'cacheResolvedModules').mockImplementationOnce(() => {})
const tmp = tempDir('compiler')
Expand Down
Loading