Skip to content

Commit

Permalink
[jest/ts] modify ts-jest.tsConfigFile config based on filePath
Browse files Browse the repository at this point in the history
  • Loading branch information
spalger committed May 16, 2018
1 parent 24f60f4 commit 8b3c446
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 49 deletions.
46 changes: 0 additions & 46 deletions src/dev/file.js

This file was deleted.

58 changes: 58 additions & 0 deletions src/dev/file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { dirname, extname, join, relative, resolve } from 'path';

import { REPO_ROOT } from './constants';

export class File {
private path: string;
private relativePath: string;
private ext: string;

constructor(path: string) {
this.path = resolve(path);
this.relativePath = relative(REPO_ROOT, this.path);
this.ext = extname(this.path);
}

public getAbsolutePath() {
return this.path;
}

public getRelativePath() {
return this.relativePath;
}

public isJs() {
return this.ext === '.js';
}

public isTypescript() {
return this.ext === '.ts' || this.ext === '.tsx';
}

public getRelativeParentDirs() {
const parents: string[] = [];

while (true) {
// NOTE: resolve() produces absolute paths, so we have to use join()
const parent = parents.length
? join(parents[parents.length - 1], '..')
: dirname(this.relativePath);

if (parent === '..' || parent === '.') {
break;
} else {
parents.push(parent);
}
}

return parents;
}

public toString() {
return this.relativePath;
}

public toJSON() {
return this.relativePath;
}
}
4 changes: 1 addition & 3 deletions src/dev/jest/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export default {
'js',
'json',
'ts',
'tsx',
],
modulePathIgnorePatterns: [
'__fixtures__/',
Expand All @@ -51,7 +50,6 @@ export default {
testMatch: [
'**/*.test.js',
'**/*.test.ts',
'**/*.test.tsx',
],
testPathIgnorePatterns: [
'<rootDir>/packages/kbn-ui-framework/(dist|doc_site|generator-kui)/',
Expand All @@ -60,7 +58,7 @@ export default {
],
transform: {
'^.+\\.js$': '<rootDir>/src/dev/jest/babel_transform.js',
'^.+\\.tsx?$': 'ts-jest',
'^.+\\.tsx?$': '<rootDir>/src/dev/jest/ts_transform.js',
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.js$',
Expand Down
2 changes: 2 additions & 0 deletions src/dev/jest/ts_transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require('../../babel-register');
module.exports = require('./ts_transform.ts');
44 changes: 44 additions & 0 deletions src/dev/jest/ts_transform.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { getCacheKey, install, process } from 'ts-jest';
import { JestConfig, TransformOptions } from 'ts-jest/dist/jest-types';

import { TS_PROJECTS, Project } from '../typescript'
import { transform } from 'typescript';

function extendJestConfigJSON(jestConfigJSON: string, filePath: string) {
const jestConfig = JSON.parse(jestConfigJSON) as JestConfig;
return JSON.stringify(extendJestConfig(jestConfig, filePath))
}

function extendJestConfig(jestConfig: JestConfig, filePath: string) {
const project = TS_PROJECTS.find(p => p.isAbsolutePathSelected(path));

if (!project) {
throw new Error('Unable to find tsconfig.json file selecting file "${filePath}". Ensure one exists and it is listed in "src/dev/typescript/projects.ts"')
}

return {
...jestConfig,
globals: {
...jestConfig.globals || {},
'ts-jest': {
tsConfigFile: project.getTsConfigPath(),
skipBabel: true
}
}
}
}


module.exports = {
process(src: string, filePath: string, jestConfig: JestConfig, transformOptions: TransformOptions) {
const extendedConfig = extendJestConfig(jestConfig, filePath);
return process(src, filePath, extendedConfig, transformOptions);
},

getCacheKey(src: string, filePath: string, jestConfigJSON: string, transformOptions: TransformOptions) {
const extendedConfigJSON = extendJestConfigJSON(jestConfigJSON, filePath);
return getCacheKey(src, filePath, extendedConfigJSON, transformOptions);
},

install,
};
1 change: 1 addition & 0 deletions src/dev/typescript/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { TS_PROJECTS, Project } from './project';
62 changes: 62 additions & 0 deletions src/dev/typescript/project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { readFileSync } from 'fs';
import { basename, dirname, relative, resolve } from 'path';

import { IMinimatch, Minimatch } from 'minimatch';
import { parseConfigFileTextToJson } from 'typescript';

import { File } from '../file';

const ROOT_DIR = resolve(__dirname, '../../../');

function makeMatchers(directory: string, patterns: string[]) {
return patterns.map(pattern => new Minimatch(resolve(directory, pattern), {
dot: true,
}));
}

export class Project {
public static fromConfig(path: string) {
const { error, config } = parseConfigFileTextToJson(path, readFileSync(path, 'utf8'));

if (error) {
throw error;
}

return new Project(path, config.files, config.include, config.exclude);
}

private include: IMinimatch[];
private exclude: IMinimatch[];

constructor(
private tsConfigPath: string,
files?: string[],
include?: string[],
exclude: string[] = []
) {
if (files || !include) {
throw new Error(
'tsconfig.json files in the Kibana repo must use "include" keys and not "files"'
);
}

this.include = makeMatchers(dirname(tsConfigPath), include);
this.exclude = makeMatchers(dirname(tsConfigPath), exclude);
}

public getTsConfigPath() {
return this.tsConfigPath;
}

public isAbsolutePathSelected(path: string) {
return this.exclude.some(exc => exc.match(path))
? false
: this.include.some(inc => inc.match(path));
}
}

export const TS_PROJECTS = [
Project.fromConfig(require.resolve('../../../tsconfig.json')),
Project.fromConfig(require.resolve('../../../packages/kbn-pm/tsconfig.json')),
Project.fromConfig(require.resolve('../../../packages/kbn-system-loader/tsconfig.json')),
];

0 comments on commit 8b3c446

Please sign in to comment.