The A | B badge stayed in the middle of the picture while the split line moved. Now A rides just left of the line and B just right of it, on the picture each one names; with one picture showing, its label sits alone.
114 lines
4.6 KiB
JavaScript
114 lines
4.6 KiB
JavaScript
import assert from "node:assert/strict";
|
||
import test from "node:test";
|
||
|
||
import {
|
||
clipFraction,
|
||
compareBadges,
|
||
slideFraction,
|
||
compareClip,
|
||
compareSizeLabel,
|
||
findCompareImages,
|
||
normalizeCompareMode,
|
||
} from "../js/shared/compare.mjs";
|
||
|
||
test("clip fraction follows the pointer and clamps to the panel", () => {
|
||
assert.equal(clipFraction(150, 100, 200), 0.25);
|
||
assert.equal(clipFraction(100, 100, 200), 0);
|
||
assert.equal(clipFraction(40, 100, 200), 0);
|
||
assert.equal(clipFraction(900, 100, 200), 1);
|
||
});
|
||
|
||
test("degenerate panels and junk input resolve to no left overlay", () => {
|
||
assert.equal(clipFraction(150, 100, 0), 0);
|
||
assert.equal(clipFraction(150, 100, -5), 0);
|
||
assert.equal(clipFraction(NaN, 100, 200), 0);
|
||
assert.equal(clipFraction(150, 100, "wide"), 0);
|
||
});
|
||
|
||
test("mode normalization", () => {
|
||
assert.equal(normalizeCompareMode("slide"), "slide");
|
||
assert.equal(normalizeCompareMode("toggle"), "toggle");
|
||
assert.equal(normalizeCompareMode("wiggle"), "slide");
|
||
assert.equal(normalizeCompareMode(undefined), "slide");
|
||
});
|
||
|
||
test("a workflow saved on the old hold mode lands on the toggle it became", () => {
|
||
// Dropping it to slide instead would silently change how a saved node
|
||
// behaves, which is exactly what someone reopening their graph notices.
|
||
assert.equal(normalizeCompareMode("hold"), "toggle");
|
||
});
|
||
|
||
test("the caption names the compared resolution, once", () => {
|
||
assert.equal(
|
||
compareSizeLabel({ a: { width: 576, height: 1024 }, b: { width: 576, height: 1024 } }),
|
||
"576×1024",
|
||
);
|
||
// One side only is the common case mid-load; A speaks for the pair.
|
||
assert.equal(compareSizeLabel({ a: { width: 512, height: 512 } }), "512×512");
|
||
});
|
||
|
||
test("a size mismatch is stated rather than hidden behind A", () => {
|
||
// Comparing images of different sizes is usually a wiring mistake, and the
|
||
// panel stretches both to fit, so nothing else on screen would show it.
|
||
assert.equal(
|
||
compareSizeLabel({ a: { width: 512, height: 512 }, b: { width: 1024, height: 1024 } }),
|
||
"A 512×512 · B 1024×1024",
|
||
);
|
||
});
|
||
|
||
test("nothing loaded means no caption at all", () => {
|
||
assert.equal(compareSizeLabel(null), "");
|
||
assert.equal(compareSizeLabel({}), "");
|
||
assert.equal(compareSizeLabel({ a: { width: 0, height: 0 } }), "");
|
||
assert.equal(compareSizeLabel({ a: { filename: "x.png" } }), "");
|
||
});
|
||
|
||
test("clip CSS keeps the overlay left of the seam and hides the seam at the edges", () => {
|
||
assert.deepEqual(compareClip(0.25), {
|
||
clipPath: "inset(0 75.00% 0 0)",
|
||
seamLeft: "25.00%",
|
||
seamVisible: true,
|
||
});
|
||
assert.equal(compareClip(0).seamVisible, false);
|
||
assert.equal(compareClip(1).seamVisible, false);
|
||
assert.equal(compareClip(2).clipPath, "inset(0 0.00% 0 0)");
|
||
assert.equal(compareClip("junk").clipPath, "inset(0 100.00% 0 0)");
|
||
});
|
||
|
||
test("compare previews are pulled from the execution payload as a pair", () => {
|
||
const a = { filename: "a.png", subfolder: "", type: "temp" };
|
||
const b = { filename: "b.png", subfolder: "", type: "temp" };
|
||
assert.deepEqual(findCompareImages({ a_images: [a], b_images: [b] }), { a, b });
|
||
assert.equal(findCompareImages({ a_images: [a] }), null);
|
||
assert.equal(findCompareImages({ a_images: [{}], b_images: [b] }), null);
|
||
assert.equal(findCompareImages(null), null);
|
||
});
|
||
|
||
test("slide gives edges a forgiving landing zone without disturbing the middle", () => {
|
||
assert.equal(slideFraction(110, 100, 200), 0);
|
||
assert.equal(slideFraction(290, 100, 200), 1);
|
||
assert.equal(slideFraction(150, 100, 200), 0.25);
|
||
});
|
||
|
||
test("leaving above or below settles to the nearest full image", () => {
|
||
assert.equal(slideFraction(175, 100, 200, true), 0);
|
||
assert.equal(slideFraction(225, 100, 200, true), 1);
|
||
assert.equal(slideFraction(200, 100, 200, true), 1);
|
||
assert.equal(slideFraction(50, 100, 200, true), 0);
|
||
assert.equal(slideFraction(350, 100, 200, true), 1);
|
||
});
|
||
|
||
test("A and B sit on either side of the split line and move with it", () => {
|
||
// At 30% of a 400 px stage the line is at 120: A just left of it, B just right.
|
||
const split = compareBadges(0.3, 400, 22, 5);
|
||
assert.deepEqual(split, { a: 93, b: 125 });
|
||
assert.deepEqual(compareBadges(0.8, 400, 22, 5), { a: 293, b: 325 });
|
||
// One picture showing: its label alone, centred.
|
||
assert.deepEqual(compareBadges(1, 400, 22), { a: 189, b: null });
|
||
assert.deepEqual(compareBadges(0, 400, 22), { a: null, b: 189 });
|
||
// A side too narrow for its label drops the label rather than cover the line.
|
||
assert.equal(compareBadges(0.05, 400, 22, 5).a, null);
|
||
assert.equal(compareBadges(0.97, 400, 22, 5).b, null);
|
||
assert.deepEqual(compareBadges(0.5, 0), { a: null, b: null });
|
||
});
|