Files
wehub-resource-sync c48612c494
CI / E2E Tests (push) Has been cancelled
CI / Lint, Typecheck & Unit Tests (push) Has been cancelled
Docs Build / Build docs site (push) Has been cancelled
Publish @openmaic packages / Build, validate & publish (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:03:23 +08:00

77 lines
2.6 KiB
TypeScript

// Test shims for the handful of browser globals the backends touch that Node
// does not provide natively. The backends themselves take their `Storage` /
// `IDBFactory` by injection, so tests pass fresh isolated instances; these
// shims only cover the ambient APIs (object URLs, IndexedDB key ranges,
// crypto) a real browser supplies.
import { webcrypto } from 'node:crypto';
import { IDBKeyRange } from 'fake-indexeddb';
import { beforeEach } from 'vitest';
// Node ≥20 exposes `globalThis.crypto`, but guard for older/edge runners so
// content-hashing (crypto.subtle.digest) works the same as in a browser.
if (!globalThis.crypto?.subtle) {
Object.defineProperty(globalThis, 'crypto', { value: webcrypto, configurable: true });
}
// The runtime backend builds its ranged record reads with the ambient
// `IDBKeyRange`, which real browsers always pair with `indexedDB` but Node
// lacks — supply the fake-indexeddb one that matches the injected factories.
if (!('IDBKeyRange' in globalThis)) {
globalThis.IDBKeyRange = IDBKeyRange;
}
// object-URL registry: `createObjectURL(blob)` mints a unique `blob:` URL and
// remembers the blob so tests can resolve the URL back to its bytes (the real
// browser provides both natively; Node provides neither).
const objectUrls = new Map<string, Blob>();
let seq = 0;
URL.createObjectURL = (obj: Blob | MediaSource): string => {
const url = `blob:maic-test/${seq++}`;
objectUrls.set(url, obj as Blob);
return url;
};
URL.revokeObjectURL = (url: string): void => {
objectUrls.delete(url);
};
/** Test-only: resolve an object URL minted by the polyfill back to its blob. */
export function blobForObjectUrl(url: string): Blob | undefined {
return objectUrls.get(url);
}
// Reset the object-URL registry between tests so nothing bleeds across cases
// (the override is a global; without this the map grows for the whole run).
beforeEach(() => {
objectUrls.clear();
seq = 0;
});
/**
* Test-only in-memory `Storage` (localStorage-shaped) for injecting into the
* browser KV backend. A fresh instance per test keeps cases isolated without
* touching any ambient global.
*/
export class MemoryStorage implements Storage {
private readonly m = new Map<string, string>();
get length(): number {
return this.m.size;
}
clear(): void {
this.m.clear();
}
getItem(key: string): string | null {
return this.m.has(key) ? this.m.get(key)! : null;
}
key(index: number): string | null {
return [...this.m.keys()][index] ?? null;
}
removeItem(key: string): void {
this.m.delete(key);
}
setItem(key: string, value: string): void {
this.m.set(key, String(value));
}
[name: string]: unknown;
}