Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

quickshell/nuguland/screenshots.test.mjs

Raw
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "node:test";
import vm from "node:vm";

// Replay the actual service functions, not a second screenshot implementation.
// This is not QML loading, native capture, input, file, or visual evidence.
const qml = readFileSync(new URL("Screenshots.qml", import.meta.url), "utf8");
const start = qml.indexOf("    function rectFromPoints(");
const end = qml.indexOf("    Connections {", start);
assert.ok(start >= 0 && end > start);
const plain = value => JSON.parse(JSON.stringify(value));
function service(available = true) {
    const calls = [];
    const state = {
        niriService: {
            available,
            screenshotScreen: path => calls.push(["screenshot-screen", path]),
            screenshotWindow: path => calls.push(["screenshot-window", path]),
            screenshot: path => calls.push(["screenshot", path]),
            pickColor: () => calls.push(["pick-color"]),
        },
        osdService: null, lastColor: "", recent: [], pending: [], requestSerial: 0,
        lastAction: {}, lastOsd: {}, selection: { phase: "idle", completionFlash: false },
        nativeActions: ["screenshot-screen", "screenshot-window", "screenshot", "pick-color"],
        boundedActions: [], toolbarActions: ["copy", "save", "cancel", "color"],
    };
    Object.defineProperty(state, "nativeActionRoute", {
        get: () => !!state.niriService?.available,
    });
    state.root = state;
    vm.createContext(state);
    vm.runInContext(qml.slice(start, end), state);
    const handler = qml.slice(end).match(/function onScreenshotCaptured\(path\) \{([^}]+)\}/);
    assert.ok(handler, "completion uses Connections");
    assert.match(qml.slice(end), /target: root\.niriService/);
    state.emit = vm.runInContext(`(function(path) { ${handler[1]} })`, state);
    state.calls = calls;
    return state;
}

for (const [kind, native] of [
    ["focused-screen", "screenshot-screen"],
    ["focused-window", "screenshot-window"],
    ["interactive", "screenshot"],
]) {
    test(`${kind}: submission is pending; exact completion alone saves`, () => {
        const s = service();
        const path = `/captures/${kind}.png`;
        const submitted = JSON.parse(s.capture(kind, path));
        assert.deepEqual(s.calls, [[native, path]]);
        assert.equal(submitted.recentCount, 0);
        assert.equal(submitted.pendingCount, 1);
        assert.equal(submitted.lastAction.status, "pending");
        assert.equal(submitted.lastAction.saved, false);
        assert.equal(submitted.lastAction.completed, false);
        s.emit(`/unrelated/${kind}.png`);
        assert.equal(s.recent.length, 0);
        assert.equal(s.pending.length, 1);
        s.emit(path);
        assert.equal(s.pending.length, 0);
        assert.deepEqual(plain(s.recent), [{
            id: submitted.lastAction.id, kind, path, source: "niri-native", saved: true,
        }]);
        assert.equal(s.lastAction.status, "saved");
        assert.equal(s.lastAction.completed, true);
        s.emit(path);
        assert.equal(s.recent.length, 1, "unmatched duplicate cannot add a record");
    });
}

test("unavailable or absent compositor never dispatches or records", () => {
    for (const kind of ["focused-screen", "focused-window", "interactive", "select-region"]) {
        for (const absent of [false, true]) {
            const s = service(false);
            if (absent) s.niriService = null;
            if (kind === "select-region") s.completeSelection("/capture.png");
            else s.capture(kind, "/capture.png");
            s.emit("/capture.png");
            assert.equal(s.calls.length, 0);
            assert.equal(s.pending.length, 0);
            assert.equal(s.recent.length, 0);
            assert.equal(s.lastAction.status, "unavailable");
            assert.equal(s.selection.completionFlash, false);
        }
    }
});

