stream = new WhisperTranscriptionStream; } public function test_extracts_sse_data_payloads_from_buffer(): void { $buffer = "data: {\"type\":\"transcript.text.delta\",\"delta\":\"Hello\"}\n\npartial"; $payloads = $this->stream->extractPayloads($buffer); $this->assertSame(['{"type":"transcript.text.delta","delta":"Hello"}'], $payloads); $this->assertSame('partial', $buffer); } public function test_parses_openai_delta_and_done_events(): void { $delta = $this->stream->parseEvent('{"type":"transcript.text.delta","delta":"Hello "}'); $done = $this->stream->parseEvent('{"type":"transcript.text.done","text":"Hello world"}'); $this->assertSame('Hello ', $delta['append']); $this->assertFalse($delta['done']); $this->assertSame('Hello world', $done['replace']); $this->assertTrue($done['done']); } public function test_parses_legacy_segment_events(): void { $event = $this->stream->parseEvent('{"text":"First segment","start":0,"end":12.5}'); $this->assertTrue($event['legacy']); $this->assertSame('First segment', $event['append']); $this->assertSame(12.5, $event['end']); } public function test_applies_delta_then_done_replace(): void { $delta = $this->stream->parseEvent('{"type":"transcript.text.delta","delta":"Hel"}'); $text = $this->stream->applyEvent('', $delta); $delta2 = $this->stream->parseEvent('{"type":"transcript.text.delta","delta":"lo"}'); $text = $this->stream->applyEvent($text, $delta2); $done = $this->stream->parseEvent('{"type":"transcript.text.done","text":"Hello world"}'); $text = $this->stream->applyEvent($text, $done); $this->assertSame('Hello world', $text); } public function test_joins_legacy_segments_with_spaces(): void { $first = $this->stream->parseEvent('{"text":"Hello from","end":10}'); $second = $this->stream->parseEvent('{"text":"whisper.","end":20}'); $text = $this->stream->applyEvent('', $first); $text = $this->stream->applyEvent($text, $second); $this->assertSame('Hello from whisper.', $text); } public function test_ignores_done_sentinel_and_non_json(): void { $buffer = "data: [DONE]\n\ndata: not-json\n\n"; $payloads = $this->stream->extractPayloads($buffer); $this->assertSame(['not-json'], $payloads); $this->assertNull($this->stream->parseEvent('not-json')); } public function test_flush_buffer_emits_trailing_frame(): void { $buffer = 'data: {"text":"Last"}'; $payloads = $this->stream->flushBuffer($buffer); $this->assertSame(['{"text":"Last"}'], $payloads); $this->assertSame('', $buffer); } }