forked from mrsone40/vets-website
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwatch-tests.js
More file actions
106 lines (92 loc) · 3.1 KB
/
watch-tests.js
File metadata and controls
106 lines (92 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* eslint-disable no-console */
const { fork } = require('child_process');
const chokidar = require('chokidar');
const util = require('util');
const glob = util.promisify(require('glob'));
const chalk = require('chalk');
const _ = require('lodash');
console.log(chalk.cyan('Performing initial set up'));
const showErrors = process.argv.includes('showErrors');
let watcher;
let busy = false;
let pendingTests = [];
// all unit test files
const allUnitTests = glob.sync('{src,script,test}/**/*.unit.spec.js?(x)');
function runMochaTests(tests) {
// fork mocha into a separate process
const forked = fork('./script/mocha.js');
return new Promise((fulfill, reject) => {
// send the mocha process the tests to run
forked.send({
tests,
showErrors,
});
forked.on('message', ({ error, requiredFiles, unitTestsForSrc }) => {
if (error) {
// mocha runner returned an error
reject(error);
} else {
// mocha runner returend a list of files it required and a map of unit tests to source files
fulfill({ requiredFiles, unitTestsForSrc });
}
// kill mocha
forked.kill('SIGHUP');
});
});
}
// runs array of test files passed in or all tests if no value provided
async function runUnitTests(unitTests = allUnitTests) {
if (busy) {
pendingTests = _.union(pendingTests, unitTests);
return;
}
console.log(chalk.cyan(`Running ${unitTests.length} unit test files`));
busy = true;
let unitTestsForSrc;
let requiredFiles;
try {
// eslint-disable-next-line no-undef
({ requiredFiles, unitTestsForSrc } = await runMochaTests(unitTests));
} catch (e) {
if (!watcher) {
// mocha errored before setting up watcher; exit process
console.log(chalk.red('Mocha failed. Fix error and restart watch'));
process.exit(1);
} else {
// mocha errored after setting up watcher; continue watching for changes
console.log(chalk.red('Mocha failed. Fix error'));
}
}
busy = false;
// changes were detected during a test run; run these tests and clear the queue
if (pendingTests.length > 0) {
busy = false;
process.nextTick(() => {
runUnitTests(pendingTests);
pendingTests = [];
});
console.log(chalk.yellow('Changes detected during last run.'));
console.log(chalk.yellow('======'));
return;
}
console.log(chalk.yellow('Watching for changes'));
console.log(chalk.yellow('======\n\n'));
// watcher is only created once- if new files are added, then watcher must be restarted
if (!watcher) {
// start watcher with the files that mocha imported
watcher = chokidar.watch(requiredFiles).on('change', file => {
// if a unit test is updated just run that unit test
if (file.includes('.unit.spec')) {
runUnitTests([file]);
}
// if change is from a src file, run unit tests that import that src file
if (file.includes('src') && unitTestsForSrc[file]) {
runUnitTests(unitTestsForSrc[file]);
} else {
// if no unit tests import src file, run all unit tests
runUnitTests();
}
});
}
}
runUnitTests();