mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
test(web): compare the worker Buffer with an unmodified Node reference
Vitest resolves the shim's `buffer` import to Node's built-in module, so the differential spec patched and then compared the same implementation. Mock node:buffer with the npm package the Worker bundle uses. Also keep the UTF-8 encoding check symmetric, call the package methods directly, and document that the patch applies to every Buffer user in the Worker.
This commit is contained in:
1 parent
4b1d4c814e
commit
39d973322b
2 files changed
+30
-15
No files matched your search
+17
-13
@@ -3,11 +3,12 @@
|
||||
* the matching `globalThis.Buffer` install. Node code treats Buffer as ambient,
|
||||
* so the global must exist before any host module evaluates.
|
||||
*
|
||||
* Whole-buffer UTF-8 conversions, `Buffer.from(string)` and `buf.toString()`,
|
||||
* use the browser's `TextEncoder` and `TextDecoder`: they apply Node's U+FFFD
|
||||
* replacement rules and run several times faster than the package's JavaScript
|
||||
* codec on multi-megabyte bundles and source maps. Other encodings and ranged
|
||||
* `toString` calls keep the package's implementation.
|
||||
* Loading this module replaces `Buffer.from`, `Buffer.prototype.toString`, and
|
||||
* `toLocaleString` on the package's class, so every Buffer user in the Worker,
|
||||
* including bundled third-party code, gets the same conversions. Whole-buffer
|
||||
* UTF-8 conversions use `TextEncoder` and `TextDecoder` with Node's U+FFFD
|
||||
* replacement and BOM retention; other encodings and ranged `toString` calls
|
||||
* keep the package's implementation.
|
||||
*/
|
||||
import { Buffer, kMaxLength } from 'buffer'
|
||||
|
||||
@@ -15,24 +16,27 @@ const encoder = new TextEncoder()
|
||||
// Node keeps a leading byte order mark in the decoded string.
|
||||
const decoder = new TextDecoder('utf-8', { ignoreBOM: true })
|
||||
const UTF8 = /^utf-?8$/i
|
||||
const packageFrom = Buffer.from.bind(Buffer)
|
||||
const packageFrom = Buffer.from.bind(Buffer) as (value: unknown, encodingOrOffset?: unknown, length?: unknown) => Buffer
|
||||
const bufferPrototype = Buffer.prototype as Buffer
|
||||
// oxlint-disable-next-line typescript/unbound-method -- Reflect.apply supplies the Buffer receiver.
|
||||
// oxlint-disable-next-line typescript/unbound-method -- Called with .call and a Buffer receiver.
|
||||
const packageToString = bufferPrototype.toString
|
||||
|
||||
/** Whether an omitted or string encoding argument names UTF-8. */
|
||||
function isUtf8(encoding: unknown): boolean {
|
||||
return encoding === undefined || (typeof encoding === 'string' && UTF8.test(encoding))
|
||||
}
|
||||
|
||||
Buffer.from = function from(value: unknown, encodingOrOffset?: unknown, length?: unknown): Buffer {
|
||||
if (typeof value === 'string' && (encodingOrOffset === undefined || (typeof encodingOrOffset === 'string' && UTF8.test(encodingOrOffset)))) {
|
||||
if (typeof value === 'string' && isUtf8(encodingOrOffset)) {
|
||||
const bytes = encoder.encode(value)
|
||||
return packageFrom(bytes.buffer, bytes.byteOffset, bytes.byteLength)
|
||||
}
|
||||
return Reflect.apply(packageFrom, Buffer, [value, encodingOrOffset, length]) as Buffer
|
||||
return packageFrom(value, encodingOrOffset, length)
|
||||
} as typeof Buffer.from
|
||||
|
||||
bufferPrototype.toString = function toString(this: Buffer, encoding?: BufferEncoding, start?: number, end?: number): string {
|
||||
if (start === undefined && end === undefined && (encoding === undefined || UTF8.test(encoding))) {
|
||||
return decoder.decode(this)
|
||||
}
|
||||
return Reflect.apply(packageToString, this, [encoding, start, end])
|
||||
if (start === undefined && end === undefined && isUtf8(encoding)) return decoder.decode(this)
|
||||
return packageToString.call(this, encoding, start, end)
|
||||
}
|
||||
// oxlint-disable-next-line typescript/unbound-method -- Installed as a Buffer method; callers supply the receiver.
|
||||
Reflect.set(bufferPrototype, 'toLocaleString', bufferPrototype.toString)
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
/**
|
||||
* Differential check of the worker's `node:buffer` UTF-8 conversions against Node.
|
||||
*/
|
||||
import { Buffer as NodeBuffer } from 'node:buffer'
|
||||
import { afterAll, expect, it } from 'vitest'
|
||||
import { createRequire } from 'node:module'
|
||||
import { afterAll, expect, it, vi } from 'vitest'
|
||||
|
||||
// The worker bundle resolves `buffer` to the npm package, while Vitest maps it to Node's built-in module.
|
||||
// Mock that module so the shim patches the npm package and Node's own Buffer stays the unmodified reference.
|
||||
const require = createRequire(import.meta.url)
|
||||
const NodeBuffer = (require('node:buffer') as typeof import('node:buffer')).Buffer
|
||||
vi.mock('node:buffer', () => require('buffer/') as object)
|
||||
|
||||
const ambient = globalThis.Buffer
|
||||
const { Buffer: WorkerBuffer } = await import('@deepseek-ai/dsh-experimental-webworker-runtime/src/node/builtin_modules/implemented/buffer.ts')
|
||||
@@ -10,6 +16,11 @@ afterAll(() => {
|
||||
Object.defineProperty(globalThis, 'Buffer', { value: ambient, writable: true, configurable: true })
|
||||
})
|
||||
|
||||
it('tests the npm package against an unmodified Node reference', () => {
|
||||
expect(WorkerBuffer).not.toBe(NodeBuffer)
|
||||
expect(NodeBuffer.from('\uFEFF').toString()).toBe('\uFEFF')
|
||||
})
|
||||
|
||||
const STRINGS = ['', 'a', '中文字符串', '\uFEFFbom', 'lone \uD800 high', 'lone \uDC00 low', '😀 pair', 'x'.repeat(100_000)]
|
||||
const BYTES = [
|
||||
[0xEF, 0xBB, 0xBF, 0x61],
|
||||
|
||||
Reference in new issue
Block a user