Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Tw9fjW75aYB8UyVRZo6fCr
52 lines
3.5 KiB
JavaScript
52 lines
3.5 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { keepsSize, qualityLabel, swap, upscale } from "./job.js";
|
|
|
|
const m = (f, sub = "") => ({ filename: f, subfolder: sub, type: "output" });
|
|
|
|
test("swap replaces the file under every render and ghost that plays it, and nothing else", () => {
|
|
const p = { scene_renders: { a: { media: m("x.mp4"), inSec: 1 }, b: { media: m("x.mp4") }, c: { media: m("y.mp4") } }, scene_ghosts: [{ id: "g", media: m("x.mp4") }] };
|
|
assert.equal(swap(p, m("x.mp4"), m("up.mp4", "funui_upscaled")), 3);
|
|
assert.equal(p.scene_renders.a.media.filename, "up.mp4"); assert.equal(p.scene_renders.a.inSec, 1);
|
|
assert.equal(p.scene_renders.c.media.filename, "y.mp4");
|
|
});
|
|
|
|
test("upscale waits while it runs, then returns the video; an error is thrown in words", async () => {
|
|
const seq = [{ state: "running" }, { state: "running" }, { state: "done", media: m("up.mp4", "funui_upscaled") }];
|
|
const api = { upscale: async () => ({ job_id: "id" }), upscaleJob: async () => seq.shift() };
|
|
assert.equal((await upscale(api, m("x.mp4"), "mdl", async () => {})).filename, "up.mp4");
|
|
const bad = { upscale: async () => ({ job_id: "id" }), upscaleJob: async () => ({ state: "error", detail: "out of memory" }) };
|
|
await assert.rejects(upscale(bad, m("x.mp4"), "mdl", async () => {}), /out of memory/);
|
|
});
|
|
|
|
test("a restarted ComfyUI is named, a dropped reply is retried longer", async () => {
|
|
const gone = { upscale: async () => ({ job_id: "id" }), upscaleJob: async () => { throw Object.assign(new Error("x"), { status: 404 }); } };
|
|
await assert.rejects(upscale(gone, m("x.mp4"), "mdl", async () => {}), /restarted/);
|
|
let n = 0;
|
|
const flaky = { upscale: async () => ({ job_id: "id" }), upscaleJob: async () => { if (++n < 5) throw new Error("net"); return { state: "done", media: m("u.mp4") }; } };
|
|
assert.equal((await upscale(flaky, m("x.mp4"), "mdl", async () => {})).filename, "u.mp4");
|
|
});
|
|
|
|
test("a take that plays the old file gets the upscaled one too, so stepping back does not undo it", async () => {
|
|
const { swap } = await import("./job.js");
|
|
const old = { filename: "a.mp4", subfolder: "", type: "output" }, up = { filename: "funui_upscaled_a.mp4", subfolder: "", type: "output" };
|
|
const p = { scene_renders: { s: { media: old } }, scene_variants: { s: [{ media: old, promptId: "p" }, { media: { filename: "other.mp4" }, promptId: "q" }] } };
|
|
swap(p, old, up);
|
|
assert.equal(p.scene_variants.s[0].media.filename, "funui_upscaled_a.mp4");
|
|
assert.equal(p.scene_variants.s[1].media.filename, "other.mp4");
|
|
});
|
|
|
|
test("quality levels read as words, and only denoise and deblur keep the video's size", () => {
|
|
assert.deepEqual(["BICUBIC", "ULTRA", "DENOISE_HIGH", "HIGHBITRATE_LOW", "STREAMING_ULTRA"].map(qualityLabel),
|
|
["Bicubic (no AI)", "Upscale · Ultra", "Denoise · High", "High bitrate · Low", "Streaming · Ultra"]);
|
|
assert.deepEqual(["ULTRA", "DENOISE_LOW", "DEBLUR_ULTRA", "HIGHBITRATE_HIGH"].map(keepsSize), [false, true, true, false]);
|
|
});
|
|
|
|
test("the RTX options reach the node as one JSON input, and a model upscale sends none", async () => {
|
|
const seen = [];
|
|
const api = { upscale: async (...a) => (seen.push(a), { job_id: "id" }), upscaleJob: async () => ({ state: "done", media: m("u.mp4") }) };
|
|
await upscale(api, m("x.mp4"), "NVIDIA RTX Super Resolution", async () => {}, { quality: "ULTRA" });
|
|
await upscale(api, m("x.mp4"), "mdl", async () => {});
|
|
assert.deepEqual(seen.map((a) => a[2]), [{ quality: "ULTRA" }, undefined]);
|
|
});
|