Skip to content

Commit 65c39cb

Browse files
committed
test: replace stdout-stderr with captureOutput and remove dependency
Replace stdout-stderr package with captureOutput from @heroku-cli/test-utils for cleaner and more consistent test output handling. Converted 7 test files and removed the stdout-stderr dependency from package.json. Files converted: - lib/confirm-command.unit.test.ts - lib/spaces/peering.unit.test.ts - lib/spaces/spaces.unit.test.ts - lib/run/log-displayer.unit.test.ts - lib/spaces/hosts.unit.test.ts - lib/data/display-quota.unit.test.ts - lib/spaces/vpn-connections.unit.test.ts
1 parent 7b8ae97 commit 65c39cb

13 files changed

Lines changed: 95 additions & 168 deletions

package-lock.json

Lines changed: 0 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@
136136
"sinon": "^21.0.2",
137137
"source-map-support": "^0.5.21",
138138
"std-mocks": "^2.0.0",
139-
"stdout-stderr": "^0.1.13",
140139
"ts-node": "^10.9.2",
141140
"typescript": "4.9.5"
142141
},

test/helpers/legacy-run-command.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

test/unit/commands/domains/add.unit.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ import {runCommand} from '@heroku-cli/test-utils'
22
import {expect} from 'chai'
33
import nock from 'nock'
44
import sinon from 'sinon'
5-
import {stderr, stdout} from 'stdout-stderr'
65

76
import DomainsAdd from '../../../../src/commands/domains/add.js'
87

