-
-
Notifications
You must be signed in to change notification settings - Fork 269
/
markdown.ts
122 lines (113 loc) · 3.53 KB
/
markdown.ts
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
// markdown representation of the test run
import { Minipass } from 'minipass'
import { parse } from 'path'
import { Parser } from 'tap-parser'
import { stringify } from 'tap-yaml'
import { Case, Suite, Suites } from './json.js'
export class MarkdownStream extends Minipass<string> {
parser: Parser = new Parser()
constructor() {
super({ encoding: 'utf8' })
const suites = new Suites(this.parser)
suites.on('suite', s => this.suiteStart(s))
suites.on('case', c => this.onCase(c))
suites.on('suiteEnd', s => this.suiteEnd(s))
this.suiteStart(suites)
this.parser.on('complete', () => {
this.suiteEnd(suites)
super.end()
})
}
onCase(c: Case) {
const { name, id, diag, ok, skip, todo } = c.result
const t =
skip !== false ? 'skip'
: todo !== false ? 'todo'
: ok ? 'pass'
: 'fail'
const color =
t === 'skip' ? 'cyan'
: t === 'todo' ? 'magenta'
: t === 'pass' ? 'green'
: 'red'
const msg =
typeof skip === 'string' ? `<span color="cyan">${skip}</span>`
: typeof todo === 'string' ?
`<span color="magenta">${todo}</span>`
: ''
const { source, diff, ...extra } = diag || {}
/* c8 ignore start */
const file = diag?.at?.fileName || diag?.at?.file || diag?.file
/* c8 ignore stop */
const srcLang = file ? parse(file).ext.substring(1) : ''
const srcPre =
source ?
`\n\n\`\`\`${srcLang}\n${source.trimEnd()}\n\`\`\``
: ''
const ymlExtra = stringify(extra).trimEnd()
const preExtra =
ymlExtra === '{}' ? '' : `\n\n\`\`\`yaml\n${ymlExtra}\n\`\`\``
const preDiff =
diff ? `\n\n\`\`\`diff\n${diff.trimEnd()}\n\`\`\`` : ''
const b = (preDiff + srcPre + preExtra)
.replace(/^/gm, ' ')
.replace(/\n \n/g, '\n\n')
const body = b.trim() ? '\n\n ' + b.trimStart() : '\n'
super.write(
`${id}. <b style="color:${color}">${t}</b> ${name}${msg}${body}\n`,
)
}
suiteStart(s: Suite) {
const h = Math.min(6, s.parser.level + 1)
super.write(`${'#'.repeat(h)} ${s.name.replace(/\n/g, ' ')}\n\n`)
}
suiteEnd(s: Suite) {
const summary = {
...s.toJSON(),
suites: undefined,
cases: undefined,
} as Record<string, any>
const { source, ...diag } = summary.diag || {}
if (summary.diag) delete summary.diag.source
/* c8 ignore start */
const file = diag.at?.fileName || diag.at?.file || diag.file
/* c8 ignore stop */
const srcLang = file ? parse(file).ext.substring(1) : ''
const srcPre =
source ? `\n\n\`\`\`${srcLang}\n${source}\n\`\`\`` : ''
const fn = summary.fullname || summary.name
delete summary.fullname
delete summary.name
super.write(
`\n----\n\n**${fn}**${srcPre}\n\n\`\`\`yaml\n${stringify(
summary,
).trimEnd()}\n\`\`\`\n\n`,
)
}
write(
chunk: Minipass.ContiguousData,
cb?: (() => void) | undefined,
): boolean
write(
chunk: Minipass.ContiguousData,
encoding?: Minipass.Encoding | undefined,
cb?: (() => void) | undefined,
): boolean
write(chunk: any, encoding?: any, cb?: any): boolean {
return this.parser.write(chunk, encoding, cb)
}
end(cb?: (() => void) | undefined): this
end(
chunk: Minipass.ContiguousData,
cb?: (() => void) | undefined,
): this
end(
chunk: Minipass.ContiguousData,
encoding?: Minipass.Encoding | undefined,
cb?: (() => void) | undefined,
): this
end(chunk?: any, encoding?: any, cb?: any): this {
this.parser.end(chunk, encoding, cb)
return this
}
}