-
-
Notifications
You must be signed in to change notification settings - Fork 37
/
server.js
173 lines (151 loc) · 5.36 KB
/
server.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* global Package */
import { mochaInstance } from 'meteor/meteortesting:mocha-core';
import { startBrowser } from 'meteor/meteortesting:browser-tests';
import setArgs from './runtimeArgs';
import handleCoverage from './server.handleCoverage';
if (Package['browser-policy-common']) {
const { BrowserPolicy } = Package['browser-policy-common'];
// Allow the remote mocha.css file to be inserted, in case any CSP stuff
// exists for the domain.
BrowserPolicy.content.allowInlineStyles();
BrowserPolicy.content.allowStyleOrigin('https://cdn.rawgit.com');
}
const { mochaOptions, runnerOptions, coverageOptions } = setArgs();
const { grep, invert, reporter, serverReporter, xUnitOutput } = mochaOptions || {};
// Since intermingling client and server log lines would be confusing,
// the idea here is to buffer all client logs until server tests have
// finished running and then dump the buffer to the screen and continue
// logging in real time after that if client tests are still running.
let serverTestsDone = false;
const clientLines = [];
function clientLogBuffer(line) {
if (serverTestsDone) {
// printing and removing the extra new-line character. The first was added by the client log, the second here.
console.log(line.replace(/\n$/, ''));
} else {
clientLines.push(line);
}
}
function printHeader(type) {
const lines = [
'\n--------------------------------',
Meteor.isAppTest ? `--- RUNNING APP ${type} TESTS ---` : `----- RUNNING ${type} TESTS -----`,
'--------------------------------\n',
];
lines.forEach((line) => {
if (type === 'CLIENT') {
clientLogBuffer(line);
} else {
console.log(line);
}
});
}
let callCount = 0;
let clientFailures = 0;
let serverFailures = 0;
function exitIfDone(type, failures) {
callCount++;
if (type === 'client') {
clientFailures = failures;
} else {
serverFailures = failures;
serverTestsDone = true;
clientLines.forEach((line) => {
// printing and removing the extra new-line character. The first was added by the client log, the second here.
console.log(line.replace(/\n$/, ''));
});
}
if (callCount === 2) {
// We only need to show this final summary if we ran both kinds of tests in the same console
if (runnerOptions.runServer && runnerOptions.runClient && runnerOptions.browserDriver) {
console.log('All tests finished!\n');
console.log('--------------------------------');
console.log(`${Meteor.isAppTest ? 'APP ' : ''}SERVER FAILURES: ${serverFailures}`);
console.log(`${Meteor.isAppTest ? 'APP ' : ''}CLIENT FAILURES: ${clientFailures}`);
console.log('--------------------------------');
}
handleCoverage(coverageOptions).then(() => {
// if no env for TEST_WATCH, tests should exit when done
if (!runnerOptions.testWatch) {
if (clientFailures + serverFailures > 0) {
process.exit(1); // exit with non-zero status if there were failures
} else {
process.exit(0);
}
}
});
}
}
function serverTests(cb) {
if (!runnerOptions.runServer) {
console.log('SKIPPING SERVER TESTS BECAUSE TEST_SERVER=0');
exitIfDone('server', 0);
if (cb) cb();
return;
}
printHeader('SERVER');
if (grep) mochaInstance.grep(grep);
if (invert) mochaInstance.options.invert = invert;
mochaInstance.options.useColors = true;
// We need to set the reporter when the tests actually run to ensure no conflicts with
// other test driver packages that may be added to the app but are not actually being
// used on this run.
mochaInstance.reporter(serverReporter || reporter || 'spec', {
output: xUnitOutput,
});
mochaInstance.run((failureCount) => {
if (typeof failureCount !== 'number') {
console.log('Mocha did not return a failure count for server tests as expected');
exitIfDone('server', 1);
} else {
exitIfDone('server', failureCount);
}
if (cb) cb();
});
}
function clientTests() {
if (!runnerOptions.runClient) {
console.log('SKIPPING CLIENT TESTS BECAUSE TEST_CLIENT=0');
exitIfDone('client', 0);
return;
}
if (!runnerOptions.browserDriver) {
console.log('Load the app in a browser to run client tests, or set the TEST_BROWSER_DRIVER environment variable. ' +
'See https://github.com/meteortesting/meteor-mocha/blob/master/README.md#run-app-tests');
exitIfDone('client', 0);
return;
}
printHeader('CLIENT');
startBrowser({
stdout(data) {
clientLogBuffer(data.toString());
},
stderr(data) {
clientLogBuffer(data.toString());
},
done(failureCount) {
if (typeof failureCount !== 'number') {
console.log('The browser driver package did not return a failure count for server tests as expected');
exitIfDone('client', 1);
} else {
exitIfDone('client', failureCount);
}
},
});
}
// Before Meteor calls the `start` function, app tests will be parsed and loaded by Mocha
function start() {
// Run in PARALLEL or SERIES
// Running in series is a better default since it avoids db and state conflicts for newbs.
// If you want parallel you will know these risks.
if (runnerOptions.runParallel) {
console.log('Warning: Running in parallel can cause side-effects from state/db sharing');
serverTests();
clientTests();
} else {
serverTests(() => {
clientTests();
});
}
}
export { start };