test("unsupported actions and missing paths never dispatch or queue", () => {
    const s = service();
    s.capture("copy", "/capture.png");
    assert.equal(s.lastAction.status, "unsupported");
    for (const path of ["", null, undefined]) {
        s.capture("interactive", path);
        assert.equal(s.lastAction.status, "invalid-path");
    }
    assert.equal(s.calls.length, 0);
    assert.equal(s.pending.length, 0);
    assert.equal(s.recent.length, 0);
});

test("null completion cannot identify clipboard-only or failed-write requests", () => {
    const s = service();
    s.capture("interactive", "/clipboard-only.png");
    s.capture("focused-screen", "/missing-parent/failure.png");
    const pending = plain(s.pending);
    for (const path of [null, null, undefined, "", 42, { path: "/clipboard-only.png" }]) s.emit(path);
    assert.deepEqual(plain(s.pending), pending);
    assert.equal(s.recent.length, 0);
    assert.equal(s.lastAction.completed, false);
});

test("no event means unconfirmed, not saved or inferred cancelled/failed", () => {
    const s = service();
    s.capture("interactive", "/cancelled.png");
    s.capture("focused-window", "/render-failure.png");
    s.niriService.available = false;
    const state = JSON.parse(s.stateJson());
    assert.equal(state.pendingCount, 2);
    assert.ok(state.pending.every(request => request.status === "pending" && !request.saved));
    assert.equal(state.recentCount, 0);
    s.emit("/render-failure.png");
    assert.equal(s.recent.length, 1, "a late matching save still counts while disconnected");
});

test("repeated kinds retain distinct requests and out-of-order completions", () => {
    const s = service();
    s.capture("focused-screen", "/first.png");
    s.capture("focused-screen", "/second.png");
    const [first, second] = plain(s.pending);
    assert.notEqual(first.id, second.id);
    s.emit(second.path);
    s.emit(first.path);
    assert.deepEqual(plain(s.recent).map(record => record.id), [first.id, second.id]);
    assert.equal(s.lastAction.id, second.id, "late completion cannot overwrite newer action");
    assert.equal(s.lastAction.status, "saved");
});

test("same-path repeats consume one FIFO match per event, without pretending request identity", () => {
    const s = service();
    s.capture("focused-screen", "/same.png");
    s.capture("focused-window", "/same.png");
    const [first, second] = plain(s.pending);
    s.emit("/same.png");
    assert.equal(s.pending.length, 1);
    assert.equal(s.recent[0].id, first.id);
    assert.equal(s.lastAction.status, "pending");
    s.emit("/same.png");
    assert.equal(s.pending.length, 0);
    assert.deepEqual(plain(s.recent).map(record => record.id), [second.id, first.id]);
    s.capture("interactive", "/same.png");
    s.emit("/same.png");
    assert.equal(s.recent.length, 3, "sequential reuse also retains a distinct saved record");
});

test("matching is exact, not basename or normalized-path guessing", () => {
    const s = service();
    s.capture("focused-screen", "capture.png");
    s.emit("/capture.png");
    s.emit("./capture.png");
    assert.equal(s.recent.length, 0);
    s.emit("capture.png");
    assert.equal(s.recent.length, 1);
});

test("completeSelection preserves geometry but does not flash success before matching save", () => {
    const s = service();
    s.beginSelection(30, 40);
    s.updateSelection(-10, -20);
    const submitted = JSON.parse(s.completeSelection("/region.png"));
    assert.deepEqual(s.calls, [["screenshot", "/region.png"]]);
    assert.deepEqual(submitted.selection.rect, { x: -10, y: -20, width: 40, height: 60 });
    assert.equal(submitted.selection.phase, "pending");
    assert.equal(submitted.selection.completionFlash, false);
    assert.equal(submitted.selectionVisuals.dimmedMask.visible, true);
    assert.equal(submitted.recentCount, 0);
    assert.equal(submitted.pending[0].kind, "select-region");
    s.emit(null);
    s.emit("/other.png");
    assert.equal(s.selection.phase, "pending");
    s.emit("/region.png");
    assert.equal(s.selection.phase, "completed");
    assert.equal(s.selection.completionFlash, true);
    assert.equal(s.recent[0].kind, "select-region");
});

