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

feat(jest-haste-map): support dependencyExtractor written in ESM #12008

Merged
merged 9 commits into from Feb 24, 2022
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -20,12 +20,15 @@
- `[jest-environment-node]` [**BREAKING**] Second argument `context` to constructor is mandatory ([#12469](https://github.com/facebook/jest/pull/12469))
- `[@jest/expect]` New module which extends `expect` with `jest-snapshot` matchers ([#12404](https://github.com/facebook/jest/pull/12404), [#12410](https://github.com/facebook/jest/pull/12410), [#12418](https://github.com/facebook/jest/pull/12418))
- `[@jest/expect-utils]` New module exporting utils for `expect` ([#12323](https://github.com/facebook/jest/pull/12323))
- `[jest-haste-map]` [**BREAKING**] `HasteMap.create` now returns a promise ([#12008](https://github.com/facebook/jest/pull/12008))
- `[jest-haste-map]` Add support for `dependencyExtractor` written in ESM ([#12008](https://github.com/facebook/jest/pull/12008))
- `[jest-mock]` [**BREAKING**] Rename exported utility types `ConstructorLike`, `MethodLike`, `ConstructorLikeKeys`, `MethodLikeKeys`, `PropertyLikeKeys`; remove exports of utility types `ArgumentsOf`, `ArgsType`, `ConstructorArgumentsOf` - TS builtin utility types `ConstructorParameters` and `Parameters` should be used instead ([#12435](https://github.com/facebook/jest/pull/12435))
- `[jest-mock]` Improve `isMockFunction` to infer types of passed function ([#12442](https://github.com/facebook/jest/pull/12442))
- `[jest-resolve]` [**BREAKING**] Add support for `package.json` `exports` ([#11961](https://github.com/facebook/jest/pull/11961), [#12373](https://github.com/facebook/jest/pull/12373))
- `[jest-resolve, jest-runtime]` Add support for `data:` URI import and mock ([#12392](https://github.com/facebook/jest/pull/12392))
- `[jest-resolve, jest-runtime]` Add support for async resolver ([#11540](https://github.com/facebook/jest/pull/11540))
- `[jest-runner]` Allow passing `testEnvironmentOptions` via docblocks ([#12470](https://github.com/facebook/jest/pull/12470))
- `[jest-runtime]` [**BREAKING**] `Runtime.createHasteMap` now returns a promise ([#12008](https://github.com/facebook/jest/pull/12008))
- `[@jest/schemas]` New module for JSON schemas for Jest's config ([#12384](https://github.com/facebook/jest/pull/12384))
- `[jest-worker]` [**BREAKING**] Allow only absolute `workerPath` ([#12343](https://github.com/facebook/jest/pull/12343))
- `[pretty-format]` New `maxWidth` parameter ([#12402](https://github.com/facebook/jest/pull/12402))
Expand Down
50 changes: 50 additions & 0 deletions e2e/__tests__/findRelatedFiles.test.ts
Expand Up @@ -116,6 +116,56 @@ describe('--findRelatedTests flag', () => {
expect(stderr).toMatch(summaryMsg);
});

test('runs tests related to filename with a custom dependency extractor written in ESM', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@SimenB I am not sure if this is a valid e2e test of ESM dependency extractor. I just found a commonjs version above and did the same against ESM.

Copy link
Member

Choose a reason for hiding this comment

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

that's fine 👍

writeFiles(DIR, {
'.watchmanconfig': '',
'__tests__/test-skip-deps.test.js': `
const dynamicImport = path => Promise.resolve(require(path));
test('a', () => dynamicImport('../a').then(a => {
expect(a.foo).toBe(5);
}));
`,
'__tests__/test.test.js': `
const dynamicImport = path => Promise.resolve(require(path));
test('a', () => dynamicImport('../a').then(a => {
expect(a.foo).toBe(5);
}));
`,
'a.js': 'module.exports = {foo: 5};',
'dependencyExtractor.mjs': `
const DYNAMIC_IMPORT_RE = /(?:^|[^.]\\s*)(\\bdynamicImport\\s*?\\(\\s*?)([\`'"])([^\`'"]+)(\\2\\s*?\\))/g;
export function extract(code, filePath) {
const dependencies = new Set();
if (filePath.includes('skip-deps')) {
return dependencies;
}
const addDependency = (match, pre, quot, dep, post) => {
dependencies.add(dep);
return match;
};
code.replace(DYNAMIC_IMPORT_RE, addDependency);
return dependencies;
};
`,
'package.json': JSON.stringify({
jest: {
dependencyExtractor: '<rootDir>/dependencyExtractor.mjs',
testEnvironment: 'node',
},
}),
});

const {stdout} = runJest(DIR, ['a.js']);
expect(stdout).toMatch('');

const {stderr} = runJest(DIR, ['--findRelatedTests', 'a.js']);
expect(stderr).toMatch('PASS __tests__/test.test.js');
expect(stderr).not.toMatch('PASS __tests__/test-skip-deps.test.js');

const summaryMsg = 'Ran all test suites related to files matching /a.js/i.';
expect(stderr).toMatch(summaryMsg);
});

test('generates coverage report for filename', () => {
writeFiles(DIR, {
'.watchmanconfig': '',
Expand Down
4 changes: 2 additions & 2 deletions e2e/__tests__/hasteMapMockChanged.test.ts
Expand Up @@ -37,11 +37,11 @@ test('should not warn when a mock file changes', async () => {
writeFiles(DIR, {
'__mocks__/fs.js': '"foo fs"',
});
await new JestHasteMap(hasteConfig).build();
await (await JestHasteMap.create(hasteConfig)).build();

// This will throw if the mock file being updated triggers a warning.
writeFiles(DIR, {
'__mocks__/fs.js': '"foo fs!"',
});
await new JestHasteMap(hasteConfig).build();
await (await JestHasteMap.create(hasteConfig)).build();
});
2 changes: 1 addition & 1 deletion e2e/__tests__/hasteMapSha1.test.ts
Expand Up @@ -26,7 +26,7 @@ test('exits the process after test are done but before timers complete', async (
'node_modules/bar/index.js': '"node modules bar"',
});

const haste = new JestHasteMap({
const haste = await JestHasteMap.create({
computeSha1: true,
extensions: ['js', 'json', 'png'],
forceNodeFilesystemAPI: true,
Expand Down
4 changes: 2 additions & 2 deletions e2e/__tests__/hasteMapSize.test.ts
Expand Up @@ -37,13 +37,13 @@ const options = {
};

test('reports the correct file size', async () => {
const hasteMap = new HasteMap(options);
const hasteMap = await HasteMap.create(options);
const hasteFS = (await hasteMap.build()).hasteFS;
expect(hasteFS.getSize(path.join(DIR, 'file.js'))).toBe(5);
});

test('updates the file size when a file changes', async () => {
const hasteMap = new HasteMap({...options, watch: true});
const hasteMap = await HasteMap.create({...options, watch: true});
await hasteMap.build();

writeFiles(DIR, {
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-core/src/cli/index.ts
Expand Up @@ -134,7 +134,7 @@ const buildContextsAndHasteMaps = async (
const contexts = await Promise.all(
configs.map(async (config, index) => {
createDirectory(config.cacheDirectory);
const hasteMapInstance = Runtime.createHasteMap(config, {
const hasteMapInstance = await Runtime.createHasteMap(config, {
console: new CustomConsole(outputStream, outputStream),
maxWorkers: Math.max(
1,
Expand Down
Expand Up @@ -21,13 +21,13 @@ const commonOptions = {
};

test('watchman crawler and node crawler both include dotfiles', async () => {
const hasteMapWithWatchman = new HasteMap({
const hasteMapWithWatchman = await HasteMap.create({
...commonOptions,
name: 'withWatchman',
useWatchman: true,
});

const hasteMapWithNode = new HasteMap({
const hasteMapWithNode = await HasteMap.create({
...commonOptions,
name: 'withNode',
useWatchman: false,
Expand Down