borp 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +13 -3
- package/README.md +65 -1
- package/borp.js +46 -10
- package/fixtures/js-esm/lib/add.js +3 -0
- package/fixtures/js-esm/test/add.test.js +7 -0
- package/fixtures/js-esm/test/add2.test.js +7 -0
- package/lib/reporters.js +114 -0
- package/lib/run.js +12 -4
- package/package.json +6 -2
- package/test/basic.test.js +21 -0
- package/test/cli.test.js +2 -0
- package/test/coverage.test.js +1 -0
- package/test/reporters.test.js +172 -0
package/.github/workflows/ci.yml
CHANGED
|
@@ -19,10 +19,10 @@ jobs:
|
|
|
19
19
|
node-version: [18.x, 20.x, 21.x]
|
|
20
20
|
os: [ubuntu-latest, windows-latest]
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
23
|
|
|
24
24
|
- name: Use Node.js
|
|
25
|
-
uses: actions/setup-node@
|
|
25
|
+
uses: actions/setup-node@v4
|
|
26
26
|
with:
|
|
27
27
|
node-version: ${{ matrix.node-version }}
|
|
28
28
|
|
|
@@ -30,6 +30,16 @@ jobs:
|
|
|
30
30
|
run: |
|
|
31
31
|
npm install
|
|
32
32
|
|
|
33
|
+
- name: Lint
|
|
34
|
+
run: |
|
|
35
|
+
npm run lint
|
|
36
|
+
|
|
33
37
|
- name: Run tests
|
|
34
38
|
run: |
|
|
35
|
-
npm run
|
|
39
|
+
npm run unit -- --reporter spec --reporter md:report.md --reporter gh
|
|
40
|
+
|
|
41
|
+
- name: Upload report
|
|
42
|
+
shell: bash
|
|
43
|
+
if: success() || failure()
|
|
44
|
+
run: |
|
|
45
|
+
cat report.md >> "$GITHUB_STEP_SUMMARY"
|
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ npm i borp --save-dev
|
|
|
17
17
|
borp --coverage
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Borp will
|
|
20
|
+
Borp will automatically run all tests files matching `*.test.{js|ts}`.
|
|
21
21
|
|
|
22
22
|
### Example project setup
|
|
23
23
|
|
|
@@ -93,6 +93,70 @@ Note the use of `incremental: true`, which speed up compilation massively.
|
|
|
93
93
|
* `--ignore` or `-i`, ignore a glob pattern, and not look for tests there
|
|
94
94
|
* `--expose-gc`, exposes the gc() function to tests
|
|
95
95
|
* `--pattern` or `-p`, run tests matching the given glob pattern
|
|
96
|
+
* `--reporter` or `-r`, set up a reporter, use a colon to set a file destination. Default: `spec`.
|
|
97
|
+
|
|
98
|
+
## Reporters
|
|
99
|
+
|
|
100
|
+
Here are the available reporters:
|
|
101
|
+
|
|
102
|
+
* `md`: creates a markdown table, useful for setting up a Summary in your GitHub Action
|
|
103
|
+
* `gh`: emits `::error` workflow commands for GitHub Actions to show inlined error. Enabled by default when running on GHA.
|
|
104
|
+
* `tap`: outputs the test results in the TAP format.
|
|
105
|
+
* `spec`: outputs the test results in a human-readable format.
|
|
106
|
+
* `dot`: outputs the test results in a compact format, where each passing test is represented by a ., and each failing test is represented by a X.
|
|
107
|
+
* `junit`: outputs test results in a jUnit XML format
|
|
108
|
+
|
|
109
|
+
## GitHub Action Summary
|
|
110
|
+
|
|
111
|
+
The following will automatically show the summary of the test run in the summary page of GitHub Actions.
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
name: ci
|
|
115
|
+
|
|
116
|
+
on:
|
|
117
|
+
push:
|
|
118
|
+
paths-ignore:
|
|
119
|
+
- 'docs/**'
|
|
120
|
+
- '*.md'
|
|
121
|
+
pull_request:
|
|
122
|
+
paths-ignore:
|
|
123
|
+
- 'docs/**'
|
|
124
|
+
- '*.md'
|
|
125
|
+
|
|
126
|
+
jobs:
|
|
127
|
+
test:
|
|
128
|
+
runs-on: ${{matrix.os}}
|
|
129
|
+
|
|
130
|
+
strategy:
|
|
131
|
+
matrix:
|
|
132
|
+
node-version: [18.x, 20.x, 21.x]
|
|
133
|
+
os: [ubuntu-latest, windows-latest]
|
|
134
|
+
steps:
|
|
135
|
+
- uses: actions/checkout@v4
|
|
136
|
+
|
|
137
|
+
- name: Use Node.js
|
|
138
|
+
uses: actions/setup-node@v4
|
|
139
|
+
with:
|
|
140
|
+
node-version: ${{ matrix.node-version }}
|
|
141
|
+
|
|
142
|
+
- name: Install
|
|
143
|
+
run: |
|
|
144
|
+
npm install
|
|
145
|
+
|
|
146
|
+
- name: Lint
|
|
147
|
+
run: |
|
|
148
|
+
npm run lint
|
|
149
|
+
|
|
150
|
+
- name: Run tests
|
|
151
|
+
run: |
|
|
152
|
+
npm run unit -- --reporter spec --reporter md:report.md
|
|
153
|
+
|
|
154
|
+
- name: Upload report
|
|
155
|
+
shell: bash
|
|
156
|
+
if: success() || failure()
|
|
157
|
+
run: |
|
|
158
|
+
cat report.md >> "$GITHUB_STEP_SUMMARY"
|
|
159
|
+
```
|
|
96
160
|
|
|
97
161
|
## License
|
|
98
162
|
|
package/borp.js
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { parseArgs } from 'node:util'
|
|
4
|
-
import
|
|
4
|
+
import Reporters from 'node:test/reporters'
|
|
5
5
|
import { mkdtemp, rm, readFile } from 'node:fs/promises'
|
|
6
|
+
import { createWriteStream } from 'node:fs'
|
|
6
7
|
import { finished } from 'node:stream/promises'
|
|
7
8
|
import { join, relative } from 'node:path'
|
|
8
9
|
import posix from 'node:path/posix'
|
|
9
10
|
import runWithTypeScript from './lib/run.js'
|
|
11
|
+
import { MarkdownReporter, GithubWorkflowFailuresReporter } from './lib/reporters.js'
|
|
10
12
|
import { Report } from 'c8'
|
|
11
13
|
import os from 'node:os'
|
|
12
14
|
import { execa } from 'execa'
|
|
13
15
|
|
|
14
|
-
let reporter
|
|
15
16
|
/* c8 ignore next 4 */
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
reporter = tap
|
|
21
|
-
}
|
|
17
|
+
process.on('unhandledRejection', (err) => {
|
|
18
|
+
console.error(err)
|
|
19
|
+
process.exit(1)
|
|
20
|
+
})
|
|
22
21
|
|
|
23
22
|
const args = parseArgs({
|
|
24
23
|
args: process.argv.slice(2),
|
|
@@ -32,7 +31,13 @@ const args = parseArgs({
|
|
|
32
31
|
'coverage-exclude': { type: 'string', short: 'X', multiple: true },
|
|
33
32
|
ignore: { type: 'string', short: 'i', multiple: true },
|
|
34
33
|
'expose-gc': { type: 'boolean' },
|
|
35
|
-
help: { type: 'boolean', short: 'h' }
|
|
34
|
+
help: { type: 'boolean', short: 'h' },
|
|
35
|
+
reporter: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
short: 'r',
|
|
38
|
+
default: ['spec'],
|
|
39
|
+
multiple: true
|
|
40
|
+
}
|
|
36
41
|
},
|
|
37
42
|
allowPositionals: true
|
|
38
43
|
})
|
|
@@ -79,13 +84,44 @@ const config = {
|
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
try {
|
|
87
|
+
const pipes = []
|
|
88
|
+
|
|
89
|
+
const reporters = {
|
|
90
|
+
...Reporters,
|
|
91
|
+
md: new MarkdownReporter(config),
|
|
92
|
+
gh: new GithubWorkflowFailuresReporter(config),
|
|
93
|
+
/* eslint new-cap: "off" */
|
|
94
|
+
spec: new Reporters.spec()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// If we're running in a GitHub action, adds the gh reporter
|
|
98
|
+
// by default so that we can report failures to GitHub
|
|
99
|
+
if (process.env.GITHUB_ACTION) {
|
|
100
|
+
args.values.reporter.push('gh')
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
for (const input of args.values.reporter) {
|
|
104
|
+
const [name, dest] = input.split(':')
|
|
105
|
+
const reporter = reporters[name]
|
|
106
|
+
if (!reporter) {
|
|
107
|
+
throw new Error(`Unknown reporter: ${name}`)
|
|
108
|
+
}
|
|
109
|
+
let output = process.stdout
|
|
110
|
+
if (dest) {
|
|
111
|
+
output = createWriteStream(dest)
|
|
112
|
+
}
|
|
113
|
+
pipes.push([reporter, output])
|
|
114
|
+
}
|
|
115
|
+
|
|
82
116
|
const stream = await runWithTypeScript(config)
|
|
83
117
|
|
|
84
118
|
stream.on('test:fail', () => {
|
|
85
119
|
process.exitCode = 1
|
|
86
120
|
})
|
|
87
121
|
|
|
88
|
-
|
|
122
|
+
for (const [reporter, output] of pipes) {
|
|
123
|
+
stream.compose(reporter).pipe(output)
|
|
124
|
+
}
|
|
89
125
|
|
|
90
126
|
await finished(stream)
|
|
91
127
|
|
package/lib/reporters.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Transform } from 'node:stream'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
|
|
4
|
+
function normalizeFile (file, cwd) {
|
|
5
|
+
let res = file
|
|
6
|
+
if (file.startsWith('file://')) {
|
|
7
|
+
try {
|
|
8
|
+
res = fileURLToPath(new URL(file))
|
|
9
|
+
} catch (err) {
|
|
10
|
+
if (err.code === 'ERR_INVALID_FILE_URL_PATH') {
|
|
11
|
+
res = fileURLToPath(new URL(file.replace('file:///', 'file://')))
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
res = res.replace(cwd, '')
|
|
16
|
+
if (res.startsWith('/') || res.startsWith('\\')) {
|
|
17
|
+
res = res.slice(1)
|
|
18
|
+
}
|
|
19
|
+
return res
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function eventToLine (event) {
|
|
23
|
+
return `* __${event.data.name}__, duration ${event.data.details.duration_ms}ms, line ${event.data.line}\n`
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class MarkdownReporter extends Transform {
|
|
27
|
+
constructor (opts) {
|
|
28
|
+
super({
|
|
29
|
+
...opts,
|
|
30
|
+
objectMode: true
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
this._files = {}
|
|
34
|
+
this._cwd = opts?.cwd
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getFile (path) {
|
|
38
|
+
const file = this._files[path] || {
|
|
39
|
+
pass: [],
|
|
40
|
+
fail: []
|
|
41
|
+
}
|
|
42
|
+
this._files[path] = file
|
|
43
|
+
return file
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_transform (event, encoding, callback) {
|
|
47
|
+
if (!event.data.file) {
|
|
48
|
+
callback()
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const path = normalizeFile(event.data.file, this._cwd)
|
|
53
|
+
const file = this.getFile(path)
|
|
54
|
+
switch (event.type) {
|
|
55
|
+
case 'test:pass':
|
|
56
|
+
file.pass.push(event)
|
|
57
|
+
break
|
|
58
|
+
case 'test:fail':
|
|
59
|
+
file.fail.push(event)
|
|
60
|
+
break
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
callback()
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_flush (callback) {
|
|
67
|
+
this.push('# Summary\n')
|
|
68
|
+
for (const [path, file] of Object.entries(this._files)) {
|
|
69
|
+
this.push(`## ${path}\n`)
|
|
70
|
+
if (file.pass.length > 0) {
|
|
71
|
+
this.push('### :white_check_mark: Pass\n')
|
|
72
|
+
for (const event of file.pass) {
|
|
73
|
+
this.push(eventToLine(event))
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (file.fail.length > 0) {
|
|
77
|
+
this.push('### :x: Fail\n')
|
|
78
|
+
for (const event of file.fail) {
|
|
79
|
+
this.push(eventToLine(event))
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
this.push(null)
|
|
84
|
+
callback()
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export class GithubWorkflowFailuresReporter extends Transform {
|
|
89
|
+
constructor (opts) {
|
|
90
|
+
super({
|
|
91
|
+
...opts,
|
|
92
|
+
objectMode: true
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
this._files = {}
|
|
96
|
+
this._cwd = opts?.cwd
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
_transform (event, encoding, callback) {
|
|
100
|
+
if (!event.data.file) {
|
|
101
|
+
callback()
|
|
102
|
+
return
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const path = normalizeFile(event.data.file, this._cwd)
|
|
106
|
+
switch (event.type) {
|
|
107
|
+
case 'test:fail':
|
|
108
|
+
this.push(`::error file=${path},line=${event.data.line}::${event.data.name}\n`)
|
|
109
|
+
break
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
callback()
|
|
113
|
+
}
|
|
114
|
+
}
|
package/lib/run.js
CHANGED
|
@@ -58,10 +58,18 @@ export default async function runWithTypeScript (config) {
|
|
|
58
58
|
}
|
|
59
59
|
config.prefix = prefix
|
|
60
60
|
config.setup = (test) => {
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
/* c8 ignore next 12 */
|
|
62
|
+
if (test.reporter) {
|
|
63
|
+
for (const chunk of pushable) {
|
|
64
|
+
test.reporter.push(chunk)
|
|
65
|
+
}
|
|
66
|
+
pushable = test.reporter
|
|
67
|
+
} else {
|
|
68
|
+
for (const chunk of pushable) {
|
|
69
|
+
test.push(chunk)
|
|
70
|
+
}
|
|
71
|
+
pushable = test
|
|
63
72
|
}
|
|
64
|
-
pushable = test.reporter
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
let tscChild
|
|
@@ -124,7 +132,7 @@ export default async function runWithTypeScript (config) {
|
|
|
124
132
|
} else if (prefix) {
|
|
125
133
|
files = await glob(join(prefix, join('**', '*.test.{cjs,mjs,js}')), { ignore, cwd, windowsPathsNoEscape: true })
|
|
126
134
|
} else {
|
|
127
|
-
files = await glob(join('**', '*.test.{cjs,mjs,js}'), { ignore, cwd, windowsPathsNoEscape: true })
|
|
135
|
+
files = await glob(join('**', '*.test.{cjs,mjs,js}'), { ignore, cwd, windowsPathsNoEscape: true, absolute: true })
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
config.files = files
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "borp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "node:test wrapper with TypeScript support",
|
|
6
6
|
"main": "borp.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"borp": "borp.js"
|
|
9
9
|
},
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/mcollina/borp"
|
|
13
|
+
},
|
|
10
14
|
"scripts": {
|
|
11
15
|
"clean": "rm -rf fixtures/*/dist .test-*",
|
|
12
16
|
"lint": "standard | snazzy",
|
|
@@ -25,7 +29,7 @@
|
|
|
25
29
|
"typescript": "^5.3.2"
|
|
26
30
|
},
|
|
27
31
|
"dependencies": {
|
|
28
|
-
"c8": "^
|
|
32
|
+
"c8": "^9.0.0",
|
|
29
33
|
"execa": "^8.0.1",
|
|
30
34
|
"find-up": "^7.0.0",
|
|
31
35
|
"glob": "^10.3.10"
|
package/test/basic.test.js
CHANGED
|
@@ -165,3 +165,24 @@ test('only-src', async (t) => {
|
|
|
165
165
|
|
|
166
166
|
await completed
|
|
167
167
|
})
|
|
168
|
+
|
|
169
|
+
test('js-esm', async (t) => {
|
|
170
|
+
const { strictEqual, completed } = tspl(t, { plan: 2 })
|
|
171
|
+
const config = {
|
|
172
|
+
files: [],
|
|
173
|
+
cwd: join(import.meta.url, '..', 'fixtures', 'js-esm')
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const stream = await runWithTypeScript(config)
|
|
177
|
+
|
|
178
|
+
const names = new Set(['add', 'add2'])
|
|
179
|
+
|
|
180
|
+
stream.on('test:pass', (test) => {
|
|
181
|
+
strictEqual(names.has(test.name), true)
|
|
182
|
+
names.delete(test.name)
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
stream.resume()
|
|
186
|
+
|
|
187
|
+
await completed
|
|
188
|
+
})
|
package/test/cli.test.js
CHANGED
package/test/coverage.test.js
CHANGED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { MarkdownReporter, GithubWorkflowFailuresReporter } from '../lib/reporters.js'
|
|
2
|
+
import { test, describe } from 'node:test'
|
|
3
|
+
import { strictEqual } from 'node:assert'
|
|
4
|
+
|
|
5
|
+
const cwd = process.platform === 'win32' ? 'C:\\foo' : '/foo'
|
|
6
|
+
const base = process.platform === 'win32' ? 'file://C:\\foo\\test\\' : 'file:///foo/test/'
|
|
7
|
+
|
|
8
|
+
describe('MarkdownReporter', async () => {
|
|
9
|
+
test('should write a report', async () => {
|
|
10
|
+
const reporter = new MarkdownReporter({ cwd })
|
|
11
|
+
|
|
12
|
+
// This is skipped
|
|
13
|
+
reporter.write({
|
|
14
|
+
type: 'test:start',
|
|
15
|
+
data: {}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
reporter.write({
|
|
19
|
+
type: 'test:pass',
|
|
20
|
+
data: {
|
|
21
|
+
name: 'add',
|
|
22
|
+
file: base + 'add.test.ts',
|
|
23
|
+
line: 1,
|
|
24
|
+
details: {
|
|
25
|
+
duration_ms: 100
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
reporter.write({
|
|
31
|
+
type: 'test:pass',
|
|
32
|
+
data: {
|
|
33
|
+
name: 'add2',
|
|
34
|
+
file: base + 'add.test.ts',
|
|
35
|
+
line: 2,
|
|
36
|
+
details: {
|
|
37
|
+
duration_ms: 100
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
reporter.write({
|
|
43
|
+
type: 'test:fail',
|
|
44
|
+
data: {
|
|
45
|
+
name: 'add3',
|
|
46
|
+
file: base + 'add.test.ts',
|
|
47
|
+
line: 10,
|
|
48
|
+
details: {
|
|
49
|
+
duration_ms: 100
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
reporter.end()
|
|
54
|
+
|
|
55
|
+
let output = ''
|
|
56
|
+
for await (const chunk of reporter) {
|
|
57
|
+
output += chunk
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
strictEqual(output.replaceAll('\\', '/'), `# Summary
|
|
61
|
+
## test/add.test.ts
|
|
62
|
+
### :white_check_mark: Pass
|
|
63
|
+
* __add__, duration 100ms, line 1
|
|
64
|
+
* __add2__, duration 100ms, line 2
|
|
65
|
+
### :x: Fail
|
|
66
|
+
* __add3__, duration 100ms, line 10
|
|
67
|
+
`)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('skip fail heading if no failing tests', async () => {
|
|
71
|
+
const reporter = new MarkdownReporter({ cwd })
|
|
72
|
+
|
|
73
|
+
reporter.write({
|
|
74
|
+
type: 'test:pass',
|
|
75
|
+
data: {
|
|
76
|
+
name: 'add',
|
|
77
|
+
file: base + 'add.test.ts',
|
|
78
|
+
line: 1,
|
|
79
|
+
details: {
|
|
80
|
+
duration_ms: 100
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
reporter.write({
|
|
86
|
+
type: 'test:pass',
|
|
87
|
+
data: {
|
|
88
|
+
name: 'add2',
|
|
89
|
+
file: base + 'add.test.ts',
|
|
90
|
+
line: 2,
|
|
91
|
+
details: {
|
|
92
|
+
duration_ms: 100
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
reporter.end()
|
|
98
|
+
|
|
99
|
+
let output = ''
|
|
100
|
+
for await (const chunk of reporter) {
|
|
101
|
+
output += chunk
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
strictEqual(output.replaceAll('\\', '/'), `# Summary
|
|
105
|
+
## test/add.test.ts
|
|
106
|
+
### :white_check_mark: Pass
|
|
107
|
+
* __add__, duration 100ms, line 1
|
|
108
|
+
* __add2__, duration 100ms, line 2
|
|
109
|
+
`)
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
describe('GithubWorkflowFailuresReporter', async () => {
|
|
114
|
+
test('should write error in github format', async () => {
|
|
115
|
+
const reporter = new GithubWorkflowFailuresReporter({ cwd })
|
|
116
|
+
|
|
117
|
+
// This is skipped
|
|
118
|
+
reporter.write({
|
|
119
|
+
type: 'test:start',
|
|
120
|
+
data: {}
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
reporter.write({
|
|
124
|
+
type: 'test:pass',
|
|
125
|
+
data: {
|
|
126
|
+
name: 'add',
|
|
127
|
+
file: base + 'add.test.ts',
|
|
128
|
+
line: 1,
|
|
129
|
+
details: {
|
|
130
|
+
duration_ms: 100
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
reporter.write({
|
|
136
|
+
type: 'test:fail',
|
|
137
|
+
data: {
|
|
138
|
+
name: 'add2',
|
|
139
|
+
file: base + 'add.test.ts',
|
|
140
|
+
line: 2,
|
|
141
|
+
details: {
|
|
142
|
+
duration_ms: 100
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
reporter.write({
|
|
148
|
+
type: 'test:fail',
|
|
149
|
+
data: {
|
|
150
|
+
name: 'add3',
|
|
151
|
+
file: base + 'add.test.ts',
|
|
152
|
+
line: 10,
|
|
153
|
+
details: {
|
|
154
|
+
duration_ms: 100
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
reporter.end()
|
|
159
|
+
|
|
160
|
+
let output = ''
|
|
161
|
+
for await (const chunk of reporter) {
|
|
162
|
+
output += chunk
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const expected = [
|
|
166
|
+
'::error file=test/add.test.ts,line=2::add2\n',
|
|
167
|
+
'::error file=test/add.test.ts,line=10::add3\n'
|
|
168
|
+
].join('')
|
|
169
|
+
|
|
170
|
+
strictEqual(output.replaceAll('\\', '/'), expected)
|
|
171
|
+
})
|
|
172
|
+
})
|