-
-
Notifications
You must be signed in to change notification settings - Fork 268
/
result.ts
90 lines (81 loc) · 2.93 KB
/
result.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
import { OPEN_BRACE_EOL } from './brace-patterns.js'
import { Parser } from './index.js'
import { Directive, parseDirective } from './parse-directive.js'
import { Plan } from './plan.js'
/**
* An indication that a violation of the TAP specification has occurred
*
* This can indicate a test point that exceeds the plan, a test point
* encountered after a trailing plan, or in the case of `pragma +strict`,
* any non-TAP data.
*/
export type TapError = Result | { tapError: string; [k: string]: any }
/**
* A representation of a TestPoint result, with diagnostics if present.
*/
export class Result {
public ok: boolean
public name: string = ''
public id: number = 0
public buffered: boolean = false
public tapError: string | null = null
public skip: boolean | string = false
public todo: boolean | string = false
public previous: Result | null = null
public plan: Plan | null = null
public diag: any | null = null
public time: number | null = null
public fullname: string = ''
public closingTestPoint: boolean = false
constructor(parsed: string[], parser: Parser) {
const ok = !parsed[1]
const id = +(parsed[2] || 0)
let buffered = parsed[4]
this.ok = ok
if (parsed[2]) this.id = id
let rest = parsed[3] || ''
let name: string
// We know at this point the parsed result cannot contain \n,
// so we can leverage that as a placeholder.
// first, replace any PAIR of \ chars with \n
// then, split on any # that is not preceeded by \
// the first of these is definitely the description
// the rest is the directive, if recognized, otherwise
// we just lump it onto the description, but escaped.
// then any \n chars in either are turned into \ (just one)
// escape \ with \
// swap out escaped \ with \n, then swap back
rest = rest.replace(/(\\\\)/g, '\n')
const [h, ...r] = rest.split(/(?<=\s|^)(?<!\\)#/g)
name = (h || '').replace(/\\#/g, '#').replace(/\n/g, '\\')
rest = r.join('#').replace(/\\#/g, '#').replace(/\n/g, '\\')
// now, let's see if there's a directive in there.
const dir = parseDirective(rest.trim())
if (!dir) name += (rest ? '#' + rest : '') + buffered
else {
// handle buffered subtests with todo/skip on them, like
// ok 1 - bar # todo foo {\n
const dirKey: Directive = dir[0]
const dirValue = dir[1]
if (dirKey === 'todo' || dirKey === 'skip') {
this[dirKey] = dirValue
} else {
if (dirKey === 'time') {
this.time = parseFloat(dirValue)
/* c8 ignore start */
}
/* c8 ignore stop */
}
}
if (OPEN_BRACE_EOL.test(name)) {
name = name.replace(OPEN_BRACE_EOL, '')
buffered = '{'
}
if (buffered === '{') this.buffered = true
if (name) this.name = name.trim()
const n: string[] = []
if (parser.fullname) n.push(parser.fullname)
if (this.name) n.push(this.name)
this.fullname = n.join(' > ').trim()
}
}