Skip to content

Commit 1a00b00

Browse files
committed
capture logging in parser
Signed-off-by: shmck <[email protected]>
1 parent 7cda121 commit 1a00b00

File tree

3 files changed

+69
-7
lines changed

3 files changed

+69
-7
lines changed

src/services/testRunner/formatOutput.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ParserOutput, Fail } from './parser'
44
// export const formatSuccessOutput = (tap: ParserOutput): string => {}
55

66
export const formatFailOutput = (tap: ParserOutput): string => {
7-
let output = `'TESTS FAILED\n`
7+
let output = `TESTS\n`
88
tap.failed.forEach((fail: Fail) => {
99
const details = fail.details ? `\n${fail.details}\n\n` : ''
1010
output += ` ✘ ${fail.message}\n${details}`

src/services/testRunner/parser.test.ts

+32-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ describe('parser', () => {
66
1..1
77
ok 1 - Should pass
88
`
9-
expect(parser(example)).toEqual({ ok: true, passed: [{ message: 'Should pass' }], failed: [] })
9+
expect(parser(example)).toEqual({ ok: true, passed: [{ message: 'Should pass' }], failed: [], logs: [] })
1010
})
1111
test('should detect multiple successes', () => {
1212
const example = `
@@ -19,6 +19,7 @@ ok 2 - Should also pass
1919
ok: true,
2020
passed: [{ message: 'Should pass' }, { message: 'Should also pass' }],
2121
failed: [],
22+
logs: [],
2223
})
2324
})
2425
test('should detect failure if no tests passed', () => {
@@ -141,4 +142,34 @@ at processImmediate (internal/timers.js:439:21)`)
141142
expect(result.failed[1].message).toBe('package.json should have a valid "description" key')
142143
expect(result.failed[1].details).toBe(`AssertionError [ERR_ASSERTION]: no "description" key provided`)
143144
})
145+
test('should capture logs', () => {
146+
const example = `
147+
1..2
148+
ok 1 package.json should have "express" installed
149+
log 1
150+
log 2
151+
not ok 2 server should log "Hello World"
152+
# AssertionError [ERR_ASSERTION]: "Hello World was not logged
153+
# at Context.<anonymous> (test/server.test.js:15:12)
154+
# at processImmediate (internal/timers.js:439:21)
155+
# tests 2
156+
# pass 1
157+
# fail 1
158+
# skip 0
159+
`
160+
expect(parser(example)).toEqual({
161+
ok: false,
162+
passed: [{ message: 'package.json should have "express" installed' }],
163+
failed: [
164+
{
165+
message: 'server should log "Hello World"',
166+
details: `AssertionError [ERR_ASSERTION]: \"Hello World was not logged
167+
at Context.<anonymous> (test/server.test.js:15:12)
168+
at processImmediate (internal/timers.js:439:21)`,
169+
logs: ['log 1', 'log 2'],
170+
},
171+
],
172+
logs: ['log 1', 'log 2'],
173+
})
174+
})
144175
})

src/services/testRunner/parser.ts

+36-5
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,47 @@
11
export interface Fail {
22
message: string
33
details?: string
4+
logs?: string[]
5+
}
6+
7+
export interface Pass {
8+
message: string
9+
logs?: string[]
410
}
511

612
export interface ParserOutput {
713
ok: boolean
8-
passed: Array<{ message: string }>
9-
failed: Array<Fail>
14+
passed: Pass[]
15+
failed: Fail[]
16+
logs: string[]
1017
}
1118

1219
const r = {
20+
start: /^1\.\.[0-9]+$/,
1321
fail: /^not ok \d+\s(\-\s)?(.+)+$/,
1422
pass: /^ok \d+\s(\-\s)?(.+)+$/,
1523
details: /^#\s{2}(.+)$/,
24+
ignore: /^#\s+(tests|pass|fail|skip)\s+[0-9]+$/,
1625
}
1726

1827
const detect = (type: 'fail' | 'pass' | 'details', text: string) => r[type].exec(text)
1928

2029
const parser = (text: string): ParserOutput => {
21-
const lines = text.split('\n')
30+
const lineList = text.split('\n')
31+
// start after 1..n output
32+
const startingPoint = lineList.findIndex((t) => t.match(r.start))
33+
const lines = lineList.slice(startingPoint + 1)
2234

2335
const result: ParserOutput = {
2436
ok: true,
2537
passed: [],
2638
failed: [],
39+
logs: [],
2740
}
2841

2942
// temporary holder of error detail strings
3043
let currentDetails: string | null = null
44+
let logs: string[] = []
3145

3246
const addCurrentDetails = () => {
3347
const failLength: number = result.failed.length
@@ -44,7 +58,12 @@ const parser = (text: string): ParserOutput => {
4458
// be optimistic! check for success
4559
const isPass = detect('pass', line)
4660
if (!!isPass) {
47-
result.passed.push({ message: isPass[2].trim() })
61+
const pass: Pass = { message: isPass[2].trim() }
62+
if (logs.length) {
63+
pass.logs = logs
64+
logs = []
65+
}
66+
result.passed.push(pass)
4867
addCurrentDetails()
4968
continue
5069
}
@@ -54,7 +73,12 @@ const parser = (text: string): ParserOutput => {
5473
if (!!isFail) {
5574
result.ok = false
5675
addCurrentDetails()
57-
result.failed.push({ message: isFail[2].trim() })
76+
const fail: Fail = { message: isFail[2].trim() }
77+
if (logs.length) {
78+
fail.logs = logs
79+
logs = []
80+
}
81+
result.failed.push(fail)
5882
continue
5983
}
6084

@@ -68,6 +92,13 @@ const parser = (text: string): ParserOutput => {
6892
// @ts-ignore ignore as it must be a string
6993
currentDetails += `\n${lineDetails}`
7094
}
95+
continue
96+
}
97+
98+
if (!r.ignore.exec(line)) {
99+
// must be a log, associate with the next test
100+
logs.push(line)
101+
result.logs.push(line)
71102
}
72103
}
73104
addCurrentDetails()

0 commit comments

Comments
 (0)