-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
watch.spec.js
142 lines (123 loc) · 3.88 KB
/
watch.spec.js
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
'use strict';
const fs = require('fs-extra');
const os = require('os');
const path = require('path');
const childProcess = require('child_process');
const helpers = require('../helpers');
const runMochaJSONRawAsync = helpers.runMochaJSONRawAsync;
const sigintExitCode = 130;
describe('--watch', function() {
describe('when enabled', function() {
this.timeout(10 * 1000);
this.slow(3000);
before(function() {
// Feature works but SIMULATING the signal (ctrl+c) via child process
// does not work due to lack of POSIX signal compliance on Windows.
if (process.platform === 'win32') {
this.skip();
}
});
beforeEach(function() {
this.tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mocha-'));
var fixtureSource = helpers.resolveFixturePath(helpers.DEFAULT_FIXTURE);
this.testFile = path.join(this.tempDir, 'test.js');
fs.copySync(fixtureSource, this.testFile);
});
afterEach(function() {
if (this.tempDir) {
return fs.remove(this.tempDir);
}
});
it('should show the cursor and signal correct exit code, when watch process is terminated', function() {
const [mocha, resultPromise] = runMochaJSONRawAsync(
helpers.DEFAULT_FIXTURE,
['--watch']
);
return sleep(1000)
.then(() => {
mocha.kill('SIGINT');
return resultPromise;
})
.then(data => {
const expectedCloseCursor = '\u001b[?25h';
expect(data.output, 'to contain', expectedCloseCursor);
expect(data.code, 'to be', sigintExitCode);
});
});
it('reruns test when watched test file is touched', function() {
var [mocha, outputPromise] = runMochaJSONWatchAsync(this.testFile, [], {
cwd: this.tempDir
});
return sleep(1000)
.then(() => {
return touchFile(this.testFile);
})
.then(() => sleep(1000))
.then(() => {
mocha.kill('SIGINT');
return outputPromise;
})
.then(results => {
expect(results, 'to have length', 2);
});
});
it('reruns test when file matching extension is touched', function() {
const watchedFile = path.join(this.tempDir, 'file.xyz');
childProcess.execSync('touch ' + watchedFile);
var [mocha, outputPromise] = runMochaJSONWatchAsync(
this.testFile,
['--extension', 'xyz'],
{
cwd: this.tempDir
}
);
return sleep(1000)
.then(() => {
return touchFile(watchedFile);
})
.then(() => sleep(1000))
.then(() => {
mocha.kill('SIGINT');
return outputPromise;
})
.then(results => {
expect(results, 'to have length', 2);
});
});
});
});
/**
* Invokes the mocha binary with the `--watch` argument for the given fixture.
*
* Returns child process and a promise for the test results. The test results
* are an array of JSON objects generated by the JSON reporter.
*
* Checks that the exit code of the mocha command is 130, i.e. mocha was killed
* by SIGINT.
*/
function runMochaJSONWatchAsync(fixture, args, spawnOpts) {
args = ['--watch'].concat(args);
const [mocha, mochaDone] = runMochaJSONRawAsync(fixture, args, spawnOpts);
const testResults = mochaDone.then(data => {
expect(data.code, 'to be', sigintExitCode);
const testResults = data.output
// eslint-disable-next-line no-control-regex
.replace(/\u001b\[\?25./g, '')
.split('\u001b[2K')
.map(x => JSON.parse(x));
return testResults;
});
return [mocha, testResults];
}
/**
* Touch a file by appending a space to the end. Returns a promise that resolves
* when the file has been touched.
*/
function touchFile(path) {
return fs.appendFile(path, ' ');
}
function sleep(time) {
return new Promise(resolve => {
setTimeout(resolve, time);
});
}