Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
- `[@jest/core]` Create new package, which is `jest-cli` minus `yargs` and `prompts` ([#7696](https://github.com/facebook/jest/pull/7696))
- `[@jest/transform]`: Migrate to TypeScript ([#7918](https://github.com/facebook/jest/pull/7918))
- `[docs]` Add missing import to docs ([#7928](https://github.com/facebook/jest/pull/7928))
- `[jest-resolve-dependencies]`: Migrate to TypeScript ([#7922](https://github.com/facebook/jest/pull/7922))

### Performance

Expand Down
10 changes: 10 additions & 0 deletions packages/jest-resolve-dependencies/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,20 @@
},
"license": "MIT",
"main": "build/index.js",
"types": "build/index.d.ts",
"dependencies": {
"@jest/types": "^24.1.0",
"jest-regex-util": "^24.0.0",
"jest-snapshot": "^24.1.0"
},
"devDependencies": {
"jest-haste-map": "^24.0.0",
"jest-resolve": "^24.1.0"
},
"peerDependencies": {
"jest-haste-map": "^24.0.0",
"jest-resolve": "^24.1.0"
},
"engines": {
"node": ">= 6"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,42 @@
*/
'use strict';

const path = require('path');
const {normalize} = require('jest-config');
const {buildSnapshotResolver} = require('jest-snapshot');
const DependencyResolver = require('../index');
import {tmpdir} from 'os';
import path from 'path';
import {Config} from '@jest/types';
import {buildSnapshotResolver} from 'jest-snapshot';
import {makeProjectConfig} from '../../../../TestUtils';

import DependencyResolver from '../index';

const maxWorkers = 1;
let dependencyResolver;
let dependencyResolver: DependencyResolver;
let Runtime;
let config;
const cases = {
let config: Config.ProjectConfig;
const cases: {[key: string]: jest.Mock} = {
fancyCondition: jest.fn(path => path.length > 10),
testRegex: jest.fn(path => /.test.js$/.test(path)),
};
const filter = path => Object.keys(cases).every(key => cases[key](path));
const filter = (path: Config.Path) =>
Object.keys(cases).every(key => cases[key](path));

beforeEach(() => {
Runtime = require('jest-runtime');
config = normalize(
{
rootDir: '.',
roots: ['./packages/jest-resolve-dependencies'],
},
{},
).options;
return Runtime.createContext(config, {maxWorkers}).then(hasteMap => {
dependencyResolver = new DependencyResolver(
hasteMap.resolver,
hasteMap.hasteFS,
buildSnapshotResolver(config),
);
config = makeProjectConfig({
cacheDirectory: path.resolve(tmpdir(), 'jest-resolve-dependencies-test'),
moduleDirectories: ['node_modules'],
rootDir: '.',
roots: ['./packages/jest-resolve-dependencies'],
});
return Runtime.createContext(config, {maxWorkers, watchman: false}).then(
(hasteMap: any) => {
Copy link
Member

Choose a reason for hiding this comment

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

Could type as HasteMap, but doesn't matter in a test

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah that's what I meant in #7922 (comment), would prefer to do it in another PR though since I expect it to become rather big

Copy link
Member

Choose a reason for hiding this comment

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

sounds good!

dependencyResolver = new DependencyResolver(
hasteMap.resolver,
hasteMap.hasteFS,
buildSnapshotResolver(config),
);
},
);
});

test('resolves no dependencies for non-existent path', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,11 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {HasteFS} from 'types/HasteMap';
import type {Path} from 'types/Config';
import type {
Resolver,
ResolveModuleConfig,
ResolvedModule,
} from 'types/Resolve';
import type {SnapshotResolver} from 'types/SnapshotResolver';
import {Config, Resolve, Snapshot} from '@jest/types';
import {FS as HasteFS} from 'jest-haste-map';
import Resolver from 'jest-resolve';
import {isSnapshotPath} from 'jest-snapshot';

/**
Expand All @@ -24,25 +17,28 @@ import {isSnapshotPath} from 'jest-snapshot';
class DependencyResolver {
_hasteFS: HasteFS;
_resolver: Resolver;
_snapshotResolver: SnapshotResolver;
_snapshotResolver: Snapshot.SnapshotResolver;

constructor(
resolver: Resolver,
hasteFS: HasteFS,
snapshotResolver: SnapshotResolver,
snapshotResolver: Snapshot.SnapshotResolver,
) {
this._resolver = resolver;
this._hasteFS = hasteFS;
this._snapshotResolver = snapshotResolver;
}

resolve(file: Path, options?: ResolveModuleConfig): Array<Path> {
resolve(
file: Config.Path,
options?: Resolve.ResolveModuleConfig,
): Array<Config.Path> {
const dependencies = this._hasteFS.getDependencies(file);
if (!dependencies) {
return [];
}

return dependencies.reduce((acc, dependency) => {
return dependencies.reduce<Array<Config.Path>>((acc, dependency) => {
if (this._resolver.isCoreModule(dependency)) {
return acc;
}
Expand All @@ -66,23 +62,27 @@ class DependencyResolver {
}

resolveInverseModuleMap(
paths: Set<Path>,
filter: (file: Path) => boolean,
options?: ResolveModuleConfig,
): Array<ResolvedModule> {
paths: Set<Config.Path>,
filter: (file: Config.Path) => boolean,
options?: Resolve.ResolveModuleConfig,
): Array<Resolve.ResolvedModule> {
if (!paths.size) {
return [];
}

const collectModules = (related, moduleMap, changed) => {
const collectModules = (
related: Set<Config.Path>,
moduleMap: Array<Resolve.ResolvedModule>,
changed: Set<Config.Path>,
) => {
const visitedModules = new Set();
const result: Array<ResolvedModule> = [];
const result: Array<Resolve.ResolvedModule> = [];
while (changed.size) {
changed = new Set(
moduleMap.reduce((acc, module) => {
moduleMap.reduce<Array<Config.Path>>((acc, module) => {
if (
visitedModules.has(module.file) ||
!module.dependencies.some(dep => dep && changed.has(dep))
!module.dependencies.some(dep => changed.has(dep))
) {
return acc;
}
Expand All @@ -98,11 +98,13 @@ class DependencyResolver {
}, []),
);
}
return result.concat(Array.from(related).map(file => ({file})));
return result.concat(
Array.from(related).map(file => ({dependencies: [], file})),
);
};

const relatedPaths = new Set<Path>();
const changed = new Set();
const relatedPaths = new Set<Config.Path>();
const changed: Set<Config.Path> = new Set();
for (const path of paths) {
if (this._hasteFS.exists(path)) {
const modulePath = isSnapshotPath(path)
Expand All @@ -114,7 +116,7 @@ class DependencyResolver {
}
}
}
const modules = [];
const modules: Array<Resolve.ResolvedModule> = [];
for (const file of this._hasteFS.getAbsoluteFileIterator()) {
modules.push({
dependencies: this.resolve(file, options),
Expand All @@ -125,14 +127,14 @@ class DependencyResolver {
}

resolveInverse(
paths: Set<Path>,
filter: (file: Path) => boolean,
options?: ResolveModuleConfig,
): Array<Path> {
paths: Set<Config.Path>,
filter: (file: Config.Path) => boolean,
options?: Resolve.ResolveModuleConfig,
): Array<Config.Path> {
return this.resolveInverseModuleMap(paths, filter, options).map(
module => module.file,
);
}
}

module.exports = DependencyResolver;
export = DependencyResolver;
12 changes: 12 additions & 0 deletions packages/jest-resolve-dependencies/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "build"
},
"references": [
{"path": "../jest-regex-util"},
{"path": "../jest-snapshot"},
{"path": "../jest-types"}
]
}
11 changes: 3 additions & 8 deletions packages/jest-resolve/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import path from 'path';
import {Config} from '@jest/types';
import {Config, Resolve} from '@jest/types';
import {ModuleMap} from 'jest-haste-map';
import {sync as realpath} from 'realpath-native';
import chalk from 'chalk';
Expand All @@ -15,11 +15,6 @@ import isBuiltinModule from './isBuiltinModule';
import defaultResolver from './defaultResolver';
import {ResolverConfig} from './types';

type ResolveModuleConfig = {
skipNodeResolution?: boolean;
paths?: Config.Path[];
};

type FindNodeModuleConfig = {
basedir: Config.Path;
browser?: boolean;
Expand Down Expand Up @@ -102,7 +97,7 @@ class Resolver {
resolveModuleFromDirIfExists(
dirname: Config.Path,
moduleName: string,
options?: ResolveModuleConfig,
options?: Resolve.ResolveModuleConfig,
): Config.Path | null {
const paths = (options && options.paths) || this._options.modulePaths;
const moduleDirectory = this._options.moduleDirectories;
Expand Down Expand Up @@ -185,7 +180,7 @@ class Resolver {
resolveModule(
from: Config.Path,
moduleName: string,
options?: ResolveModuleConfig,
options?: Resolve.ResolveModuleConfig,
): Config.Path {
const dirname = path.dirname(from);
const module = this.resolveModuleFromDirIfExists(
Expand Down
17 changes: 17 additions & 0 deletions packages/jest-types/src/Resolve.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import {Path} from './Config';

export type ResolveModuleConfig = {
skipNodeResolution?: boolean;
paths?: Path[];
};
export type ResolvedModule = {
file: Path;
dependencies: Path[];
};
14 changes: 14 additions & 0 deletions packages/jest-types/src/Snapshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import {Path} from './Config';

export type SnapshotResolver = {
testPathForConsistencyCheck: string;
resolveSnapshotPath(testPath: Path, extension?: string): Path;
resolveTestPath(snapshotPath: Path, extension?: string): Path;
};
20 changes: 16 additions & 4 deletions packages/jest-types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,22 @@

import * as Config from './Config';
import * as Console from './Console';
import * as SourceMaps from './SourceMaps';
import * as TestResult from './TestResult';
import * as Matchers from './Matchers';
import * as Mocks from './Mocks';
import * as PrettyFormat from './PrettyFormat';
import * as Matchers from './Matchers';
import * as Resolve from './Resolve';
import * as Snapshot from './Snapshot';
import * as SourceMaps from './SourceMaps';
import * as TestResult from './TestResult';

export {Config, Console, SourceMaps, TestResult, Mocks, PrettyFormat, Matchers};
export {
Config,
Console,
Matchers,
Mocks,
PrettyFormat,
Resolve,
Snapshot,
SourceMaps,
TestResult,
};