-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjest.preprocessor.js
107 lines (91 loc) · 2.83 KB
/
jest.preprocessor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* Custom Jest prepocesor
* It is necessary for proper testing using Jest, Typescript and ESNext features
*
* It customized version of
* [this preprocessor](https://github.com/kulshekhar/ts-jest/issues/68#issuecomment-271075354)
*
* I have removed `babel-preset-es2015` and replaced it with `transform-es2015-modules-commonjs`
* plugin. It is the only necessary plugin when running node 7.7+ with --harmony flag.
*/
const babel = require('babel-core');
const tsc = require('typescript');
const crypto = require('crypto');
const fs = require('fs');
const jestPreset = require('babel-preset-jest');
const path = require('path');
const BABELRC_FILENAME = '.babelrc';
const cache = Object.create(null);
const tsconfig = require('./tsconfig.json');
const getBabelRC = (filename, { useCache }) => {
const paths = [];
let directory = filename;
while (directory !== (directory = path.dirname(directory))) {
if (useCache && cache[directory]) {
break;
}
paths.push(directory);
const configFilePath = path.join(directory, BABELRC_FILENAME);
if (fs.existsSync(configFilePath)) {
cache[directory] = fs.readFileSync(configFilePath, 'utf8');
break;
}
}
paths.forEach(directoryPath => {
cache[directoryPath] = cache[directory];
});
return cache[directory] || '';
};
const createTransformer = options => {
options = Object.assign({}, options, {
presets: [...(options && options.presets || []), jestPreset],
plugins: [...(options && options.plugins || []), "transform-es2015-modules-commonjs"],
retainLines: true,
});
delete options.cacheDirectory;
return {
canInstrument: true,
getCacheKey(
fileData,
filename,
configString,
{ instrument, watch }
) {
return crypto.createHash('md5')
.update(fileData)
.update(configString)
.update(getBabelRC(filename, { useCache: !watch }))
.update(instrument ? 'instrument' : '')
.digest('hex');
},
process(
src,
filename,
config,
transformOptions
) {
let plugins = options.plugins || [];
if (transformOptions && transformOptions.instrument) {
plugins = plugins.concat([
[
require('babel-plugin-istanbul').default,
{
cwd: config.rootDir,
exclude: [],
},
],
]);
}
const diag = [];
const tsOutput = tsc.transpileModule(src, { diagnostics: diag, filename, compilerOptions: tsconfig.compilerOptions, reportDiagnostics: true });
if (babel.util.canCompile(filename) || true) {
const babelOutput = babel.transform(
tsOutput.outputText,
Object.assign({}, options, { filename, plugins })
);
return babelOutput.code;
}
},
};
};
module.exports = createTransformer();