Files
bun.sh/test/js/web/workers/worker_blob.test.ts

127 lines
3.2 KiB
TypeScript

import { 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 () => {
const { promise, reject } = Promise.withResolvers();
const worker = new Worker("blob:i dont exist!");
worker.addEventListener("error", e => reject(e.message));
expect(promise).rejects.toBe('BuildMessage: ModuleNotFound resolving "blob:i dont exist!" (entry point)');
});
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).toBe("BuildMessage: Blob URL is missing");
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.");
});