mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
85 lines
2.8 KiB
TypeScript
85 lines
2.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { afterEach, expect, it, vi } from 'vitest'
|
|
import { WorkerTunnel } from '../../src/client/client.ts'
|
|
|
|
type StubListener = (event: { data?: unknown }) => void
|
|
|
|
function stubWorker(): {
|
|
worker: Worker
|
|
sent: { t: string; id: number; url: string }[]
|
|
deliver: (frame: unknown) => void
|
|
} {
|
|
const listeners: StubListener[] = []
|
|
const sent: { t: string; id: number; url: string }[] = []
|
|
return {
|
|
worker: {
|
|
addEventListener: (type: string, listener: StubListener) => {
|
|
if (type === 'message') listeners.push(listener)
|
|
},
|
|
postMessage: (frame: unknown) => { sent.push(frame as { t: string; id: number; url: string }) },
|
|
} as unknown as Worker,
|
|
sent,
|
|
deliver: (frame) => { for (const listener of listeners) listener({ data: frame }) },
|
|
}
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks()
|
|
vi.unstubAllGlobals()
|
|
document.head.innerHTML = ''
|
|
})
|
|
|
|
it('loads a combo map through the tunnel and embeds it in the blob script', async () => {
|
|
const { worker, sent, deliver } = stubWorker()
|
|
const tunnel = new WorkerTunnel(worker)
|
|
const blobs: Blob[] = []
|
|
const revoked: string[] = []
|
|
const NativeURL = URL
|
|
class StubURL extends NativeURL {
|
|
static override createObjectURL(blob: Blob): string {
|
|
blobs.push(blob)
|
|
return `blob:fixture-${String(blobs.length)}`
|
|
}
|
|
|
|
static override revokeObjectURL(url: string): void {
|
|
revoked.push(url)
|
|
}
|
|
}
|
|
vi.stubGlobal('URL', StubURL)
|
|
vi.spyOn(document.head, 'append').mockImplementation((...nodes) => {
|
|
for (const node of nodes) {
|
|
if (typeof node !== 'string') queueMicrotask(() => { node.dispatchEvent(new Event('load')) })
|
|
}
|
|
})
|
|
|
|
const scriptUrl = '/plugins/??a/client.js,b/client.js&rev=abc'
|
|
const mapUrl = '/plugins/??a/client.js.map,b/client.js.map&rev=abc'
|
|
const loading = tunnel.loadBundle(scriptUrl)
|
|
expect(sent[0]?.url).toBe(`http://localhost:3000${scriptUrl}`)
|
|
deliver({
|
|
t: 'res',
|
|
id: 1,
|
|
status: 200,
|
|
headers: { 'content-type': 'text/javascript' },
|
|
body: new TextEncoder().encode(`factory();\n//# sourceMappingURL=${mapUrl}\n`).buffer,
|
|
})
|
|
await vi.waitFor(() => { expect(sent).toHaveLength(2) })
|
|
expect(sent[1]?.url).toBe(`http://localhost:3000${mapUrl}`)
|
|
const map = '{"version":3,"sections":[]}'
|
|
deliver({
|
|
t: 'res',
|
|
id: 2,
|
|
status: 200,
|
|
headers: { 'content-type': 'application/json' },
|
|
body: new TextEncoder().encode(map).buffer,
|
|
})
|
|
await loading
|
|
|
|
const source = await blobs[0]?.text()
|
|
const encoded = /sourceMappingURL=data:application\/json;charset=utf-8;base64,([^\s]+)/.exec(source ?? '')?.[1]
|
|
if (encoded === undefined) throw new Error('localized bundle has no inline source map')
|
|
const decoded = Uint8Array.from(atob(encoded), char => char.charCodeAt(0))
|
|
expect(new TextDecoder().decode(decoded)).toBe(map)
|
|
expect(revoked).toEqual(['blob:fixture-1'])
|
|
})
|