From bd5544812cddcc119a18e5a3f7def49d3b1bc2a1 Mon Sep 17 00:00:00 2001 From: Huafu Gandon Date: Sun, 12 Aug 2018 18:04:44 +0200 Subject: [PATCH] feat: cache key + tests --- .npmignore | 1 - e2e/jest.config.js | 13 ++- jest.config.js | 12 ++- package-lock.json | 5 + package.json | 1 + .../__helpers__/fakers.ts | 34 ++++++- src/__helpers__/spy-these.ts | 29 ++++++ src/__mocks__/ts-program.ts | 21 +++++ .../ts-jest-transformer.spec.ts.snap | 2 +- .../__snapshots__/ts-program.spec.ts.snap | 0 src/ts-jest-transformer.spec.ts | 92 +++++++++++++++++++ src/ts-jest-transformer.ts | 70 ++++++++++++-- {test => src}/ts-program.spec.ts | 8 +- src/ts-program.ts | 23 +---- src/types.ts | 14 ++- src/utils/__mocks__/backports.ts | 5 + src/utils/__mocks__/closest-package-json.ts | 17 ++++ src/utils/closest-package-json.ts | 67 ++++++++++++++ src/utils/sha1.ts | 28 ++++++ test/__helpers__/jest-config-mock.ts | 17 ---- test/__helpers__/ts-jest-config-mock.ts | 7 -- test/ts-jest-transformer.spec.ts | 32 ------- tsconfig.build.json | 7 +- tsconfig.json | 2 + 24 files changed, 401 insertions(+), 106 deletions(-) rename test/__helpers__/sources-mock.ts => src/__helpers__/fakers.ts (56%) create mode 100644 src/__helpers__/spy-these.ts create mode 100644 src/__mocks__/ts-program.ts rename {test => src}/__snapshots__/ts-jest-transformer.spec.ts.snap (97%) rename {test => src}/__snapshots__/ts-program.spec.ts.snap (100%) create mode 100644 src/ts-jest-transformer.spec.ts rename {test => src}/ts-program.spec.ts (81%) create mode 100644 src/utils/__mocks__/backports.ts create mode 100644 src/utils/__mocks__/closest-package-json.ts create mode 100644 src/utils/closest-package-json.ts create mode 100644 src/utils/sha1.ts delete mode 100644 test/__helpers__/jest-config-mock.ts delete mode 100644 test/__helpers__/ts-jest-config-mock.ts delete mode 100644 test/ts-jest-transformer.spec.ts diff --git a/.npmignore b/.npmignore index 7cfff8b0a7..47251ba739 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,5 @@ # Tests e2e -test # Developement scripts scripts diff --git a/e2e/jest.config.js b/e2e/jest.config.js index fd9fcb11bf..0c83f1c1f4 100644 --- a/e2e/jest.config.js +++ b/e2e/jest.config.js @@ -1,10 +1,9 @@ +const base = require('../jest.config'); + module.exports = { - transform: { - '\\.ts$': '/../dist/index.js', - }, - testRegex: '/__tests__/.+\\.test\\.ts$', - collectCoverageFrom: ['/../src/**/*.ts'], - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], - testEnvironment: 'node', + ...base, + rootDir: '.', + testRegex: '/__tests__/.+\\.(test|spec)\\.ts$', + coverageDirectory: '/../coverage/e2e', snapshotSerializers: ['/__serializers__/test-run-result.ts'], }; diff --git a/jest.config.js b/jest.config.js index e2371dd51d..2c7c0c18ac 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,10 +1,16 @@ module.exports = { - rootDir: './test', + rootDir: 'src', transform: { '\\.ts$': '/../dist/index.js', }, - testRegex: '/.+\\.spec\\.ts$', - collectCoverageFrom: ['/../src/**/*.ts'], + testRegex: '\\.(spec|test)\\.ts$', + coverageDirectory: '/../coverage/unit', + collectCoverageFrom: [ + '/../src/**/*.ts', + '!/../src/**/*.spec.ts', + '!/../src/**/*.test.ts', + '!/../src/**/__*__/', + ], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'], testEnvironment: 'node', }; diff --git a/package-lock.json b/package-lock.json index 21b5ff5ef0..77987e0f15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,6 +62,11 @@ "@types/node": "*" } }, + "@types/gist-package-json": { + "version": "git+https://gist.github.com/5c1cc527fe6b5b7dba41fec7fe54bf6e.git#2444af3c30cbcb867b9699df9f1cf97d814cd2d8", + "from": "git+https://gist.github.com/5c1cc527fe6b5b7dba41fec7fe54bf6e.git", + "dev": true + }, "@types/jest": { "version": "23.3.1", "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.3.1.tgz", diff --git a/package.json b/package.json index 0cb3843245..cc945838ed 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "devDependencies": { "@types/babel__core": "^7.0.1", "@types/fs-extra": "5.0.4", + "@types/gist-package-json": "git+https://gist.github.com/5c1cc527fe6b5b7dba41fec7fe54bf6e.git", "@types/jest": "^23.3.1", "@types/node": "^10.5.7", "closest-file-data": "^0.1.4", diff --git a/test/__helpers__/sources-mock.ts b/src/__helpers__/fakers.ts similarity index 56% rename from test/__helpers__/sources-mock.ts rename to src/__helpers__/fakers.ts index dbfd0cedab..04b26284cd 100644 --- a/test/__helpers__/sources-mock.ts +++ b/src/__helpers__/fakers.ts @@ -1,10 +1,15 @@ -import { resolve } from 'path'; +import { TsJestGlobalOptions } from '../types'; +import { resolve, relative } from 'path'; +import spyThese from './spy-these'; +import realFs from 'fs'; -export function filePathMock(relPath: string): string { +export function filePath(relPath: string): string { return resolve(__dirname, '..', '..', relPath); } -export function transpiledTsSourceMock() { +export const rootDir = filePath(''); + +export function transpiledTsSource() { return ` "use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { @@ -23,7 +28,7 @@ describe('hello', function () { `; } -export function tsSourceMock() { +export function typescriptSource() { return ` import upper from './upper'; import lower from './lower'; @@ -39,3 +44,24 @@ describe('hello', () => { }); `; } + +export function tsJestConfig( + options?: TsJestGlobalOptions, +): T { + return { ...options } as any; +} + +export function jestConfig( + options?: jest.InitialOptions, + tsJestOptions?: TsJestGlobalOptions, +): T { + const res = { + globals: {}, + moduleFileExtensions: ['ts', 'js'], + ...options, + } as any; + if (tsJestOptions) { + res.globals['ts-jest'] = tsJestConfig(tsJestOptions); + } + return res; +} diff --git a/src/__helpers__/spy-these.ts b/src/__helpers__/spy-these.ts new file mode 100644 index 0000000000..865171d85a --- /dev/null +++ b/src/__helpers__/spy-these.ts @@ -0,0 +1,29 @@ +export default function spyThese( + object: T, + implementations: { [key in K]: T[K] | any | undefined }, +): { [key in K]: jest.SpyInstance } & { mockRestore: () => void } { + const keys = Object.keys(implementations) as K[]; + const res = keys.reduce( + (map, key) => { + const actual = object[key] as any; + const spy = jest.spyOn(object, key as K); + if (implementations[key]) { + const impl = implementations[key] as (...args: any[]) => any; + if (impl.length && /\W\$super\W/.test(impl.toString())) { + spy.mockImplementation(function(this: T, ...args: any[]) { + return impl.call(this, () => actual.apply(this, args), ...args); + }); + } else { + spy.mockImplementation(impl); + } + } + return map; + }, + {} as any, + ); + // utility to restore all + res.mockRestore = () => { + keys.forEach(key => res[key].mockRestore()); + }; + return res; +} diff --git a/src/__mocks__/ts-program.ts b/src/__mocks__/ts-program.ts new file mode 100644 index 0000000000..a5868f570f --- /dev/null +++ b/src/__mocks__/ts-program.ts @@ -0,0 +1,21 @@ +import * as fakers from '../__helpers__/fakers'; +import { TsJestConfig, TsJestProgram } from '../types'; +import { ParsedCommandLine } from 'typescript'; + +// tslint:disable-next-line:variable-name +export let __tsConfig: any = {}; + +export default class TsProgramMock implements TsJestProgram { + get parsedConfig(): ParsedCommandLine { + return __tsConfig; + } + + constructor( + public rootDir: string = fakers.filePath(''), + public tsJestConfig: TsJestConfig = fakers.tsJestConfig(), + ) {} + + transpileModule(_: string, source: string) { + return source; + } +} diff --git a/test/__snapshots__/ts-jest-transformer.spec.ts.snap b/src/__snapshots__/ts-jest-transformer.spec.ts.snap similarity index 97% rename from test/__snapshots__/ts-jest-transformer.spec.ts.snap rename to src/__snapshots__/ts-jest-transformer.spec.ts.snap index b3fb932181..7f52f44c72 100644 --- a/test/__snapshots__/ts-jest-transformer.spec.ts.snap +++ b/src/__snapshots__/ts-jest-transformer.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`hoisting should hoist jest.mock calls using babel 1`] = ` +exports[`process hoisting should hoist jest.mock calls using babel 1`] = ` " \\"use strict\\"; diff --git a/test/__snapshots__/ts-program.spec.ts.snap b/src/__snapshots__/ts-program.spec.ts.snap similarity index 100% rename from test/__snapshots__/ts-program.spec.ts.snap rename to src/__snapshots__/ts-program.spec.ts.snap diff --git a/src/ts-jest-transformer.spec.ts b/src/ts-jest-transformer.spec.ts new file mode 100644 index 0000000000..8230439d1f --- /dev/null +++ b/src/ts-jest-transformer.spec.ts @@ -0,0 +1,92 @@ +import TsJestTransformer from './ts-jest-transformer'; +import * as fakers from './__helpers__/fakers'; +import * as babelCfg from './utils/babel-config'; +import * as closesPkgJson from './utils/closest-package-json'; +import * as TsJestProgram from './ts-program'; + +jest.mock('./ts-program'); +jest.mock('./utils/closest-package-json'); +jest.mock('./utils/backports'); + +const mocks = { + babelConfig: undefined as any, + set packageJson(val: any) { + (closesPkgJson as any).__default = val; + }, + set tsConfig(val: any) { + (TsJestProgram as any).__tsConfig = val; + }, + reset() { + this.babelConfig = undefined; + this.packageJson = { name: 'mock' }; + this.tsConfig = {}; + }, +}; +beforeAll(() => { + jest + .spyOn(babelCfg, 'loadDefault') + .mockImplementation(() => mocks.babelConfig); +}); +afterEach(() => { + mocks.reset(); +}); + +describe('process', () => { + describe('hoisting', () => { + const transformer = new TsJestTransformer(); + it('should hoist jest.mock calls using babel', () => { + const config = fakers.jestConfig({}, { babelJest: true }); + const result = transformer.process( + fakers.transpiledTsSource(), + fakers.filePath('path/to/file.ts'), + config, + ) as jest.TransformedSource; + expect(result.code).toMatchSnapshot(); + }); + }); // hoisting +}); // process + +describe('getCacheKey', () => { + const fakeSource = fakers.typescriptSource(); + const fakeFilePath = fakers.filePath('file.ts'); + const fakeJestConfig = JSON.stringify( + fakers.jestConfig({}, { babelJest: true }), + ); + + const call: typeof TsJestTransformer['prototype']['getCacheKey'] = ( + // tslint:disable-next-line:trailing-comma + ...args + ) => new TsJestTransformer().getCacheKey(...args); + const defaultCall = () => call(fakeSource, fakeFilePath, fakeJestConfig); + + it('should be a 28 chars string, different for each case', () => { + const allCacheKeys = [ + defaultCall(), + call('const b = 2', fakeFilePath, fakeJestConfig), + call(fakeSource, fakers.filePath('other-file.ts'), fakeJestConfig), + call(fakeSource, fakeFilePath, '{"rootDir": "./sub"}'), + call(fakeSource, fakeFilePath, fakeJestConfig, { instrument: true }), + call(fakeSource, fakeFilePath, fakeJestConfig, { rootDir: '/child' }), + ]; + + mocks.babelConfig = '{sourceMaps: true}'; + allCacheKeys.push(defaultCall()); + mocks.reset(); + + mocks.tsConfig = '{"files": []}'; + allCacheKeys.push(defaultCall()); + mocks.reset(); + + mocks.packageJson = '{"name": "dummy"}'; + allCacheKeys.push(defaultCall()); + mocks.reset(); + + // uniq array should equal original + expect( + allCacheKeys.filter((k, i) => allCacheKeys.indexOf(k) === i), + ).toEqual(allCacheKeys); + allCacheKeys.forEach(cacheKey => { + expect(cacheKey).toHaveLength(28); + }); + }); // all different and 28 chars +}); // getCacheKey diff --git a/src/ts-jest-transformer.ts b/src/ts-jest-transformer.ts index 5f689cbee9..1c3a839acc 100644 --- a/src/ts-jest-transformer.ts +++ b/src/ts-jest-transformer.ts @@ -7,16 +7,23 @@ import jestRootDir from './utils/jest-root-dir'; import { sep, resolve } from 'path'; import parseJsonUnsafe from './utils/parse-json-unsafe'; import * as babelCfg from './utils/babel-config'; - -// TODO: could be used if we need to handle the cache key ourself -// const normalizeJestConfig = (jestConfig: jest.ProjectConfig): jest.ProjectConfig => { -// const config = { ...jestConfig, rootDir: rootDirFor(jestConfig) }; -// delete config.cacheDirectory; -// delete config.name; -// return config; -// }; +import closestPatckageJson from './utils/closest-package-json'; +import sha1 from './utils/sha1'; export default class TsJestTransformer implements jest.Transformer { + @Memoize(jestRootDir) + sanitizedJestConfigFor( + jestConfig: T, + ): T { + const config = { + ...(jestConfig as object), + rootDir: jestRootDir(jestConfig), + } as T; + delete config.cacheDirectory; + delete config.name; + return config; + } + @Memoize(jestRootDir) babelJestFor(jestConfig: jest.ProjectConfig): jest.Transformer { // babel-jest is shipped with jest, no need to use the importer @@ -99,6 +106,53 @@ export default class TsJestTransformer implements jest.Transformer { return result; } + // we can cache as for same instance the cache key won't change as soon as the path/content pair + // doesn't change + // TODO: find out if jest is already using this cache strategy and remove it if so + @Memoize((data: string, path: string) => `${path}::${data}`) + getCacheKey( + fileContent: string, + filePath: string, + jestConfigStr: string, + { + instrument = false, + rootDir, + }: { instrument?: boolean; rootDir?: string } = {}, + ): string { + const CHAR0 = '\0'; + // will be used as the hashing data source + const hashData: string[] = []; + const hashUpdate = (data: string) => hashData.push(data, CHAR0); + + // add file path and its content + hashUpdate(filePath); + hashUpdate(fileContent); + + // saniize and normalize jest config + const jestConfig: jest.ProjectConfig = JSON.parse(jestConfigStr); + jestConfig.rootDir = rootDir = jestRootDir({ + rootDir: rootDir || jestConfig.rootDir, + }); + const sanitizedJestConfig: jest.ProjectConfig = this.sanitizedJestConfigFor( + jestConfig, + ); + // add jest config + hashUpdate(JSON.stringify(sanitizedJestConfig)); + // add project's package.json + const projectPkg = closestPatckageJson(rootDir, true); + hashUpdate(projectPkg); + // add babel config if using babel jest + const babelConfig = this.babelConfigFor(jestConfig) || {}; + hashUpdate(JSON.stringify(babelConfig)); + // add tsconfig + const tsConfig = this.programFor(sanitizedJestConfig).parsedConfig; + hashUpdate(JSON.stringify(tsConfig)); + // add instrument, even if we don't use it since `canInstrument` is false + hashUpdate(`instrument:${instrument ? 'on' : 'off'}`); + + return sha1(...hashData); + } + // TODO: use jest-config package to try to get current config and see if we are going to use babel jest or not // in which case we'd return `true` there: // get canInstrument() {} diff --git a/test/ts-program.spec.ts b/src/ts-program.spec.ts similarity index 81% rename from test/ts-program.spec.ts rename to src/ts-program.spec.ts index 757331cb4e..6cae099b8a 100644 --- a/test/ts-program.spec.ts +++ b/src/ts-program.spec.ts @@ -1,9 +1,9 @@ -import TsProgram from '../src/ts-program'; +import TsProgram from './ts-program'; import { resolve } from 'path'; -import { tsSourceMock, filePathMock } from './__helpers__/sources-mock'; +import * as fakers from './__helpers__/fakers'; -const path = filePathMock('path/to/file.ts'); -const content = tsSourceMock(); +const path = fakers.filePath('path/to/file.ts'); +const content = fakers.typescriptSource(); describe('hoisting', () => { describe('without babel', () => { diff --git a/src/ts-program.ts b/src/ts-program.ts index c32c0a1050..b4c7738efd 100644 --- a/src/ts-program.ts +++ b/src/ts-program.ts @@ -1,7 +1,6 @@ // tslint:disable:member-ordering -import { TsJestConfig } from './types'; +import { TsJestConfig, TsJestProgram } from './types'; import { - FormatDiagnosticsHost, sys, findConfigFile, CompilerOptions, @@ -32,25 +31,9 @@ export const compilerOptionsOverrides: Readonly = { inlineSourceMap: true, }; -export default class TsProgram { +export default class TsProgram implements TsJestProgram { constructor(readonly rootDir: string, readonly tsJestConfig: TsJestConfig) {} - @Memoize() - get formatHost(): FormatDiagnosticsHost { - return { - getCanonicalFileName: path => path, - getCurrentDirectory: () => this.rootDir, - getNewLine: () => sys.newLine, - }; - } - - @Memoize() - get fileNameNormalizer() { - // const { rootDir } = this; - // return (path: string): string => resolve(rootDir, path); - return (path: string): string => path; - } - @Memoize() get configFile(): string | null { const given = this.tsJestConfig.inputOptions.tsConfig; @@ -172,7 +155,7 @@ export default class TsProgram { const message = flattenDiagnosticMessageText( diagnostic.messageText, - this.formatHost.getNewLine(), + sys.newLine, ); throw new Error(`${diagnostic.code}: ${message}`); } diff --git a/src/types.ts b/src/types.ts index 3594ff2c0c..e2fbdbbcb4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,8 +1,10 @@ import * as _babelJest from 'babel-jest'; -import { CompilerOptions } from 'typescript'; +import { CompilerOptions, ParsedCommandLine } from 'typescript'; import _closestFileData from 'closest-file-data'; import * as _babel from 'babel__core'; +import { IPackageJSON } from 'gist-package-json'; +export type TPackageJson = IPackageJSON; export type TBabelJest = typeof _babelJest; export type TClosestFileData = typeof _closestFileData; @@ -57,3 +59,13 @@ export interface TsJestConfig { // to deprecate / deprecated === === === stringifyContentRegex?: RegExp; } + +export interface TsJestProgram { + readonly parsedConfig: ParsedCommandLine; + transpileModule( + path: string, + content: string, + instrument?: boolean, + extraCompilerOptions?: CompilerOptions, + ): string; +} diff --git a/src/utils/__mocks__/backports.ts b/src/utils/__mocks__/backports.ts new file mode 100644 index 0000000000..0cadc790b6 --- /dev/null +++ b/src/utils/__mocks__/backports.ts @@ -0,0 +1,5 @@ +import * as _backports from '../backports'; + +export const backportJestConfig: typeof _backports['backportJestConfig'] = val => ({ + ...(val as any), +}); diff --git a/src/utils/__mocks__/closest-package-json.ts b/src/utils/__mocks__/closest-package-json.ts new file mode 100644 index 0000000000..3ef526a5ce --- /dev/null +++ b/src/utils/__mocks__/closest-package-json.ts @@ -0,0 +1,17 @@ +import _closestPackageJson from '../closest-package-json'; +import { TPackageJson } from '../../types'; + +// tslint:disable-next-line:variable-name +export const __byPath: Record = {}; +// tslint:disable-next-line:variable-name +export const __default: TPackageJson = { name: 'mock' }; + +const closestPackageJson: typeof _closestPackageJson = ( + fromPath: string, + asString: boolean = false, +) => { + const res = fromPath in __byPath ? __byPath[fromPath] : __default; + return (asString ? JSON.stringify(res) : res) as any; +}; + +export default closestPackageJson; diff --git a/src/utils/closest-package-json.ts b/src/utils/closest-package-json.ts new file mode 100644 index 0000000000..b3ac4a29b4 --- /dev/null +++ b/src/utils/closest-package-json.ts @@ -0,0 +1,67 @@ +// we could have used `closest-file-data` but since it's more simple than finding babel +// config, if the user dosn't need babel processing he won't need to add closest-file-data +// to its dependencies +import { resolve, join } from 'path'; +import { TPackageJson } from '../types'; +import { existsSync, readFileSync } from 'fs'; + +interface CacheItem { + data: Readonly; + _data?: Readonly; + str: string; +} +export let cache: { + [file: string]: CacheItem; +} = Object.create(null); + +export default function ownerPackageData( + fromPath: string, + asString?: false, +): TPackageJson; +export default function ownerPackageData( + fromPath: string, + asString: true, +): string; +export default function ownerPackageData( + fromPath: string, + asString: boolean = false, +): TPackageJson | string { + if (fromPath in cache) { + return cache[fromPath][asString ? 'str' : 'data']; + } + + let path: string = fromPath; + let oldPath: string; + let packagePath: string | undefined; + do { + oldPath = path; + packagePath = join(path, 'package.json'); + if (existsSync(packagePath)) { + break; + } + } while ( + // tslint:disable-next-line:no-conditional-assignment + (path = resolve(path, '..')) !== oldPath || + // allows to reset the packagePath when exiting the loop + // tslint:disable-next-line:no-conditional-assignment + (packagePath = undefined) + ); + + // fail if not found + if (!packagePath) { + throw new Error(`[ts-jest] Unable to find package.json from "${fromPath}"`); + } + + const str = readFileSync(packagePath, 'utf8'); + const cached: CacheItem = Object.freeze({ + str, + get data() { + return ( + cached._data || + (cached._data = Object.freeze({ ...JSON.parse(cached.str) })) + ); + }, + }); + cache[fromPath] = cached; + return asString ? str : cached.data; +} diff --git a/src/utils/sha1.ts b/src/utils/sha1.ts new file mode 100644 index 0000000000..70c02f23d3 --- /dev/null +++ b/src/utils/sha1.ts @@ -0,0 +1,28 @@ +import { createHash } from 'crypto'; + +// stores hashes made out of only one argument being a string +export const cache: { [key: string]: string } = Object.create(null); + +type DataItem = string | Buffer; + +export default function sha1(...data: DataItem[]): string { + const canCache = data.length === 1 && typeof data[0] === 'string'; + // caching + let cacheKey!: string; + if (canCache) { + cacheKey = data[0] as string; + if (cacheKey in cache) { + return cache[cacheKey]; + } + } + + // we use SHA1 because it's the fastest provided by node and we are not concerned about security + const hash = createHash('sha1'); + data.forEach(item => hash.update(item)); + const res = hash.digest('base64').toString(); + + if (canCache) { + cache[cacheKey] = res; + } + return res; +} diff --git a/test/__helpers__/jest-config-mock.ts b/test/__helpers__/jest-config-mock.ts deleted file mode 100644 index 60698e412c..0000000000 --- a/test/__helpers__/jest-config-mock.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TsJestGlobalOptions } from '../../src/types'; -import tsJestConfigMock from './ts-jest-config-mock'; - -export default function jestConfigMock( - options?: jest.InitialOptions, - tsJestOptions?: TsJestGlobalOptions, -): T { - const res = { - globals: {}, - moduleFileExtensions: ['ts', 'js'], - ...options, - } as any; - if (tsJestOptions) { - res.globals['ts-jest'] = tsJestConfigMock(tsJestOptions); - } - return res; -} diff --git a/test/__helpers__/ts-jest-config-mock.ts b/test/__helpers__/ts-jest-config-mock.ts deleted file mode 100644 index cc3c16f94d..0000000000 --- a/test/__helpers__/ts-jest-config-mock.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TsJestGlobalOptions } from '../../src/types'; - -export default function tsJestConfigMock( - options: TsJestGlobalOptions, -): T { - return { ...options } as any; -} diff --git a/test/ts-jest-transformer.spec.ts b/test/ts-jest-transformer.spec.ts deleted file mode 100644 index a65a71f843..0000000000 --- a/test/ts-jest-transformer.spec.ts +++ /dev/null @@ -1,32 +0,0 @@ -import TsJestTransformer from '../src/ts-jest-transformer'; -import jestConfigMock from './__helpers__/jest-config-mock'; -import { - transpiledTsSourceMock, - filePathMock, -} from './__helpers__/sources-mock'; - -jest.mock( - '../src/ts-program', - () => - class TsProgramMock { - transpileModule(_: string, source: string) { - return source; - } - }, -); - -const path = filePathMock('path/to/file.ts'); -const content = transpiledTsSourceMock(); - -describe('hoisting', () => { - const transformer = new TsJestTransformer(); - it('should hoist jest.mock calls using babel', () => { - const config = jestConfigMock({}, { babelJest: true }); - const result = transformer.process( - content, - path, - config, - ) as jest.TransformedSource; - expect(result.code).toMatchSnapshot(); - }); -}); diff --git a/tsconfig.build.json b/tsconfig.build.json index 1954b7c79b..31477963df 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -7,5 +7,10 @@ "outDir": "dist", "rootDir": "src", }, - "include": ["src"] + "include": ["src"], + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/__*__", + ] } diff --git a/tsconfig.json b/tsconfig.json index 4df47a5e3d..e781a9a10c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,8 +16,10 @@ "experimentalDecorators": true, "esModuleInterop": true, "skipLibCheck": true, + "resolveJsonModule": true, "lib": ["es2015", "es2016.array.include"], "types": ["jest", "node"], + "sourceRoot": "src" }, "include": [ "src",