Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import { LogContexts, LogLevels } from 'bs-logger'
import { readFileSync } from 'fs'
import { resolve } from 'path'
import { createJestPreset as createJestPresetCore } from './config/create-jest-preset'
import { pathsToModuleNameMapper as pathsToModuleNameMapperCore } from './config/paths-to-module-name-mapper'
import { TsJestTransformer } from './ts-jest-transformer'
import { TsJestGlobalOptions } from './types'
import { rootLogger } from './util/logger'
import { Deprecateds, interpolate } from './util/messages'
import { mocked as mockedCore } from './util/testing'
import { VersionCheckers } from './util/version-checkers'
// deprecate helpers
const warn = rootLogger.child({ [LogContexts.logLevel]: LogLevels.warn })
const helperMoved = any>(name: string, helper: T) =>
warn.wrap(interpolate(Deprecateds.HelperMovedToUtils, { helper: name }), helper)
/** @deprecated */
export const mocked = helperMoved('mocked', mockedCore)
/** @deprecated */
export const createJestPreset = helperMoved('createJestPreset', createJestPresetCore)
/** @deprecated */
export const pathsToModuleNameMapper = helperMoved('pathsToModuleNameMapper', pathsToModuleNameMapperCore)
// tslint:disable-next-line:no-var-requires
export const version: string = require('../package.json').version
export const digest: string = readFileSync(resolve(__dirname, '..', '.ts-jest-digest'), 'utf8')
let transformer!: TsJestTransformer
function defaultTransformer(): TsJestTransformer {
}
// Use full language services when the fast option is disabled.
if (!configs.tsJest.isolatedModules) {
// Set the file contents into cache.
const updateMemoryCache = (code: string, fileName: string) => {
logger.debug({ fileName }, `updateMemoryCache()`)
if (memoryCache.contents[fileName] !== code) {
memoryCache.contents[fileName] = code
memoryCache.versions[fileName] = (memoryCache.versions[fileName] || 0) + 1
}
}
// Create the compiler host for type checking.
const serviceHostDebugCtx = {
[LogContexts.logLevel]: LogLevels.debug,
namespace: 'ts:serviceHost',
call: null,
}
const serviceHostTraceCtx = {
...serviceHostDebugCtx,
[LogContexts.logLevel]: LogLevels.trace,
}
const serviceHost = {
getScriptFileNames: () => Object.keys(memoryCache.versions),
getScriptVersion: (fileName: string) => {
const normalizedFileName = normalize(fileName)
const version = memoryCache.versions[normalizedFileName]
// We need to return `undefined` and not a string here because TypeScript will use
// `getScriptVersion` and compare against their own version - which can be `undefined`.
import { LogContexts } from 'bs-logger'
import { CompilerOptions } from 'typescript'
import { rootLogger } from '../util/logger'
import { Errors, interpolate } from '../util/messages'
type TsPathMapping = Exclude
type JestPathMapping = jest.InitialOptions['moduleNameMapper']
// we don't need to escape all chars, so commented out is the real one
// const escapeRegex = (str: string) => str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
const escapeRegex = (str: string) => str.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
const logger = rootLogger.child({ [LogContexts.namespace]: 'path-mapper' })
export const pathsToModuleNameMapper = (
mapping: TsPathMapping,
{ prefix = '' }: { prefix?: string } = {},
): JestPathMapping => {
const jestMap: JestPathMapping = {}
for (const fromPath of Object.keys(mapping)) {
let pattern: string
const toPaths = mapping[fromPath]
// check that we have only one target path
if (toPaths.length === 0) {
logger.warn(interpolate(Errors.NotMappingPathWithEmptyMap, { path: fromPath }))
continue
} else if (toPaths.length > 1) {
logger.warn(
interpolate(Errors.MappingOnlyFirstTargetOfPath, {
[LogContexts.logLevel]: LogLevels.trace,
version: require('../../package.json').version,
},
targets: process.env.TS_JEST_LOG || undefined,
})
/**
* @internal
*/
export let rootLogger = createLogger(buildOptions())
backportTsJestDebugEnvVar(rootLogger)
// re-create the logger if the env var has been backported
if (original !== process.env.TS_JEST_LOG) {
rootLogger = createLogger(buildOptions())
}
const original = process.env.TS_JEST_LOG
const buildOptions = () => ({
context: {
[LogContexts.package]: 'ts-jest',
[LogContexts.logLevel]: LogLevels.trace,
version: require('../../package.json').version,
},
targets: process.env.TS_JEST_LOG || undefined,
})
/**
* @internal
*/
export let rootLogger = createLogger(buildOptions())
backportTsJestDebugEnvVar(rootLogger)
// re-create the logger if the env var has been backported
if (original !== process.env.TS_JEST_LOG) {
rootLogger = createLogger(buildOptions())
}
logger.debug({ fileName }, `updateMemoryCache()`)
if (memoryCache.contents[fileName] !== code) {
memoryCache.contents[fileName] = code
memoryCache.versions[fileName] = (memoryCache.versions[fileName] || 0) + 1
}
}
// Create the compiler host for type checking.
const serviceHostDebugCtx = {
[LogContexts.logLevel]: LogLevels.debug,
namespace: 'ts:serviceHost',
call: null,
}
const serviceHostTraceCtx = {
...serviceHostDebugCtx,
[LogContexts.logLevel]: LogLevels.trace,
}
const serviceHost = {
getScriptFileNames: () => Object.keys(memoryCache.versions),
getScriptVersion: (fileName: string) => {
const normalizedFileName = normalize(fileName)
const version = memoryCache.versions[normalizedFileName]
// We need to return `undefined` and not a string here because TypeScript will use
// `getScriptVersion` and compare against their own version - which can be `undefined`.
// If we don't return `undefined` it results in `undefined === "undefined"` and run
// `createProgram` again (which is very slow). Using a `string` assertion here to avoid
// TypeScript errors from the function signature (expects `(x: string) => string`).
return version === undefined ? ((undefined as any) as string) : String(version)
},
getScriptSnapshot(fileName: string) {
console.log(bar)
jest.unmock('./foo')
jest.mock('./bar')
jest.mock('./bar/foo', () => 'foo')
jest.unmock('./foo/bar')
}
const func2 = () => {
const bar = 'bar'
console.log(bar)
jest.mock('./bar')
jest.unmock('./foo/bar')
jest.mock('./bar/foo', () => 'foo')
jest.unmock('./foo')
}
`
const logger = testing.createLoggerMock()
const createFactory = () => {
return hoist.factory({ logger, compilerModule: tsc } as any)
}
const transpile = (source: string) => tsc.transpileModule(source, { transformers: { before: [createFactory()] } })
describe('hoisting', () => {
it('should have correct signature', () => {
expect(hoist.name).toBe('hoisting-jest-mock')
expect(typeof hoist.version).toBe('number')
expect(hoist.version).toBeGreaterThan(0)
expect(typeof hoist.factory).toBe('function')
})
it('should hoist jest mock() and unmock() statements', () => {
const out = transpile(CODE_WITH_HOISTING)
expect(out.outputText).toMatchInlineSnapshot(`
it('should use the cache', () => {
const compiled1 = compiler.compile(source, __filename)
expect(logTarget.filteredLines(LogLevels.debug, Infinity)).toMatchInlineSnapshot(`
Array [
"[level:20] readThrough(): cache miss
",
"[level:20] getOutput(): compiling using language service
",
"[level:20] updateMemoryCache()
",
"[level:20] visitSourceFileNode(): hoisting
",
"[level:20] getOutput(): computing diagnostics
",
"[level:20] readThrough(): writing caches
",
]
`)
export const run: CliCommand = async (args: Arguments /*, logger: Logger*/) => {
const nullLogger = createLogger({ targets: [] })
const file = args._[0]
const filePath = resolve(process.cwd(), file)
const footNotes: string[] = []
if (!existsSync(filePath)) {
throw new Error(`Configuration file ${file} does not exists.`)
}
const name = basename(file)
const isPackage = name === 'package.json'
if (!/\.(js|json)$/.test(name)) {
throw new TypeError(`Configuration file ${file} must be a JavaScript or JSON file.`)
}
let actualConfig: jest.InitialOptions = require(filePath)
if (isPackage) {
actualConfig = (actualConfig as any).jest
}
if (!actualConfig) actualConfig = {}
describe('raiseDiagnostics', () => {
const createTsError = jest.fn(
(list: Diagnostic[]) => new Error(list.map(d => `[TS${d.code}] ${d.messageText}`).join('\n')),
)
const filterDiagnostics = jest.fn(list => list)
const logger = testing.createLoggerMock()
const makeDiagnostic = ({
messageText = 'foo',
code = 9999,
category = DiagnosticCategory.Warning,
}: Partial = {}): Diagnostic => ({ messageText, code, category } as any)
it('should throw when warnOnly is false', () => {
const { raiseDiagnostics } = createConfigSet({ createTsError, filterDiagnostics })
expect(() => raiseDiagnostics([])).not.toThrow()
expect(() => raiseDiagnostics([makeDiagnostic()])).toThrowErrorMatchingInlineSnapshot(`"[TS9999] foo"`)
expect(() => raiseDiagnostics([makeDiagnostic({ category: DiagnosticCategory.Message })])).not.toThrow()
})
it('should not throw when warnOnly is true', () => {
const { raiseDiagnostics } = createConfigSet({
createTsError,
filterDiagnostics,
logger,