Files
bun.sh/test/js/web/workers/worker_blob.test.ts
Jarred Sumner 6a756bf979 Implement blob: URLs in fetch, import, and Worker (#11537)
Co-authored-by: Jarred-Sumner <Jarred-Sumner@users.noreply.github.com>
Co-authored-by: dave caruso <me@paperdave.net>
2024-06-05 18:49:03 -07:00

126 lines
3.0 KiB
TypeScript

import { describe, expect, test } from "bun:test";
test("Worker from a Blob", async () => {
const worker = new Worker(
URL.createObjectURL(
new Blob(
[
`self.onmessage = e => {
self.postMessage(e.data);
};`,
],
{ type: "application/javascript" },
),
),
);
const result = await new Promise(resolve => {
worker.onmessage = e => {
worker.onmessage = () => {};
resolve(e.data);
};
worker.postMessage("hello");
});
expect(result).toBe("hello");
});
test("TypeScript Worker from a Blob", async () => {
const worker = new Worker(
URL.createObjectURL(
new File(
[
`
export function supportsTypescript(): boolean {
return true;
}
self.onmessage = e => {
self.postMessage(supportsTypescript() ? e.data : "typescript not supported" );
};
`,
],
"worker.ts",
),
),
);
const result = await new Promise(resolve => {
worker.onmessage = e => {
worker.onmessage = () => {};
resolve(e.data);
};
worker.postMessage("i support typescript");
});
expect(result).toBe("i support typescript");
});
test("Worker from a blob errors on invalid blob", async () => {
expect(() => {
new Worker("blob:i dont exist!");
}).toThrow();
});
test("Revoking an object URL after a Worker is created before it loads should throw an error", async () => {
const blob = new Blob([`self.postMessage("I survived. I should not have survived. That is a bug.");`], {
type: "application/javascript",
});
// This is inherently kind of racy.
// So we try a few times to make sure it's not just a fluke.
for (let attempt = 0; attempt < 10; attempt++) {
const url = URL.createObjectURL(blob);
const worker = new Worker(url);
URL.revokeObjectURL(url);
try {
const result = await new Promise((resolve, reject) => {
worker.onmessage = reject;
worker.onerror = resolve;
});
expect(result).toBeInstanceOf(ErrorEvent);
expect((result as ErrorEvent).message).toContain(url);
break;
} catch (e) {
if (attempt === 9) {
throw e;
}
}
}
});
test("Worker on a revoked blob still works", async () => {
const blob = new Blob(
[
`self.onmessage = e => {
self.postMessage(e.data);
};`,
],
{ type: "application/javascript" },
);
const url = URL.createObjectURL(blob);
const worker = new Worker(url);
const result = await new Promise(resolve => {
worker.onmessage = e => {
worker.onmessage = () => {};
resolve(e.data);
};
worker.postMessage("hello");
});
expect(result).toBe("hello");
const revoked = await new Promise(resolve => {
URL.revokeObjectURL(url);
worker.onmessage = e => {
worker.onmessage = () => {};
resolve(e.data);
};
worker.postMessage("revoked.");
});
expect(revoked).toBe("revoked.");
});