-
Notifications
You must be signed in to change notification settings - Fork 782
/
Copy pathtest-on-node.js
99 lines (83 loc) · 2.73 KB
/
test-on-node.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
'use strict';
module.exports = function (grunt) {
grunt.registerMultiTask('test-on-node', async function () {
let done = this.async();
const totals = { files: 0, failed: 0 };
for (const file of this.data) {
totals.failed += await runQUnit(file);
totals.files++;
}
if (totals.failed) {
grunt.log.error(`Ran ${totals.files} files, ${totals.failed} failed tests`);
} else {
grunt.log.ok(`Ran ${totals.files} files`);
}
done(!totals.failed);
});
function requireFreshQUnit () {
// Resolve current QUnit path and remove it from the require cache
// to avoid stacking the QUnit logs.
const path = '../../qunit/qunit.js';
const resolvedPath = require.resolve(path);
delete require.cache[resolvedPath];
// Clear any QUnit global from a previous test
delete globalThis.QUnit;
return require(path);
}
async function runQUnit (file) {
const QUnit = requireFreshQUnit();
QUnit.config.autostart = false;
await import('../../' + file);
const runEnd = new Promise(resolve => registerEvents(QUnit, file, resolve));
QUnit.start();
await runEnd;
}
function registerEvents (QUnit, fileName, callback) {
// Silence deprecation warnings
const warn = process.stderr.write;
process.stderr.write = function () {};
function restore () {
process.stderr.write = warn;
}
// These tests are relatively short. Buffer the output so that we
// only have to restore once, and can craft more condensed output.
let out = '';
QUnit.on('runStart', () => {
out += 'Testing ' + fileName;
});
QUnit.on('testEnd', (testEnd) => {
if (testEnd.status === 'todo') {
return;
}
testEnd.errors.forEach((assertion) => {
out += `\n\ntest: ${testEnd.fullName.join(' > ')}\n`
+ `actual : ${QUnit.dump.parse(assertion.actual)}\n`
+ `expected: ${QUnit.dump.parse(assertion.expected)}\n`
+ `message: ${assertion.message}\n${assertion.stack || ''}`;
});
});
QUnit.on('runEnd', (suiteEnd) => {
restore();
const stats = suiteEnd.testCounts;
if (suiteEnd.status === 'failed') {
out += '\n' + `${stats.total} tests in ${suiteEnd.runtime}ms`;
out += `, ${stats.passed} passed`;
if (stats.failed) {
out += `, ${stats.failed} failed`;
}
if (stats.skipped) {
out += `, ${stats.skipped} skipped`;
}
if (stats.todo) {
out += `, ${stats.todo} todo`;
}
out += '.';
grunt.log.error(out);
} else {
out += ` (${stats.total} tests in ${suiteEnd.runtime}ms)`;
grunt.log.writeln(out);
}
callback(stats.failed);
});
}
};