mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-14 15:24:00 -04:00
89 lines
4.6 KiB
JavaScript
89 lines
4.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import vm from "node:vm";
|
|
import test from "node:test";
|
|
|
|
const read = path => readFileSync(new URL("../" + path, import.meta.url), "utf8");
|
|
const model = vm.createContext({});
|
|
vm.runInContext(read("Modules/DBar/WidgetModel.js").replace(/^\.pragma.*$/m, ""), model);
|
|
const plain = value => JSON.parse(JSON.stringify(value));
|
|
|
|
function method(source, name) {
|
|
const start = source.indexOf(" function " + name + "(");
|
|
const end = source.indexOf("\n }", start) + 6;
|
|
return source.slice(start, end);
|
|
}
|
|
|
|
test("widget normalization preserves metadata, defaults and positional occurrences", () => {
|
|
const entries = ["clock", { id: "clock", enabled: false, clockDateOrder: "dateFirst", extra: { value: 4 } },
|
|
{ widgetId: "plugin:variant", size: 0, enabled: null }, { id: "spacer", widgetId: "ignored", enabled: 0 }, "clock"];
|
|
const original = structuredClone(entries);
|
|
assert.deepEqual(plain(model.normalize(entries)), [
|
|
{ widgetId: "clock", id: "clock_0", enabled: true },
|
|
{ widgetId: "clock", id: "clock_1", enabled: false, clockDateOrder: "dateFirst", extra: { value: 4 } },
|
|
{ widgetId: "plugin:variant", id: "plugin:variant_2", size: 0, enabled: true },
|
|
{ widgetId: "spacer", id: "spacer_3", enabled: true },
|
|
{ widgetId: "clock", id: "clock_4", enabled: true }
|
|
]);
|
|
assert.deepEqual(entries, original);
|
|
assert.deepEqual(plain(model.normalize()), []);
|
|
assert.deepEqual(plain(model.normalize([])), []);
|
|
assert.deepEqual(plain(model.normalize([entries[4], entries[2]])).map(entry => entry.id), ["clock_0", "plugin:variant_1"]);
|
|
});
|
|
|
|
test("focus discovery keeps compositor names separate from first-screen fallback", () => {
|
|
const source = read("Services/CompositorService.qml");
|
|
const context = vm.createContext({
|
|
isAqueous: false, isHyprland: false, isNiri: false, isSway: false, isScroll: false, isMiracle: false, isMango: false, isUmbriel: false,
|
|
AqueousService: { available: true, focusedOutput: "second" }, Hyprland: { focusedMonitor: { name: "second" } },
|
|
NiriService: { currentOutput: "second" }, I3: { workspaces: { values: [{ focused: true, monitor: { name: "second" } }] } },
|
|
MangoService: { activeOutput: "second" }, Quickshell: { screens: [{ name: "first" }, { name: "second" }] }
|
|
});
|
|
vm.runInContext(method(source, "getFocusedScreenName") + method(source, "getFocusedScreen"), context);
|
|
assert.equal(context.getFocusedScreenName(), "");
|
|
assert.equal(context.getFocusedScreen().name, "first");
|
|
for (const compositor of ["isAqueous", "isHyprland", "isNiri", "isSway", "isScroll", "isMiracle", "isMango"]) {
|
|
context[compositor] = true;
|
|
assert.equal(context.getFocusedScreenName(), "second", compositor);
|
|
assert.equal(context.getFocusedScreen().name, "second", compositor);
|
|
context[compositor] = false;
|
|
}
|
|
context.isNiri = true;
|
|
context.NiriService.currentOutput = "unmapped";
|
|
assert.equal(context.getFocusedScreenName(), "unmapped");
|
|
assert.equal(context.getFocusedScreen().name, "first");
|
|
context.isNiri = false;
|
|
context.Quickshell.screens = [];
|
|
assert.equal(context.getFocusedScreen(), null);
|
|
});
|
|
|
|
test("center placement preserves configured anchors, visible fallbacks and geometric extents", () => {
|
|
const layout = vm.createContext({});
|
|
vm.runInContext(read("Modules/DBar/CenterLayout.js").replace(/^\.pragma.*$/m, ""), layout);
|
|
const cases = [
|
|
[[], 600, 4, "index", [], 0],
|
|
[[30, 80, 60], 600, 4, "geometric", [211, 245, 329], 178],
|
|
[[30, 80, 60], 600, 4, "index", [226, 260, 344], 178],
|
|
[[30, null, 60], 600, 4, "index", [268, null, 302], 94],
|
|
[[30, 80, 60, 20], 600, 4, "index", [184, 218, 302, 366], 202],
|
|
[[30, 80], 31, 0, "geometric", [-39.5, -9.5], 110]
|
|
];
|
|
for (const [sizes, length, spacing, mode, positions, totalSize] of cases) {
|
|
const original = [...sizes];
|
|
assert.deepEqual(plain(layout.resolve(sizes, length, spacing, mode)), { positions, totalSize });
|
|
assert.deepEqual(sizes, original);
|
|
}
|
|
});
|
|
|
|
test("center placement yields to side sections without overlapping them", () => {
|
|
const layout = vm.createContext({});
|
|
vm.runInContext(read("Modules/DBar/CenterLayout.js").replace(/^\.pragma.*$/m, ""), layout);
|
|
const cases = [
|
|
[{ min: 250 }, [250, 284, 368]],
|
|
[{ max: 300 }, [122, 156, 240]],
|
|
[{ min: 100, max: 200 }, [61, 95, 179]]
|
|
];
|
|
for (const [bounds, positions] of cases)
|
|
assert.deepEqual(plain(layout.resolve([30, 80, 60], 600, 4, "geometric", bounds)), { positions, totalSize: 178 });
|
|
});
|