Skip to content

Commit

Permalink
global_config.js for multi-project runner
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronabramov committed Jul 13, 2017
1 parent dd6c5c4 commit 3ab9f2a
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`can pass projects or global config 1`] = `
"Test Suites: 2 failed, 2 total
Tests: 0 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
"
`;
exports[`can pass projects or global config 2`] = `
"Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites in 2 projects.
"
`;
exports[`can pass projects or global config 3`] = `
"PASS project1/__tests__/file1.test.js
PASS project2/__tests__/file1.test.js"
`;
exports[`can pass projects or global config 4`] = `
"Test Suites: 2 passed, 2 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites in 2 projects.
"
`;
exports[`can pass projects or global config 5`] = `
"PASS project1/__tests__/file1.test.js
PASS project2/__tests__/file1.test.js"
`;
89 changes: 89 additions & 0 deletions integration_tests/__tests__/multi_project_runner.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

'use strict';

import runJest from '../runJest';
import {cleanup, extractSummary, writeFiles} from '../utils';
import os from 'os';
import path from 'path';

const skipOnWindows = require('skipOnWindows');
const DIR = path.resolve(os.tmpdir(), 'multi_project_runner_test');

skipOnWindows.suite();

const fileContentWithProvidesModule = name => `/*
* @providesModule ${name}
*/
module.exports = {};
`;

beforeEach(() => cleanup(DIR));
afterEach(() => cleanup(DIR));

// Since Jest does not guarantee the order of tests we'll sort the output.
const sortLines = output =>
output
.split(/\n/)
.sort()
.map(str => str.trim())
.filter(str => Boolean(str))
.join('\n');

test('can pass projects or global config', () => {
writeFiles(DIR, {
'.watchmanconfig': '',
'package.json': '{}',
'project1/__tests__/file1.test.js': `
const file1 = require('file1');
test('file1', () => {});
`,
'project1/file1.js': fileContentWithProvidesModule('file1'),
'project1/jest.config.js': `module.exports = {rootDir: './'}`,
'project2/__tests__/file1.test.js': `
const file1 = require('file1');
test('file1', () => {});
`,
'project2/file1.js': fileContentWithProvidesModule('file1'),
'project2/jest.config.js': `module.exports = {rootDir: './'}`,
});
let stderr;

({stderr} = runJest(DIR));
expect(stderr).toMatch(
'The name `file1` was looked up in the Haste module map. It cannot be resolved, because there exists several different files',
);

expect(extractSummary(stderr).summary).toMatchSnapshot();

writeFiles(DIR, {
'global_config.js': `
module.exports = {
projects: ['project1/', 'project2/'],
};
`,
});

({stderr} = runJest(DIR, ['-i', '--projects', 'project1', 'project2']));

const result1 = extractSummary(stderr);
expect(result1.summary).toMatchSnapshot();
expect(sortLines(result1.rest)).toMatchSnapshot();

({stderr} = runJest(DIR, ['-i', '--config', 'global_config.js']));
const result2 = extractSummary(stderr);

expect(result2.summary).toMatchSnapshot();
expect(sortLines(result2.rest)).toMatchSnapshot();

// make sure different ways of passing projects work exactly the same
expect(result1.summary).toBe(result2.summary);
expect(sortLines(result1.rest)).toBe(sortLines(result2.rest));
});
2 changes: 1 addition & 1 deletion packages/jest-cli/src/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ const _getConfigs = (
}

if (projects.length > 1) {
const parsedConfigs = projects.map(root => readConfig(argv, root));
const parsedConfigs = projects.map(root => readConfig(argv, root, true));
configs = parsedConfigs.map(({config}) => config);
if (!hasDeprecationWarnings) {
hasDeprecationWarnings = parsedConfigs.some(
Expand Down
27 changes: 16 additions & 11 deletions packages/jest-config/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,17 @@ import normalize from './normalize';
function readConfig(
argv: Argv,
packageRoot: string,
// Whether it needs to look into `--config` arg passed to CLI.
// It only used to read initial config. If the initial config contains
// `project` property, we don't want to read `--config` value and rather
// read individual configs for every project.
skipArgvConfigOption?: boolean,
): {
config: ProjectConfig,
globalConfig: GlobalConfig,
hasDeprecationWarnings: boolean,
} {
const rawOptions = readOptions(argv, packageRoot);
const rawOptions = readOptions(argv, packageRoot, skipArgvConfigOption);
const {options, hasDeprecationWarnings} = normalize(rawOptions, argv);
const {globalConfig, projectConfig} = getConfigs(options);
return {
Expand All @@ -34,22 +39,22 @@ function readConfig(
};
}

const parseConfig = argv =>
isJSONString(argv.config) ? JSON.parse(argv.config) : argv.config;

const readOptions = (argv, root) => {
const rawOptions = parseConfig(argv);

if (typeof rawOptions === 'object') {
const config = Object.assign({}, rawOptions);
const readOptions = (argv, root, skipArgvConfigOption) => {
// A JSON string was passed to `--config` argument and we can parse it
// and use as is.
if (isJSONString(argv.config)) {
const config = JSON.parse(argv.config);
config.rootDir = config.rootDir || root;
return config;
}

if (typeof rawOptions === 'string') {
root = path.resolve(process.cwd(), rawOptions);
// A string passed to `--config`, which is either a direct path to the config
// or a path to directory containing `package.json` or `jest.conf.js`
if (!skipArgvConfigOption && typeof argv.config == 'string') {
return findConfig(path.resolve(process.cwd(), argv.config));
}

// Otherwise just try to find config in the current rootDir.
return findConfig(root);
};

Expand Down

0 comments on commit 3ab9f2a

Please sign in to comment.