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

Mark maxWorkers as optional #8848

Merged
merged 3 commits into from Oct 26, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -59,6 +59,8 @@
- `[jest-environment-jsdom]` [**BREAKING**] Upgrade JSDOM from v11 to v15 ([#8851](https://github.com/facebook/jest/pull/8851))
- `[jest-util]` [**BREAKING**] Remove deprecated exports ([#8863](https://github.com/facebook/jest/pull/8863))
- `[jest-validate]` [**BREAKING**] Use ESM exports ([#8874](https://github.com/facebook/jest/pull/8874))
- `[jest-types]` Mark `InitialOptions` as `Partial` ([#8848](https://github.com/facebook/jest/pull/8848))
- `[jest-config]` Refactor `normalize` to be more type safe ([#8848](https://github.com/facebook/jest/pull/8848))

### Performance

Expand Down
41 changes: 22 additions & 19 deletions packages/jest-config/src/normalize.ts
Expand Up @@ -48,7 +48,7 @@ const createConfigError = (message: string) =>

// TS 3.5 forces us to split these into 2
const mergeModuleNameMapperWithPreset = (
options: Config.InitialOptions,
options: Config.InitialOptionsWithRootDir,
preset: Config.InitialOptions,
) => {
if (options['moduleNameMapper'] && preset['moduleNameMapper']) {
Expand All @@ -61,7 +61,7 @@ const mergeModuleNameMapperWithPreset = (
};

const mergeTransformWithPreset = (
options: Config.InitialOptions,
options: Config.InitialOptionsWithRootDir,
preset: Config.InitialOptions,
) => {
if (options['transform'] && preset['transform']) {
Expand All @@ -88,9 +88,9 @@ const mergeGlobalsWithPreset = (
};

const setupPreset = (
options: Config.InitialOptions,
options: Config.InitialOptionsWithRootDir,
optionsPreset: string,
): Config.InitialOptions => {
): Config.InitialOptionsWithRootDir => {
let preset: Config.InitialOptions;
const presetPath = replaceRootDirInPath(options.rootDir, optionsPreset);
const presetModule = Resolver.findNodeModule(
Expand Down Expand Up @@ -168,7 +168,7 @@ const setupPreset = (
return {...preset, ...options};
};

const setupBabelJest = (options: Config.InitialOptions) => {
const setupBabelJest = (options: Config.InitialOptionsWithRootDir) => {
const transform = options.transform;
let babelJest;
if (transform) {
Expand Down Expand Up @@ -210,7 +210,7 @@ const setupBabelJest = (options: Config.InitialOptions) => {
};

const normalizeCollectCoverageOnlyFrom = (
options: Config.InitialOptions &
options: Config.InitialOptionsWithRootDir &
Required<Pick<Config.InitialOptions, 'collectCoverageOnlyFrom'>>,
key: keyof Pick<Config.InitialOptions, 'collectCoverageOnlyFrom'>,
) => {
Expand Down Expand Up @@ -263,7 +263,7 @@ const normalizeCollectCoverageFrom = (
};

const normalizeUnmockedModulePathPatterns = (
options: Config.InitialOptions,
options: Config.InitialOptionsWithRootDir,
key: keyof Pick<
Config.InitialOptions,
| 'coveragePathIgnorePatterns'
Expand All @@ -285,8 +285,8 @@ const normalizeUnmockedModulePathPatterns = (
);

const normalizePreprocessor = (
options: Config.InitialOptions,
): Config.InitialOptions => {
options: Config.InitialOptionsWithRootDir,
): Config.InitialOptionsWithRootDir => {
if (options.scriptPreprocessor && options.transform) {
throw createConfigError(
` Options: ${chalk.bold('scriptPreprocessor')} and ${chalk.bold(
Expand Down Expand Up @@ -323,10 +323,10 @@ const normalizePreprocessor = (
};

const normalizeMissingOptions = (
options: Config.InitialOptions,
options: Config.InitialOptionsWithRootDir,
configPath: Config.Path | null | undefined,
projectIndex: number,
): Config.InitialOptions => {
): Config.InitialOptionsWithRootDir => {
if (!options.name) {
options.name = createHash('md5')
.update(options.rootDir)
Expand All @@ -345,9 +345,9 @@ const normalizeMissingOptions = (

const normalizeRootDir = (
options: Config.InitialOptions,
): Config.InitialOptions => {
): Config.InitialOptionsWithRootDir => {
// Assert that there *is* a rootDir
if (!options.hasOwnProperty('rootDir')) {
if (!options.rootDir) {
throw createConfigError(
` Configuration option ${chalk.bold('rootDir')} must be specified.`,
);
Expand All @@ -361,10 +361,13 @@ const normalizeRootDir = (
// ignored
}

return options;
return {
...options,
rootDir: options.rootDir,
};
};

const normalizeReporters = (options: Config.InitialOptions) => {
const normalizeReporters = (options: Config.InitialOptionsWithRootDir) => {
const reporters = options.reporters;
if (!reporters || !Array.isArray(reporters)) {
return options;
Expand Down Expand Up @@ -441,15 +444,15 @@ const showTestPathPatternError = (testPathPattern: string) => {
};

export default function normalize(
options: Config.InitialOptions,
initialOptions: Config.InitialOptions,
argv: Config.Argv,
configPath?: Config.Path | null,
projectIndex: number = Infinity,
): {
hasDeprecationWarnings: boolean;
options: AllOptions;
} {
const {hasDeprecationWarnings} = validate(options, {
const {hasDeprecationWarnings} = validate(initialOptions, {
comment: DOCUMENTATION_NOTE,
deprecatedConfig: DEPRECATED_CONFIG,
exampleConfig: VALID_CONFIG,
Expand All @@ -465,10 +468,10 @@ export default function normalize(
],
});

options = normalizePreprocessor(
let options = normalizePreprocessor(
normalizeReporters(
normalizeMissingOptions(
normalizeRootDir(setFromArgv(options, argv)),
normalizeRootDir(setFromArgv(initialOptions, argv)),
configPath,
projectIndex,
),
Expand Down
201 changes: 102 additions & 99 deletions packages/jest-types/src/Config.ts
Expand Up @@ -115,117 +115,120 @@ export type DisplayName =
color: DisplayNameColor;
};

export type InitialOptions = {
automock?: boolean;
bail?: boolean | number;
browser?: boolean;
cache?: boolean;
cacheDirectory?: Path;
clearMocks?: boolean;
changedFilesWithAncestor?: boolean;
changedSince?: string;
collectCoverage?: boolean;
collectCoverageFrom?: Array<Glob>;
collectCoverageOnlyFrom?: {
export type InitialOptionsWithRootDir = InitialOptions &
Required<Pick<InitialOptions, 'rootDir'>>;

export type InitialOptions = Partial<{
automock: boolean;
bail: boolean | number;
browser: boolean;
cache: boolean;
cacheDirectory: Path;
clearMocks: boolean;
changedFilesWithAncestor: boolean;
changedSince: string;
collectCoverage: boolean;
collectCoverageFrom: Array<Glob>;
collectCoverageOnlyFrom: {
[key: string]: boolean;
};
coverageDirectory?: string;
coveragePathIgnorePatterns?: Array<string>;
coverageReporters?: Array<string>;
coverageThreshold?: {
coverageDirectory: string;
coveragePathIgnorePatterns: Array<string>;
coverageReporters: Array<string>;
coverageThreshold: {
global: {
[key: string]: number;
};
};
dependencyExtractor?: string;
detectLeaks?: boolean;
detectOpenHandles?: boolean;
displayName?: DisplayName;
expand?: boolean;
extraGlobals?: Array<string>;
filter?: Path;
findRelatedTests?: boolean;
forceCoverageMatch?: Array<Glob>;
forceExit?: boolean;
json?: boolean;
globals?: ConfigGlobals;
globalSetup?: string | null | undefined;
globalTeardown?: string | null | undefined;
haste?: HasteConfig;
reporters?: Array<string | ReporterConfig>;
logHeapUsage?: boolean;
lastCommit?: boolean;
listTests?: boolean;
mapCoverage?: boolean;
maxConcurrency?: number;
dependencyExtractor: string;
detectLeaks: boolean;
detectOpenHandles: boolean;
displayName: DisplayName;
expand: boolean;
extraGlobals: Array<string>;
filter: Path;
findRelatedTests: boolean;
forceCoverageMatch: Array<Glob>;
forceExit: boolean;
json: boolean;
globals: ConfigGlobals;
globalSetup: string | null | undefined;
globalTeardown: string | null | undefined;
haste: HasteConfig;
reporters: Array<string | ReporterConfig>;
logHeapUsage: boolean;
lastCommit: boolean;
listTests: boolean;
mapCoverage: boolean;
maxConcurrency: number;
maxWorkers: number | string;
moduleDirectories?: Array<string>;
moduleFileExtensions?: Array<string>;
moduleLoader?: Path;
moduleNameMapper?: {
moduleDirectories: Array<string>;
moduleFileExtensions: Array<string>;
moduleLoader: Path;
moduleNameMapper: {
[key: string]: string;
};
modulePathIgnorePatterns?: Array<string>;
modulePaths?: Array<string>;
name?: string;
noStackTrace?: boolean;
notify?: boolean;
notifyMode?: string;
onlyChanged?: boolean;
outputFile?: Path;
passWithNoTests?: boolean;
preprocessorIgnorePatterns?: Array<Glob>;
preset?: string | null | undefined;
prettierPath?: string | null | undefined;
projects?: Array<Glob>;
replname?: string | null | undefined;
resetMocks?: boolean;
resetModules?: boolean;
resolver?: Path | null | undefined;
restoreMocks?: boolean;
modulePathIgnorePatterns: Array<string>;
modulePaths: Array<string>;
name: string;
noStackTrace: boolean;
notify: boolean;
notifyMode: string;
onlyChanged: boolean;
outputFile: Path;
passWithNoTests: boolean;
preprocessorIgnorePatterns: Array<Glob>;
preset: string | null | undefined;
prettierPath: string | null | undefined;
projects: Array<Glob>;
replname: string | null | undefined;
resetMocks: boolean;
resetModules: boolean;
resolver: Path | null | undefined;
restoreMocks: boolean;
rootDir: Path;
roots?: Array<Path>;
runner?: string;
runTestsByPath?: boolean;
scriptPreprocessor?: string;
setupFiles?: Array<Path>;
setupTestFrameworkScriptFile?: Path;
setupFilesAfterEnv?: Array<Path>;
silent?: boolean;
skipFilter?: boolean;
skipNodeResolution?: boolean;
snapshotResolver?: Path;
snapshotSerializers?: Array<Path>;
errorOnDeprecated?: boolean;
testEnvironment?: string;
testEnvironmentOptions?: Record<string, any>;
testFailureExitCode?: string | number;
testLocationInResults?: boolean;
testMatch?: Array<Glob>;
testNamePattern?: string;
testPathDirs?: Array<Path>;
testPathIgnorePatterns?: Array<string>;
testRegex?: string | Array<string>;
testResultsProcessor?: string | null | undefined;
testRunner?: string;
testSequencer?: string;
testURL?: string;
testTimeout?: number;
timers?: 'real' | 'fake';
transform?: {
roots: Array<Path>;
runner: string;
runTestsByPath: boolean;
scriptPreprocessor: string;
setupFiles: Array<Path>;
setupTestFrameworkScriptFile: Path;
setupFilesAfterEnv: Array<Path>;
silent: boolean;
skipFilter: boolean;
skipNodeResolution: boolean;
snapshotResolver: Path;
snapshotSerializers: Array<Path>;
errorOnDeprecated: boolean;
testEnvironment: string;
testEnvironmentOptions: Record<string, any>;
testFailureExitCode: string | number;
testLocationInResults: boolean;
testMatch: Array<Glob>;
testNamePattern: string;
testPathDirs: Array<Path>;
testPathIgnorePatterns: Array<string>;
testRegex: string | Array<string>;
testResultsProcessor: string | null | undefined;
testRunner: string;
testSequencer: string;
testURL: string;
testTimeout: number;
timers: 'real' | 'fake';
transform: {
[regex: string]: Path | TransformerConfig;
};
transformIgnorePatterns?: Array<Glob>;
watchPathIgnorePatterns?: Array<string>;
unmockedModulePathPatterns?: Array<string>;
updateSnapshot?: boolean;
useStderr?: boolean;
verbose?: boolean | null | undefined;
watch?: boolean;
watchAll?: boolean;
watchman?: boolean;
watchPlugins?: Array<string | [string, Record<string, any>]>;
};
transformIgnorePatterns: Array<Glob>;
watchPathIgnorePatterns: Array<string>;
unmockedModulePathPatterns: Array<string>;
updateSnapshot: boolean;
useStderr: boolean;
verbose: boolean | null | undefined;
watch: boolean;
watchAll: boolean;
watchman: boolean;
watchPlugins: Array<string | [string, Record<string, any>]>;
}>;

export type SnapshotUpdateState = 'all' | 'new' | 'none';

Expand Down