Skip to content

Commit f8d02f4

Browse files
committed
Seperate summary data from display
1 parent 8dd32ca commit f8d02f4

File tree

3 files changed

+213
-165
lines changed

3 files changed

+213
-165
lines changed

index.js

+1-165
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,2 @@
1-
var through = require('through2')
2-
var duplexer = require('duplexer2')
3-
var parser = require('tap-out')
4-
var format = require('ansi-escape')
5-
var symbols = require('figures')
6-
var prettyMs = require('pretty-ms')
7-
var LF = '\n'
8-
9-
module.exports = function () {
10-
var tap = parser()
11-
var output = through()
12-
var test
13-
14-
var duration = 0
15-
output.push(LF + splitter(' Tests '))
16-
tap.on('test', function (res) {
17-
update()
18-
test = {
19-
name: res.name,
20-
pass: 0,
21-
fail: 0,
22-
get title() {
23-
return this.name +
24-
' [' +
25-
'pass: ' + this.pass +
26-
', fail: ' + this.fail +
27-
(test.end ? ', duration: ' + prettyMs(test.duration) : '') +
28-
']'
29-
},
30-
start: new Date(),
31-
}
32-
output.push(LF + format.cha.eraseLine.escape('# ' + test.title))
33-
})
34-
35-
tap.on('pass', function () {
36-
++test.pass
37-
output.push(format.cha.eraseLine.escape('# ' + test.title))
38-
})
39-
40-
tap.on('fail', function () {
41-
++test.fail
42-
output.push(format.cha.eraseLine.escape('# ' + test.title))
43-
})
44-
45-
tap.on('output', function (res) {
46-
update()
47-
output.push(formatSummary(res, { duration: duration }))
48-
if (res.fail.length) {
49-
dup.failed = true
50-
output.push(formatFail(res))
51-
}
52-
if (res.comments.length) {
53-
output.push(formatComment(res))
54-
}
55-
output.push(LF + LF)
56-
output.push(null)
57-
})
58-
59-
function update() {
60-
if (test) {
61-
test.end = new Date()
62-
test.duration = test.end - test.start
63-
duration += test.duration
64-
if (test.fail) {
65-
output.push(format.cha.red.eraseLine.escape(symbols.cross + ' ' + test.title))
66-
} else {
67-
output.push(format.cha.green.eraseLine.escape(symbols.tick + ' ' + test.title))
68-
}
69-
}
70-
}
71-
72-
var dup = duplexer(tap, output)
73-
return dup
74-
}
75-
76-
function formatSummary(res, extra) {
77-
var output = [LF]
78-
output.push(splitter(' Summary '))
79-
output.push(format.cyan.escape('duration: ' + prettyMs(extra.duration)))
80-
output.push(format.cyan.escape('assertions: ' + res.asserts.length))
81-
if (res.pass.length) {
82-
output.push(format.green.escape('pass: ' + res.pass.length))
83-
} else {
84-
output.push(format.cyan.escape('pass: ' + res.pass.length))
85-
}
86-
if (res.fail.length) {
87-
output.push(format.red.escape('fail: ' + res.fail.length))
88-
} else {
89-
output.push(format.cyan.escape('fail: ' + res.fail.length))
90-
}
91-
return output.join(LF)
92-
}
93-
94-
function formatComment(res) {
95-
var comments = res.comments.reduce(function (o, c) {
96-
var name = getTest(c.test, res.tests).raw
97-
o[name] = o[name] || []
98-
o[name].push(c.raw)
99-
return o
100-
}, {})
101-
var output = [LF]
102-
output.push(splitter(' Comments '))
103-
output.push(Object.keys(comments).map(function (name) {
104-
return format.cyan.underline.escape(name) + LF + comments[name].join(LF)
105-
}).join(LF + LF))
106-
return output.join(LF)
107-
}
108-
109-
function splitter(s) {
110-
var len = s && s.length || 0
111-
var max = 80
112-
var left = max - len >> 1
113-
return format.yellow.escape(
114-
repeat('-', left) + (s || '') + repeat('-', max - len - left)
115-
)
116-
}
117-
118-
function repeat(str, n) {
119-
if (str.repeat) {
120-
return str.repeat(n)
121-
}
122-
return (new Array(n + 1)).join(str)
123-
}
124-
125-
function getTest(n, tests) {
126-
for (var i = 0, len = tests.length; i < len; ++i) {
127-
if (~~n === tests[i].number) {
128-
return tests[i]
129-
}
130-
}
131-
return null
132-
}
133-
134-
function formatFail(res) {
135-
var fail = res.fail.reduce(function (o, c) {
136-
var name = getTest(c.test, res.tests).name
137-
o[name] = o[name] || [format.cyan.underline.escape('# ' + name)]
138-
o[name].push(format.red.escape(' ' + symbols.cross + ' ' + c.name))
139-
o[name].push(prettifyError(c))
140-
return o
141-
}, {})
142-
143-
var output = [LF]
144-
output.push(splitter(' Fails '))
145-
output.push(
146-
Object.keys(fail).map(function (name) {
147-
return fail[name].join(LF)
148-
}).join(LF + LF)
149-
)
150-
return output.join(LF)
151-
}
152-
153-
function prettifyError(assertion) {
154-
var rawError = assertion.error.raw
155-
var ret = rawError.split(LF)
156-
var stack = assertion.error.stack
157-
if (stack) {
158-
stack = stack.split(LF)
159-
var padding = repeat(' ', ret[ret.length - 1].length)
160-
ret = ret.concat(stack.map(function (s) {
161-
return padding + s
162-
}))
163-
}
164-
return format.cyan.escape(ret.join(LF))
165-
}
1+
module.exports = require('./lib/summary')
1662

