推进 INI 面板 shell control-page contract helper

This commit is contained in:
2026-06-15 05:58:15 +08:00
parent f7de24d4a5
commit 41caecf116
8 changed files with 199 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ import {
controlPageStatusText,
createControlPageSessionLoadState,
createIniPanelLauncherLinkViewModel,
createIniPanelShellControlPageContract,
createIniPanelShellViewModel,
createMachineSessionReadonlyStatus,
createMachineSessionReadonlyStatusApiManifest,
@@ -35,6 +36,7 @@ const requiredShellExports = [
"controlPageStatusText",
"createControlPageSessionLoadState",
"createIniPanelLauncherLinkViewModel",
"createIniPanelShellControlPageContract",
"createIniPanelShellViewModel",
"getIniPanelEntryByHref",
"getVisibleIniPanelEntries",
@@ -90,6 +92,10 @@ assert.deepEqual(
);
assert.deepEqual(createIniPanelShellViewModel().pages, getVisibleIniPanelEntries());
assert.deepEqual(createIniPanelShellViewModel().launcherLinks, createIniPanelLauncherLinkViewModel());
assert.deepEqual(
createIniPanelShellViewModel().controlPage.contract,
createIniPanelShellControlPageContract(),
);
assert.equal(controlPageStatusText({ lastAction: "run-gcode", runStatus: "ok", error: null }), "run-gcode | ok | -");
assert.deepEqual(createControlPageSessionLoadState({ phase: "waiting-panel" }), {
phase: "waiting-panel",

View File

@@ -0,0 +1,88 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import {
createIniPanelShellControlPageContract,
createIniPanelShellViewModel,
createMachineSessionControlPageController,
createMachineSessionReadonlyStatusApiManifest,
loadMachineSessionForControlPageWorkflow,
readMachineSessionReadonlyStatus,
refreshMachineSessionControlPage,
renderMachineSessionControlView,
} from "../../../runtime/ui/ini-panel/ui-shell.js";
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, "../../..");
const shellText = readFileSync(resolve(root, "runtime/ui/ini-panel/ui-shell.js"), "utf8");
const docText = readFileSync(resolve(root, "docs/panel-entry.md"), "utf8");
const expectedMethodNames = [
"createController",
"loadSessionState",
"readStatus",
"refresh",
"renderView",
];
const contract = createIniPanelShellControlPageContract();
const manifest = createMachineSessionReadonlyStatusApiManifest();
assert.deepEqual(contract, {
methodNames: expectedMethodNames,
readonlyStatusApiManifest: manifest,
readonlyStatusApiMethodNames: ["readStatus"],
readonlyStatusApiStatusFields: [
"stateBundle",
"workflowStatus",
"overview",
"controlView",
"report",
"runReadiness",
"run",
"session",
"status",
],
relatedControlPageMethods: [
"loadSessionState",
"readStatus",
"refresh",
"renderView",
],
});
const shellViewModel = createIniPanelShellViewModel();
assert.deepEqual(Object.keys(shellViewModel.controlPage), [
"contract",
"createController",
"loadSessionState",
"readonlyStatusApiManifest",
"readStatus",
"refresh",
"renderView",
]);
assert.deepEqual(shellViewModel.controlPage.contract, contract);
assert.deepEqual(shellViewModel.controlPage.readonlyStatusApiManifest, manifest);
assert.equal(shellViewModel.controlPage.createController, createMachineSessionControlPageController);
assert.equal(shellViewModel.controlPage.loadSessionState, loadMachineSessionForControlPageWorkflow);
assert.equal(shellViewModel.controlPage.readStatus, readMachineSessionReadonlyStatus);
assert.equal(shellViewModel.controlPage.refresh, refreshMachineSessionControlPage);
assert.equal(shellViewModel.controlPage.renderView, renderMachineSessionControlView);
for (const methodName of contract.methodNames) {
assert.equal(typeof shellViewModel.controlPage[methodName], "function");
assert.match(docText, new RegExp(`\\b${methodName}\\b`));
}
for (const fieldName of contract.readonlyStatusApiStatusFields) {
assert.match(docText, new RegExp(`\\b${fieldName}\\b`));
}
assert.match(shellText, /\bexport function createIniPanelShellControlPageContract\b/);
assert.match(docText, /\bcreateIniPanelShellControlPageContract\b/);
assert.match(docText, /\bcontrolPage\.contract\b/);
assert.doesNotMatch(shellText, /\bparseGcode\b|\bcanonicalEvents\b|\btoolTable\b|\bplanner\b/);
console.log("ini_panel_shell_control_page_contract_node_smoke=ok");

View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
node "$ROOT_DIR/tests/ui/node/verify_ini_panel_shell_control_page_contract.mjs"

View File

@@ -4,6 +4,7 @@ import {
INI_PANEL_ENTRIES,
controlPageStatusText,
createIniPanelLauncherLinkViewModel,
createIniPanelShellControlPageContract,
createIniPanelShellViewModel,
createMachineSessionReadonlyStatus,
createMachineSessionReadonlyStatusApiManifest,
@@ -43,6 +44,7 @@ assert.equal(getIniPanelEntryByHref("./index.html")?.id, "edit-run");
assert.equal(typeof createMachineSessionControlPageController, "function");
assert.equal(typeof createMachineSessionReadonlyStatus, "function");
assert.equal(typeof createMachineSessionReadonlyStatusApiManifest, "function");
assert.equal(typeof createIniPanelShellControlPageContract, "function");
assert.equal(typeof loadMachineSessionForControlPageWorkflow, "function");
assert.equal(typeof readMachineSessionReadonlyStatus, "function");
assert.equal(typeof refreshMachineSessionControlPage, "function");
@@ -84,6 +86,7 @@ assert.deepEqual(shellViewModel.pages, [
]);
assert.deepEqual(shellViewModel.launcherLinks, createIniPanelLauncherLinkViewModel());
assert.equal(shellViewModel.controlPage.createController, createMachineSessionControlPageController);
assert.deepEqual(shellViewModel.controlPage.contract, createIniPanelShellControlPageContract());
assert.equal(shellViewModel.controlPage.loadSessionState, loadMachineSessionForControlPageWorkflow);
assert.equal(shellViewModel.controlPage.readonlyStatusApiManifest.apiName, "machine-session-readonly-status");
assert.deepEqual(shellViewModel.controlPage.readonlyStatusApiManifest, createMachineSessionReadonlyStatusApiManifest());

View File

@@ -15,6 +15,7 @@ ROOT_DIR="$(cd "$(dirname "$0")/../../.." && pwd)"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_readonly_status_api.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_entry_manifest.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_ui_shell.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_shell_control_page_contract.sh"
"$ROOT_DIR/tests/ui/node/verify_ini_panel_entry_docs.sh"
echo "ui_node_smokes=ok"