import assert from "node:assert/strict"; import { readFileSync } from "node:fs"; import { test } from "node:test"; import vm from "node:vm"; function processor() { let Processor; class Base { constructor() { this.port = { sent: [], postMessage(data) { this.sent.push(data); } }; } } vm.runInNewContext(readFileSync(new URL("../../src/voice_assistant/audio_gateway/web/pcm-worklet.js", import.meta.url), "utf8"), { AudioWorkletProcessor: Base, sampleRate: 16000, registerProcessor(name, constructor) { assert.equal(name, "pcm-input"); Processor = constructor; }, }); return new Processor(); } test("negotiated capture emits complete little-endian PCM16 frames", () => { const input = processor(); input.port.onmessage({ data: { type: "start", chunkSamples: 2 } }); input.process([[new Float32Array([-1, 0, 1])]]); const chunk = input.port.sent[0]; assert.equal(chunk.type, "pcm"); assert.equal(chunk.buffer.byteLength, 4); const samples = new DataView(chunk.buffer); assert.equal(samples.getInt16(0, true), -32768); assert.equal(samples.getInt16(2, true), 0); }); test("capture continues across process callbacks until stop", () => { const input = processor(); input.port.onmessage({ data: { type: "start", chunkSamples: 2 } }); input.process([[new Float32Array([0, 0, 0])]]); input.process([[new Float32Array([0, 0])]]); assert.equal(input.port.sent.filter((event) => event.type === "pcm").length, 2); input.port.onmessage({ data: { type: "stop" } }); input.process([[new Float32Array([0, 0, 0])]]); assert.equal(input.port.sent.length, 2); }); test("invalid capture window reports an error", () => { const input = processor(); input.port.onmessage({ data: { type: "start", chunkSamples: 0 } }); assert.equal(input.port.sent[0].type, "error"); assert.equal(input.capturing, false); });