Files
cjk-autospace/test/demo-controls.test.mjs
T
admin 3a4fa1c932 fix: 修复行缘、切分还原与语言解析并同步文档
保留逐字 margin/jiya.bias 字体后备方案;补齐 demo 重排、量测边界说明及共享规则 1.0.1 反例向量。

验证:完整构建通过,Node 376 项、WKWebView 64 项及原生 demo 9 项通过;Firefox 仍暂缓。
2026-10-03 21:15:54 +08:00

93 lines
4.2 KiB
JavaScript

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "node:test";
import { JSDOM } from "jsdom";
function openDemo(name)
{
const html = readFileSync(new URL("../demo/" + name, import.meta.url), "utf8");
const dom = new JSDOM(html, { runScripts: "outside-only" });
const { window } = dom;
const observers = [];
window.ResizeObserver = class
{
constructor(callback) { this.callback = callback; this.disconnected = false; observers.push(this); }
observe(root) { this.root = root; }
disconnect() { this.disconnected = true; }
};
// 此處驗證事件刷新與觀察目標;矩形模型不作真實 layout 驗收。
const rect = { top: 0, bottom: 20, left: 0, right: 20, width: 20, height: 20 };
window.Element.prototype.getClientRects = () => [ rect ];
window.Range.prototype.getClientRects = () => [ rect ];
window.eval(readFileSync(new URL("../dist/juzhen.iife.js", import.meta.url), "utf8"));
for (const script of window.document.querySelectorAll("script:not([src])"))
{
window.eval(script.textContent);
}
return { dom, window, document: window.document, observers };
}
function change(window, id, checked)
{
const input = window.document.getElementById(id);
input.checked = checked;
input.dispatchEvent(new window.Event("change"));
}
test("index demo:對齊與寬度明確重排,revert 後開關不重新啟用", () =>
{
const { dom, window, document, observers } = openDemo("index.html");
try
{
for (const [ id, checked ] of [ [ "justify", true ], [ "wide", true ] ])
{
const oldGap = document.querySelector("jz-hws");
const oldObservers = observers.filter((observer) => !observer.disconnected);
assert.ok(oldGap);
change(window, id, checked);
assert.equal(oldGap.isConnected, false, id + " 撤回舊產物");
assert.ok(document.querySelector("jz-hws"), id + " 重新建立產物");
assert.ok(oldObservers.every((observer) => observer.disconnected), id + " 更換 layout 安裝");
}
assert.ok(document.body.classList.contains("justify"));
assert.equal(document.querySelector(".narrow").style.maxWidth, "none");
document.getElementById("revert").click();
const count = observers.length;
assert.equal(document.querySelector("[data-jz]"), null);
change(window, "justify", false);
change(window, "wide", false);
change(window, "force-kaiming", true);
assert.equal(document.querySelector("[data-jz]"), null, "revert 狀態仍保持");
assert.equal(observers.length, count, "停用時不新增 layout 安裝");
document.getElementById("render").click();
assert.ok(document.querySelector("jz-hws"), "手動 render 可重新啟用");
assert.ok(document.getElementById("status").textContent.includes("开明式"));
}
finally { dom.window.close(); }
});
test("resize demo:各拖曳框各自被觀察,切換對齊刷新所有框", () =>
{
const { dom, window, document, observers } = openDemo("resize-check.html");
try
{
const boxes = Array.from(document.querySelectorAll(".box.juzhen"));
const targets = new Set(observers.map((observer) => observer.root));
assert.equal(targets.size, boxes.length);
assert.ok(boxes.every((box) => targets.has(box)));
assert.equal(targets.has(document.body), false);
const oldGaps = boxes.flatMap((box) => Array.from(box.querySelectorAll("jz-hws")));
const oldObservers = observers.slice();
assert.ok(oldGaps.length > 0);
change(window, "t-justify", true);
assert.ok(oldGaps.every((gap) => !gap.isConnected), "所有框撤回舊間隙");
assert.ok(oldObservers.every((observer) => observer.disconnected));
const activeTargets = new Set(observers.filter((observer) => !observer.disconnected)
.map((observer) => observer.root));
assert.equal(activeTargets.size, boxes.length);
assert.ok(boxes.every((box) => activeTargets.has(box)));
assert.ok(document.querySelector("jz-hws"), "新產物仍存在");
}
finally { dom.window.close(); }
});