67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { decodeLocalImage } from "../../src/palette/decode";
|
|
|
|
const nativeUrl = globalThis.URL;
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
const installImageElementDecoder = (loadImmediately: boolean) => {
|
|
const createObjectURL = vi.fn(() => "blob:local-image");
|
|
const revokeObjectURL = vi.fn();
|
|
class MockUrl extends nativeUrl {
|
|
static createObjectURL = createObjectURL;
|
|
static revokeObjectURL = revokeObjectURL;
|
|
}
|
|
class MockImage {
|
|
decoding = "auto";
|
|
naturalWidth = 320;
|
|
naturalHeight = 180;
|
|
onload: (() => void) | null = null;
|
|
onerror: (() => void) | null = null;
|
|
private source = "";
|
|
|
|
set src(value: string) {
|
|
this.source = value;
|
|
if (value && loadImmediately) queueMicrotask(() => this.onload?.());
|
|
}
|
|
|
|
get src(): string {
|
|
return this.source;
|
|
}
|
|
}
|
|
|
|
vi.stubGlobal("URL", MockUrl);
|
|
vi.stubGlobal("Image", MockImage);
|
|
vi.stubGlobal("createImageBitmap", undefined);
|
|
return { createObjectURL, revokeObjectURL };
|
|
};
|
|
|
|
describe("local image decoding", () => {
|
|
it("revokes its object URL as soon as the image has decoded", async () => {
|
|
const spies = installImageElementDecoder(true);
|
|
const image = await decodeLocalImage(
|
|
new File(["image"], "sample.png", { type: "image/png" }),
|
|
);
|
|
|
|
expect(image).toMatchObject({ width: 320, height: 180 });
|
|
expect(spies.createObjectURL).toHaveBeenCalledOnce();
|
|
expect(spies.revokeObjectURL).toHaveBeenCalledWith("blob:local-image");
|
|
image.dispose();
|
|
});
|
|
|
|
it("revokes its object URL when decoding is cancelled", async () => {
|
|
const spies = installImageElementDecoder(false);
|
|
const controller = new AbortController();
|
|
const decoding = decodeLocalImage(
|
|
new File(["image"], "sample.png", { type: "image/png" }),
|
|
controller.signal,
|
|
);
|
|
controller.abort();
|
|
|
|
await expect(decoding).rejects.toMatchObject({ name: "AbortError" });
|
|
expect(spies.revokeObjectURL).toHaveBeenCalledWith("blob:local-image");
|
|
});
|
|
});
|