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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '../dist/util/exported'
1 change: 1 addition & 0 deletions utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../dist/util/exported')

0 comments on commit 33ff29f

Please sign in to comment.