{"version":3,"file":"testing.mjs","names":[],"sources":["../../src/test-stream.ts"],"sourcesContent":["//\n// Copyright 2022 DXOS.org\n//\n\nimport { Event } from './events.ts';\nimport { asyncTimeout } from './timeout.ts';\n\nconst encoder = new TextEncoder();\n\nconst toBytes = (data: Uint8Array | string): Uint8Array => (typeof data === 'string' ? encoder.encode(data) : data);\n\nconst concat = (first: Uint8Array, second: Uint8Array): Uint8Array => {\n  const result = new Uint8Array(first.length + second.length);\n  result.set(first);\n  result.set(second, first.length);\n  return result;\n};\n\nconst equal = (first: Uint8Array, second: Uint8Array): boolean =>\n  first.length === second.length && first.every((byte, index) => byte === second[index]);\n\n/**\n * Duplex byte stream for testing.\n * If this stream is connected to another stream, use `push` to send data, and `assertReceivedAsync` to assert the\n * received data.\n */\nexport class TestStream {\n  static async assertConnectivity(\n    stream1: TestStream,\n    stream2: TestStream,\n    { timeout = 200 }: { timeout?: number } = {},\n  ): Promise<void> {\n    stream1.push('ping');\n    stream2.push('pong');\n\n    await Promise.all([\n      stream2.assertReceivedAsync('ping', { timeout }),\n      stream1.assertReceivedAsync('pong', { timeout }),\n    ]);\n  }\n\n  #controller!: ReadableStreamDefaultController<Uint8Array>;\n  #received: Uint8Array = new Uint8Array(0);\n  #onWrite = new Event();\n\n  readonly readable = new ReadableStream<Uint8Array>({\n    start: (controller) => {\n      this.#controller = controller;\n    },\n  });\n\n  readonly writable = new WritableStream<Uint8Array>({\n    write: (chunk) => {\n      this.#received = concat(this.#received, chunk);\n      this.#onWrite.emit();\n    },\n  });\n\n  push(data: Uint8Array | string): void {\n    this.#controller.enqueue(toBytes(data));\n  }\n\n  assertReceivedAsync(data: Uint8Array | string, { timeout = 200 }: { timeout?: number } = {}): Promise<void> {\n    const expected = toBytes(data);\n    return asyncTimeout(\n      this.#onWrite.waitForCondition(() => equal(this.#received, expected)),\n      timeout,\n    );\n  }\n}\n"],"mappings":";;AAOA,IAAM,UAAU,IAAI,YAAY;AAEhC,IAAM,WAAW,SAA2C,OAAO,SAAS,WAAW,QAAQ,OAAO,IAAI,IAAI;AAE9G,IAAM,UAAU,OAAmB,WAAmC;CACpE,MAAM,SAAS,IAAI,WAAW,MAAM,SAAS,OAAO,MAAM;CAC1D,OAAO,IAAI,KAAK;CAChB,OAAO,IAAI,QAAQ,MAAM,MAAM;CAC/B,OAAO;AACT;AAEA,IAAM,SAAS,OAAmB,WAChC,MAAM,WAAW,OAAO,UAAU,MAAM,OAAO,MAAM,UAAU,SAAS,OAAO,MAAM;;;;;;AAOvF,IAAa,aAAb,MAAwB;CACtB,aAAa,mBACX,SACA,SACA,EAAE,UAAU,QAA8B,CAAC,GAC5B;EACf,QAAQ,KAAK,MAAM;EACnB,QAAQ,KAAK,MAAM;EAEnB,MAAM,QAAQ,IAAI,CAChB,QAAQ,oBAAoB,QAAQ,EAAE,QAAQ,CAAC,GAC/C,QAAQ,oBAAoB,QAAQ,EAAE,QAAQ,CAAC,CACjD,CAAC;CACH;CAEA;CACA,4BAAwB,IAAI,WAAW,CAAC;CACxC,WAAW,IAAI,MAAM;CAErB,WAAoB,IAAI,eAA2B,EACjD,QAAQ,eAAe;EACrB,KAAK,cAAc;CACrB,EACF,CAAC;CAED,WAAoB,IAAI,eAA2B,EACjD,QAAQ,UAAU;EAChB,KAAK,YAAY,OAAO,KAAK,WAAW,KAAK;EAC7C,KAAK,SAAS,KAAK;CACrB,EACF,CAAC;CAED,KAAK,MAAiC;EACpC,KAAK,YAAY,QAAQ,QAAQ,IAAI,CAAC;CACxC;CAEA,oBAAoB,MAA2B,EAAE,UAAU,QAA8B,CAAC,GAAkB;EAC1G,MAAM,WAAW,QAAQ,IAAI;EAC7B,OAAO,aACL,KAAK,SAAS,uBAAuB,MAAM,KAAK,WAAW,QAAQ,CAAC,GACpE,OACF;CACF;AACF"}