test("repeated selections only complete the current preview", () => {
    const s = service();
    s.completeSelection("/first.png");
    s.completeSelection("/second.png");
    s.emit("/first.png");
    assert.equal(s.selection.phase, "pending");
    s.emit("/second.png");
    assert.equal(s.selection.phase, "completed");
    s.completeSelection("/third.png");
    s.updateSelection(10, 20);
    s.emit("/third.png");
    assert.equal(s.selection.phase, "dragging", "new drag is not completed by an older request");
});

test("local preview cancellation does not claim native cancellation or fabricate a save", () => {
    const s = service();
    s.completeSelection("/region.png");
    s.cancelSelection();
    assert.equal(s.selection.phase, "idle");
    assert.equal(s.selection.completionFlash, false);
    assert.equal(s.pending.length, 1, "native outcome remains unknown");
    assert.equal(s.recent.length, 0);
    assert.equal(s.calls.length, 1, "no invented native cancel command");
    s.emit("/region.png");
    assert.equal(s.recent.length, 1, "real late save remains visible in history");
    assert.equal(s.selection.phase, "idle");
    assert.equal(s.lastAction.kind, "cancel");
});

test("pending is registered before native dispatch", () => {
    const s = service();
    s.niriService.screenshot = path => s.emit(path);
    const result = JSON.parse(s.completeSelection("/immediate.png"));
    assert.equal(result.recentCount, 1);
    assert.equal(result.pendingCount, 0);
    assert.equal(result.lastAction.status, "saved");
    assert.equal(result.selection.completionFlash, true);
});

test("history stays capped at twelve successes; clear forgets pending without cancelling Niri", () => {
    const s = service();
    for (let i = 0; i < 14; i++) {
        s.capture("focused-window", `/capture-${i}.png`);
        s.emit(`/capture-${i}.png`);
    }
    assert.equal(s.recent.length, 12);
    assert.equal(s.recent[0].path, "/capture-13.png");
    assert.equal(s.recent[11].path, "/capture-2.png");
    s.completeSelection("/pending.png");
    const serial = s.requestSerial;
    const cleared = JSON.parse(s.clear());
    assert.equal(cleared.recentCount, 0);
    assert.equal(cleared.pendingCount, 0);
    assert.equal(cleared.lastAction.kind, "clear");
    assert.equal(cleared.selection.phase, "idle");
    assert.equal(s.calls.length, 15);
    s.emit("/pending.png");
    assert.equal(s.recent.length, 0);
    s.capture("focused-screen", "/new.png");
    assert.ok(s.requestSerial > serial, "clear cannot reuse local IDs");
});

test("color picking, OSD fallback and metadata-only record actions remain independent", () => {
    const s = service();
    s.capture("focused-screen", "/capture.png");
    s.pickColor();
    assert.deepEqual(s.calls.at(-1), ["pick-color"]);
    s.acceptPickedColor("not a color");
    assert.equal(s.lastColor, "");
    s.acceptPickedColor("#ABCDEF");
    assert.equal(s.lastColor, "#abcdef");
    assert.deepEqual(plain(s.lastOsd), { event: "color", value: "#abcdef" });
    s.osdService = { trigger: (event, value) => JSON.stringify({ event, value, delivered: true }) };
    s.acceptPickedColor("#123456");
    assert.equal(s.lastOsd.delivered, true);
    s.osdService = { trigger() { throw Error("unavailable"); } };
    s.acceptPickedColor("#654321");
    assert.equal(s.lastOsd.value, "#654321");
    s.emit("/capture.png");
    assert.equal(s.lastAction.kind, "pick-color");
    s.recordAction("copy", s.recent[0].id);
    assert.equal(s.lastAction.nativeActionRoute, false);
    assert.equal(s.recent.length, 1);
    s.niriService = null;
    s.pickColor();
    assert.equal(s.calls.length, 2, "unavailable color picking does not dispatch");
});