98
describe('domains:add', function () {
109
afterEach(function () {
1110
nock.cleanAll()
12-
stdout.stop()
13-
stderr.stop()
1411
})
1512

1613
const domainsResponse = {

test/unit/commands/domains/index.unit.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {hux} from '@heroku/heroku-cli-util'
33
import {expect} from 'chai'
44
import nock from 'nock'
55
import sinon from 'sinon'
6-
import {stderr, stdout} from 'stdout-stderr'
76

87
import DomainsIndex from '../../../../src/commands/domains/index.js'
98
import removeAllWhitespace from '../../../helpers/utils/remove-whitespaces.js'
@@ -24,8 +23,6 @@ describe('domains', function () {
2423
api.done()
2524
confirmStub.restore()
2625
nock.cleanAll()
27-
stdout.stop()
28-
stderr.stop()
2926
})
3027

3128
const herokuOnlyDomainsResponse = [

test/unit/lib/confirm-command.unit.test.ts

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import {captureOutput} from '@heroku-cli/test-utils'
12
import {hux} from '@heroku/heroku-cli-util'
23
import ansis from 'ansis'
34
import {expect} from 'chai'
45
import sinon from 'sinon'
5-
import {stderr, stdout} from 'stdout-stderr'
66

77
import ConfirmCommand from '../../../src/lib/confirm-command.js'
88

@@ -12,67 +12,55 @@ describe('confirmApp', function () {
1212
})
1313

1414
it('should not error or prompt with confirm flag match', async function () {
15-
stdout.start()
16-
stderr.start()
15+
const {stderr, stdout} = await captureOutput(async () => {
16+
await new ConfirmCommand().confirm('app', 'app')
17+
})
1718

18-
await new ConfirmCommand().confirm('app', 'app')
19-
20-
stdout.stop()
21-
stderr.stop()
22-
23-
expect(stderr.output).to.equal('')
24-
expect(stdout.output).to.equal('')
19+
expect(stderr).to.equal('')
20+
expect(stdout).to.equal('')
2521
})
2622

2723
it('should err on confirm flag mismatch', async function () {
28-
stdout.start()
29-
stderr.start()
30-
3124
try {
32-
await new ConfirmCommand().confirm('app', 'nope')
25+
await captureOutput(async () => {
26+
await new ConfirmCommand().confirm('app', 'nope')
27+
})
3328
expect.fail('Expected confirm to throw error')
3429
} catch (error: any) {
3530
expect(ansis.strip(error.message)).to.equal('Confirmation nope did not match app. Aborted.')
36-
} finally {
37-
stdout.stop()
38-
stderr.stop()
3931
}
4032
})
4133

4234
it('should not err on confirm prompt match', async function () {
4335
sinon.stub(hux, 'prompt').resolves('app')
44-
stdout.start()
45-
stderr.start()
46-
47-
await new ConfirmCommand().confirm('app')
4836

49-
stdout.stop()
50-
stderr.stop()
37+
const {stderr, stdout} = await captureOutput(async () => {
38+
await new ConfirmCommand().confirm('app')
39+
})
5140

52-
expect(stderr.output).to.contain('Warning: Destructive Action')
53-
expect(stdout.output).to.equal('')
41+
expect(stderr).to.contain('Warning: Destructive Action')
42+
expect(stdout).to.equal('')
5443
})
5544

5645
it('should display custom message', async function () {
5746
const customMessage = 'custom message'
5847
sinon.stub(hux, 'prompt').resolves('app')
59-
stdout.start()
60-
stderr.start()
61-
62-
await new ConfirmCommand().confirm('app', undefined, customMessage)
6348

64-
stdout.stop()
65-
stderr.stop()
49+
const {stderr, stdout} = await captureOutput(async () => {
50+
await new ConfirmCommand().confirm('app', undefined, customMessage)
51+
})
6652

67-
expect(stderr.output).to.contain(customMessage)
68-
expect(stdout.output).to.equal('')
53+
expect(stderr).to.contain(customMessage)
54+
expect(stdout).to.equal('')
6955
})
7056

7157
it('should err on confirm prompt mismatch', async function () {
7258
sinon.stub(hux, 'prompt').resolves('nope')
7359

7460
try {
75-
await new ConfirmCommand().confirm('app')
61+
await captureOutput(async () => {
62+
await new ConfirmCommand().confirm('app')
63+
})
7664
expect.fail('Expected confirm to throw error')
7765
} catch (error: any) {
7866
expect(ansis.strip(error.message)).to.equal('Confirmation did not match app. Aborted.')

test/unit/lib/data/display-quota.unit.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import {captureOutput} from '@heroku-cli/test-utils'
12
import {expect} from 'chai'
2-
import {stdout} from 'stdout-stderr'
33
import tsheredoc from 'tsheredoc'
44

55
import {displayQuota, formatQuotaStatus} from '../../../../src/lib/data/display-quota.js'
@@ -30,12 +30,12 @@ describe('lib/displayQuota', function () {
3030
})
3131

3232
describe('displayQuota', function () {
33-
it('displays the quota information in a human-readable format', function () {
34-
stdout.start()
35-
displayQuota(storageQuotaResponse)
36-
stdout.stop()
33+
it('displays the quota information in a human-readable format', async function () {
34+
const {stdout} = await captureOutput(async () => {
35+
displayQuota(storageQuotaResponse)
36+
})
3737

38-
expect(stdout.output).to.equal(heredoc(`
38+
expect(stdout).to.equal(heredoc(`
3939
=== Storage
4040
4141
Warning: 50.00 GB

test/unit/lib/pg/psql.unit.test.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {expect} from 'chai'
33
import * as fs from 'node:fs'
44
import * as path from 'node:path'
55
import * as proxyquire from 'proxyquire'
6-
import {stderr} from 'stdout-stderr'
76
import {ConnectionDetails, ConnectionDetailsWithAttachment, utils} from '@heroku/heroku-cli-util'
87
import {unwrap} from '../../../helpers/utils/unwrap.js'
98
import sinon = require('sinon')
@@ -81,13 +80,11 @@ describe('psql', function () {
8180
},
8281
})
8382
sandbox.stub(Math, 'random').callsFake(() => 0)
84-
stderr.start()
8583
})
8684
8785
afterEach(async function () {
8886
queryString = ''
8987
sandbox.restore()
90-
stderr.stop()
9188
process.env = env
9289
})
9390

test/unit/lib/run/log-displayer.unit.test.ts

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* eslint-disable unicorn/prefer-add-event-listener */
22
import {APIClient} from '@heroku-cli/command'
3+
import {captureOutput} from '@heroku-cli/test-utils'
34
import {Config, Errors} from '@oclif/core'
45
import {expect} from 'chai'
56
import nock from 'nock'
67
import sinon from 'sinon'
7-
import {stderr, stdout} from 'stdout-stderr'
88
import tsheredoc from 'tsheredoc'
99

1010
import {LogDisplayer} from '../../../../src/lib/run/log-displayer.js'
@@ -306,15 +306,15 @@ describe('logDisplayer', function () {
306306
data: 2024-10-17T22:23:23.032789+00:00 app[web.1]: log line 2\n\n\n
307307
`)
308308

309-
stdout.start()
310-
await displayer.display({
311-
app: 'my-cedar-app',
312-
tail: false,
309+
const {stdout} = await captureOutput(async () => {
310+
await displayer.display({
311+
app: 'my-cedar-app',
312+
tail: false,
313+
})
313314
})
314-
stdout.stop()
315315

316316
// Note: logServer.done() is not called because our MockEventSource intercepts the request
317-
expect(stdout.output).to.eq(heredoc`
317+
expect(stdout).to.eq(heredoc`
318318
2024-10-17T22:23:22.209776+00:00 app[web.1]: log line 1
319319
2024-10-17T22:23:23.032789+00:00 app[web.1]: log line 2
320320
`)
@@ -353,20 +353,22 @@ describe('logDisplayer', function () {
353353

354354
context('when the log server responds with a stream of log lines and then timeouts', function () {
355355
it('displays log lines and exits showing a timeout error', async function () {
356+
let stdout = ''
356357
try {
357-
stdout.start()
358-
await displayer.display({
359-
app: 'my-cedar-app',
360-
tail: true,
358+
const output = await captureOutput(async () => {
359+
await displayer.display({
360+
app: 'my-cedar-app',
361+
tail: true,
362+
})
361363
})
364+
stdout = output.stdout
362365
} catch (error: unknown) {
363-
stdout.stop()
364366
const {message, oclif} = error as CLIError
365367
expect(message).to.equal('Logs eventsource failed with: 401')
366368
expect(oclif.exit).to.eq(1)
367369
}
368370

369-
expect(stdout.output).to.eq('')
371+
expect(stdout).to.eq('')
370372
})
371373
})
372374
})
@@ -386,22 +388,22 @@ describe('logDisplayer', function () {
386388
})
387389

388390
it('displays logs and recreates log sessions on timeout', async function () {
391+
let stderr = ''
389392
try {
390-
stdout.start()
391-
stderr.start()
392-
await displayer.display({
393-
app: 'my-fir-app',
394-
tail: false,
393+
const output = await captureOutput(async () => {
394+
await displayer.display({
395+
app: 'my-fir-app',
396+
tail: false,
397+
})
395398
})
399+
stderr = output.stderr
396400
} catch (error: unknown) {
397-
stdout.stop()
398-
stderr.stop()
399401
const {message} = error as Error
400402
expect(message.trim()).to.equal('HTTP Error 500 for POST https://api.heroku.com/apps/my-fir-app/log-sessions')
401403
}
402404

403405
// it displays message about fetching logs for fir apps
404-
expect(stderr.output).to.eq('Fetching logs...\n\n')
406+
expect(stderr).to.eq('Fetching logs...\n\n')
405407
})
406408
})
407409
})

test/unit/lib/spaces/hosts.unit.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import {captureOutput} from '@heroku-cli/test-utils'
12
import {expect} from 'chai'
2-
import {stdout} from 'stdout-stderr'
33

44
import {displayHosts, displayHostsAsJSON, Host} from '../../../../src/lib/spaces/hosts.js'
55
import removeAllWhitespace from '../../../helpers/utils/remove-whitespaces.js'
@@ -21,12 +21,12 @@ const hosts: Host[] = [
2121
]
2222

2323
describe('displayHosts', function () {
24-
it('displays hosts when json flag is false', function () {
25-
stdout.start()
26-
displayHosts('my-space', hosts)
27-
stdout.stop()
24+
it('displays hosts when json flag is false', async function () {
25+
const {stdout} = await captureOutput(async () => {
26+
displayHosts('my-space', hosts)
27+
})
2828

29-
const actual = removeAllWhitespace(stdout.output)
29+
const actual = removeAllWhitespace(stdout)
3030
expect(actual).to.include(removeAllWhitespace('=== my-space Hosts'))
3131
expect(actual).to.include(removeAllWhitespace('Host ID State Available Capacity Allocated At Released At'))
3232
expect(actual).to.include(removeAllWhitespace('h-0f927460a59aac18e available 72% 2020-05-28T04:15:59Z'))
@@ -35,10 +35,10 @@ describe('displayHosts', function () {
3535
})
3636

3737
describe('displayHostsAsJSON', function () {
38-
it('displays hosts when json flag is true', function () {
39-
stdout.start()
40-
displayHostsAsJSON(hosts)
41-
stdout.stop()
42-
expect(JSON.parse(stdout.output)).to.eql(hosts)
38+
it('displays hosts when json flag is true', async function () {
39+
const {stdout} = await captureOutput(async () => {
40+
displayHostsAsJSON(hosts)
41+
})
42+
expect(JSON.parse(stdout)).to.eql(hosts)
4343
})
4444
})

0 commit comments

Comments
 (0)