(
{ stdout = [], stderr = [], idleTimeoutMs }: { stdout?: (string | RegExp)[]; stderr?: (string | RegExp)[]; idleTimeoutMs?: number },
subcommand: SubCommand,
)
| 46 | * Rejects if there are queries remaning after the |
| 47 | */ |
| 48 | export function lookForOutput( |
| 49 | { stdout = [], stderr = [], idleTimeoutMs }: { stdout?: (string | RegExp)[]; stderr?: (string | RegExp)[]; idleTimeoutMs?: number }, |
| 50 | subcommand: SubCommand, |
| 51 | ): Promise<true> { |
| 52 | const [idleTimer, touch, complete] = timeoutOnIdle(idleTimeoutMs); |
| 53 | |
| 54 | const monitor = (requiredQueries: (string | RegExp)[]) => { |
| 55 | let queries = requiredQueries.slice(); |
| 56 | let onDone: (value: true) => void, onError: (error: Error) => void; |
| 57 | |
| 58 | const promise = new Promise((resolve, reject) => { |
| 59 | onDone = resolve; |
| 60 | onError = reject; |
| 61 | |
| 62 | // If queries are empty to start with resolve immediately |
| 63 | if (queries.length === 0) { |
| 64 | resolve(true); |
| 65 | } |
| 66 | }); |
| 67 | |
| 68 | const isDone = () => queries.length === 0; |
| 69 | |
| 70 | return { |
| 71 | promise, |
| 72 | isDone, |
| 73 | onEachLine: onEachLine(line => { |
| 74 | touch(); |
| 75 | queries = queries.filter((query): boolean => { |
| 76 | if (typeof query === 'string') { |
| 77 | return !line.toString().includes(query); |
| 78 | } |
| 79 | if (query instanceof RegExp) { |
| 80 | return !query.test(line.toString('utf8')); |
| 81 | } |
| 82 | onError(new Error('invalid query')); |
| 83 | return false; |
| 84 | }); |
| 85 | |
| 86 | if (isDone()) { |
| 87 | onDone(true); |
| 88 | return; |
| 89 | } |
| 90 | }), |
| 91 | }; |
| 92 | }; |
| 93 | |
| 94 | const stdoutMonitor = monitor(stdout); |
| 95 | const stderrMonitor = monitor(stderr); |
| 96 | |
| 97 | subcommand.process.stdout.compose(stdoutMonitor.onEachLine).pipe(process.stdout); |
| 98 | subcommand.process.stderr.compose(stderrMonitor.onEachLine).pipe(process.stderr); |
| 99 | |
| 100 | return Promise.race([ |
| 101 | idleTimer, |
| 102 | subcommand |
| 103 | .wait() |
| 104 | .then((): true => { |
| 105 | const allFound = [stderrMonitor, stderrMonitor].every(monitor => monitor.isDone()); |
no test coverage detected