Skip to content

Commit 5db683f

Browse files
committed
Add —experimentalProjects to run multiple projects within the same jest-cli test run.
1 parent 6e331d4 commit 5db683f

File tree

6 files changed

+182
-130
lines changed

6 files changed

+182
-130
lines changed

packages/jest-cli/src/TestRunner.js

+31-28
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ class TestRunner {
9292
}
9393
});
9494

95-
const config = this._config;
9695
const aggregatedResults = createAggregatedResults(tests.length);
9796
const estimatedTime = Math.ceil(
9897
getEstimatedTime(timings, this._options.maxWorkers) / 1000,
@@ -120,7 +119,7 @@ class TestRunner {
120119
return;
121120
}
122121
addResult(aggregatedResults, testResult);
123-
this._dispatcher.onTestResult(config, testResult, aggregatedResults);
122+
this._dispatcher.onTestResult(test.config, testResult, aggregatedResults);
124123
this._bailIfNeeded(aggregatedResults, watcher);
125124
};
126125

@@ -135,10 +134,11 @@ class TestRunner {
135134
test.path,
136135
);
137136
addResult(aggregatedResults, testResult);
138-
this._dispatcher.onTestResult(config, testResult, aggregatedResults);
137+
this._dispatcher.onTestResult(test.config, testResult, aggregatedResults);
139138
};
140139

141140
const updateSnapshotState = () => {
141+
const config = this._config;
142142
const status = snapshot.cleanup(
143143
this._context.hasteFS,
144144
config.updateSnapshot,
@@ -151,7 +151,7 @@ class TestRunner {
151151
aggregatedResults.snapshot.filesRemoved));
152152
};
153153

