@@ -2,6 +2,7 @@ import * as promisify from 'util.promisify';
22import { PassThrough } from 'stream' ;
33import { getStream , TEST_DIR , tsNodeTypes } from '../helpers' ;
44import type { ExecutionContext } from 'ava' ;
5+ import { expect , TestInterface } from '../testlib' ;
56
67export interface ContextWithTsNodeUnderTest {
78 tsNodeUnderTest : Pick <
@@ -10,12 +11,24 @@ export interface ContextWithTsNodeUnderTest {
1011 > ;
1112}
1213
14+ export type ContextWithReplHelpers = ContextWithTsNodeUnderTest &
15+ Awaited < ReturnType < typeof contextReplHelpers > > ;
16+
1317export interface CreateReplViaApiOptions {
14- registerHooks : true ;
18+ registerHooks : boolean ;
1519 createReplOpts ?: Partial < tsNodeTypes . CreateReplOptions > ;
1620 createServiceOpts ?: Partial < tsNodeTypes . CreateOptions > ;
1721}
1822
23+ export interface ExecuteInReplOptions extends CreateReplViaApiOptions {
24+ waitMs ?: number ;
25+ waitPattern ?: string | RegExp ;
26+ /** When specified, calls `startInternal` instead of `start` and passes options */
27+ startInternalOptions ?: Parameters <
28+ tsNodeTypes . ReplService [ 'startInternal' ]
29+ > [ 0 ] ;
30+ }
31+
1932/**
2033 * pass to test.context() to get REPL testing helper functions
2134 */
@@ -55,18 +68,7 @@ export async function contextReplHelpers(
5568 return { stdin, stdout, stderr, replService, service } ;
5669 }
5770
58- // Todo combine with replApiMacro
59- async function executeInRepl (
60- input : string ,
61- options : CreateReplViaApiOptions & {
62- waitMs ?: number ;
63- waitPattern ?: string | RegExp ;
64- /** When specified, calls `startInternal` instead of `start` and passes options */
65- startInternalOptions ?: Parameters <
66- tsNodeTypes . ReplService [ 'startInternal' ]
67- > [ 0 ] ;
68- }
69- ) {
71+ async function executeInRepl ( input : string , options : ExecuteInReplOptions ) {
7072 const {
7173 waitPattern,
7274 // Wait longer if there's a signal to end it early
@@ -102,3 +104,53 @@ export async function contextReplHelpers(
102104 } ;
103105 }
104106}
107+
108+ export function replMacros < T extends ContextWithReplHelpers > (
109+ _test : TestInterface < T >
110+ ) {
111+ return { noErrorsAndStdoutContains, stderrContains } ;
112+
113+ function noErrorsAndStdoutContains (
114+ title : string ,
115+ script : string ,
116+ contains : string ,
117+ options ?: Partial < ExecuteInReplOptions >
118+ ) {
119+ testReplInternal ( title , script , contains , undefined , contains , options ) ;
120+ }
121+ function stderrContains (
122+ title : string ,
123+ script : string ,
124+ errorContains : string ,
125+ options ?: Partial < ExecuteInReplOptions >
126+ ) {
127+ testReplInternal (
128+ title ,
129+ script ,
130+ undefined ,
131+ errorContains ,
132+ errorContains ,
133+ options
134+ ) ;
135+ }
136+ function testReplInternal (
137+ title : string ,
138+ script : string ,
139+ stdoutContains : string | undefined ,
140+ stderrContains : string | undefined ,
141+ waitPattern : string ,
142+ options ?: Partial < ExecuteInReplOptions >
143+ ) {
144+ _test ( title , async ( t ) => {
145+ const { stdout, stderr } = await t . context . executeInRepl ( script , {
146+ registerHooks : true ,
147+ startInternalOptions : { useGlobal : false } ,
148+ waitPattern,
149+ ...options ,
150+ } ) ;
151+ if ( stderrContains ) expect ( stderr ) . toContain ( stderrContains ) ;
152+ else expect ( stderr ) . toBe ( '' ) ;
153+ if ( stdoutContains ) expect ( stdout ) . toContain ( stdoutContains ) ;
154+ } ) ;
155+ }
156+ }
0 commit comments