lib/summarize.js

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
var duplexer = require('duplexer2')
2+
var parser = require('tap-out')
3+
var PassThrough = require('stream').PassThrough
4+
5+
module.exports = function () {
6+
var tap = parser()
7+
var output = PassThrough()
8+
var dup = duplexer(tap, output)
9+
dup.output = output
10+
11+
var test
12+
var duration = 0
13+
14+
function handleTestEnd() {
15+
if (test) {
16+
test.end = new Date()
17+
test.duration = test.end - test.start
18+
duration += test.duration
19+
dup.emit('test.end', test)
20+
}
21+
}
22+
23+
tap.on('test', function (res) {
24+
handleTestEnd()
25+
test = {
26+
name: res.name,
27+
pass: 0,
28+
fail: 0,
29+
start: new Date(),
30+
}
31+
dup.emit('test.start', test)
32+
})
33+
34+
tap.on('pass', function () {
35+
++test.pass
36+
dup.emit('test.pass', test)
37+
})
38+
39+
tap.on('fail', function () {
40+
++test.fail
41+
dup.emit('test.fail', test)
42+
})
43+
44+
tap.on('output', function (res) {
45+
handleTestEnd()
46+
47+
if (res.fail.length) {
48+
dup.failed = true
49+
}
50+
51+
dup.emit('summary', {
52+
duration: duration,
53+
assertions: res.asserts.length,
54+
pass: res.pass.length,
55+
fail: res.fail.length,
56+
comments: res.comments.length,
57+
}, res.fail.reduce(function (o, assertion) {
58+
var name = getTest(assertion.test, res.tests).name
59+
o[name] = o[name] || []
60+
o[name].push(assertion)
61+
return o
62+
}, {}), res.comments.reduce(function (o, assertion) {
63+
var name = getTest(assertion.test, res.tests).raw
64+
o[name] = o[name] || []
65+
o[name].push(assertion.raw)
66+
return o
67+
}, {}), res)
68+
})
69+
70+
return dup
71+
}
72+
73+
function getTest(n, tests) {
74+
for (var i = 0, len = tests.length; i < len; ++i) {
75+
if (~~n === tests[i].number) {
76+
return tests[i]
77+
}
78+
}
79+
return null
80+
}
81+

