Skip to content

Commit

Permalink
fix(helpers): deprecate import from ts-jest, now ts-jest/utils
Browse files Browse the repository at this point in the history
Importing from `ts-jest` everything will possibly make collision with
future jest API. Also any star export or import might not be compatible
with the target project. Now all helpers to be used in tests or config
files have been moved to `ts-jest/utils`. Original ones have been kept
in `ts-jest` for now, with a deprecation warning when using them.

Closes #782
  • Loading branch information
huafu committed Oct 6, 2018
1 parent 645558b commit 33ff29f
Show file tree
Hide file tree
Showing 17 changed files with 133 additions and 80 deletions.
9 changes: 9 additions & 0 deletions e2e/__cases__/test-helpers/deprecated.spec.ts
@@ -0,0 +1,9 @@
import { mocked } from 'ts-jest'
import { foo } from './to-mock'
jest.mock('./to-mock')

test('foo', () => {
foo()
// it should log that the helper moved
expect(mocked(foo).mock.calls.length).toBe(1)
})
2 changes: 1 addition & 1 deletion e2e/__cases__/test-helpers/fail.spec.ts
@@ -1,4 +1,4 @@
import { mocked } from 'ts-jest'
import { mocked } from 'ts-jest/utils'
import { foo, bar } from './to-mock'
jest.mock('./to-mock')

Expand Down
2 changes: 1 addition & 1 deletion e2e/__cases__/test-helpers/pass.spec.ts
@@ -1,4 +1,4 @@
import { mocked } from 'ts-jest'
import { mocked } from 'ts-jest/utils'
import { foo, bar } from './to-mock'
jest.mock('./to-mock')

Expand Down
4 changes: 2 additions & 2 deletions e2e/__templates__/with-jest-22/jest.config.js
@@ -1,6 +1,6 @@
const { jestPreset } = require('ts-jest')
const presets = require('ts-jest/presets')

