Skip to content

Commit

Permalink
feat: pass in wrapper arguments to transformer
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Dec 1, 2019
1 parent 000e193 commit 607c123
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- `[jest-snapshot]` Improve colors when snapshots are updatable ([#9132](https://github.com/facebook/jest/pull/9132))
- `[jest-snapshot]` Ignore indentation for most serialized objects ([#9203](https://github.com/facebook/jest/pull/9203))
- `[jest-transform]` Create `createTranspilingRequire` function for easy transpiling modules ([#9194](https://github.com/facebook/jest/pull/9194))
- `[jest-transform]` [**BREAKING**] Do not automatically wrap functions in a module wrapper ([#9253](https://github.com/facebook/jest/pull/9253))
- `[@jest/test-result]` Create method to create empty `TestResult` ([#8867](https://github.com/facebook/jest/pull/8867))
- `[jest-worker]` [**BREAKING**] Return a promise from `end()`, resolving with the information whether workers exited gracefully ([#8206](https://github.com/facebook/jest/pull/8206))
- `[jest-reporters]` Transform file paths into hyperlinks ([#8980](https://github.com/facebook/jest/pull/8980))
Expand Down
15 changes: 14 additions & 1 deletion packages/jest-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ class Runtime {
collectCoverage: this._coverageOptions.collectCoverage,
collectCoverageFrom: this._coverageOptions.collectCoverageFrom,
collectCoverageOnlyFrom: this._coverageOptions.collectCoverageOnlyFrom,
extraGlobals: this._config.extraGlobals,
moduleArguments: this.constructInjectedModuleArguments(),
};
}

Expand Down Expand Up @@ -1086,6 +1086,19 @@ class Runtime {
formatStackTrace(stack, this._config, {noStackTrace: false}),
);
}

private constructInjectedModuleArguments() {
return [
'module',
'exports',
'require',
'__dirname',
'__filename',
'global',
'jest',
...this._config.extraGlobals,
];
}
}

Runtime.ScriptTransformer = ScriptTransformer;
Expand Down
53 changes: 25 additions & 28 deletions packages/jest-transform/src/ScriptTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,12 @@ export default class ScriptTransformer {
): TransformResult {
const isInternalModule = !!(options && options.isInternalModule);
const isCoreModule = !!(options && options.isCoreModule);
const extraGlobals = (options && options.extraGlobals) || [];
const moduleArguments = (options && options.moduleArguments) || [];
const content = stripShebang(
fileSource || fs.readFileSync(filename, 'utf8'),
);

let wrappedCode: string;
let scriptContent: string;
let sourceMapPath: string | null = null;
let mapCoverage = false;

Expand All @@ -369,19 +369,20 @@ export default class ScriptTransformer {
instrument,
);

wrappedCode = wrap(transformedSource.code, ...extraGlobals);
scriptContent = wrap(transformedSource.code, moduleArguments);
sourceMapPath = transformedSource.sourceMapPath;
mapCoverage = transformedSource.mapCoverage;
} else {
wrappedCode = wrap(content, ...extraGlobals);
scriptContent = wrap(content, moduleArguments);
}

return {
mapCoverage,
script: new Script(wrappedCode, {
script: new Script(scriptContent, {
displayErrors: true,
filename: isCoreModule ? 'jest-nodejs-core-' + filename : filename,
}),
scriptContent,
sourceMapPath,
};
} catch (e) {
Expand Down Expand Up @@ -412,7 +413,7 @@ export default class ScriptTransformer {

if (!options.isCoreModule) {
instrument = shouldInstrument(filename, options, this._config);
scriptCacheKey = getScriptCacheKey(filename, instrument);
scriptCacheKey = getScriptCacheKey(filename, instrument, options);
const result = this._cache.transformedFiles.get(scriptCacheKey);
if (result) {
return result;
Expand Down Expand Up @@ -666,9 +667,19 @@ const readCacheFile = (cachePath: Config.Path): string | null => {
return fileData;
};

const getScriptCacheKey = (filename: Config.Path, instrument: boolean) => {
const getScriptCacheKey = (
filename: Config.Path,
instrument: boolean,
options: Options,
) => {
const mtime = fs.statSync(filename).mtime;
return filename + '_' + mtime.getTime() + (instrument ? '_instrumented' : '');
return (
filename +
'_' +
mtime.getTime() +
(instrument ? '_instrumented' : '') +
(options.moduleArguments ? options.moduleArguments.join('') : '')
);
};

const calcIgnorePatternRegExp = (config: Config.ProjectConfig) => {
Expand Down Expand Up @@ -699,26 +710,12 @@ const calcTransformRegExp = (config: Config.ProjectConfig) => {
return transformRegexp;
};

const wrap = (content: string, ...extras: Array<string>) => {
const globals = new Set([
'module',
'exports',
'require',
'__dirname',
'__filename',
'global',
'jest',
...extras,
]);

return (
'({"' +
ScriptTransformer.EVAL_RESULT_VARIABLE +
`":function(${Array.from(globals).join(',')}){` +
content +
'\n}});'
);
};
const wrap = (content: string, moduleArguments: Array<string>) =>
'({"' +
ScriptTransformer.EVAL_RESULT_VARIABLE +
`":function(${moduleArguments.join(',')}){` +
content +
'\n}});';

// TODO: Can this be added to the static property?
ScriptTransformer.EVAL_RESULT_VARIABLE = 'Object.<anonymous>';
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Object {
`;

exports[`ScriptTransformer transforms a file properly 1`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){/* istanbul ignore next */
"({\\"Object.<anonymous>\\":function(){/* istanbul ignore next */
function cov_25u22311x4() {
var path = \\"/fruits/banana.js\\";
var hash = \\"4be0f6184160be573fc43f7c2a5877c28b7ce249\\";
Expand Down Expand Up @@ -126,7 +126,7 @@ module.exports = \\"banana\\";
`;

exports[`ScriptTransformer transforms a file properly 2`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){/* istanbul ignore next */
"({\\"Object.<anonymous>\\":function(){/* istanbul ignore next */
function cov_23yvu8etmu() {
var path = \\"/fruits/kiwi.js\\";
var hash = \\"7705dd5fcfbc884dcea7062944cfb8cc5d141d1a\\";
Expand Down Expand Up @@ -221,12 +221,12 @@ module.exports = () => {
`;

exports[`ScriptTransformer transforms a file properly 3`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest,Math){module.exports = \\"banana\\";
"({\\"Object.<anonymous>\\":function(){module.exports = \\"banana\\";
}});"
`;

exports[`ScriptTransformer uses multiple preprocessors 1`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){
"({\\"Object.<anonymous>\\":function(){
const TRANSFORMED = {
filename: '/fruits/banana.js',
script: 'module.exports = \\"banana\\";',
Expand All @@ -237,7 +237,7 @@ exports[`ScriptTransformer uses multiple preprocessors 1`] = `
`;

exports[`ScriptTransformer uses multiple preprocessors 2`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){
"({\\"Object.<anonymous>\\":function(){
module.exports = {
filename: /styles/App.css,
rawFirstLine: root {,
Expand All @@ -247,12 +247,12 @@ exports[`ScriptTransformer uses multiple preprocessors 2`] = `
`;
exports[`ScriptTransformer uses multiple preprocessors 3`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){module.exports = \\"react\\";
"({\\"Object.<anonymous>\\":function(){module.exports = \\"react\\";
}});"
`;
exports[`ScriptTransformer uses the supplied preprocessor 1`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){
"({\\"Object.<anonymous>\\":function(){
const TRANSFORMED = {
filename: '/fruits/banana.js',
script: 'module.exports = \\"banana\\";',
Expand All @@ -263,7 +263,7 @@ exports[`ScriptTransformer uses the supplied preprocessor 1`] = `
`;
exports[`ScriptTransformer uses the supplied preprocessor 2`] = `
"({\\"Object.<anonymous>\\":function(module,exports,require,__dirname,__filename,global,jest){module.exports = \\"react\\";
"({\\"Object.<anonymous>\\":function(){module.exports = \\"react\\";
}});"
`;
Expand Down
30 changes: 30 additions & 0 deletions packages/jest-transform/src/__tests__/script_transformer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -685,4 +685,34 @@ describe('ScriptTransformer', () => {
['test_preprocessor', expect.any(Object)],
]);
});

it('adds `moduleArguments` to transform wrapper', () => {
config = {...config, transform: [['^.+\\.js$', 'test_preprocessor']]};
const scriptTransformer = new ScriptTransformer(config);
const {scriptContent} = scriptTransformer.transform('/fruits/banana.js', {
moduleArguments: ['foo', 'bar', 'foobar'],
});

expect(scriptContent.split('\n')[0]).toEqual(
'({"Object.<anonymous>":function(foo,bar,foobar){',
);
});

it('moduleArguments should be part of cache key', () => {
config = {...config, transform: [['^.+\\.js$', 'test_preprocessor']]};
const scriptTransformer = new ScriptTransformer(config);
let result = scriptTransformer.transform('/fruits/banana.js', {});

expect(result.scriptContent.split('\n')[0]).toEqual(
'({"Object.<anonymous>":function(){',
);

result = scriptTransformer.transform('/fruits/banana.js', {
moduleArguments: ['foo', 'bar', 'foobar'],
});

expect(result.scriptContent.split('\n')[0]).toEqual(
'({"Object.<anonymous>":function(foo,bar,foobar){',
);
});
});
14 changes: 7 additions & 7 deletions packages/jest-transform/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ import {Config} from '@jest/types';
export type ShouldInstrumentOptions = Pick<
Config.GlobalConfig,
'collectCoverage' | 'collectCoverageFrom' | 'collectCoverageOnlyFrom'
> & {
changedFiles?: Set<Config.Path>;
};
> & {changedFiles?: Set<Config.Path>};

export type Options = ShouldInstrumentOptions &
Partial<Pick<Config.ProjectConfig, 'extraGlobals'>> & {
isCoreModule?: boolean;
isInternalModule?: boolean;
};
Partial<{
isCoreModule: boolean;
isInternalModule: boolean;
moduleArguments: Array<string>;
}>;

// https://stackoverflow.com/a/48216010/1850276
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
Expand All @@ -38,6 +37,7 @@ export type TransformedSource = {

export type TransformResult = {
script: Script;
scriptContent: string;
mapCoverage: boolean;
sourceMapPath: string | null;
};
Expand Down

0 comments on commit 607c123

Please sign in to comment.