-
-
Notifications
You must be signed in to change notification settings - Fork 25
/
index.js
123 lines (106 loc) · 3.53 KB
/
index.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
var through2 = require('through2');
var duplexer = require('duplexer');
var parser = require('tap-parser');
var sprintf = require('sprintf');
module.exports = function (opts) {
if (!opts) opts = {};
var tap = parser();
var out = through2();
var test, lastAssert;
tap.on('comment', function (comment) {
if (comment === 'fail 0') return; // a mocha thing
if (test && test.ok && test.assertions.length === 0
&& /^(tests|pass)\s+\d+$/.test(test.name)) {
out.push('\r' + trim(test.name));
}
else if (test && test.ok) {
var s = updateName(test.offset + 1, '✓ ' + test.name, 32);
out.push('\r' + s);
}
test = {
name: comment,
assertions: [],
offset: 0,
ok: true
};
out.push('\r' + trim('# ' + comment) + '\x1b[K\n');
});
tap.on('assert', function (res) {
var ok = res.ok ? 'ok' : 'not ok';
var c = res.ok ? 32 : 31;
if (!test) {
// mocha produces TAP results this way, whatever
var s = trim(res.name.trim());
out.push(sprintf(
'\x1b[1m\x1b[' + c + 'm%s\x1b[0m\n',
trim((res.ok ? '✓' : '⨯') + ' ' + s)
));
return;
}
var fmt = '\r %s \x1b[1m\x1b[' + c + 'm%d\x1b[0m %s\x1b[K';
var str = sprintf(fmt, ok, res.number, res.name);
if (!res.ok) {
var y = (++ test.offset) + 1;
str += '\n';
if (test.ok) {
str += updateName(y, '⨯ ' + test.name, 31)
}
test.ok = false;
}
out.push(str);
test.assertions.push(res);
});
tap.on('extra', function (extra) {
if (!test || test.assertions.length === 0) return;
var last = test.assertions[test.assertions.length-1];
if (!last.ok) {
out.push(extra.split('\n').map(function (line) {
return ' ' + line;
}).join('\n') + '\n');
}
});
tap.on('results', function (res) {
if (test && /^fail\s+\d+$/.test(test.name)) {
out.push(updateName(test.offset + 1, '⨯ ' + test.name, 31));
}
else if (test && test.ok) {
out.push(updateName(test.offset + 1, '✓ ' + test.name, 32));
}
res.errors.forEach(function (err, ix) {
out.push(sprintf(
'not ok \x1b[1m\x1b[31m%d\x1b[0m %s\n',
ix + 1 + res.asserts.length, err.message
));
});
if (!res.ok && !/^fail\s+\d+$/.test(test && test.name)) {
out.push(sprintf(
'\r\x1b[1m\x1b[31m⨯ fail %s\x1b[0m\x1b[K\n',
(res.errors.length + res.fail.length) || ''
));
}
out.push(null);
dup.emit('results', res);
if (!res.ok) dup.emit('fail');
dup.exitCode = res.ok ? 0 : 1;
});
var dup = duplexer(tap, out);
return dup;
function showTest (test) {
out.push('\r');
}
function trim (s) {
if (opts.width && s.length > opts.width - 2) {
s = s.slice(0, opts.width - 5) + '...';
}
return s;
}
function updateName (y, str, c) {
return '\x1b[' + y + 'A'
+ '\x1b[1G'
+ '\x1b[1m\x1b[' + c + 'm'
+ trim(str)
+ '\x1b[0m'
+ '\x1b[' + y + 'B\x1b[1G'
;
}
};