Open5

Node.js の process.stdin を Jest の mock にする(たぶん Jest でなくても動く)

hankei6kmhankei6km

process.stdin のモックで pipe が使えるものが欲しくなった。

hankei6kmhankei6km

非同期ジェネレーターを使う(pipe は使えない)

process.stdinfor awai..of で処理する場合は非同期ジェネレーターを作成することでも対応できる、と思う。

単発でデータを yield する場合(複数にわける場合は配列などにしておく)。

async function* mockStdin(data: string) {
    yield data
}
hankei6kmhankei6km

pipe にも対応した process.stdin の mock を作る

Notion のメモで上記のようなことを書いたあとに AI で続きを書くと下記のようなコードが生成される。

import { Readable } from 'node:stream'

const mockStdin = (data: string) => {
    return new Readable({
        read(size) {
            this.push(data)
            this.push(null)
        }
    })
}

// example
mockStdin('some data').pipe(process.stdout)

size が十分に大きく、data を 1 回で読めるならこれでも動く(メモに貼り付けておいた非同期ジェネレーターのコードをそのようにしていたので影響されたかな?)。

作り方はななんとなくわかったので少し変更した。

import { Readable } from 'node:stream'

  const mockStdin = (data: string) => {
    let offset = 0
    const len = data.length
    return new Readable({
      read(size) {
        const end = offset + size
        this.push(data.slice(offset, offset + size))
        if (len < end) {
          this.push(null)
        }
        offset = end
      }
    })
  }
hankei6kmhankei6km

タイトルに Jest と入れたけど、Jest でなくても動くかな。