154-
this._dispatcher.onRunStart(config, aggregatedResults, {
154+
this._dispatcher.onRunStart(this._config, aggregatedResults, {
155155
estimatedTime,
156156
showStatus: !runInBand,
157157
});
@@ -169,7 +169,7 @@ class TestRunner {
169169
updateSnapshotState();
170170
aggregatedResults.wasInterrupted = watcher.isInterrupted();
171171

172-
this._dispatcher.onRunComplete(config, aggregatedResults);
172+
this._dispatcher.onRunComplete(this._config, aggregatedResults);
173173

174174
const anyTestFailures = !(aggregatedResults.numFailedTests === 0 &&
175175
aggregatedResults.numRuntimeErrorTestSuites === 0);
@@ -190,17 +190,19 @@ class TestRunner {
190190
) {
191191
const mutex = throat(1);
192192
return tests.reduce(
193-
(promise, test) => mutex(() => promise
194-
.then(() => {
195-
if (watcher.isInterrupted()) {
196-
throw new CancelRun();
197-
}
198-
199-
this._dispatcher.onTestStart(test.config, test.path);
200-
return runTest(test.path, test.config, this._context.resolver);
201-
})
202-
.then(result => onResult(test, result))
203-
.catch(err => onFailure(test, err))),
193+
(promise, test) =>
194+
mutex(() =>
195+
promise
196+
.then(() => {
197+
if (watcher.isInterrupted()) {
198+
throw new CancelRun();
199+
}
200+
201+
this._dispatcher.onTestStart(test.config, test.path);
202+
return runTest(test.path, test.config, this._context.resolver);
203+
})
204+
.then(result => onResult(test, result))
205+
.catch(err => onFailure(test, err))),
204206
Promise.resolve(),
205207
);
206208
}
@@ -225,19 +227,20 @@ class TestRunner {
225227

226228
// Send test suites to workers continuously instead of all at once to track
227229
// the start time of individual tests.
228-
const runTestInWorker = ({config, path}) => mutex(() => {
229-
if (watcher.isInterrupted()) {
230-
return Promise.reject();
231-
}
232-
this._dispatcher.onTestStart(config, path);
233-
return worker({
234-
config,
235-
path,
236-
rawModuleMap: watcher.isWatchMode()
237-
? this._context.moduleMap.getRawModuleMap()
238-
: null,
230+
const runTestInWorker = ({config, path}) =>
231+
mutex(() => {
232+
if (watcher.isInterrupted()) {
233+
return Promise.reject();
234+
}
235+
this._dispatcher.onTestStart(config, path);
236+
return worker({
237+
config,
238+
path,
239+
rawModuleMap: watcher.isWatchMode()
240+
? this._context.moduleMap.getRawModuleMap()
241+
: null,
242+
});
239243
});
240-
});
241244

242245
const onError = (err, test) => {
243246
onFailure(test, err);

packages/jest-cli/src/cli/args.js

+5
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ const options = {
113113
description: 'Use this flag to show full diffs instead of a patch.',
114114
type: 'boolean',
115115
},
116+
experimentalProjects: {
117+
description: 'A list of projects that use Jest to run all tests in a ' +
118+
'single run.',
119+
type: 'array',
120+
},
116121
findRelatedTests: {
117122
description: 'Find related tests for a list of source files that were ' +
118123
'passed in as arguments. Useful for pre-commit hook integration to run ' +

packages/jest-cli/src/cli/index.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ function run(argv?: Object, root?: Path) {
4040
root = pkgDir.sync();
4141
}
4242

43-
getJest(root).runCLI(argv, root, result => {
43+
argv.projects = argv.experimentalProjects;
44+
if (!argv.projects) {
45+
argv.projects = [root];
46+
}
47+
48+
const execute = argv.projects.length === 1 ? getJest(root).runCLI : runCLI;
49+
execute(argv, argv.projects, result => {
4450
const code = !result || result.success ? 0 : 1;
4551
process.on('exit', () => process.exit(code));
4652
if (argv && argv.forceExit) {

packages/jest-cli/src/cli/runCLI.js

+41-27
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
'use strict';
1111

1212
import type {AggregatedResult} from 'types/TestResult';
13-
import type {Path} from 'types/Config';
13+
import type {Config, Path} from 'types/Config';
1414

1515
const Runtime = require('jest-runtime');
1616

@@ -28,9 +28,9 @@ const watch = require('../watch');
2828

2929
const VERSION = require('../../package.json').version;
3030

31-
module.exports = (
31+
module.exports = async (
3232
argv: Object,
33-
root: Path,
33+
roots: Array<Path>,
3434
onComplete: (results: ?AggregatedResult) => void,
3535
) => {
3636
const realFs = require('fs');
@@ -45,52 +45,66 @@ module.exports = (
4545
return;
4646
}
4747

48-
const _run = async ({config, hasDeprecationWarnings}) => {
48+
const _run = async (
49+
configs: Array<{config: Config, hasDeprecationWarnings: boolean}>,
50+
) => {
4951
if (argv.debug) {
50-
logDebugMessages(config, pipe);
52+
// TODO fix/remove this: there should be a `--show-config` argument.
53+
logDebugMessages(configs[0].config, pipe);
5154
}
5255

53-
createDirectory(config.cacheDirectory);
54-
const hasteMapInstance = Runtime.createHasteMap(config, {
55-
console: new Console(pipe, pipe),
56-
maxWorkers: getMaxWorkers(argv),
57-
resetCache: !config.cache,
58-
watch: config.watch,
59-
});
60-
61-
const hasteMap = await hasteMapInstance.build();
62-
const hasteContext = createHasteContext(config, hasteMap);
6356
if (argv.watch || argv.watchAll) {
57+
const {config} = configs[0];
58+
createDirectory(config.cacheDirectory);
59+
const hasteMapInstance = Runtime.createHasteMap(config, {
60+
console: new Console(pipe, pipe),
61+
maxWorkers: getMaxWorkers(argv),
62+
resetCache: !config.cache,
63+
watch: config.watch,
64+
});
65+
66+
const hasteMap = await hasteMapInstance.build();
67+
const hasteContext = createTestContext(config, hasteMap);
6468
return watch(
6569
config,
6670
pipe,
6771
argv,
6872
hasteMapInstance,
6973
hasteContext,
70-
hasDeprecationWarnings,
74+
// TODO
75+
configs[0].hasDeprecationWarnings,
7176
);
7277
} else {
78+
const contexts = await Promise.all(
79+
configs.map(async ({config}) => {
80+
createDirectory(config.cacheDirectory);
81+
return createTestContext(
82+
config,
83+
await Runtime.createHasteMap(config, {
84+
console: new Console(pipe, pipe),
85+
maxWorkers: getMaxWorkers(argv),
86+
resetCache: !config.cache,
87+
watch: config.watch,
88+
}).build(),
89+
);
90+
}),
91+
);
92+
7393
const startRun = () => {
7494
preRunMessage.print(pipe);
7595
const testWatcher = new TestWatcher({isWatchMode: false});
76-
return runJest(
77-
hasteContext,
78-
config,
79-
argv,
80-
pipe,
81-
testWatcher,
82-
startRun,
83-
onComplete,
84-
);
96+
runJest(contexts, argv, pipe, testWatcher, startRun, onComplete);
8597
};
8698
return startRun();
8799
}
88100
};
89101

90-
readConfig(argv, root).then(_run).catch(error => {
102+
try {
103+
await _run(await Promise.all(roots.map(root => readConfig(argv, root))));
104+
} catch (error) {
91105
clearLine(process.stderr);
92106
clearLine(process.stdout);
93107
console.error(chalk.red(error.stack));
94108
process.exit(1);
95-
});
109+
}
96110
};

0 commit comments

Comments
 (0)