Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(jest-transform): improve runtime errors and warnings #11998

Merged
merged 5 commits into from Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
### Fixes

- `[expect]` Allow again `expect.Matchers` generic with single value ([#11986](https://github.com/facebook/jest/pull/11986))
- `[jest-transform]` Improve the invalid transformer module error message ([#11998](https://github.com/facebook/jest/pull/11998))

### Chore & Maintenance

Expand Down
22 changes: 18 additions & 4 deletions packages/jest-transform/src/ScriptTransformer.ts
Expand Up @@ -10,6 +10,7 @@ import * as path from 'path';
import {transformSync as babelTransform} from '@babel/core';
// @ts-expect-error: should just be `require.resolve`, but the tests mess that up
import babelPluginIstanbul from 'babel-plugin-istanbul';
import chalk = require('chalk');
import {fromSource as sourcemapFromSource} from 'convert-source-map';
import stableStringify = require('fast-json-stable-stringify');
import * as fs from 'graceful-fs';
Expand Down Expand Up @@ -250,6 +251,21 @@ class ScriptTransformer {
}

async loadTransformers(): Promise<void> {
const makeInvalidTransformerError = (transformPath: string) =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could also live outside the class, of course. The class is huge, not so easy to decide.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense to move it outside rather than defining it inline 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or even better to move it to separate file together with other runtime errors for this module. Had to think a bit, will do it later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that also works - as you say the class is huge and somewhat hard to grok/navigate

chalk.red(
[
chalk.bold('\u25cf Invalid transformer module:'),
` "${slash(
transformPath,
)}" specified in the "transform" object of Jest configuration`,
' must export a `process` or `processAsync` or `createTransformer` function.',
'',
' Code Transformation Documentation:',
' https://jestjs.io/docs/code-transformation',
'',
].join('\n'),
);

await Promise.all(
this._config.transform.map(
async ([, transformPath, transformerConfig]) => {
Expand All @@ -258,7 +274,7 @@ class ScriptTransformer {
);

if (!transformer) {
throw new TypeError('Jest: a transform must export something.');
throw new Error(makeInvalidTransformerError(transformPath));
}
if (typeof transformer.createTransformer === 'function') {
transformer = transformer.createTransformer(transformerConfig);
Expand All @@ -267,9 +283,7 @@ class ScriptTransformer {
typeof transformer.process !== 'function' &&
typeof transformer.processAsync !== 'function'
) {
throw new TypeError(
'Jest: a transform must export a `process` or `processAsync` function.',
);
throw new Error(makeInvalidTransformerError(transformPath));
}
const res = {transformer, transformerConfig};
this._transformCache.set(transformPath, res);
Expand Down
14 changes: 7 additions & 7 deletions packages/jest-transform/src/__tests__/ScriptTransformer.test.ts
Expand Up @@ -486,14 +486,14 @@ describe('ScriptTransformer', () => {
await Promise.all([...promisesToReject, ...promisesToResolve]);
});

it('throws an error if neither `process` nor `processAsync is defined', async () => {
it('throws an error if neither `process` nor `processAsync` is defined', async () => {
config = {
...config,
transform: [['\\.js$', 'skipped-required-props-preprocessor', {}]],
};
await expect(() => createScriptTransformer(config)).rejects.toThrow(
'Jest: a transform must export a `process` or `processAsync` function.',
);
await expect(() =>
createScriptTransformer(config),
).rejects.toThrowErrorMatchingSnapshot();
});

it("(in sync mode) throws an error if `process` isn't defined", async () => {
Expand Down Expand Up @@ -537,9 +537,9 @@ describe('ScriptTransformer', () => {
],
],
};
await expect(() => createScriptTransformer(config)).rejects.toThrow(
'Jest: a transform must export a `process` or `processAsync` function.',
);
await expect(() =>
createScriptTransformer(config),
).rejects.toThrowErrorMatchingSnapshot();
});

it("shouldn't throw error without process method. But with correct createTransformer method", async () => {
Expand Down
Expand Up @@ -340,6 +340,26 @@ exports[`ScriptTransformer passes expected transform options to getCacheKeyAsync
}
`;

exports[`ScriptTransformer throws an error if createTransformer returns object without \`process\` method 1`] = `
"<red><bold>● Invalid transformer module:</></>
<red> \\"skipped-required-create-transformer-props-preprocessor\\" specified in the \\"transform\\" object of Jest configuration</>
<red> must export a \`process\` or \`processAsync\` or \`createTransformer\` function.</>
<red></>
<red> Code Transformation Documentation:</>
<red> https://jestjs.io/docs/code-transformation</>
<red></>"
`;

exports[`ScriptTransformer throws an error if neither \`process\` nor \`processAsync\` is defined 1`] = `
"<red><bold>● Invalid transformer module:</></>
<red> \\"skipped-required-props-preprocessor\\" specified in the \\"transform\\" object of Jest configuration</>
<red> must export a \`process\` or \`processAsync\` or \`createTransformer\` function.</>
<red></>
<red> Code Transformation Documentation:</>
<red> https://jestjs.io/docs/code-transformation</>
<red></>"
`;

exports[`ScriptTransformer transforms a file async properly 1`] = `
/* istanbul ignore next */
function cov_25u22311x4() {
Expand Down