diff --git a/CHANGELOG.md b/CHANGELOG.md index c4de63c19772..707c65973a85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### Features +* `[jest-runtime]` Allow for transform plugins to skip the definition process + method if createTransformer method was defined. + ([#5999](https://github.com/facebook/jest/pull/5999)) * `[expect]` Add stack trace for async errors ([#6008](https://github.com/facebook/jest/pull/6008)) * `[jest-jasmine2]` Add stack trace for timeouts diff --git a/packages/jest-runtime/src/__tests__/script_transformer.test.js b/packages/jest-runtime/src/__tests__/script_transformer.test.js index a7b74ffb95c6..b0ee5c1e5512 100644 --- a/packages/jest-runtime/src/__tests__/script_transformer.test.js +++ b/packages/jest-runtime/src/__tests__/script_transformer.test.js @@ -85,6 +85,44 @@ jest.mock( {virtual: true}, ); +// Bad preprocessor +jest.mock( + 'skipped-required-props-preprocessor', + () => { + return {}; + }, + {virtual: true}, +); + +// Bad preprocessor +jest.mock( + 'skipped-required-create-transformer-props-preprocessor', + () => { + return { + createTransformer() { + return {}; + }, + }; + }, + {virtual: true}, +); + +jest.mock( + 'skipped-process-method-preprocessor', + () => { + return { + createTransformer() { + const mockProcess = jest.fn(); + mockProcess.mockReturnValue('code'); + return { + process: mockProcess, + }; + }, + }; + }, + {virtual: true}, +); + const getCachePath = (fs, config) => { for (const path in mockFs) { if (path.startsWith(config.cacheDirectory)) { @@ -262,6 +300,38 @@ describe('ScriptTransformer', () => { }, ); + it("throws an error if `process` doesn't defined", () => { + Object.assign(config, { + transform: [['^.+\\.js$', 'skipped-required-props-preprocessor']], + }); + const scriptTransformer = new ScriptTransformer(config); + expect(() => + scriptTransformer.transformSource('sample.js', '', false), + ).toThrow('Jest: a transform must export a `process` function.'); + }); + + it('throws an error if createTransformer returns object without `process` method', () => { + Object.assign(config, { + transform: [ + ['^.+\\.js$', 'skipped-required-create-transformer-props-preprocessor'], + ], + }); + const scriptTransformer = new ScriptTransformer(config); + expect(() => + scriptTransformer.transformSource('sample.js', '', false), + ).toThrow('Jest: a transform must export a `process` function.'); + }); + + it("shouldn't throw error without process method. But with corrent createTransformer method", () => { + Object.assign(config, { + transform: [['^.+\\.js$', 'skipped-process-method-preprocessor']], + }); + const scriptTransformer = new ScriptTransformer(config); + expect(() => + scriptTransformer.transformSource('sample.js', '', false), + ).not.toThrow(); + }); + it('uses the supplied preprocessor', () => { config = Object.assign(config, { transform: [['^.+\\.js$', 'test_preprocessor']], diff --git a/packages/jest-runtime/src/script_transformer.js b/packages/jest-runtime/src/script_transformer.js index 45026af2dd33..895e9bd1b9ae 100644 --- a/packages/jest-runtime/src/script_transformer.js +++ b/packages/jest-runtime/src/script_transformer.js @@ -137,14 +137,14 @@ export default class ScriptTransformer { // $FlowFixMe transform = (require(transformPath): Transformer); + if (typeof transform.createTransformer === 'function') { + transform = transform.createTransformer(); + } if (typeof transform.process !== 'function') { throw new TypeError( 'Jest: a transform must export a `process` function.', ); } - if (typeof transform.createTransformer === 'function') { - transform = transform.createTransformer(); - } this._transformCache.set(transformPath, transform); } return transform;