88 lines
2.3 KiB
TypeScript
88 lines
2.3 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { RevolutionaryTypedFetch } from '../src/core/typed-fetch.js'
|
|
|
|
const createChunkedStream = (chunks: number[]) => {
|
|
let index = 0
|
|
return {
|
|
getReader() {
|
|
return {
|
|
async read() {
|
|
if (index >= chunks.length) {
|
|
return { done: true as const, value: undefined }
|
|
}
|
|
const size = chunks[index++] ?? 0
|
|
return { done: false as const, value: new Uint8Array(size || 0) }
|
|
},
|
|
async cancel() {
|
|
/* noop */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
describe('throttled helper', () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
it('throttles response streams before delivering subsequent chunks', async () => {
|
|
const tf = new RevolutionaryTypedFetch()
|
|
let current = 0
|
|
const sleep = vi.fn(async (ms: number) => {
|
|
current += ms
|
|
})
|
|
|
|
const stream = createChunkedStream([1024, 1024])
|
|
const throttled = await tf.throttled(() => Promise.resolve(stream), {
|
|
bandwidth: '1KB/s',
|
|
sleep,
|
|
now: () => current
|
|
})
|
|
expect(typeof throttled.getReader).toBe('function')
|
|
|
|
const reader = throttled.getReader()
|
|
const first = await reader.read()
|
|
expect(first.value?.length).toBe(1024)
|
|
|
|
const second = await reader.read()
|
|
expect(second.value?.length).toBe(1024)
|
|
expect(sleep).toHaveBeenCalled()
|
|
|
|
const final = await reader.read()
|
|
expect(final.done).toBe(true)
|
|
})
|
|
|
|
it('wraps nested response objects without touching data payloads', async () => {
|
|
const tf = new RevolutionaryTypedFetch()
|
|
let current = 0
|
|
const sleep = vi.fn(async (ms: number) => {
|
|
current += ms
|
|
})
|
|
|
|
const original = {
|
|
body: createChunkedStream([2048, 2048]),
|
|
headers: new Headers({ 'X-Test': '1' }),
|
|
status: 202,
|
|
statusText: 'Accepted'
|
|
}
|
|
const payload = { data: { ok: true }, response: original }
|
|
|
|
const result = await tf.throttled(() => Promise.resolve(payload), {
|
|
bandwidth: '1KB/s',
|
|
sleep,
|
|
now: () => current
|
|
})
|
|
|
|
expect(result.data).toEqual({ ok: true })
|
|
expect(result.response).not.toBe(original)
|
|
expect(result.response.status).toBe(202)
|
|
|
|
const reader = result.response.body!.getReader()
|
|
await reader.read()
|
|
await reader.read()
|
|
const tail = await reader.read()
|
|
expect(tail.done).toBe(true)
|
|
})
|
|
})
|