module.exports = Object.assign({}, jestPreset, {
module.exports = Object.assign({}, presets.defaults, {
testEnvironment: 'node',
globals: { 'ts-jest': { tsConfig: {} } },
})
29 changes: 0 additions & 29 deletions e2e/__tests__/__snapshots__/test-helpers.test.ts.snap

This file was deleted.

8 changes: 8 additions & 0 deletions e2e/__tests__/test-helpers.test.ts
Expand Up @@ -4,3 +4,11 @@ test('test-helpers', () => {
const test = configureTestCase('test-helpers', { noCache: true })
expect(test.run(1)).toMatchSnapshot()
})

test('with esModuleInterop set to false', () => {
const test = configureTestCase('test-helpers', {
noCache: true,
tsJestConfig: { tsConfig: { esModuleInterop: false, allowSyntheticDefaultImports: false } },
})
expect(test.run(1)).toMatchSnapshot()
})
2 changes: 1 addition & 1 deletion src/cli/config/migrate.ts
Expand Up @@ -6,7 +6,7 @@ import { basename, resolve } from 'path'
import { Arguments } from 'yargs'

import { CliCommand } from '..'
import { TsJestPresets } from '../../types'
import { TsJestPresets } from '../../config/create-jest-preset'
import { backportJestConfig } from '../../util/backports'

const DEFAULT_PRESET = 'ts-jest/presets/default'
Expand Down
11 changes: 10 additions & 1 deletion src/config/create-jest-preset.ts
@@ -1,6 +1,5 @@
import * as jestConfig from 'jest-config'

import { CreateJestPresetOptions, TsJestPresets } from '../types'
import { rootLogger } from '../util/logger'

const logger = rootLogger.child({ namespace: 'jest-preset' })
Expand All @@ -12,6 +11,16 @@ const defaults = jestConfig.defaults || {
moduleFileExtensions: ['js', 'json', 'jsx', 'node'],
}

export interface TsJestPresets {
transform: Record<string, string>
testMatch: string[]
moduleFileExtensions: string[]
}

export interface CreateJestPresetOptions {
allowJs?: boolean
}

export function createJestPreset(
{ allowJs = false }: CreateJestPresetOptions = {},
from?: jest.InitialOptions,
Expand Down
38 changes: 38 additions & 0 deletions src/index.spec.ts
@@ -1,5 +1,8 @@
// tslint:disable:max-line-length
import { testing } from 'bs-logger'

import * as tsJest from '.'
import { logTargetMock } from './__helpers__/mocks'
import { TsJestTransformer } from './ts-jest-transformer'

jest.mock('./ts-jest-transformer', () => {
Expand Down Expand Up @@ -58,6 +61,41 @@ Array [
})
})

describe('moved helpers', () => {
let target: testing.LogTargetMock
beforeEach(() => {
target = logTargetMock()
target.clear()
})
it('should warn when using mocked', () => {
tsJest.mocked(42)
expect(target.lines.warn).toMatchInlineSnapshot(`
Array [
"[level:40] The \`mocked\` helper has been moved to \`ts-jest/utils\`. Use \`import { mocked } from 'ts-jest/utils'\` instead.
",
]
`)
})
it('should warn when using createJestPreset', () => {
tsJest.createJestPreset()
expect(target.lines.warn).toMatchInlineSnapshot(`
Array [
"[level:40] The \`createJestPreset\` helper has been moved to \`ts-jest/utils\`. Use \`import { createJestPreset } from 'ts-jest/utils'\` instead.
",
]
`)
})
it('should warn when using pathsToModuleNameMapper', () => {
tsJest.pathsToModuleNameMapper({})
expect(target.lines.warn).toMatchInlineSnapshot(`
Array [
"[level:40] The \`pathsToModuleNameMapper\` helper has been moved to \`ts-jest/utils\`. Use \`import { pathsToModuleNameMapper } from 'ts-jest/utils'\` instead.
",
]
`)
})
})

describe('createTransformer', () => {
it('should create different instances', () => {
const tr1 = tsJest.createTransformer()
Expand Down
21 changes: 15 additions & 6 deletions src/index.ts
@@ -1,13 +1,24 @@
import { LogContexts, LogLevels } from 'bs-logger'
import { readFileSync } from 'fs'
import { resolve } from 'path'

import { createJestPreset } from './config/create-jest-preset'
import { pathsToModuleNameMapper } from './config/paths-to-module-name-mapper'
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'

export * from './util/testing'
// deprecate helpers
const warn = rootLogger.child({ [LogContexts.logLevel]: LogLevels.warn })
const helperMoved = <T extends (...args: any[]) => any>(name: string, helper: T) =>
warn.wrap(interpolate(Deprecateds.HelperMovedToUtils, { helper: name }), helper)

export const mocked = helperMoved('mocked', mockedCore)
export const createJestPreset = helperMoved('createJestPreset', createJestPresetCore)
export const pathsToModuleNameMapper = helperMoved('pathsToModuleNameMapper', pathsToModuleNameMapperCore)

// tslint:disable-next-line:no-var-requires
export const version: string = require('../package.json').version
Expand Down Expand Up @@ -41,7 +52,7 @@ export function getCacheKey(...args: any[]): any {
// we let jest doing the instrumentation, it does it well
export const canInstrument = false

const jestPreset = createJestPreset()
const jestPreset = createJestPresetCore()

/**
* @internal
Expand All @@ -57,7 +68,5 @@ export const __resetModule = () => (transformer = undefined as any)

export {
// extra ==================
createJestPreset,
jestPreset,
pathsToModuleNameMapper,
}
38 changes: 0 additions & 38 deletions src/types.ts
Expand Up @@ -69,12 +69,6 @@ export interface TsJestGlobalOptions {
stringifyContentPathRegex?: string | RegExp
}

export interface TsJestPresets {
transform: Record<string, string>
testMatch: string[]
moduleFileExtensions: string[]
}

interface TsJestConfig$tsConfig$file {
kind: 'file'
value: string | undefined
Expand Down Expand Up @@ -117,10 +111,6 @@ export interface TsJestHooksMap {
afterProcess?(args: any[], result: string | jest.TransformedSource): string | jest.TransformedSource | void
}

export interface CreateJestPresetOptions {
allowJs?: boolean
}

/**
* @internal
*/
Expand Down Expand Up @@ -180,31 +170,3 @@ export interface AstTransformerDesc {
version: number
factory(cs: ConfigSet): TransformerFactory<SourceFile>
}

// test helpers

interface MockWithArgs<T> extends Function, jest.MockInstance<T> {
new (...args: ArgumentsOf<T>): T
(...args: ArgumentsOf<T>): any
}

// tslint:disable-next-line:ban-types
type MethodKeysOf<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]
// tslint:disable-next-line:ban-types
type PropertyKeysOf<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]
type ArgumentsOf<T> = T extends (...args: infer A) => any ? A : never
interface MockWithArgs<T> extends Function, jest.MockInstance<T> {
new (...args: ArgumentsOf<T>): T
(...args: ArgumentsOf<T>): any
}

type MockedFunction<T> = MockWithArgs<T> & { [K in keyof T]: T[K] }
type MockedFunctionDeep<T> = MockWithArgs<T> & MockedObjectDeep<T>
type MockedObject<T> = { [K in MethodKeysOf<T>]: MockedFunction<T[K]> } & { [K in PropertyKeysOf<T>]: T[K] }
type MockedObjectDeep<T> = { [K in MethodKeysOf<T>]: MockedFunctionDeep<T[K]> } &
{ [K in PropertyKeysOf<T>]: MaybeMockedDeep<T[K]> }

// tslint:disable-next-line:ban-types
export type MaybeMockedDeep<T> = T extends Function ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T
// tslint:disable-next-line:ban-types
export type MaybeMocked<T> = T extends Function ? MockedFunction<T> : T extends object ? MockedObject<T> : T
17 changes: 17 additions & 0 deletions src/util/exported.spec.ts
@@ -0,0 +1,17 @@
import { createJestPreset } from '../config/create-jest-preset'
import { pathsToModuleNameMapper } from '../config/paths-to-module-name-mapper'

import * as subject from './exported'
import { mocked } from './testing'

describe('exported helpers', () => {
it('should have mocked', () => {
expect(subject).toHaveProperty('mocked', mocked)
})
it('should have createJestPreset', () => {
expect(subject).toHaveProperty('createJestPreset', createJestPreset)
})
it('should have pathsToModuleNameMapper', () => {
expect(subject).toHaveProperty('pathsToModuleNameMapper', pathsToModuleNameMapper)
})
})
3 changes: 3 additions & 0 deletions src/util/exported.ts
@@ -0,0 +1,3 @@
export { mocked } from './testing'
export { createJestPreset } from '../config/create-jest-preset'
export { pathsToModuleNameMapper } from '../config/paths-to-module-name-mapper'
1 change: 1 addition & 0 deletions src/util/messages.ts
Expand Up @@ -40,6 +40,7 @@ export enum Deprecateds {
ConfigOption = '"[jest-config].{{oldPath}}" is deprecated, use "[jest-config].{{newPath}}" instead.',
ConfigOptionWithNote = '"[jest-config].{{oldPath}}" is deprecated, use "[jest-config].{{newPath}}" instead.\n ↳ {{note}}',
ConfigOptionUseBabelRcNote = 'See `babel-jest` related issue: https://github.com/facebook/jest/issues/3845',
HelperMovedToUtils = "The `{{helper}}` helper has been moved to `ts-jest/utils`. Use `import { {{helper}} } from 'ts-jest/utils'` instead.",
}

/**
Expand Down
26 changes: 25 additions & 1 deletion src/util/testing.ts
@@ -1,4 +1,28 @@
import { MaybeMocked, MaybeMockedDeep } from '../types'
interface MockWithArgs<T> extends Function, jest.MockInstance<T> {
new (...args: ArgumentsOf<T>): T
(...args: ArgumentsOf<T>): any
}

// tslint:disable-next-line:ban-types
type MethodKeysOf<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]
// tslint:disable-next-line:ban-types
type PropertyKeysOf<T> = { [K in keyof T]: T[K] extends Function ? never : K }[keyof T]
type ArgumentsOf<T> = T extends (...args: infer A) => any ? A : never
interface MockWithArgs<T> extends Function, jest.MockInstance<T> {
new (...args: ArgumentsOf<T>): T
(...args: ArgumentsOf<T>): any
}

type MockedFunction<T> = MockWithArgs<T> & { [K in keyof T]: T[K] }
type MockedFunctionDeep<T> = MockWithArgs<T> & MockedObjectDeep<T>
type MockedObject<T> = { [K in MethodKeysOf<T>]: MockedFunction<T[K]> } & { [K in PropertyKeysOf<T>]: T[K] }
type MockedObjectDeep<T> = { [K in MethodKeysOf<T>]: MockedFunctionDeep<T[K]> } &
{ [K in PropertyKeysOf<T>]: MaybeMockedDeep<T[K]> }

// tslint:disable-next-line:ban-types
export type MaybeMockedDeep<T> = T extends Function ? MockedFunctionDeep<T> : T extends object ? MockedObjectDeep<T> : T
// tslint:disable-next-line:ban-types
export type MaybeMocked<T> = T extends Function ? MockedFunction<T> : T extends object ? MockedObject<T> : T

// the typings test helper
export function mocked<T>(item: T, deep?: false): MaybeMocked<T>
Expand Down
1 change: 1 addition & 0 deletions utils/index.d.ts
@@ -0,0 +1 @@
export * from '../dist/util/exported'
1 change: 1 addition & 0 deletions utils/index.js
@@ -0,0 +1 @@
module.exports = require('../dist/util/exported')

0 comments on commit 33ff29f

Please sign in to comment.