Skip to content

Commit

Permalink
fix: CLI Testing Library should now run in Node 12
Browse files Browse the repository at this point in the history
  • Loading branch information
crutchcorn committed Dec 13, 2021
1 parent ad2d3c9 commit a04fa18
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 17 deletions.
13 changes: 8 additions & 5 deletions src/__tests__/render-basics.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
const {resolve} = require('path')
const {render} = require('../pure')
const {waitFor} = require('../wait-for')

test('Should expect error codes when intended', async () => {
const instance = await render('node', [resolve(__dirname, './execute-scripts/throw.js')])
expect(instance.hasExit()).toMatchObject({exitCode: 1})
const instance = await render('node', [
resolve(__dirname, './execute-scripts/throw.js'),
])
await waitFor(() => expect(instance.hasExit()).toMatchObject({exitCode: 1}))
})

test('Should handle argument passing', async () => {
Expand All @@ -20,7 +23,7 @@ test('Is able to make terminal input and view in-progress stdout', async () => {
resolve(__dirname, './execute-scripts/stdio-inquirer.js'),
])

const {clear, findByText, userEvent} = props;
const {clear, findByText, userEvent} = props

const instance = await findByText('First option')

Expand All @@ -31,13 +34,13 @@ test('Is able to make terminal input and view in-progress stdout', async () => {

clear()

userEvent.keyboard("[ArrowDown]")
userEvent.keyboard('[ArrowDown]')

expect(await findByText(/[❯>] Two/)).toBeTruthy()

clear()

userEvent.keyboard("[Enter]")
userEvent.keyboard('[Enter]')

expect(await findByText('First option: Two')).toBeTruthy()
})
38 changes: 26 additions & 12 deletions src/pure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {getQueriesForElement} from './get-queries-for-instance'
import userEvent from './user-event'
import {bindObjectFnsToInstance, setCurrentInstance} from './helpers'
import {fireEvent} from './events'
import {getConfig} from "./config";
import {getConfig} from './config'

const mountedInstances = new Set<TestInstance>()

Expand All @@ -25,18 +25,20 @@ async function render(
})

let _readyPromiseInternals: null | {resolve: Function; reject: Function} =
null
null

let _resolved = false

const execOutputAPI = {
__exitCode: null as null | number,
_isOutputAPI: true,
_isReady: new Promise(
(resolve, reject) => (_readyPromiseInternals = {resolve, reject}),
(resolve, reject) => (_readyPromiseInternals = {resolve, reject}),
),
process: exec,
// Clear buffer of stdout to do more accurate `t.regex` checks
clear() {
execOutputAPI.stdoutArr = []
execOutputAPI.stdoutArr = []
},
// An array of strings gathered from stdout when unable to do
// `await stdout` because of inquirer interactive prompts
Expand All @@ -50,30 +52,42 @@ async function render(
mountedInstances.add(execOutputAPI as unknown as TestInstance)

exec.stdout.on('data', (result: string | Buffer) => {
// `on('spawn') doesn't work the same way in Node12.
// Instead, we have to rely on this working as-expected.
if (_readyPromiseInternals && !_resolved) {
_readyPromiseInternals.resolve()
_resolved = true
}

const resStr = stripFinalNewline(result as string)
execOutputAPI.stdoutArr.push(resStr)
_runObservers()
})

exec.stderr.on('data', (result: string | Buffer) => {
if (_readyPromiseInternals && !_resolved) {
_readyPromiseInternals.resolve()
_resolved = true
}

const resStr = stripFinalNewline(result as string)
execOutputAPI.stderrArr.push(resStr)
_runObservers()
})

exec.on('error', result => {
if (_readyPromiseInternals) {
_readyPromiseInternals.reject(result);
_readyPromiseInternals.reject(result)
}
})

exec.on('spawn', () => {
setTimeout(() => {
if (_readyPromiseInternals) {

_readyPromiseInternals.resolve();
}
}, getConfig().renderAwaitTime)
setTimeout(() => {
if (_readyPromiseInternals && !_resolved) {
_readyPromiseInternals.resolve()
_resolved = true
}
}, getConfig().renderAwaitTime)
})

exec.on('exit', code => {
Expand All @@ -87,7 +101,7 @@ async function render(
return Object.assign(
execOutputAPI,
{
userEvent: bindObjectFnsToInstance(execOutputAPI, userEvent)
userEvent: bindObjectFnsToInstance(execOutputAPI, userEvent),
},
getQueriesForElement(execOutputAPI),
) as TestInstance as RenderResult
Expand Down

0 comments on commit a04fa18

Please sign in to comment.