From 595d6b863ed158af63bedc3c90b3bf55ed70d396 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 14 Jan 2019 17:05:52 +0100 Subject: [PATCH] chore: make sure to call `realpath` when accessing `cwd` (#7613) --- packages/babel-jest/src/index.js | 19 +++++++++--------- packages/jest-cli/src/SearchSource.js | 6 ++++-- packages/jest-cli/src/getNoTestFound.js | 19 +++++++++++++++--- .../jest-cli/src/getNoTestsFoundMessage.js | 16 ++++++++++++--- packages/jest-cli/src/lib/init/index.js | 3 ++- packages/jest-cli/src/runJest.js | 20 ++++++++----------- packages/jest-resolve/src/index.js | 4 ++-- packages/jest-runtime/src/cli/index.js | 3 ++- types/TestRunner.js | 5 +++++ 9 files changed, 62 insertions(+), 33 deletions(-) diff --git a/packages/babel-jest/src/index.js b/packages/babel-jest/src/index.js index 9db0d2210912..bae5553dbe6c 100644 --- a/packages/babel-jest/src/index.js +++ b/packages/babel-jest/src/index.js @@ -23,11 +23,10 @@ import {transformSync as babelTransform, loadPartialConfig} from '@babel/core'; const THIS_FILE = fs.readFileSync(__filename); const jestPresetPath = require.resolve('babel-preset-jest'); const babelIstanbulPlugin = require.resolve('babel-plugin-istanbul'); -const cwd = process.cwd(); const createTransformer = (options: any): Transformer => { - // Allow incoming options to override `cwd` - options = Object.assign({cwd}, options, { + options = { + ...options, caller: { name: 'babel-jest', supportsStaticESM: false, @@ -36,20 +35,24 @@ const createTransformer = (options: any): Transformer => { plugins: (options && options.plugins) || [], presets: ((options && options.presets) || []).concat(jestPresetPath), sourceMaps: 'both', - }); + }; delete options.cacheDirectory; delete options.filename; + const loadBabelConfig = (cwd, filename) => + // `cwd` first to allow incoming options to override it + loadPartialConfig({cwd, ...options, filename}); + return { canInstrument: true, getCacheKey( fileData: string, filename: Path, configString: string, - {instrument, rootDir}: CacheKeyOptions, + {config, instrument, rootDir}: {config: ProjectConfig} & CacheKeyOptions, ): string { - const babelOptions = loadPartialConfig({...options, filename}); + const babelOptions = loadBabelConfig(config.cwd, filename); const configPath = [ babelOptions.config || '', babelOptions.babelrc || '', @@ -82,9 +85,7 @@ const createTransformer = (options: any): Transformer => { config: ProjectConfig, transformOptions?: TransformOptions, ): string | TransformedSource { - const babelOptions = { - ...loadPartialConfig({...options, filename}).options, - }; + const babelOptions = {...loadBabelConfig(config.cwd, filename).options}; if (transformOptions && transformOptions.instrument) { babelOptions.auxiliaryCommentBefore = ' istanbul ignore next '; diff --git a/packages/jest-cli/src/SearchSource.js b/packages/jest-cli/src/SearchSource.js index 27862d6a7dac..38892285b8d9 100644 --- a/packages/jest-cli/src/SearchSource.js +++ b/packages/jest-cli/src/SearchSource.js @@ -186,7 +186,7 @@ export default class SearchSource { tests: toTests( this._context, paths - .map(p => path.resolve(process.cwd(), p)) + .map(p => path.resolve(this._context.config.cwd, p)) .filter(this.isTestFilePath.bind(this)), ), }; @@ -197,7 +197,9 @@ export default class SearchSource { collectCoverage: boolean, ): SearchResult { if (Array.isArray(paths) && paths.length) { - const resolvedPaths = paths.map(p => path.resolve(process.cwd(), p)); + const resolvedPaths = paths.map(p => + path.resolve(this._context.config.cwd, p), + ); return this.findRelatedTests(new Set(resolvedPaths), collectCoverage); } return {tests: []}; diff --git a/packages/jest-cli/src/getNoTestFound.js b/packages/jest-cli/src/getNoTestFound.js index 93961c902207..bd6ec71b13ac 100644 --- a/packages/jest-cli/src/getNoTestFound.js +++ b/packages/jest-cli/src/getNoTestFound.js @@ -1,9 +1,22 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +/** + * 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. + * + * @flow + */ + +import type {GlobalConfig} from 'types/Config'; +import type {TestRunData} from 'types/TestRunner'; import chalk from 'chalk'; import pluralize from './pluralize'; -export default function getNoTestFound(testRunData, globalConfig): string { +export default function getNoTestFound( + testRunData: TestRunData, + globalConfig: GlobalConfig, +): string { const testFiles = testRunData.reduce( (current, testRun) => current + testRun.matches.total || 0, 0, @@ -25,7 +38,7 @@ export default function getNoTestFound(testRunData, globalConfig): string { '\n' + 'Run with `--passWithNoTests` to exit with code 0' + '\n' + - `In ${chalk.bold(process.cwd())}` + + `In ${chalk.bold(globalConfig.rootDir)}` + '\n' + ` ${pluralize('file', testFiles, 's')} checked across ${pluralize( 'project', diff --git a/packages/jest-cli/src/getNoTestsFoundMessage.js b/packages/jest-cli/src/getNoTestsFoundMessage.js index a351279b9216..be2211172597 100644 --- a/packages/jest-cli/src/getNoTestsFoundMessage.js +++ b/packages/jest-cli/src/getNoTestsFoundMessage.js @@ -1,4 +1,14 @@ -// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. +/** + * 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. + * + * @flow + */ + +import type {GlobalConfig} from 'types/Config'; +import type {TestRunData} from 'types/TestRunner'; import getNoTestFound from './getNoTestFound'; import getNoTestFoundRelatedToChangedFiles from './getNoTestFoundRelatedToChangedFiles'; @@ -6,8 +16,8 @@ import getNoTestFoundVerbose from './getNoTestFoundVerbose'; import getNoTestFoundFailed from './getNoTestFoundFailed'; export default function getNoTestsFoundMessage( - testRunData, - globalConfig, + testRunData: TestRunData, + globalConfig: GlobalConfig, ): string { if (globalConfig.onlyFailures) { return getNoTestFoundFailed(); diff --git a/packages/jest-cli/src/lib/init/index.js b/packages/jest-cli/src/lib/init/index.js index 4ee7e82f873e..4ae03318470e 100644 --- a/packages/jest-cli/src/lib/init/index.js +++ b/packages/jest-cli/src/lib/init/index.js @@ -11,6 +11,7 @@ import chalk from 'chalk'; import fs from 'fs'; import path from 'path'; import prompts from 'prompts'; +import {sync as realpath} from 'realpath-native'; import defaultQuestions, {testScriptQuestion} from './questions'; import {NotFoundPackageJsonError, MalformedPackageJsonError} from './errors'; import {PACKAGE_JSON, JEST_CONFIG} from '../../constants'; @@ -24,7 +25,7 @@ type PromptsResults = { scripts: boolean, }; -export default async (rootDir: string = process.cwd()) => { +export default async (rootDir: string = realpath(process.cwd())) => { // prerequisite checks const projectPackageJsonPath: string = path.join(rootDir, PACKAGE_JSON); const jestConfigPath: string = path.join(rootDir, JEST_CONFIG); diff --git a/packages/jest-cli/src/runJest.js b/packages/jest-cli/src/runJest.js index 6fa276269605..d7660791f418 100644 --- a/packages/jest-cli/src/runJest.js +++ b/packages/jest-cli/src/runJest.js @@ -11,12 +11,14 @@ import type {Context} from 'types/Context'; import type {ChangedFilesPromise} from 'types/ChangedFiles'; import type {GlobalConfig} from 'types/Config'; import type {AggregatedResult} from 'types/TestResult'; +import type {TestRunData} from 'types/TestRunner'; import type {JestHookEmitter} from 'types/JestHooks'; import type TestWatcher from './TestWatcher'; import micromatch from 'micromatch'; import chalk from 'chalk'; import path from 'path'; +import {sync as realpath} from 'realpath-native'; import {Console, formatTestResults} from 'jest-util'; import exit from 'exit'; import fs from 'graceful-fs'; @@ -62,10 +64,7 @@ const getTestPaths = async ( const filteredTests = data.tests.filter((test, i) => shouldTestArray[i]); - return Object.assign({}, data, { - allTests: filteredTests.length, - tests: filteredTests, - }); + return {...data, allTests: filteredTests.length, tests: filteredTests}; }; const processResults = (runResults, options) => { @@ -90,12 +89,12 @@ const processResults = (runResults, options) => { } if (isJSON) { if (outputFile) { - const filePath = path.resolve(process.cwd(), outputFile); + const cwd = realpath(process.cwd()); + const filePath = path.resolve(cwd, outputFile); fs.writeFileSync(filePath, JSON.stringify(formatTestResults(runResults))); outputStream.write( - `Test results written to: ` + - `${path.relative(process.cwd(), filePath)}\n`, + `Test results written to: ${path.relative(cwd, filePath)}\n`, ); } else { process.stdout.write(JSON.stringify(formatTestResults(runResults))); @@ -150,7 +149,7 @@ export default (async function runJest({ let collectCoverageFrom = []; - const testRunData = await Promise.all( + const testRunData: TestRunData = await Promise.all( contexts.map(async context => { const matches = await getTestPaths( globalConfig, @@ -242,10 +241,7 @@ export default (async function runJest({ globalConfig.silent !== true && globalConfig.verbose !== false ) { - // $FlowFixMe Object.assign - const newConfig: GlobalConfig = Object.assign({}, globalConfig, { - verbose: true, - }); + const newConfig: GlobalConfig = {...globalConfig, verbose: true}; globalConfig = Object.freeze(newConfig); } diff --git a/packages/jest-resolve/src/index.js b/packages/jest-resolve/src/index.js index 49804a309521..70b3c867a9cf 100644 --- a/packages/jest-resolve/src/index.js +++ b/packages/jest-resolve/src/index.js @@ -12,8 +12,8 @@ import type {ModuleMap} from 'types/HasteMap'; import type {ResolveModuleConfig} from 'types/Resolve'; import type {ErrorWithCode} from 'types/Errors'; -import fs from 'fs'; import path from 'path'; +import {sync as realpath} from 'realpath-native'; import nodeModulesPaths from './nodeModulesPaths'; import isBuiltinModule from './isBuiltinModule'; import defaultResolver from './defaultResolver'; @@ -53,7 +53,7 @@ const NATIVE_PLATFORM = 'native'; // We might be inside a symlink. const cwd = process.cwd(); -const resolvedCwd = fs.realpathSync(cwd) || cwd; +const resolvedCwd = realpath(cwd) || cwd; const nodePaths = process.env.NODE_PATH ? process.env.NODE_PATH.split(path.delimiter) .filter(Boolean) diff --git a/packages/jest-runtime/src/cli/index.js b/packages/jest-runtime/src/cli/index.js index 601f9aea4d28..fbc3ed4ec8ef 100644 --- a/packages/jest-runtime/src/cli/index.js +++ b/packages/jest-runtime/src/cli/index.js @@ -13,6 +13,7 @@ import type {EnvironmentClass} from 'types/Environment'; import chalk from 'chalk'; import os from 'os'; import path from 'path'; +import {sync as realpath} from 'realpath-native'; import yargs from 'yargs'; import {Console, setGlobal} from 'jest-util'; import {validateCLIOptions} from 'jest-validate'; @@ -59,7 +60,7 @@ export function run(cliArgv?: Argv, cliInfo?: Array) { return; } - const root = process.cwd(); + const root = realpath(process.cwd()); const filePath = path.resolve(root, argv._[0]); if (argv.debug) { diff --git a/types/TestRunner.js b/types/TestRunner.js index 42e97cb6d382..2eac8afcd349 100644 --- a/types/TestRunner.js +++ b/types/TestRunner.js @@ -60,3 +60,8 @@ export type TestFramework = ( export type TestRunnerOptions = { serial: boolean, }; + +export type TestRunData = Array<{ + context: Context, + matches: {allTests: number, tests: Array, total: number}, +}>;