borp 0.7.0 → 0.9.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.
@@ -36,10 +36,4 @@ jobs:
36
36
 
37
37
  - name: Run tests
38
38
  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"
39
+ npm run unit -- --reporter spec
package/README.md CHANGED
@@ -100,65 +100,12 @@ Note the use of `incremental: true`, which speed up compilation massively.
100
100
 
101
101
  Here are the available reporters:
102
102
 
103
- * `md`: creates a markdown table, useful for setting up a Summary in your GitHub Action
104
- * `gh`: emits `::error` workflow commands for GitHub Actions to show inlined error. Enabled by default when running on GHA.
103
+ * `gh`: emits `::error` workflow commands for GitHub Actions to show inlined errors. Enabled by default when running on GHA.
105
104
  * `tap`: outputs the test results in the TAP format.
106
105
  * `spec`: outputs the test results in a human-readable format.
107
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.
108
107
  * `junit`: outputs test results in a jUnit XML format
109
108
 
110
- ## GitHub Action Summary
111
-
112
- The following will automatically show the summary of the test run in the summary page of GitHub Actions.
113
-
114
- ```yaml
115
- name: ci
116
-
117
- on:
118
- push:
119
- paths-ignore:
120
- - 'docs/**'
121
- - '*.md'
122
- pull_request:
123
- paths-ignore:
124
- - 'docs/**'
125
- - '*.md'
126
-
127
- jobs:
128
- test:
129
- runs-on: ${{matrix.os}}
130
-
131
- strategy:
132
- matrix:
133
- node-version: [18.x, 20.x, 21.x]
134
- os: [ubuntu-latest, windows-latest]
135
- steps:
136
- - uses: actions/checkout@v4
137
-
138
- - name: Use Node.js
139
- uses: actions/setup-node@v4
140
- with:
141
- node-version: ${{ matrix.node-version }}
142
-
143
- - name: Install
144
- run: |
145
- npm install
146
-
147
- - name: Lint
148
- run: |
149
- npm run lint
150
-
151
- - name: Run tests
152
- run: |
153
- npm run unit -- --reporter spec --reporter md:report.md
154
-
155
- - name: Upload report
156
- shell: bash
157
- if: success() || failure()
158
- run: |
159
- cat report.md >> "$GITHUB_STEP_SUMMARY"
160
- ```
161
-
162
109
  ## License
163
110
 
164
111
  MIT
package/borp.js CHANGED
@@ -8,7 +8,7 @@ import { finished } from 'node:stream/promises'
8
8
  import { join, relative } from 'node:path'
9
9
  import posix from 'node:path/posix'
10
10
  import runWithTypeScript from './lib/run.js'
11
- import { MarkdownReporter, GithubWorkflowFailuresReporter } from './lib/reporters.js'
11
+ import githubReporter from '@reporters/github'
12
12
  import { Report } from 'c8'
13
13
  import os from 'node:os'
14
14
  import { execa } from 'execa'
@@ -90,10 +90,7 @@ try {
90
90
 
91
91
  const reporters = {
92
92
  ...Reporters,
93
- md: new MarkdownReporter(config),
94
- gh: new GithubWorkflowFailuresReporter(config),
95
- /* eslint new-cap: "off" */
96
- spec: new Reporters.spec()
93
+ gh: githubReporter
97
94
  }
98
95
 
99
96
  // If we're running in a GitHub action, adds the gh reporter
@@ -104,10 +101,8 @@ try {
104
101
 
105
102
  for (const input of args.values.reporter) {
106
103
  const [name, dest] = input.split(':')
107
- const reporter = reporters[name]
108
- if (!reporter) {
109
- throw new Error(`Unknown reporter: ${name}`)
110
- }
104
+ const Ctor = reporters[name] || await import(name).then((m) => m.default || m)
105
+ const reporter = Object.getOwnPropertyDescriptor(Ctor.prototype, 'constructor') ? new Ctor() : Ctor
111
106
  let output = process.stdout
112
107
  if (dest) {
113
108
  output = createWriteStream(dest)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "borp",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "description": "node:test wrapper with TypeScript support",
6
6
  "main": "borp.js",
@@ -22,6 +22,7 @@
22
22
  "license": "MIT",
23
23
  "devDependencies": {
24
24
  "@matteo.collina/tspl": "^0.1.0",
25
+ "@reporters/silent": "^1.2.4",
25
26
  "@types/node": "^20.10.0",
26
27
  "desm": "^1.3.0",
27
28
  "snazzy": "^9.0.0",
@@ -29,6 +30,7 @@
29
30
  "typescript": "^5.3.2"
30
31
  },
31
32
  "dependencies": {
33
+ "@reporters/github": "^1.5.4",
32
34
  "c8": "^9.0.0",
33
35
  "execa": "^8.0.1",
34
36
  "find-up": "^7.0.0",
package/test/cli.test.js CHANGED
@@ -60,3 +60,18 @@ test('disable ts and run no tests', async () => {
60
60
 
61
61
  strictEqual(stdout.indexOf('tests 0') >= 0, true)
62
62
  })
63
+
64
+ test('reporter from node_modules', async () => {
65
+ const cwd = join(import.meta.url, '..', 'fixtures', 'ts-esm2')
66
+ await rm(path.join(cwd, 'dist'), { recursive: true, force: true })
67
+ const { stdout } = await execa('node', [
68
+ borp,
69
+ '--reporter=spec',
70
+ '--reporter=@reporters/silent',
71
+ '--no-typescript'
72
+ ], {
73
+ cwd
74
+ })
75
+
76
+ strictEqual(stdout.indexOf('tests 0') >= 0, true)
77
+ })
package/lib/reporters.js DELETED
@@ -1,114 +0,0 @@
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
- }
@@ -1,172 +0,0 @@
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
- })