Skip to content

Commit c4dcc05

Browse files
committed
feat: add streaming tests for streamText function
This commit introduces a new test suite for the streamText function, verifying that it correctly emits a stream_done event when the stream ends. Additionally, a utility function, iterableFromArray, is added to facilitate the creation of async iterables for testing purposes.
1 parent 5503622 commit c4dcc05

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

src/lib/streaming.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
import { describe, it, expect } from 'vitest'
22
import { stopStreamProcessing } from './utils/streaming'
3+
import { streamText } from './streaming'
4+
5+
function iterableFromArray<T>(arr: T[]): AsyncIterable<T> {
6+
return {
7+
[Symbol.asyncIterator]() {
8+
let i = 0
9+
return {
10+
next: async () =>
11+
i < arr.length
12+
? { value: arr[i++], done: false }
13+
: { value: undefined, done: true },
14+
}
15+
},
16+
}
17+
}
318

419
describe('stopStreamProcessing', () => {
520
it('replaces response body with an empty closed stream', async () => {
@@ -59,3 +74,73 @@ describe('stopStreamProcessing', () => {
5974
expect(response.body).toBeInstanceOf(ReadableStream)
6075
})
6176
})
77+
78+
describe('streamText', () => {
79+
it('emits stream_done when the stream ends', async () => {
80+
// Simulate a normal completion (not timing out)
81+
const chunks = [
82+
{ type: 'response.output_text.delta', delta: "I'm glad you asked!" },
83+
{
84+
type: 'response.output_text.delta',
85+
delta: ' Here are a few universally nice things that',
86+
},
87+
{
88+
type: 'response.output_text.delta',
89+
delta: ' could have happened today:\n\n',
90+
},
91+
{
92+
type: 'response.output_text.delta',
93+
delta: '- Someone smiled at a stranger, brightening',
94+
},
95+
{ type: 'response.output_text.delta', delta: ' their day\n' },
96+
{
97+
type: 'response.output_text.delta',
98+
delta: '- A teacher helped a student understand a',
99+
},
100+
{ type: 'response.output_text.delta', delta: ' difficult concept\n' },
101+
{
102+
type: 'response.output_text.delta',
103+
delta: '- A kind person paid for someone’s coffee',
104+
},
105+
{ type: 'response.output_text.delta', delta: ' in line\n' },
106+
{
107+
type: 'response.output_text.delta',
108+
delta: '- A pet reunited with its owner at a local',
109+
},
110+
{ type: 'response.output_text.delta', delta: ' animal shelter\n' },
111+
{
112+
type: 'response.output_text.delta',
113+
delta: '- A friend reached out just to say hello\n\n',
114+
},
115+
{
116+
type: 'response.output_text.delta',
117+
delta: 'Would you like to hear some real, uplifting',
118+
},
119+
{ type: 'response.output_text.delta', delta: ' news from today?' },
120+
{ type: 'response.output_text.delta', delta: ' Just let me know!' },
121+
{
122+
type: 'response.tool_call_completed',
123+
response: {
124+
/* ...omitted... */
125+
},
126+
},
127+
{
128+
type: 'response.completed',
129+
response: {
130+
/* ...omitted... */
131+
},
132+
},
133+
]
134+
const response = streamText(iterableFromArray(chunks))
135+
const reader = response.body!.getReader()
136+
let result = ''
137+
let done = false
138+
while (!done) {
139+
const { value, done: d } = await reader.read()
140+
if (value) result += new TextDecoder().decode(value)
141+
done = d
142+
}
143+
// Should include t:{...stream_done...}
144+
expect(result).toMatch(/t:{\"type\":\"stream_done\"}/)
145+
})
146+
})

0 commit comments

Comments
 (0)