From b8a9a71075f49c4c5186dac3ec2015c52ee12676 Mon Sep 17 00:00:00 2001 From: Tim Seckinger Date: Tue, 19 Feb 2019 20:09:08 +0100 Subject: [PATCH] chore: migrate jest-resolve-dependencies to TypeScript (#7922) --- CHANGELOG.md | 1 + .../jest-resolve-dependencies/package.json | 11 +++ ...er.test.js => dependency_resolver.test.ts} | 49 ++++++------- .../src/{index.js => index.ts} | 68 ++++++++++--------- .../jest-resolve-dependencies/tsconfig.json | 12 ++++ packages/jest-resolve/src/index.ts | 11 +-- packages/jest-snapshot/src/index.ts | 5 +- .../jest-snapshot/src/snapshot_resolver.ts | 24 +++---- packages/jest-types/src/Resolve.ts | 17 +++++ packages/jest-types/src/Snapshot.ts | 14 ++++ packages/jest-types/src/index.ts | 20 ++++-- 11 files changed, 146 insertions(+), 86 deletions(-) rename packages/jest-resolve-dependencies/src/__tests__/{dependency_resolver.test.js => dependency_resolver.test.ts} (73%) rename packages/jest-resolve-dependencies/src/{index.js => index.ts} (63%) create mode 100644 packages/jest-resolve-dependencies/tsconfig.json create mode 100644 packages/jest-types/src/Resolve.ts create mode 100644 packages/jest-types/src/Snapshot.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b33fe1e4bf73..2dfdb20b44cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,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 diff --git a/packages/jest-resolve-dependencies/package.json b/packages/jest-resolve-dependencies/package.json index 3e4bd3dbaa75..047647ee7dc9 100644 --- a/packages/jest-resolve-dependencies/package.json +++ b/packages/jest-resolve-dependencies/package.json @@ -8,10 +8,21 @@ }, "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", + "jest-runtime": "^24.1.0" + }, + "peerDependencies": { + "jest-haste-map": "^24.0.0", + "jest-resolve": "^24.1.0" + }, "engines": { "node": ">= 6" }, diff --git a/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.js b/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts similarity index 73% rename from packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.js rename to packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts index 3725c9bc951f..c2f50429462e 100644 --- a/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.js +++ b/packages/jest-resolve-dependencies/src/__tests__/dependency_resolver.test.ts @@ -3,41 +3,44 @@ * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. - * */ -'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) => { + dependencyResolver = new DependencyResolver( + hasteMap.resolver, + hasteMap.hasteFS, + buildSnapshotResolver(config), + ); + }, + ); }); test('resolves no dependencies for non-existent path', () => { diff --git a/packages/jest-resolve-dependencies/src/index.js b/packages/jest-resolve-dependencies/src/index.ts similarity index 63% rename from packages/jest-resolve-dependencies/src/index.js rename to packages/jest-resolve-dependencies/src/index.ts index bebb7a76e212..583ab2f91f85 100644 --- a/packages/jest-resolve-dependencies/src/index.js +++ b/packages/jest-resolve-dependencies/src/index.ts @@ -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'; /** @@ -22,27 +15,30 @@ import {isSnapshotPath} from 'jest-snapshot'; * to retrieve a list of all transitive inverse dependencies. */ class DependencyResolver { - _hasteFS: HasteFS; - _resolver: Resolver; - _snapshotResolver: SnapshotResolver; + private _hasteFS: HasteFS; + private _resolver: Resolver; + private _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 { + resolve( + file: Config.Path, + options?: Resolve.ResolveModuleConfig, + ): Array { const dependencies = this._hasteFS.getDependencies(file); if (!dependencies) { return []; } - return dependencies.reduce((acc, dependency) => { + return dependencies.reduce>((acc, dependency) => { if (this._resolver.isCoreModule(dependency)) { return acc; } @@ -66,23 +62,27 @@ class DependencyResolver { } resolveInverseModuleMap( - paths: Set, - filter: (file: Path) => boolean, - options?: ResolveModuleConfig, - ): Array { + paths: Set, + filter: (file: Config.Path) => boolean, + options?: Resolve.ResolveModuleConfig, + ): Array { if (!paths.size) { return []; } - const collectModules = (related, moduleMap, changed) => { + const collectModules = ( + related: Set, + moduleMap: Array, + changed: Set, + ) => { const visitedModules = new Set(); - const result: Array = []; + const result: Array = []; while (changed.size) { changed = new Set( - moduleMap.reduce((acc, module) => { + moduleMap.reduce>((acc, module) => { if ( visitedModules.has(module.file) || - !module.dependencies.some(dep => dep && changed.has(dep)) + !module.dependencies.some(dep => changed.has(dep)) ) { return acc; } @@ -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(); - const changed = new Set(); + const relatedPaths = new Set(); + const changed: Set = new Set(); for (const path of paths) { if (this._hasteFS.exists(path)) { const modulePath = isSnapshotPath(path) @@ -114,7 +116,7 @@ class DependencyResolver { } } } - const modules = []; + const modules: Array = []; for (const file of this._hasteFS.getAbsoluteFileIterator()) { modules.push({ dependencies: this.resolve(file, options), @@ -125,14 +127,14 @@ class DependencyResolver { } resolveInverse( - paths: Set, - filter: (file: Path) => boolean, - options?: ResolveModuleConfig, - ): Array { + paths: Set, + filter: (file: Config.Path) => boolean, + options?: Resolve.ResolveModuleConfig, + ): Array { return this.resolveInverseModuleMap(paths, filter, options).map( module => module.file, ); } } -module.exports = DependencyResolver; +export = DependencyResolver; diff --git a/packages/jest-resolve-dependencies/tsconfig.json b/packages/jest-resolve-dependencies/tsconfig.json new file mode 100644 index 000000000000..330ebb703e00 --- /dev/null +++ b/packages/jest-resolve-dependencies/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "build" + }, + "references": [ + {"path": "../jest-regex-util"}, + {"path": "../jest-snapshot"}, + {"path": "../jest-types"} + ] +} diff --git a/packages/jest-resolve/src/index.ts b/packages/jest-resolve/src/index.ts index cfc053f08001..666116b2db5d 100644 --- a/packages/jest-resolve/src/index.ts +++ b/packages/jest-resolve/src/index.ts @@ -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'; @@ -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; @@ -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; @@ -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( diff --git a/packages/jest-snapshot/src/index.ts b/packages/jest-snapshot/src/index.ts index bc22a7e4b9d9..b9b60ec9bab8 100644 --- a/packages/jest-snapshot/src/index.ts +++ b/packages/jest-snapshot/src/index.ts @@ -6,7 +6,7 @@ */ import fs from 'fs'; -import {Config, Matchers} from '@jest/types'; +import {Config, Matchers, Snapshot} from '@jest/types'; import {FS as HasteFS} from 'jest-haste-map'; import diff from 'jest-diff'; @@ -14,7 +14,6 @@ import {EXPECTED_COLOR, matcherHint, RECEIVED_COLOR} from 'jest-matcher-utils'; import { buildSnapshotResolver, isSnapshotPath, - SnapshotResolver, EXTENSION, } from './snapshot_resolver'; import SnapshotState from './State'; @@ -31,7 +30,7 @@ const fileExists = (filePath: Config.Path, hasteFS: HasteFS): boolean => const cleanup = ( hasteFS: HasteFS, update: Config.SnapshotUpdateState, - snapshotResolver: SnapshotResolver, + snapshotResolver: Snapshot.SnapshotResolver, ) => { const pattern = '\\.' + EXTENSION + '$'; const files = hasteFS.matchFiles(pattern); diff --git a/packages/jest-snapshot/src/snapshot_resolver.ts b/packages/jest-snapshot/src/snapshot_resolver.ts index 824fb5307dfa..838345c30b23 100644 --- a/packages/jest-snapshot/src/snapshot_resolver.ts +++ b/packages/jest-snapshot/src/snapshot_resolver.ts @@ -6,25 +6,19 @@ */ import path from 'path'; -import {Config} from '@jest/types'; +import {Config, Snapshot} from '@jest/types'; import chalk from 'chalk'; -export type SnapshotResolver = { - testPathForConsistencyCheck: string; - resolveSnapshotPath(testPath: Config.Path, extension?: string): Config.Path; - resolveTestPath(snapshotPath: Config.Path, extension?: string): Config.Path; -}; - export const EXTENSION = 'snap'; export const DOT_EXTENSION = '.' + EXTENSION; export const isSnapshotPath = (path: string): boolean => path.endsWith(DOT_EXTENSION); -const cache: Map = new Map(); +const cache: Map = new Map(); export const buildSnapshotResolver = ( config: Config.ProjectConfig, -): SnapshotResolver => { +): Snapshot.SnapshotResolver => { const key = config.rootDir; if (!cache.has(key)) { cache.set(key, createSnapshotResolver(config.snapshotResolver)); @@ -34,13 +28,13 @@ export const buildSnapshotResolver = ( function createSnapshotResolver( snapshotResolverPath?: Config.Path | null, -): SnapshotResolver { +): Snapshot.SnapshotResolver { return typeof snapshotResolverPath === 'string' ? createCustomSnapshotResolver(snapshotResolverPath) : createDefaultSnapshotResolver(); } -function createDefaultSnapshotResolver(): SnapshotResolver { +function createDefaultSnapshotResolver(): Snapshot.SnapshotResolver { return { resolveSnapshotPath: (testPath: Config.Path) => path.join( @@ -65,10 +59,10 @@ function createDefaultSnapshotResolver(): SnapshotResolver { function createCustomSnapshotResolver( snapshotResolverPath: Config.Path, -): SnapshotResolver { - const custom: SnapshotResolver = require(snapshotResolverPath); +): Snapshot.SnapshotResolver { + const custom: Snapshot.SnapshotResolver = require(snapshotResolverPath); - const keys: [keyof SnapshotResolver, string][] = [ + const keys: [keyof Snapshot.SnapshotResolver, string][] = [ ['resolveSnapshotPath', 'function'], ['resolveTestPath', 'function'], ['testPathForConsistencyCheck', 'string'], @@ -101,7 +95,7 @@ function mustImplement(propName: string, requiredType: string) { ); } -function verifyConsistentTransformations(custom: SnapshotResolver) { +function verifyConsistentTransformations(custom: Snapshot.SnapshotResolver) { const resolvedSnapshotPath = custom.resolveSnapshotPath( custom.testPathForConsistencyCheck, ); diff --git a/packages/jest-types/src/Resolve.ts b/packages/jest-types/src/Resolve.ts new file mode 100644 index 000000000000..61ce0329cb95 --- /dev/null +++ b/packages/jest-types/src/Resolve.ts @@ -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[]; +}; diff --git a/packages/jest-types/src/Snapshot.ts b/packages/jest-types/src/Snapshot.ts new file mode 100644 index 000000000000..c372b924d750 --- /dev/null +++ b/packages/jest-types/src/Snapshot.ts @@ -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; +}; diff --git a/packages/jest-types/src/index.ts b/packages/jest-types/src/index.ts index 70361152f936..0226a0a00820 100644 --- a/packages/jest-types/src/index.ts +++ b/packages/jest-types/src/index.ts @@ -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, +};