import assert from "node:assert/strict"; import { createGmoccapyCommunicationSummary, gmoccapyCommunicationModel, } from "../../app/src/runtime/gmoccapy-communication-model.js"; const model = gmoccapyCommunicationModel; assert.equal(model.apiName, "web-rtcp-5axis-gmoccapy-communication-model"); assert.equal(model.profileId, "gmoccapy-xyzab"); assert.equal(model.nativeConfigPath.endsWith("gmoccapy_XYZAB.ini"), true); assert.equal(model.cycleTimeMs, 100); assert.equal(model.semanticBoundary, "native_gmoccapy_nml_hal_reference_web_store_runtime_mapping"); assert.deepEqual(model.nativePaths.command.path, ["gmoccapy", "linuxcnc.command()", "NML emcCommand", "milltask"]); assert.equal(model.nativePaths.status.path.includes("linuxcnc.stat()"), true); assert.equal(model.nativePaths.status.path.includes("linuxcnc.error_channel()"), true); assert.equal(model.nativePaths.hal.path.includes("HAL shared memory"), true); assert.equal(model.nativePaths.hardwareButtons.path.includes("_button_pin_changed"), true); assert.equal(model.nativePaths.halPins.path.includes("hal_glib.GPin value_changed"), true); assert.equal(model.nativePaths.remap.path.includes("Python remap prolog/ngc/epilog"), true); assert.equal(model.nativePaths.filePage.path.includes("IconFileSelection1"), true); assert.equal(model.nativePaths.macroPage.path.includes("_on_btn_macro_pressed"), true); assert.equal(model.nativePaths.toolEditorPage.path.includes("tooledit1.reload()"), true); assert.equal(model.nativePaths.nativePages.path.includes("Web implementation matrix"), true); assert.deepEqual(model.webPath.path, ["button", "store.dispatch", "linuxcnc-task-policy", "runtime/status snapshot", "UI/Three.js"]); assert.equal(model.startupStages.length, 9); assert.equal(model.startupStages[0].id, "parse-ini"); assert.equal(model.startupStages.at(-1).id, "postgui"); assert.equal(model.startupStages.at(-1).nativeStep.includes("halcomp.ready()"), true); const actionIds = model.actionMappings.map((mapping) => mapping.actionId); for (const actionId of [ "estop", "estop-reset", "power-on", "mode-manual", "mode-mdi", "mode-auto", "jog", "home", "mdi", "auto-run", "auto-pause", "auto-resume", "abort", "spindle", "coolant", "hardware-button", "hal-pin-input", "hal-settings-unlock", "hal-jog-pin", "hal-tool-measurement", "hal-user-message", "hal-warning-confirm", "file-page", "macro-page", "tool-editor-page", "native-page-diagnostic", ]) { assert.equal(actionIds.includes(actionId), true, `${actionId} missing`); } const runMapping = model.actionMappings.find((mapping) => mapping.actionId === "auto-run"); assert.equal(runMapping.nativeCommand, "command.auto(AUTO_RUN, start_line)"); assert.equal(runMapping.webAction, "RUN"); assert.equal(runMapping.gate.includes("INI loaded"), true); assert.equal(runMapping.gate.includes("runtime ready"), true); const jogMapping = model.actionMappings.find((mapping) => mapping.actionId === "jog"); assert.equal(jogMapping.nativeCommand.includes("JOG_CONTINUOUS"), true); assert.equal(jogMapping.gate, "machine on, manual mode, not running"); const spindleMapping = model.actionMappings.find((mapping) => mapping.actionId === "spindle"); assert.equal(spindleMapping.nativeStatus.includes("spindle.0.forward"), true); assert.equal(spindleMapping.gate.includes("restricted during interpreter"), true); const hardwareButtonMapping = model.actionMappings.find((mapping) => mapping.actionId === "hardware-button"); assert.equal(hardwareButtonMapping.nativeCommand.includes("_button_pin_changed"), true); assert.equal(hardwareButtonMapping.gate.includes("rising-edge"), true); assert.equal(hardwareButtonMapping.gate.includes("insensitive"), true); const halPinMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-pin-input"); assert.equal(halPinMapping.webAction, "GMOCAPY_HAL_PIN"); assert.equal(halPinMapping.nativeCommand.includes("_optional_blocks"), true); assert.equal(halPinMapping.nativeCommand.includes("_on_counts_changed"), true); assert.equal(halPinMapping.nativeCommand.includes("_del_message_changed"), true); assert.equal(halPinMapping.gate.includes("counts require count-enable"), true); assert.equal(halPinMapping.gate.includes("direct-value requires analog-enable"), true); assert.equal(halPinMapping.gate.includes("delete-message pins are rising-edge only"), true); const settingsUnlockMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-settings-unlock"); assert.equal(settingsUnlockMapping.nativeCommand, "_on_unlock_settings_changed"); assert.equal(settingsUnlockMapping.gate.includes("unlock_way"), true); assert.equal(settingsUnlockMapping.gate.includes("HAL unlock"), true); const halJogMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-jog-pin"); assert.equal(halJogMapping.webAction, "GMOCAPY_HAL_PIN jog.axis/jog-inc"); assert.equal(halJogMapping.nativeCommand.includes("_on_pin_jog_changed"), true); assert.equal(halJogMapping.nativeCommand.includes("_on_pin_incr_changed"), true); assert.equal(halJogMapping.gate.includes("press/release level"), true); assert.equal(halJogMapping.gate.includes("increment pins are rising-edge only"), true); const toolMeasurementMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-tool-measurement"); assert.equal(toolMeasurementMapping.nativeCommand.includes("_check_toolmeasurement"), true); assert.equal(toolMeasurementMapping.nativeStatus.includes("probeheight"), true); assert.equal(toolMeasurementMapping.gate.includes("no [TOOLSENSOR]"), true); const userMessageMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-user-message"); assert.equal(userMessageMapping.nativeCommand.includes("_init_user_messages"), true); assert.equal(userMessageMapping.nativeStatus.includes("messages."), true); assert.equal(userMessageMapping.gate.includes("no MESSAGE_*"), true); const warningConfirmMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-warning-confirm"); assert.equal(warningConfirmMapping.nativeCommand.includes("confirm_pin"), true); assert.equal(warningConfirmMapping.gate, "level-polled while warning dialog is active"); const filePageMapping = model.actionMappings.find((mapping) => mapping.actionId === "file-page"); assert.equal(filePageMapping.nativeCommand.includes("IconFileSelection1"), true); assert.equal(filePageMapping.gate.includes("native GTK file chooser"), true); const macroPageMapping = model.actionMappings.find((mapping) => mapping.actionId === "macro-page"); assert.equal(macroPageMapping.webAction, "GMOCAPY_RUN_MACRO"); assert.equal(macroPageMapping.nativeCommand.includes("command.mdi"), true); assert.equal(macroPageMapping.gate.includes("same as RUN_MDI"), true); const toolEditorPageMapping = model.actionMappings.find((mapping) => mapping.actionId === "tool-editor-page"); assert.equal(toolEditorPageMapping.nativeCommand.includes("_show_tooledit_tab"), true); assert.equal(toolEditorPageMapping.gate.includes("writeback is disabled"), true); const nativePageMapping = model.actionMappings.find((mapping) => mapping.actionId === "native-page-diagnostic"); assert.equal(nativePageMapping.webAction, "GMOCAPY_NATIVE_PAGE"); assert.equal(nativePageMapping.gate.includes("do not emit fake GTK"), true); const summary = createGmoccapyCommunicationSummary(model); assert.equal(summary.apiName, "web-rtcp-5axis-gmoccapy-communication-model-summary"); assert.equal(summary.profileId, "gmoccapy-xyzab"); assert.equal(summary.nativePathCount, 10); assert.equal(summary.startupStageCount, 9); assert.equal(summary.actionCount, 26); assert.equal(summary.pagePathCount, 4); assert.equal(summary.postguiAfterHalcompReady, true); assert.equal(summary.hasNativeNmlCommandPath, true); assert.equal(summary.hasNativeHalPath, true); assert.equal(summary.hasNativeHardwareButtonPath, true); assert.equal(summary.hasNativeHalPinInputPath, true); assert.equal(summary.hasWebStorePath, true); assert.equal(summary.semanticBoundary, model.semanticBoundary); console.log("gmoccapy_communication_model_smoke=ok");