158 lines
5.2 KiB
TypeScript
158 lines
5.2 KiB
TypeScript
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import { AudioCodecFfmpegNativeError } from "../error-codes/error-codes.js";
|
|
import { extractInstallerPath, resolveBinary } from "./binary.js";
|
|
|
|
describe("binary/resolveBinary", () => {
|
|
it("uses binaryProvider when it returns non-empty", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const res = await resolveBinary({
|
|
binaryProvider: () => "/from/provider",
|
|
installerLoader: async () => ({ path: "/from/installer" }),
|
|
pathLookup: () => "/from/path",
|
|
});
|
|
expect(res).toEqual({ path: "/from/provider", source: "provider" });
|
|
});
|
|
|
|
it("supports async binaryProvider", { timeout: 5000 }, async () => {
|
|
const res = await resolveBinary({
|
|
binaryProvider: async () => "/async/provider",
|
|
installerLoader: async () => null,
|
|
});
|
|
expect(res).toEqual({ path: "/async/provider", source: "provider" });
|
|
});
|
|
|
|
it("falls through provider empty string to explicit binaryPath", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const res = await resolveBinary({
|
|
binaryProvider: () => "",
|
|
binaryPath: "/explicit",
|
|
installerLoader: async () => null,
|
|
});
|
|
expect(res).toEqual({ path: "/explicit", source: "explicit" });
|
|
});
|
|
|
|
it("uses installer when provider+explicit absent", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const res = await resolveBinary({
|
|
installerLoader: async () => ({ path: "/installer" }),
|
|
});
|
|
expect(res).toEqual({ path: "/installer", source: "installer" });
|
|
});
|
|
|
|
it("falls through installer throw to pathLookup", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const res = await resolveBinary({
|
|
installerLoader: async () => {
|
|
throw new Error("missing");
|
|
},
|
|
pathLookup: () => "/from/path",
|
|
});
|
|
expect(res).toEqual({ path: "/from/path", source: "path" });
|
|
});
|
|
|
|
it("falls through installer null to pathLookup", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const res = await resolveBinary({
|
|
installerLoader: async () => null,
|
|
pathLookup: () => "/from/path",
|
|
});
|
|
expect(res).toEqual({ path: "/from/path", source: "path" });
|
|
});
|
|
|
|
it("falls through installer empty path to pathLookup", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
const res = await resolveBinary({
|
|
installerLoader: async () => ({ path: "" }),
|
|
pathLookup: () => "/from/path",
|
|
});
|
|
expect(res).toEqual({ path: "/from/path", source: "path" });
|
|
});
|
|
|
|
it("falls through empty pathLookup to BINARY_MISSING", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
await expect(
|
|
resolveBinary({
|
|
installerLoader: async () => null,
|
|
pathLookup: () => undefined,
|
|
})
|
|
).rejects.toBeInstanceOf(AudioCodecFfmpegNativeError);
|
|
});
|
|
|
|
it("throws BINARY_MISSING when every step misses", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
await expect(
|
|
resolveBinary({
|
|
installerLoader: async () => null,
|
|
})
|
|
).rejects.toMatchObject({
|
|
code: "AUDIO_CODEC_FFMPEG_NATIVE.BINARY_MISSING",
|
|
});
|
|
});
|
|
|
|
it("memoises by options reference", { timeout: 5000 }, async () => {
|
|
let calls = 0;
|
|
const opts = {
|
|
binaryProvider: () => {
|
|
calls += 1;
|
|
return "/cached";
|
|
},
|
|
};
|
|
await resolveBinary(opts);
|
|
await resolveBinary(opts);
|
|
await resolveBinary(opts);
|
|
expect(calls).toBe(1);
|
|
});
|
|
|
|
it("default installer loader resolves real @ffmpeg-installer/ffmpeg", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
// Real @ffmpeg-installer/ffmpeg IS installed via catalog:audio in
|
|
// this monorepo, so the default loader returns its bundled path.
|
|
const res = await resolveBinary({});
|
|
expect(res.source === "installer" || res.source === "path").toBe(true);
|
|
expect(res.path.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it("resolveBinary supports no-argument invocation", {
|
|
timeout: 5000,
|
|
}, async () => {
|
|
// Covers the `opts: BinaryResolverOptions = {}` default-argument
|
|
// branch — without it we fall back to the default installer.
|
|
const res = await resolveBinary();
|
|
expect(res.path.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe("binary/extractInstallerPath", () => {
|
|
it("returns { path } from default-exported shape", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(extractInstallerPath({ default: { path: "/d" } })).toEqual({
|
|
path: "/d",
|
|
});
|
|
});
|
|
|
|
it("falls back to named `path` when default has no `path`", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(extractInstallerPath({ path: "/named" })).toEqual({
|
|
path: "/named",
|
|
});
|
|
});
|
|
|
|
it("returns null when neither default nor named path is present", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
expect(extractInstallerPath({})).toBeNull();
|
|
expect(extractInstallerPath({ default: {} })).toBeNull();
|
|
});
|
|
});
|