lib/summary.js

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
var format = require('ansi-escape')
2+
var symbols = require('figures')
3+
var prettyMs = require('pretty-ms')
4+
var LF = '\n'
5+
6+
var summarize = require('./summarize')
7+
8+
module.exports = function () {
9+
var summary = summarize()
10+
var output = summary.output
11+
12+
output.push(LF + splitter(' Tests '))
13+
14+
summary.on('test.start', function (test) {
15+
Object.defineProperty(test, 'title', { get: getTitle })
16+
output.push(LF + format.cha.eraseLine.escape('# ' + test.title))
17+
})
18+
19+
summary.on('test.end', function (test) {
20+
if (test.fail) {
21+
output.push(format.cha.red.eraseLine.escape(symbols.cross + ' ' + test.title))
22+
} else {
23+
output.push(format.cha.green.eraseLine.escape(symbols.tick + ' ' + test.title))
24+
}
25+
})
26+
27+
summary.on('test.pass', function (test) {
28+
output.push(format.cha.eraseLine.escape('# ' + test.title))
29+
})
30+
31+
summary.on('test.fail', function (test) {
32+
output.push(format.cha.eraseLine.escape('# ' + test.title))
33+
})
34+
35+
summary.on('summary', function (sum, fails, comments) {
36+
output.push(formatSummary(sum))
37+
38+
if (sum.fail) {
39+
output.push(formatFail(fails))
40+
}
41+
if (sum.comments) {
42+
output.push(formatComment(comments))
43+
}
44+
output.push(LF + LF)
45+
output.push(null)
46+
})
47+
48+
return summary
49+
}
50+
51+
function getTitle() {
52+
return this.name + ' [' +
53+
'pass: ' + this.pass + ', fail: ' + this.fail +
54+
(this.duration ? ', duration: ' + prettyMs(this.duration) : '') +
55+
']'
56+
}
57+
58+
function formatSummary(res) {
59+
var output = [LF]
60+
output.push(splitter(' Summary '))
61+
output.push(format.cyan.escape('duration: ' + prettyMs(res.duration)))
62+
output.push(format.cyan.escape('assertions: ' + res.assertions))
63+
if (res.pass) {
64+
output.push(format.green.escape('pass: ' + res.pass))
65+
} else {
66+
output.push(format.cyan.escape('pass: ' + res.pass))
67+
}
68+
if (res.fail) {
69+
output.push(format.red.escape('fail: ' + res.fail))
70+
} else {
71+
output.push(format.cyan.escape('fail: ' + res.fail))
72+
}
73+
return output.join(LF)
74+
}
75+
76+
function formatComment(comments) {
77+
var output = [LF]
78+
output.push(splitter(' Comments '))
79+
output.push(Object.keys(comments).map(function (name) {
80+
return format.cyan.underline.escape(name) + LF + comments[name].join(LF)
81+
}).join(LF + LF))
82+
return output.join(LF)
83+
}
84+
85+
function splitter(s) {
86+
var len = s && s.length || 0
87+
var max = 80
88+
var left = max - len >> 1
89+
return format.yellow.escape(
90+
repeat('-', left) + (s || '') + repeat('-', max - len - left)
91+
)
92+
}
93+
94+
function repeat(str, n) {
95+
if (str.repeat) {
96+
return str.repeat(n)
97+
}
98+
return (new Array(n + 1)).join(str)
99+
}
100+
101+
function formatFail(fail) {
102+
var output = [LF]
103+
output.push(splitter(' Fails '))
104+
output.push(
105+
Object.keys(fail).map(function (name) {
106+
var res = [format.cyan.underline.escape('# ' + name)]
107+
fail[name].forEach(function (assertion) {
108+
res.push(format.red.escape(' ' + symbols.cross + ' ' + assertion.name))
109+
res.push(prettifyError(assertion))
110+
})
111+
return res.join(LF)
112+
}).join(LF + LF)
113+
)
114+
115+
return output.join(LF)
116+
}
117+
118+
function prettifyError(assertion) {
119+
var rawError = assertion.error.raw
120+
var ret = rawError.split(LF)
121+
var stack = assertion.error.stack
122+
if (stack) {
123+
stack = stack.split(LF)
124+
var padding = repeat(' ', ret[ret.length - 1].length)
125+
ret = ret.concat(stack.map(function (s) {
126+
return padding + s
127+
}))
128+
}
129+
return format.cyan.escape(ret.join(LF))
130+
}
131+

0 commit comments

Comments
 (0)