UNPKG

3.08 kBJavaScriptView Raw
1/** Copyright (c) 2018 Uber Technologies, Inc.
2 *
3 * This source code is licensed under the MIT license found in the
4 * LICENSE file in the root directory of this source tree.
5 *
6 * @flow
7 */
8
9/* eslint-env node */
10
11const path = require('path');
12const {spawn} = require('child_process');
13const rimraf = require('rimraf');
14
15const convertCoverage = require('./convert-coverage');
16
17module.exports.TestAppRuntime = function(
18 {
19 dir = '.',
20 debug = false,
21 match,
22 env,
23 testFolder, // deprecated
24 testMatch,
25 testRegex,
26 updateSnapshot,
27 collectCoverageFrom,
28 configPath = `${__dirname}/jest/jest-config.js`,
29 jestArgs = {},
30 } /*: any */
31) {
32 const state = {procs: []};
33 const rootDir = path.resolve(process.cwd(), dir);
34
35 this.run = () => {
36 this.stop();
37 const getArgs = () => {
38 let args = [require.resolve('jest/bin/jest.js')];
39 if (debug) {
40 args = [
41 '--inspect-brk',
42 require.resolve('jest/bin/jest.js'),
43 '--runInBand',
44 // --no-cache is required to allow debugging from vscode
45 '--no-cache',
46 ];
47 }
48
49 args = args.concat(['--config', configPath]);
50 Object.keys(jestArgs).forEach(arg => {
51 const value = jestArgs[arg];
52 if (value && typeof value === 'boolean') {
53 args.push(`--${arg}`);
54 }
55 });
56
57 if (match && match.length > 0) {
58 args.push(match);
59 }
60
61 args.push('--verbose');
62 return args;
63 };
64
65 const setup = () => {
66 if (!jestArgs.coverage) {
67 return Promise.resolve();
68 }
69
70 // Remove existing coverage directories
71 const folders = [`${rootDir}/coverage/`];
72 return Promise.all(
73 folders.map(folder => new Promise(resolve => rimraf(folder, resolve)))
74 );
75 };
76
77 const spawnProc = () => {
78 return new Promise((resolve, reject) => {
79 const args = getArgs();
80 const procEnv = {
81 JEST_ENV: env,
82 TEST_FOLDER: testFolder, // deprecated
83 TEST_MATCH: testMatch,
84 TEST_REGEX: testRegex,
85 COVERAGE_PATHS: collectCoverageFrom,
86 };
87 const proc = spawn('node', args, {
88 cwd: rootDir,
89 stdio: 'inherit',
90 env: Object.assign(procEnv, process.env),
91 });
92 proc.on('error', reject);
93 proc.on('exit', (code, signal) => {
94 if (code) {
95 return reject(new Error(`Test exited with code ${code}`));
96 }
97
98 if (signal) {
99 return reject(
100 new Error(`Test process exited with signal ${signal}`)
101 );
102 }
103
104 return resolve();
105 });
106 state.procs.push(proc);
107 });
108 };
109
110 const finish = () => {
111 if (!jestArgs.coverage) {
112 return Promise.resolve();
113 }
114 return convertCoverage(rootDir);
115 };
116
117 return setup()
118 .then(spawnProc)
119 .then(finish);
120 };
121
122 this.stop = () => {
123 if (state.procs.length) {
124 state.procs.forEach(proc => proc.kill());
125 state.procs = [];
126 }
127 };
128};