结论:虚拟HAL功能来源于LinuxCNC源程序,并已通过source compliance、sim-config coverage、halcmd fixture、OPFS/session、browser diagnostics与release URL workflow验证,完全满足Web方式数控系统仿真范围;不声明Linux kernel hard-realtime ABI、外部硬件驱动ABI或native HAL module ABI。
1338 lines
65 KiB
JavaScript
1338 lines
65 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { dirname, resolve } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import {
|
|
INI_PANEL_ENTRIES,
|
|
analyzeIniRuntimeBoundaries,
|
|
createControlPageBrowserApiManifest,
|
|
createControlPageBrowserApiMethods,
|
|
createControlPageBrowserApiSchema,
|
|
createIniPanelLaunchApiManifest,
|
|
createIniPanelLauncherLinkViewModel,
|
|
createIniPanelShellApiSurfaceInventory,
|
|
createIniPanelShellControlPageContract,
|
|
createIniPanelShellIntegrationManifest,
|
|
createIniPanelShellIntegrationReadiness,
|
|
createIniPanelShellIntegrationSchema,
|
|
createIniPanelShellIntegrationWorkflowPlan,
|
|
createIniPanelShellSessionReadinessWorkflowReport,
|
|
createIniPanelShellViewModel,
|
|
createIniPanelShellWorkflowOverviewContract,
|
|
createIniPanelShellWorkflowOverviewEmbeddingMountDomContract,
|
|
createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
|
VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES,
|
|
VIRTUAL_HAL_COVERAGE_STATES,
|
|
VIRTUAL_HAL_PROJECT_PIN_GROUPS,
|
|
VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS,
|
|
VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES,
|
|
VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS,
|
|
VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES,
|
|
VIRTUAL_HAL_SOURCE_FILES,
|
|
VIRTUAL_HAL_SYSTEM_PIN_FAMILIES,
|
|
VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS,
|
|
applyVirtualHalAction,
|
|
applyVirtualHalPinUpdates,
|
|
applyVirtualHalToInterpSdk,
|
|
createVirtualHalSimulationRuntimeReport,
|
|
createLinuxCncIniSdk,
|
|
createLinuxCncInterpSdk,
|
|
createLinuxCncVirtualHalRuntime,
|
|
createVirtualHalIntegrityReport,
|
|
createMachineSessionSnapshotPayload,
|
|
createVirtualHalSessionPayload,
|
|
createMachineSessionPersistenceDisplayViewModel,
|
|
createMachineSessionPersistenceRenderState,
|
|
createMachineSessionPersistenceSummary,
|
|
createProjectBatchAcceptanceActionPlan,
|
|
createProjectBatchAcceptanceCapabilityMatrix,
|
|
createProjectBatchAcceptanceChecklist,
|
|
createProjectBatchAcceptanceReport,
|
|
createProjectBatchAcceptanceReportJsonWorkflow,
|
|
createProjectBatchAcceptanceReportUrlWorkflowActionPlan,
|
|
createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel,
|
|
createProjectBatchAcceptanceReportValidationActionPlan,
|
|
createProjectBatchAcceptanceReportValidationSummaryViewModel,
|
|
createProjectBatchAcceptanceReportValidation,
|
|
createProjectBatchAcceptanceSummaryViewModel,
|
|
createProjectBatchAcceptanceWorkflow,
|
|
createProjectReleaseBrowserDiagnosticsArtifactValidation,
|
|
createProjectReleaseGateActionPlan,
|
|
createProjectReleaseGateExecutionManifest,
|
|
createProjectReleaseGateExecutionSummaryViewModel,
|
|
createProjectReleaseGateManifest,
|
|
createProjectReleaseGateResultMatrix,
|
|
createProjectReleaseReadinessArtifactJsonWorkflow,
|
|
createProjectReleaseReadinessArtifactUrlWorkflowActionPlan,
|
|
createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
|
|
createProjectReleaseReadinessArtifactValidation,
|
|
createProjectReleaseReadinessArtifactValidationActionPlan,
|
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
|
createProjectReleaseReadinessReport,
|
|
createProjectReleaseReadinessSummaryViewModel,
|
|
createVirtualHalBridgeActionPlan,
|
|
createVirtualHalBridgeReadiness,
|
|
createVirtualHalCommandScriptFixtureReport,
|
|
createVirtualHalPinInventory,
|
|
createVirtualHalPinRegistry,
|
|
createVirtualHalProjectReport,
|
|
createVirtualHalSimConfigSourceCoverageReport,
|
|
createVirtualHalSimulationReplacementReport,
|
|
createVirtualHalState,
|
|
createVirtualHalSourceComplianceReport,
|
|
createVirtualHalSystemCoverageReport,
|
|
createVirtualHalWasmBridgeSnapshot,
|
|
executeVirtualHalCommand,
|
|
executeVirtualHalcmd,
|
|
readVirtualHalPin,
|
|
stepVirtualHalMotionController,
|
|
stepVirtualHalMotion,
|
|
writeVirtualHalPin,
|
|
parseProjectReleaseReadinessArtifactJson,
|
|
createSessionSnapshot,
|
|
defaultMachinePaths,
|
|
gcodeFilenameFromProgramPath,
|
|
gcodeProgramPath,
|
|
getIniPanelEntryByHref,
|
|
getIniPanelEntryManifest,
|
|
getOpfsRoot,
|
|
getVisibleIniPanelEntries,
|
|
isSupportedIniPanelControlPageApiManifest,
|
|
isSupportedIniPanelLaunchApiManifest,
|
|
isSupportedIniPanelShellIntegrationManifest,
|
|
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
|
loadProjectBatchAcceptanceReportUrlWorkflow,
|
|
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness,
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState,
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness,
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState,
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract,
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness,
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState,
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState,
|
|
loadProjectReleaseReadinessArtifactUrlWorkflow,
|
|
loadMachineSessionFromOpfs,
|
|
loadMachineSessionSnapshot,
|
|
loadMachineTextFiles,
|
|
loadMachineToolTableFromOpfs,
|
|
loadTextFile,
|
|
machineFilePaths,
|
|
machineIniPath,
|
|
mountIniPanelShellWorkflowOverviewEmbeddingMountState,
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState,
|
|
normalizeOpfsPath,
|
|
parameterFilePath,
|
|
planIniFileContextStaging,
|
|
planSimConfigStaging,
|
|
readMachineSessionReadiness,
|
|
renderIniPanelShellWorkflowOverviewEmbeddingMountState,
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState,
|
|
restoreMachineParametersFromOpfs,
|
|
restoreVirtualHalStateFromSessionSnapshot,
|
|
saveMachineSessionSnapshot,
|
|
saveMachineTextFiles,
|
|
saveSessionSnapshot,
|
|
saveTextFile,
|
|
sessionSnapshotPath,
|
|
toolTablePath,
|
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
|
|
validateSessionSnapshot,
|
|
} from "../../../runtime/sdk/src/index.js";
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const root = resolve(__dirname, "../../..");
|
|
const sdkIndexText = readFileSync(resolve(root, "runtime/sdk/src/index.js"), "utf8");
|
|
const sdkReadmeText = readFileSync(resolve(root, "runtime/sdk/README.md"), "utf8");
|
|
const sourceManifestText = readFileSync(resolve(root, "tools/source-manifest.txt"), "utf8");
|
|
const trackerText = readFileSync(resolve(root, "../PROJECT_COMPLETION_TRACKER.md"), "utf8");
|
|
|
|
const requiredExports = [
|
|
["createLinuxCncIniSdk", createLinuxCncIniSdk],
|
|
["createLinuxCncInterpSdk", createLinuxCncInterpSdk],
|
|
["createProjectBatchAcceptanceActionPlan", createProjectBatchAcceptanceActionPlan],
|
|
["createProjectBatchAcceptanceCapabilityMatrix", createProjectBatchAcceptanceCapabilityMatrix],
|
|
["createProjectBatchAcceptanceChecklist", createProjectBatchAcceptanceChecklist],
|
|
["createProjectBatchAcceptanceReport", createProjectBatchAcceptanceReport],
|
|
["createProjectBatchAcceptanceReportJsonWorkflow", createProjectBatchAcceptanceReportJsonWorkflow],
|
|
[
|
|
"createProjectBatchAcceptanceReportUrlWorkflowActionPlan",
|
|
createProjectBatchAcceptanceReportUrlWorkflowActionPlan,
|
|
],
|
|
[
|
|
"createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel",
|
|
createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel,
|
|
],
|
|
[
|
|
"createProjectBatchAcceptanceReportValidationActionPlan",
|
|
createProjectBatchAcceptanceReportValidationActionPlan,
|
|
],
|
|
[
|
|
"createProjectBatchAcceptanceReportValidationSummaryViewModel",
|
|
createProjectBatchAcceptanceReportValidationSummaryViewModel,
|
|
],
|
|
["createProjectBatchAcceptanceReportValidation", createProjectBatchAcceptanceReportValidation],
|
|
["createProjectBatchAcceptanceSummaryViewModel", createProjectBatchAcceptanceSummaryViewModel],
|
|
["createProjectBatchAcceptanceWorkflow", createProjectBatchAcceptanceWorkflow],
|
|
["createProjectReleaseBrowserDiagnosticsArtifactValidation", createProjectReleaseBrowserDiagnosticsArtifactValidation],
|
|
["createProjectReleaseGateActionPlan", createProjectReleaseGateActionPlan],
|
|
["createProjectReleaseGateExecutionManifest", createProjectReleaseGateExecutionManifest],
|
|
["createProjectReleaseGateExecutionSummaryViewModel", createProjectReleaseGateExecutionSummaryViewModel],
|
|
["createProjectReleaseGateManifest", createProjectReleaseGateManifest],
|
|
["createProjectReleaseGateResultMatrix", createProjectReleaseGateResultMatrix],
|
|
["createProjectReleaseReadinessArtifactJsonWorkflow", createProjectReleaseReadinessArtifactJsonWorkflow],
|
|
[
|
|
"createProjectReleaseReadinessArtifactUrlWorkflowActionPlan",
|
|
createProjectReleaseReadinessArtifactUrlWorkflowActionPlan,
|
|
],
|
|
[
|
|
"createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel",
|
|
createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
|
|
],
|
|
["createProjectReleaseReadinessArtifactValidation", createProjectReleaseReadinessArtifactValidation],
|
|
[
|
|
"createProjectReleaseReadinessArtifactValidationActionPlan",
|
|
createProjectReleaseReadinessArtifactValidationActionPlan,
|
|
],
|
|
[
|
|
"createProjectReleaseReadinessArtifactValidationSummaryViewModel",
|
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel,
|
|
],
|
|
["createProjectReleaseReadinessReport", createProjectReleaseReadinessReport],
|
|
["createProjectReleaseReadinessSummaryViewModel", createProjectReleaseReadinessSummaryViewModel],
|
|
["applyVirtualHalAction", applyVirtualHalAction],
|
|
["applyVirtualHalPinUpdates", applyVirtualHalPinUpdates],
|
|
["applyVirtualHalToInterpSdk", applyVirtualHalToInterpSdk],
|
|
["createLinuxCncVirtualHalRuntime", createLinuxCncVirtualHalRuntime],
|
|
["createVirtualHalBridgeActionPlan", createVirtualHalBridgeActionPlan],
|
|
["createVirtualHalBridgeReadiness", createVirtualHalBridgeReadiness],
|
|
["createVirtualHalCommandScriptFixtureReport", createVirtualHalCommandScriptFixtureReport],
|
|
["createVirtualHalIntegrityReport", createVirtualHalIntegrityReport],
|
|
["createVirtualHalPinInventory", createVirtualHalPinInventory],
|
|
["createVirtualHalPinRegistry", createVirtualHalPinRegistry],
|
|
["createVirtualHalProjectReport", createVirtualHalProjectReport],
|
|
["createVirtualHalSimConfigSourceCoverageReport", createVirtualHalSimConfigSourceCoverageReport],
|
|
["createVirtualHalSimulationReplacementReport", createVirtualHalSimulationReplacementReport],
|
|
["createVirtualHalSimulationRuntimeReport", createVirtualHalSimulationRuntimeReport],
|
|
["createVirtualHalSourceComplianceReport", createVirtualHalSourceComplianceReport],
|
|
["createVirtualHalState", createVirtualHalState],
|
|
["createVirtualHalSystemCoverageReport", createVirtualHalSystemCoverageReport],
|
|
["createVirtualHalWasmBridgeSnapshot", createVirtualHalWasmBridgeSnapshot],
|
|
["executeVirtualHalCommand", executeVirtualHalCommand],
|
|
["executeVirtualHalcmd", executeVirtualHalcmd],
|
|
["readVirtualHalPin", readVirtualHalPin],
|
|
["stepVirtualHalMotionController", stepVirtualHalMotionController],
|
|
["stepVirtualHalMotion", stepVirtualHalMotion],
|
|
["writeVirtualHalPin", writeVirtualHalPin],
|
|
["parseProjectReleaseReadinessArtifactJson", parseProjectReleaseReadinessArtifactJson],
|
|
[
|
|
"validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson",
|
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson,
|
|
],
|
|
[
|
|
"runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow",
|
|
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness,
|
|
],
|
|
[
|
|
"renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState",
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState,
|
|
],
|
|
[
|
|
"mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState",
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness,
|
|
],
|
|
[
|
|
"renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState",
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
|
|
],
|
|
[
|
|
"mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState",
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness,
|
|
],
|
|
[
|
|
"renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState",
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState,
|
|
],
|
|
[
|
|
"mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState",
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness,
|
|
],
|
|
[
|
|
"renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState",
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState,
|
|
],
|
|
[
|
|
"mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState",
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState,
|
|
],
|
|
[
|
|
"loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl",
|
|
loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl,
|
|
],
|
|
["loadProjectBatchAcceptanceReportUrlWorkflow", loadProjectBatchAcceptanceReportUrlWorkflow],
|
|
["loadProjectReleaseReadinessArtifactUrlWorkflow", loadProjectReleaseReadinessArtifactUrlWorkflow],
|
|
["planIniFileContextStaging", planIniFileContextStaging],
|
|
["planSimConfigStaging", planSimConfigStaging],
|
|
["analyzeIniRuntimeBoundaries", analyzeIniRuntimeBoundaries],
|
|
["getIniPanelEntryManifest", getIniPanelEntryManifest],
|
|
["getIniPanelEntryByHref", getIniPanelEntryByHref],
|
|
["getVisibleIniPanelEntries", getVisibleIniPanelEntries],
|
|
["createIniPanelLauncherLinkViewModel", createIniPanelLauncherLinkViewModel],
|
|
["createMachineSessionPersistenceDisplayViewModel", createMachineSessionPersistenceDisplayViewModel],
|
|
["createMachineSessionPersistenceRenderState", createMachineSessionPersistenceRenderState],
|
|
["createMachineSessionPersistenceSummary", createMachineSessionPersistenceSummary],
|
|
["getOpfsRoot", getOpfsRoot],
|
|
["saveTextFile", saveTextFile],
|
|
["loadTextFile", loadTextFile],
|
|
["machineIniPath", machineIniPath],
|
|
["toolTablePath", toolTablePath],
|
|
["parameterFilePath", parameterFilePath],
|
|
["gcodeProgramPath", gcodeProgramPath],
|
|
["sessionSnapshotPath", sessionSnapshotPath],
|
|
["defaultMachinePaths", defaultMachinePaths],
|
|
["normalizeOpfsPath", normalizeOpfsPath],
|
|
["createMachineSessionSnapshotPayload", createMachineSessionSnapshotPayload],
|
|
["createVirtualHalSessionPayload", createVirtualHalSessionPayload],
|
|
["createSessionSnapshot", createSessionSnapshot],
|
|
["saveSessionSnapshot", saveSessionSnapshot],
|
|
["saveMachineSessionSnapshot", saveMachineSessionSnapshot],
|
|
["loadMachineSessionSnapshot", loadMachineSessionSnapshot],
|
|
["restoreVirtualHalStateFromSessionSnapshot", restoreVirtualHalStateFromSessionSnapshot],
|
|
["validateSessionSnapshot", validateSessionSnapshot],
|
|
["machineFilePaths", machineFilePaths],
|
|
["saveMachineTextFiles", saveMachineTextFiles],
|
|
["loadMachineTextFiles", loadMachineTextFiles],
|
|
["gcodeFilenameFromProgramPath", gcodeFilenameFromProgramPath],
|
|
["restoreMachineParametersFromOpfs", restoreMachineParametersFromOpfs],
|
|
["loadMachineToolTableFromOpfs", loadMachineToolTableFromOpfs],
|
|
["loadMachineSessionFromOpfs", loadMachineSessionFromOpfs],
|
|
["readMachineSessionReadiness", readMachineSessionReadiness],
|
|
["createControlPageBrowserApiSchema", createControlPageBrowserApiSchema],
|
|
["createControlPageBrowserApiManifest", createControlPageBrowserApiManifest],
|
|
["createControlPageBrowserApiMethods", createControlPageBrowserApiMethods],
|
|
["createIniPanelShellControlPageContract", createIniPanelShellControlPageContract],
|
|
["isSupportedIniPanelControlPageApiManifest", isSupportedIniPanelControlPageApiManifest],
|
|
["createIniPanelLaunchApiManifest", createIniPanelLaunchApiManifest],
|
|
["isSupportedIniPanelLaunchApiManifest", isSupportedIniPanelLaunchApiManifest],
|
|
["createIniPanelShellIntegrationSchema", createIniPanelShellIntegrationSchema],
|
|
["createIniPanelShellIntegrationManifest", createIniPanelShellIntegrationManifest],
|
|
["createIniPanelShellIntegrationReadiness", createIniPanelShellIntegrationReadiness],
|
|
["createIniPanelShellIntegrationWorkflowPlan", createIniPanelShellIntegrationWorkflowPlan],
|
|
["isSupportedIniPanelShellIntegrationManifest", isSupportedIniPanelShellIntegrationManifest],
|
|
["createIniPanelShellViewModel", createIniPanelShellViewModel],
|
|
["createIniPanelShellApiSurfaceInventory", createIniPanelShellApiSurfaceInventory],
|
|
["createIniPanelShellSessionReadinessWorkflowReport", createIniPanelShellSessionReadinessWorkflowReport],
|
|
["createIniPanelShellWorkflowOverviewContract", createIniPanelShellWorkflowOverviewContract],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewEmbeddingMountDomContract",
|
|
createIniPanelShellWorkflowOverviewEmbeddingMountDomContract,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness",
|
|
createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract,
|
|
],
|
|
[
|
|
"createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness",
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness,
|
|
],
|
|
[
|
|
"renderIniPanelShellWorkflowOverviewEmbeddingMountState",
|
|
renderIniPanelShellWorkflowOverviewEmbeddingMountState,
|
|
],
|
|
[
|
|
"renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState",
|
|
renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState,
|
|
],
|
|
[
|
|
"mountIniPanelShellWorkflowOverviewEmbeddingMountState",
|
|
mountIniPanelShellWorkflowOverviewEmbeddingMountState,
|
|
],
|
|
[
|
|
"mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState",
|
|
mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState,
|
|
],
|
|
];
|
|
|
|
for (const [name, value] of requiredExports) {
|
|
assert.equal(typeof value, "function", `${name} SDK export drift`);
|
|
assert.match(sdkIndexText, new RegExp(`\\b${name}\\b`));
|
|
assert.match(sdkReadmeText, new RegExp(`\\b${name}\\b`));
|
|
}
|
|
|
|
assert.equal(VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS.includes("lcinterp_hal_set_value"), true);
|
|
assert.equal(VIRTUAL_HAL_PROJECT_PIN_GROUPS.some(({ id }) => id === "axisui"), true);
|
|
assert.equal(VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES.includes("halcmd-setp-sets-net-show-getp-gets"), true);
|
|
assert.equal(VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES.includes("realtime-hal-simulation-replacement"), true);
|
|
assert.equal(VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES.includes("motion-controller-simulation-replacement"), true);
|
|
assert.equal(VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS.includes("linuxcnc-realtime-hal"), true);
|
|
assert.equal(VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS.includes("halcmd"), true);
|
|
assert.equal(VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS.includes("motion-controller"), true);
|
|
assert.equal(VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES.some(({ id }) => id === "pin-signal-net-show"), true);
|
|
assert.equal(VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES.some(({ id }) => id === "load-thread-start-stop"), true);
|
|
assert.equal(VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS.some(({ id }) => id === "axis-foam"), true);
|
|
assert.equal(VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS.some(({ id }) => id === "qtdragon-on-abort"), true);
|
|
assert.equal(VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS
|
|
.find(({ id }) => id === "external-offsets")
|
|
.sourceFiles.includes("linuxcnc/configs/sim/axis/external_offsets/M111"), true);
|
|
assert.equal(VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES["halcmd-simulation-replacement"].sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
|
assert.equal(VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES["motion-controller-simulation-replacement"].sourceFiles.includes("linuxcnc/src/emc/motion/motion.c"), true);
|
|
assert.equal(VIRTUAL_HAL_COVERAGE_STATES.runtimeBoundary, "runtime-boundary");
|
|
assert.equal(VIRTUAL_HAL_SOURCE_FILES.halui, "linuxcnc/src/emc/usr_intf/halui.cc");
|
|
assert.equal(VIRTUAL_HAL_SYSTEM_PIN_FAMILIES.some(({ id }) => id === "iocontrol"), true);
|
|
assert.equal(VIRTUAL_HAL_SYSTEM_PIN_FAMILIES.some(({ id }) => id === "motion-core"), true);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_PROJECT_PIN_GROUPS\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS\b/);
|
|
assert.match(sdkIndexText, /\bVIRTUAL_HAL_SYSTEM_PIN_FAMILIES\b/);
|
|
assert.match(sdkReadmeText, /\bVIRTUAL_HAL_SYSTEM_PIN_FAMILIES\b/);
|
|
assert.match(sdkIndexText, /\bexecuteVirtualHalCommand\b/);
|
|
assert.match(sdkReadmeText, /\bexecuteVirtualHalCommand\b/);
|
|
assert.match(sdkIndexText, /\bexecuteVirtualHalcmd\b/);
|
|
assert.match(sdkReadmeText, /\bexecuteVirtualHalcmd\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalCommandScriptFixtureReport\b/);
|
|
assert.match(sdkIndexText, /\bstepVirtualHalMotion\b/);
|
|
assert.match(sdkReadmeText, /\bstepVirtualHalMotion\b/);
|
|
assert.match(sdkIndexText, /\bstepVirtualHalMotionController\b/);
|
|
assert.match(sdkReadmeText, /\bstepVirtualHalMotionController\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalSimulationRuntimeReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalSimulationRuntimeReport\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalSimulationReplacementReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalSimulationReplacementReport\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalSimConfigSourceCoverageReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalSimConfigSourceCoverageReport\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalSourceComplianceReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalSourceComplianceReport\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalSystemCoverageReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalSystemCoverageReport\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalPinRegistry\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalPinRegistry\b/);
|
|
assert.match(sdkIndexText, /\bcreateVirtualHalIntegrityReport\b/);
|
|
assert.match(sdkReadmeText, /\bcreateVirtualHalIntegrityReport\b/);
|
|
assert.match(sdkIndexText, /\breadVirtualHalPin\b/);
|
|
assert.match(sdkReadmeText, /\breadVirtualHalPin\b/);
|
|
assert.match(sdkIndexText, /\bwriteVirtualHalPin\b/);
|
|
assert.match(sdkReadmeText, /\bwriteVirtualHalPin\b/);
|
|
|
|
let sdkVirtualHal = createVirtualHalState();
|
|
sdkVirtualHal = applyVirtualHalAction(sdkVirtualHal, "estop");
|
|
sdkVirtualHal = applyVirtualHalAction(sdkVirtualHal, "power");
|
|
sdkVirtualHal = applyVirtualHalAction(sdkVirtualHal, "jog", { axis: "x", increment: "0.01 in", direction: 1 });
|
|
sdkVirtualHal = writeVirtualHalPin(sdkVirtualHal, { name: "spindle.0.speed-out", type: "HAL_FLOAT", value: 1800 });
|
|
sdkVirtualHal = writeVirtualHalPin(sdkVirtualHal, { name: "motion.tooloffset.z", type: "HAL_FLOAT", value: 2.5 });
|
|
sdkVirtualHal = applyVirtualHalPinUpdates(sdkVirtualHal, [
|
|
{ name: "halui.tool.number", type: "HAL_U32", value: 7 },
|
|
{ name: "halui.feed-override.value", type: "HAL_FLOAT", value: 0.8 },
|
|
]);
|
|
assert.equal(readVirtualHalPin(sdkVirtualHal, "spindle.0.speed-out").value, 1800);
|
|
assert.equal(readVirtualHalPin(sdkVirtualHal, "motion.tooloffset.z").value, 2.5);
|
|
assert.equal(readVirtualHalPin(sdkVirtualHal, "halui.tool.number").value, 7);
|
|
assert.equal(sdkVirtualHal.overrides.feed, 80);
|
|
const virtualHalSnapshot = createVirtualHalWasmBridgeSnapshot(sdkVirtualHal);
|
|
assert.equal(virtualHalSnapshot.apiName, "linuxcnc-wasm-virtual-hal-bridge-snapshot");
|
|
assert.ok(virtualHalSnapshot.values.some(({ name }) => name === "axisui.jog.x"));
|
|
assert.ok(virtualHalSnapshot.values.some(({ name, value }) => name === "spindle.0.speed-out" && value === 1800));
|
|
assert.ok(virtualHalSnapshot.values.some(({ name, value }) => name === "motion.tooloffset.z" && value === 2.5));
|
|
const virtualHalRegistry = createVirtualHalPinRegistry(sdkVirtualHal);
|
|
assert.equal(virtualHalRegistry.apiName, "linuxcnc-wasm-virtual-hal-pin-registry");
|
|
assert.equal(virtualHalRegistry.byName["spindle.0.speed-out"].value, 1800);
|
|
assert.equal(virtualHalRegistry.byName["motion.tooloffset.z"].value, 2.5);
|
|
assert.equal(virtualHalRegistry.byName["halui.tool.number"].value, 7);
|
|
assert.equal(virtualHalRegistry.rows.some(({ name, writable }) => name === "halui.machine.on" && writable === true), true);
|
|
const virtualHalIntegrity = createVirtualHalIntegrityReport({ halState: sdkVirtualHal, registry: virtualHalRegistry });
|
|
assert.equal(virtualHalIntegrity.apiName, "linuxcnc-wasm-virtual-hal-integrity-report");
|
|
assert.equal(virtualHalIntegrity.complete, true);
|
|
assert.equal(virtualHalIntegrity.missingPins.length, 0);
|
|
const virtualHalInventory = createVirtualHalPinInventory(sdkVirtualHal);
|
|
assert.equal(virtualHalInventory.apiName, "linuxcnc-wasm-virtual-hal-pin-inventory");
|
|
assert.equal(virtualHalInventory.groups.some(({ id, pinCount }) => id === "axisui" && pinCount > 0), true);
|
|
assert.equal(virtualHalInventory.groups.some(({ id, pinCount }) => id === "axis-motion" && pinCount > 0), true);
|
|
assert.equal(virtualHalInventory.groups.some(({ id, pinCount }) => id === "tool" && pinCount > 0), true);
|
|
const virtualHalSystemCoverage = createVirtualHalSystemCoverageReport({ snapshot: virtualHalSnapshot });
|
|
assert.equal(virtualHalSystemCoverage.apiName, "linuxcnc-wasm-virtual-hal-system-coverage-report");
|
|
assert.equal(virtualHalSystemCoverage.complete, true);
|
|
assert.equal(virtualHalSystemCoverage.realtimeHalRuntime, false);
|
|
assert.equal(virtualHalSystemCoverage.sourceFiles.includes("linuxcnc/bin/axis"), true);
|
|
assert.equal(virtualHalSystemCoverage.sourceFiles.includes("linuxcnc/src/emc/usr_intf/halui.cc"), true);
|
|
assert.equal(virtualHalSystemCoverage.sourceFiles.includes("linuxcnc/src/emc/task/taskclass.cc"), true);
|
|
assert.equal(virtualHalSystemCoverage.sourceFiles.includes("linuxcnc/src/emc/motion/motion.c"), true);
|
|
assert.equal(virtualHalSystemCoverage.families.some(({ id, coverage }) => id === "motion-core" && coverage === "runtime-boundary"), true);
|
|
assert.equal(virtualHalSystemCoverage.boundaryRows.some(({ id }) => id === "halui-task"), true);
|
|
const virtualHalBlockedReadiness = createVirtualHalBridgeReadiness({ snapshot: virtualHalSnapshot });
|
|
assert.equal(virtualHalBlockedReadiness.ready, false);
|
|
assert.equal(virtualHalBlockedReadiness.missing.includes("wasm-function-evidence"), true);
|
|
const virtualHalReadyReadiness = createVirtualHalBridgeReadiness({
|
|
snapshot: virtualHalSnapshot,
|
|
availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS,
|
|
});
|
|
assert.equal(virtualHalReadyReadiness.ready, true);
|
|
assert.equal(createVirtualHalBridgeActionPlan(virtualHalReadyReadiness).nextCommand, null);
|
|
const virtualHalReport = createVirtualHalProjectReport({
|
|
halState: sdkVirtualHal,
|
|
availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS,
|
|
});
|
|
assert.equal(virtualHalReport.apiName, "linuxcnc-wasm-virtual-hal-project-report");
|
|
assert.equal(virtualHalReport.ready, true);
|
|
assert.equal(virtualHalReport.pinInventory.pinCount, virtualHalReport.wasmBridgeSnapshot.values.length);
|
|
assert.equal(virtualHalReport.systemCoverage.phase, "covered-with-runtime-boundaries");
|
|
assert.equal(virtualHalReport.systemCoverage.unclassifiedSnapshotPins.length, 0);
|
|
assert.equal(virtualHalReport.pinRegistry.byName["spindle.0.speed-out"].value, 1800);
|
|
assert.equal(virtualHalReport.integrity.complete, true);
|
|
const virtualHalRuntime = createLinuxCncVirtualHalRuntime(sdkVirtualHal);
|
|
assert.equal(virtualHalRuntime.getProjectReport({ availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS }).ready, true);
|
|
const virtualHalcmdResult = virtualHalRuntime.executeHalCommand(`
|
|
loadrt trivkins
|
|
addf motion-controller servo-thread
|
|
net x-pos axis.x.pos-cmd joint.0.pos-fb
|
|
setp axis.x.pos-cmd 2.5
|
|
sets x-pos 1.25
|
|
show pin axis.x.*
|
|
motion-step x=2.0
|
|
`);
|
|
assert.equal(virtualHalcmdResult.apiName, "linuxcnc-wasm-virtual-halcmd-result");
|
|
assert.equal(virtualHalcmdResult.ok, true);
|
|
assert.equal(virtualHalcmdResult.rows.some(({ action }) => action === "net"), true);
|
|
assert.equal(virtualHalRuntime.getState().hal.signals["x-pos"].value, 1.25);
|
|
assert.equal(virtualHalRuntime.getState().hal.nets["x-pos"].includes("axis.x.pos-cmd"), true);
|
|
assert.equal(virtualHalRuntime.getState().hal.loadedComponents.some(({ component }) => component === "trivkins"), true);
|
|
assert.equal(virtualHalRuntime.getState().hal.functions.some(({ name }) => name === "motion-controller"), true);
|
|
assert.ok(virtualHalRuntime.getState().position.x > 1.25);
|
|
const directHalcmdResult = executeVirtualHalCommand(virtualHalRuntime.getState(), "getp axis.x.pos-cmd\ngets x-pos");
|
|
assert.equal(directHalcmdResult.ok, true);
|
|
assert.match(directHalcmdResult.output, /axis\.x\.pos-cmd/);
|
|
assert.match(directHalcmdResult.output, /x-pos/);
|
|
const directHalcmdAliasResult = executeVirtualHalcmd(virtualHalRuntime.getState(), "setp halui.machine.on 1\nshow pin halui.machine.*");
|
|
assert.equal(directHalcmdAliasResult.ok, true);
|
|
assert.equal(directHalcmdAliasResult.apiName, "linuxcnc-wasm-virtual-halcmd-result");
|
|
assert.match(directHalcmdAliasResult.output, /halui\.machine\.is-on/);
|
|
const commandScriptFixtureReport = createVirtualHalCommandScriptFixtureReport({ halState: virtualHalRuntime.getState() });
|
|
assert.equal(commandScriptFixtureReport.apiName, "linuxcnc-wasm-virtual-hal-command-script-fixture-report");
|
|
assert.equal(commandScriptFixtureReport.complete, true);
|
|
assert.equal(commandScriptFixtureReport.webSimulationSatisfied, true);
|
|
assert.equal(commandScriptFixtureReport.missingActions.length, 0);
|
|
assert.equal(commandScriptFixtureReport.missingFixtures.length, 0);
|
|
assert.equal(commandScriptFixtureReport.sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
|
for (const action of ["setp", "sets", "net", "show", "getp", "gets", "loadrt", "loadusr", "addf", "start", "stop"]) {
|
|
assert.equal(commandScriptFixtureReport.coveredActions.includes(action), true);
|
|
}
|
|
assert.equal(virtualHalRuntime.getCommandScriptFixtureReport().complete, true);
|
|
const steppedVirtualHal = stepVirtualHalMotion(virtualHalRuntime.getState(), {
|
|
target: { x: 3 },
|
|
maxVelocity: 10,
|
|
dt: 0.1,
|
|
});
|
|
assert.ok(steppedVirtualHal.position.x > virtualHalRuntime.getState().position.x);
|
|
const motionControllerStep = stepVirtualHalMotionController(virtualHalRuntime.getState(), {
|
|
target: { x: 4 },
|
|
maxVelocity: 10,
|
|
dt: 0.1,
|
|
cycleCount: 3,
|
|
});
|
|
assert.equal(motionControllerStep.apiName, "linuxcnc-wasm-virtual-motion-controller-step");
|
|
assert.equal(motionControllerStep.ok, true);
|
|
assert.ok(motionControllerStep.cycleCount >= 1);
|
|
assert.ok(motionControllerStep.state.position.x > virtualHalRuntime.getState().position.x);
|
|
const simulationRuntimeReport = virtualHalRuntime.getSimulationRuntimeReport();
|
|
assert.equal(simulationRuntimeReport.apiName, "linuxcnc-wasm-virtual-hal-simulation-runtime-report");
|
|
assert.equal(simulationRuntimeReport.replacesHostRuntimeForSimulation, true);
|
|
assert.deepEqual(simulationRuntimeReport.replacementTargets, VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS);
|
|
assert.equal(simulationRuntimeReport.hardRealtime, false);
|
|
assert.deepEqual(simulationRuntimeReport.hostRequirements, []);
|
|
assert.equal(simulationRuntimeReport.capabilities.includes("servo-period-motion-step"), true);
|
|
assert.equal(createVirtualHalSimulationRuntimeReport(virtualHalRuntime.getState()).ready, true);
|
|
const runtimeMotionControllerStep = virtualHalRuntime.stepMotionController({
|
|
target: { x: 4.5 },
|
|
maxVelocity: 20,
|
|
dt: 0.1,
|
|
cycleCount: 2,
|
|
});
|
|
assert.equal(runtimeMotionControllerStep.apiName, "linuxcnc-wasm-virtual-motion-controller-step");
|
|
assert.ok(virtualHalRuntime.getState().position.x > motionControllerStep.state.position.x);
|
|
const replacementReport = createVirtualHalSimulationReplacementReport(virtualHalRuntime.getState());
|
|
assert.equal(replacementReport.apiName, "linuxcnc-wasm-virtual-hal-simulation-replacement-report");
|
|
assert.equal(replacementReport.ready, true);
|
|
assert.equal(replacementReport.replacesHostRuntimeForSimulation, true);
|
|
assert.equal(replacementReport.replacements["linuxcnc-realtime-hal"].ready, true);
|
|
assert.equal(replacementReport.replacements.halcmd.ready, true);
|
|
assert.equal(replacementReport.replacements["motion-controller"].ready, true);
|
|
assert.equal(replacementReport.hardRealtime, false);
|
|
assert.equal(replacementReport.sourceCompliance.complete, true);
|
|
assert.equal(replacementReport.sourceCompliance.webSimulationSatisfied, true);
|
|
assert.equal(replacementReport.simConfigSourceCoverage.complete, true);
|
|
assert.equal(replacementReport.commandScriptFixtures.complete, true);
|
|
assert.equal(virtualHalRuntime.getSimulationReplacementReport().ready, true);
|
|
const simConfigSourceCoverageReport = createVirtualHalSimConfigSourceCoverageReport({ manifestText: sourceManifestText });
|
|
assert.equal(simConfigSourceCoverageReport.apiName, "linuxcnc-wasm-virtual-hal-sim-config-source-coverage-report");
|
|
assert.equal(simConfigSourceCoverageReport.complete, true);
|
|
assert.equal(simConfigSourceCoverageReport.webSimulationSatisfied, true);
|
|
assert.equal(simConfigSourceCoverageReport.manifestChecked, true);
|
|
assert.equal(simConfigSourceCoverageReport.missingTargets.length, 0);
|
|
assert.equal(simConfigSourceCoverageReport.missingCapabilities.length, 0);
|
|
assert.equal(simConfigSourceCoverageReport.sourceFiles.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini"), true);
|
|
assert.equal(simConfigSourceCoverageReport.sourceFiles.includes("linuxcnc/configs/sim/qtdragon/qtdragon_xyz/on_abort.ngc"), true);
|
|
assert.equal(simConfigSourceCoverageReport.rows.every(({ sourceDerived }) => sourceDerived), true);
|
|
assert.equal(virtualHalRuntime.getSimConfigSourceCoverageReport({ manifestText: sourceManifestText }).complete, true);
|
|
const sourceComplianceReport = createVirtualHalSourceComplianceReport({ halState: virtualHalRuntime.getState() });
|
|
assert.equal(sourceComplianceReport.apiName, "linuxcnc-wasm-virtual-hal-source-compliance-report");
|
|
assert.equal(sourceComplianceReport.complete, true);
|
|
assert.equal(sourceComplianceReport.webSimulationSatisfied, true);
|
|
assert.equal(sourceComplianceReport.missingCapabilitySources.length, 0);
|
|
assert.equal(sourceComplianceReport.missingFamilySources.length, 0);
|
|
assert.equal(sourceComplianceReport.targetRows.every(({ sourceDerived }) => sourceDerived), true);
|
|
assert.equal(sourceComplianceReport.capabilityRows.every(({ sourceDerived }) => sourceDerived), true);
|
|
assert.equal(sourceComplianceReport.familyRows.every(({ sourceDerived }) => sourceDerived), true);
|
|
assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/bin/axis"), true);
|
|
assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
|
assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/src/emc/motion/motion.c"), true);
|
|
assert.equal(sourceComplianceReport.sourceFiles.includes("linuxcnc/configs/sim/axis/foam/axis_foam.ini"), true);
|
|
assert.equal(sourceComplianceReport.simConfigSourceCoverage.complete, true);
|
|
assert.equal(sourceComplianceReport.commandScriptFixtures.complete, true);
|
|
assert.equal(virtualHalRuntime.getSourceComplianceReport().complete, true);
|
|
const virtualHalSessionPayload = createVirtualHalSessionPayload(virtualHalRuntime.getState(), {
|
|
simConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
commandScriptFixtures: commandScriptFixtureReport,
|
|
});
|
|
assert.equal(virtualHalSessionPayload.apiName, "linuxcnc-wasm-virtual-hal-session-payload");
|
|
assert.equal(virtualHalSessionPayload.state.hal.signals["x-pos"].value, 1.25);
|
|
assert.equal(virtualHalSessionPayload.sourceCompliance.complete, true);
|
|
assert.equal(virtualHalSessionPayload.simConfigSourceCoverage.complete, true);
|
|
assert.equal(virtualHalSessionPayload.commandScriptFixtures.complete, true);
|
|
const virtualHalSessionSnapshot = createSessionSnapshot(
|
|
"sdk-virtual-hal-session",
|
|
createMachineSessionSnapshotPayload("sdk-mill", {
|
|
gcodeFilename: "demo.ngc",
|
|
virtualHal: virtualHalSessionPayload,
|
|
}),
|
|
{ createdAt: "2026-06-17T00:00:00.000Z" },
|
|
);
|
|
assert.equal(
|
|
restoreVirtualHalStateFromSessionSnapshot(virtualHalSessionSnapshot).hal.nets["x-pos"].includes("axis.x.pos-cmd"),
|
|
true,
|
|
);
|
|
const browserDiagnosticsArtifactValidation = createProjectReleaseBrowserDiagnosticsArtifactValidation({
|
|
apiName: "real-browser-simulation-diagnostics-artifact",
|
|
virtualHal: virtualHalRuntime.getState(),
|
|
virtualHalSimulationReplacement: replacementReport,
|
|
virtualHalSourceCompliance: sourceComplianceReport,
|
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
virtualHalCommandScriptFixtures: commandScriptFixtureReport,
|
|
});
|
|
assert.equal(browserDiagnosticsArtifactValidation.apiName, "project-release-browser-diagnostics-artifact-validation");
|
|
assert.equal(browserDiagnosticsArtifactValidation.ready, true);
|
|
assert.equal(browserDiagnosticsArtifactValidation.sourceComplianceReady, true);
|
|
assert.equal(browserDiagnosticsArtifactValidation.simConfigSourceCoverageReady, true);
|
|
assert.equal(browserDiagnosticsArtifactValidation.commandScriptFixturesReady, true);
|
|
assert.equal(browserDiagnosticsArtifactValidation.sourceFiles.includes("linuxcnc/src/hal/utils/halcmd_commands.cc"), true);
|
|
const runtimeProjectReport = virtualHalRuntime.getProjectReport({ availableFunctions: VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS });
|
|
assert.equal(runtimeProjectReport.simulationRuntime.replacesHostRuntimeForSimulation, true);
|
|
assert.equal(runtimeProjectReport.systemCoverage.unclassifiedSnapshotPins.length, 0);
|
|
const fakeInterpApplyResult = applyVirtualHalToInterpSdk(
|
|
{
|
|
applyVirtualHalSnapshot(snapshot, options) {
|
|
return {
|
|
apiName: "fake-virtual-hal-apply-result",
|
|
applied: snapshot.values.length,
|
|
reset: options.reset !== false,
|
|
};
|
|
},
|
|
},
|
|
sdkVirtualHal,
|
|
{ reset: false },
|
|
);
|
|
assert.equal(fakeInterpApplyResult.apiName, "fake-virtual-hal-apply-result");
|
|
assert.equal(fakeInterpApplyResult.reset, false);
|
|
|
|
assert.equal(machineIniPath("sdk-mill"), "linuxcnc/machines/sdk-mill/machine.ini");
|
|
assert.deepEqual(defaultMachinePaths("sdk-mill"), machineFilePaths("sdk-mill"));
|
|
assert.equal(gcodeProgramPath("demo.ngc"), "linuxcnc/gcode/demo.ngc");
|
|
assert.equal(sessionSnapshotPath("sdk-session"), "linuxcnc/sessions/sdk-session/snapshot.json");
|
|
assert.equal(normalizeOpfsPath("linuxcnc/machines/sdk-mill/tool.tbl"), "linuxcnc/machines/sdk-mill/tool.tbl");
|
|
assert.equal(gcodeFilenameFromProgramPath("linuxcnc/gcode/demo.ngc"), "demo.ngc");
|
|
|
|
const releaseReadinessWaiting = createProjectReleaseReadinessReport();
|
|
const batchCapabilityMatrix = createProjectBatchAcceptanceCapabilityMatrix({
|
|
capabilities: [
|
|
{
|
|
id: "sdk-surface-api",
|
|
type: "api",
|
|
label: "SDK surface API",
|
|
},
|
|
],
|
|
});
|
|
assert.equal(batchCapabilityMatrix.ready, true);
|
|
assert.equal(batchCapabilityMatrix.countsByType.api, 1);
|
|
const batchAcceptanceWorkflow = createProjectBatchAcceptanceWorkflow({
|
|
batchId: "sdk-surface-batch",
|
|
capabilities: [
|
|
{
|
|
id: "sdk-surface-api",
|
|
type: "api",
|
|
label: "SDK surface API",
|
|
},
|
|
],
|
|
observedOutputs: ["project_batch_acceptance_workflow_node_smoke=ok"],
|
|
});
|
|
assert.equal(batchAcceptanceWorkflow.ready, true);
|
|
assert.equal(batchAcceptanceWorkflow.capabilityTypes[0], "api");
|
|
assert.equal(
|
|
createProjectBatchAcceptanceSummaryViewModel(batchAcceptanceWorkflow).statusLine,
|
|
"Ready: Batch acceptance evidence complete",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceActionPlan(batchAcceptanceWorkflow).shellScript,
|
|
"# Project batch acceptance workflow is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceChecklist({ workflow: batchAcceptanceWorkflow }).rows[0].value,
|
|
"pass: api",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceReport({
|
|
batchId: "sdk-surface-batch",
|
|
capabilities: batchAcceptanceWorkflow.capabilities,
|
|
observedOutputs: ["project_batch_acceptance_workflow_node_smoke=ok"],
|
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
}).rows.find(({ id }) => id === "checklist")?.value,
|
|
"4/4 passed",
|
|
);
|
|
const batchAcceptanceReport = createProjectBatchAcceptanceReport({
|
|
batchId: "sdk-surface-batch",
|
|
capabilities: batchAcceptanceWorkflow.capabilities,
|
|
observedOutputs: ["project_batch_acceptance_workflow_node_smoke=ok"],
|
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
});
|
|
assert.equal(batchAcceptanceReport.virtualHalSimConfigSourceCoverage.complete, true);
|
|
assert.equal(createProjectBatchAcceptanceReportValidation(batchAcceptanceReport).ready, true);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceReportValidationSummaryViewModel(
|
|
createProjectBatchAcceptanceReportValidation(batchAcceptanceReport),
|
|
).statusLine,
|
|
"Ready: Batch acceptance report evidence complete",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceReportValidationActionPlan(
|
|
createProjectBatchAcceptanceReportValidation(batchAcceptanceReport),
|
|
).shellScript,
|
|
"# Project batch acceptance report validation is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceReportJsonWorkflow({
|
|
reportJson: JSON.stringify(batchAcceptanceReport),
|
|
}).ready,
|
|
true,
|
|
);
|
|
const batchAcceptanceReportUrlWorkflow = await loadProjectBatchAcceptanceReportUrlWorkflow({
|
|
reportUrl: "/project-batch-acceptance.json",
|
|
fetchRef: async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
text: async () => JSON.stringify(batchAcceptanceReport),
|
|
}),
|
|
});
|
|
assert.equal(batchAcceptanceReportUrlWorkflow.ready, true);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel(
|
|
batchAcceptanceReportUrlWorkflow,
|
|
).statusLine,
|
|
"Ready: Batch report URL workflow complete",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceReportUrlWorkflowActionPlan(
|
|
batchAcceptanceReportUrlWorkflow,
|
|
).shellScript,
|
|
"# Project batch acceptance report URL workflow is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
(await loadProjectBatchAcceptanceReportUrlWorkflow({
|
|
reportUrl: "/missing-project-batch-acceptance.json",
|
|
fetchRef: async () => ({ ok: false, status: 404, text: async () => "" }),
|
|
})).missing[0],
|
|
"report-fetch",
|
|
);
|
|
assert.equal(
|
|
createProjectBatchAcceptanceActionPlan(createProjectBatchAcceptanceWorkflow()).nextCommand,
|
|
"wasm-port/tests/sdk/node/verify_project_batch_acceptance_workflow.sh",
|
|
);
|
|
assert.equal(releaseReadinessWaiting.apiName, "project-release-readiness-report");
|
|
assert.equal(releaseReadinessWaiting.ready, false);
|
|
assert.deepEqual(releaseReadinessWaiting.missing, ["project-release-gate", "virtual-hal-sim-config-source-coverage"]);
|
|
assert.equal(releaseReadinessWaiting.simConfigInventory.unexpectedFail, 0);
|
|
assert.deepEqual(releaseReadinessWaiting.promotedBlockedFamilies, []);
|
|
assert.equal(releaseReadinessWaiting.gateActionPlan.apiName, "project-release-gate-action-plan");
|
|
assert.equal(releaseReadinessWaiting.gateActionPlan.pendingCount, createProjectReleaseGateManifest().gateCount);
|
|
assert.equal(releaseReadinessWaiting.gateActionPlan.nextGateId, "diff-check");
|
|
assert.equal(
|
|
releaseReadinessWaiting.rows.find(({ id }) => id === "blocked-runtime-families")?.value,
|
|
"L4-USER-M-PROCESS, L4-TOOL-DB, L4-PYTHON-REMAP",
|
|
);
|
|
const releaseReadinessReady = createProjectReleaseReadinessReport({
|
|
observedOutputs: ["project_release_gate=ok"],
|
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
});
|
|
assert.equal(releaseReadinessReady.ready, true);
|
|
assert.equal(releaseReadinessReady.releaseGate.passed, true);
|
|
assert.equal(releaseReadinessReady.virtualHalSimConfigSourceCoverageReady, true);
|
|
assert.deepEqual(releaseReadinessReady.gateManifest, createProjectReleaseGateManifest());
|
|
assert.equal(releaseReadinessReady.gateResultMatrix.rows.length, createProjectReleaseGateManifest().gateCount);
|
|
assert.equal(createProjectReleaseGateActionPlan({
|
|
gateResultMatrix: releaseReadinessReady.gateResultMatrix,
|
|
}).ready, false);
|
|
assert.equal(createProjectReleaseGateActionPlan({
|
|
gateResults: Object.fromEntries(createProjectReleaseGateManifest().gateIds.map((id) => [id, true])),
|
|
}).shellScript, "# Project release gates are already marked passed.\n");
|
|
assert.equal(createProjectReleaseReadinessSummaryViewModel(releaseReadinessReady).statusLine, "Ready: No blocking reasons");
|
|
assert.equal(
|
|
createProjectReleaseReadinessSummaryViewModel(releaseReadinessReady).rows.find(({ id }) => id === "axis-screenshot-artifacts")?.value,
|
|
"not captured",
|
|
);
|
|
const releaseReadinessWithScreenshots = createProjectReleaseReadinessReport({
|
|
gateResults: Object.fromEntries(createProjectReleaseGateManifest().gateIds.map((id) => [id, true])),
|
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
axisScreenshotArtifacts: ["desktop-preview", "desktop-dro", "mobile-preview", "mobile-mdi"].map((viewportName) => ({
|
|
apiName: "real-browser-simulation-axis-screenshot-artifact",
|
|
artifactVersion: 1,
|
|
viewportName,
|
|
windowSize: viewportName.startsWith("mobile") ? "390,920" : "1280,900",
|
|
query: viewportName.endsWith("dro") ? "?axis_right=dro" : "",
|
|
screenshotBytes: 20000,
|
|
validatedBy: "browser_real_simulation_page_smoke",
|
|
fullDiagnosticsApiName: "real-browser-simulation-diagnostics-artifact",
|
|
fullDiagnosticsPath: `/tmp/${viewportName}-full.json`,
|
|
previewRenderer: "threejs",
|
|
previewViewMode: viewportName.endsWith("dro") ? "top" : "top",
|
|
threeReady: true,
|
|
threePathPoints: 3,
|
|
screenshotPath: `/tmp/${viewportName}.png`,
|
|
diagnosticsPath: `/tmp/${viewportName}.json`,
|
|
})),
|
|
});
|
|
assert.equal(releaseReadinessWithScreenshots.ready, true);
|
|
assert.equal(releaseReadinessWithScreenshots.axisScreenshotArtifactSummary.ready, true);
|
|
assert.equal(releaseReadinessWithScreenshots.axisScreenshotArtifactSummary.artifactCount, 4);
|
|
assert.equal(
|
|
createProjectReleaseReadinessSummaryViewModel(releaseReadinessWithScreenshots).rows.find(({ id }) => id === "axis-screenshot-artifacts")?.value,
|
|
"4/4 captured",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseGateResultMatrix({
|
|
observedOutputs: ["project_release_gate=ok"],
|
|
}).rows.find(({ id }) => id === "project-release-gate")?.passed,
|
|
true,
|
|
);
|
|
const releaseReadinessArtifact = parseProjectReleaseReadinessArtifactJson(JSON.stringify(createProjectReleaseReadinessReport({
|
|
gateResults: Object.fromEntries(createProjectReleaseGateManifest().gateIds.map((id) => [id, true])),
|
|
virtualHalSimConfigSourceCoverage: simConfigSourceCoverageReport,
|
|
})));
|
|
assert.equal(releaseReadinessArtifact.apiName, "project-release-readiness-report");
|
|
const releaseReadinessArtifactValidation = createProjectReleaseReadinessArtifactValidation(releaseReadinessArtifact);
|
|
assert.deepEqual(releaseReadinessArtifactValidation, {
|
|
apiName: "project-release-readiness-artifact-validation",
|
|
validationVersion: 1,
|
|
phase: "ready",
|
|
ready: true,
|
|
missing: [],
|
|
artifactApiName: "project-release-readiness-report",
|
|
artifactVersion: 1,
|
|
gateCount: createProjectReleaseGateManifest().gateCount,
|
|
expectedGateCount: createProjectReleaseGateManifest().gateCount,
|
|
expectedGateIds: createProjectReleaseGateManifest().gateIds,
|
|
gateManifestReady: true,
|
|
gateExecutionManifestReady: true,
|
|
gateExecutionSummaryReady: true,
|
|
gateResultMatrixReady: true,
|
|
gateActionPlanReady: true,
|
|
virtualHalSimConfigSourceCoverageReady: true,
|
|
axisScreenshotArtifactSummaryReady: true,
|
|
axisScreenshotArtifactCount: 0,
|
|
blockedRuntimeFamilies: [
|
|
"L4-USER-M-PROCESS",
|
|
"L4-TOOL-DB",
|
|
"L4-PYTHON-REMAP",
|
|
],
|
|
rows: [
|
|
{
|
|
id: "artifact",
|
|
label: "Readiness artifact",
|
|
value: "project-release-readiness-report",
|
|
},
|
|
{
|
|
id: "project-release-gate",
|
|
label: "Project release gate",
|
|
value: "passed",
|
|
},
|
|
{
|
|
id: "gate-manifest",
|
|
label: "Gate manifest",
|
|
value: "ready",
|
|
},
|
|
{
|
|
id: "gate-execution-manifest",
|
|
label: "Gate execution manifest",
|
|
value: "ready",
|
|
},
|
|
{
|
|
id: "gate-execution-summary",
|
|
label: "Gate execution summary",
|
|
value: "ready",
|
|
},
|
|
{
|
|
id: "gate-result-matrix",
|
|
label: "Gate result matrix",
|
|
value: "ready",
|
|
},
|
|
{
|
|
id: "gate-action-plan",
|
|
label: "Gate action plan",
|
|
value: "ready",
|
|
},
|
|
{
|
|
id: "virtual-hal-sim-config-source-coverage",
|
|
label: "Virtual HAL sim-config source coverage",
|
|
value: "ready",
|
|
},
|
|
{
|
|
id: "axis-screenshot-artifacts",
|
|
label: "AXIS screenshot artifacts",
|
|
value: "not captured",
|
|
},
|
|
{
|
|
id: "validation",
|
|
label: "Artifact validation",
|
|
value: "ready",
|
|
},
|
|
],
|
|
});
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactValidationSummaryViewModel(
|
|
releaseReadinessArtifactValidation,
|
|
).statusLine,
|
|
"Ready: Artifact evidence complete",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactValidationActionPlan(releaseReadinessArtifactValidation).shellScript,
|
|
"# Project release readiness artifact validation is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactValidationActionPlan(createProjectReleaseReadinessArtifactValidation({}))
|
|
.nextCommand,
|
|
"wasm-port/tests/host/verify_project_release_gate.sh",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactJsonWorkflow({
|
|
artifactJson: JSON.stringify(releaseReadinessArtifact),
|
|
}).summaryViewModel.statusLine,
|
|
"Ready: Artifact evidence complete",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactJsonWorkflow({ artifactJson: "not-json" }).parsed,
|
|
false,
|
|
);
|
|
assert.equal(
|
|
(await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
|
artifactUrl: "/project-release-readiness.json",
|
|
fetchRef: async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
text: async () => JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
})).summaryViewModel.statusLine,
|
|
"Ready: Artifact evidence complete",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel(
|
|
await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
|
artifactUrl: "/project-release-readiness.json",
|
|
fetchRef: async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
text: async () => JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
}),
|
|
).statusLine,
|
|
"Ready: Artifact URL workflow complete",
|
|
);
|
|
assert.equal(
|
|
createProjectReleaseReadinessArtifactUrlWorkflowActionPlan(
|
|
await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
|
artifactUrl: "/project-release-readiness.json",
|
|
fetchRef: async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
text: async () => JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
}),
|
|
).shellScript,
|
|
"# Project release readiness artifact URL workflow is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
(await loadProjectReleaseReadinessArtifactUrlWorkflow({
|
|
artifactUrl: "/missing.json",
|
|
fetchRef: async () => ({ ok: false, status: 404, text: async () => "" }),
|
|
})).missing[0],
|
|
"artifact-fetch",
|
|
);
|
|
assert.deepEqual(
|
|
createProjectReleaseReadinessArtifactValidation({}).missing,
|
|
[
|
|
"apiName",
|
|
"reportVersion",
|
|
"phase",
|
|
"ready",
|
|
"missing",
|
|
"releaseGate.command",
|
|
"releaseGate.passed",
|
|
"releaseGate.expectedOutput",
|
|
"simConfigInventory.executed",
|
|
"simConfigInventory.passed",
|
|
"simConfigInventory.skipped",
|
|
"simConfigInventory.unexpectedFail",
|
|
"virtualHalSimConfigSourceCoverage",
|
|
"blockedRuntimeFamilies",
|
|
"gateManifest",
|
|
"gateExecutionManifest",
|
|
"gateExecutionSummaryViewModel",
|
|
"gateResultMatrix",
|
|
"gateActionPlan",
|
|
"gates.length",
|
|
"gates.passed",
|
|
"rows.project-release-gate",
|
|
],
|
|
);
|
|
assert.equal(
|
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(JSON.stringify(releaseReadinessArtifact)).ready,
|
|
true,
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan(
|
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(JSON.stringify(releaseReadinessArtifact)),
|
|
).shellScript,
|
|
"# Project release readiness artifact validation is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow({
|
|
artifactJson: JSON.stringify(releaseReadinessArtifact),
|
|
}).statusLine,
|
|
"Ready: Artifact JSON workflow complete",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel(
|
|
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow({
|
|
artifactJson: JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
).statusLine,
|
|
"Ready: Artifact JSON workflow complete",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan(
|
|
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow({
|
|
artifactJson: JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
).nextCommand,
|
|
null,
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel(
|
|
runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow({
|
|
artifactJson: JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
),
|
|
).dataset.handoffScope,
|
|
"workflow-overview-release-readiness-artifact-json-workflow",
|
|
);
|
|
const releaseReadinessArtifactUrlWorkflow = await loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl({
|
|
artifactUrl: "/project-release-readiness.json",
|
|
fetchRef: async () => ({
|
|
ok: true,
|
|
status: 200,
|
|
text: async () => JSON.stringify(releaseReadinessArtifact),
|
|
}),
|
|
});
|
|
assert.equal(releaseReadinessArtifactUrlWorkflow.ready, true);
|
|
assert.equal(
|
|
releaseReadinessArtifactUrlWorkflow.validationSummaryViewModel.statusLine,
|
|
"Ready: Artifact evidence complete",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel(
|
|
releaseReadinessArtifactUrlWorkflow,
|
|
).statusLine,
|
|
"Ready: Artifact URL workflow complete",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan(
|
|
releaseReadinessArtifactUrlWorkflow,
|
|
).shellScript,
|
|
"# Project release readiness artifact URL workflow is already ready.\n",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel(
|
|
validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson(JSON.stringify(releaseReadinessArtifact)),
|
|
),
|
|
).dataset.handoffScope,
|
|
"workflow-overview-release-readiness-artifact",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract().selectors.rows,
|
|
"[data-workflow-overview-release-readiness-artifact-rows]",
|
|
);
|
|
assert.equal(createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness().ready, false);
|
|
assert.equal(
|
|
createProjectReleaseReadinessReport({
|
|
observedOutputs: ["project_release_gate=ok"],
|
|
promotedRuntimeFamilies: ["L4-TOOL-DB"],
|
|
}).missing.includes("blocked-runtime-families"),
|
|
true,
|
|
);
|
|
|
|
assert.deepEqual(getIniPanelEntryManifest(), INI_PANEL_ENTRIES);
|
|
assert.deepEqual(getVisibleIniPanelEntries(), INI_PANEL_ENTRIES);
|
|
assert.deepEqual(getIniPanelEntryByHref("./control-page.html"), {
|
|
id: "control-view",
|
|
title: "Open read-only control view",
|
|
href: "./control-page.html",
|
|
});
|
|
assert.deepEqual(createIniPanelLauncherLinkViewModel(), [
|
|
{
|
|
entryId: "edit-run",
|
|
href: "./index.html",
|
|
label: "Open edit and run panel",
|
|
},
|
|
{
|
|
entryId: "control-view",
|
|
href: "./control-page.html",
|
|
label: "Open read-only control view",
|
|
},
|
|
{
|
|
entryId: "workflow-overview",
|
|
href: "./workflow-overview.html",
|
|
label: "Open shell handoff overview",
|
|
},
|
|
]);
|
|
assert.equal(
|
|
createMachineSessionPersistenceSummary({
|
|
state: {
|
|
badges: { opfs: "OPFS: ready" },
|
|
fields: { sessionSnapshot: "sdk-session/snapshot.json", sessionIni: "/work/session-machine.ini" },
|
|
sessionLoad: { iniWasmPath: "/work/session-machine.ini" },
|
|
sessionReadiness: { phase: "ready", ready: true, missing: [] },
|
|
},
|
|
}).rows.find(({ id }) => id === "session-load")?.value,
|
|
"loaded: /work/session-machine.ini",
|
|
);
|
|
assert.equal(
|
|
createMachineSessionPersistenceRenderState(
|
|
createMachineSessionPersistenceDisplayViewModel(createMachineSessionPersistenceSummary()),
|
|
).apiName,
|
|
"machine-session-persistence-render-state",
|
|
);
|
|
|
|
const controlPageApiSchema = createControlPageBrowserApiSchema();
|
|
const controlPageApiManifest = createControlPageBrowserApiManifest();
|
|
assert.equal(controlPageApiSchema.apiName, "ini-panel-control-page");
|
|
assert.equal(isSupportedIniPanelControlPageApiManifest(controlPageApiManifest), true);
|
|
assert.deepEqual(controlPageApiManifest.methods, createControlPageBrowserApiMethods());
|
|
assert.equal(
|
|
createIniPanelShellControlPageContract().readonlyStatusApiManifest.apiName,
|
|
"machine-session-readonly-status",
|
|
);
|
|
|
|
const launchManifest = createIniPanelLaunchApiManifest();
|
|
assert.equal(isSupportedIniPanelLaunchApiManifest(launchManifest), true);
|
|
assert.equal(
|
|
launchManifest.methods.includes("mountWorkflowOverviewEmbeddingMountState"),
|
|
true,
|
|
);
|
|
assert.deepEqual(
|
|
launchManifest.visibleEntries,
|
|
getVisibleIniPanelEntries().map(({ id, href, title }) => ({ id, href, title })),
|
|
);
|
|
|
|
const shellIntegrationManifest = createIniPanelShellIntegrationManifest();
|
|
assert.equal(createIniPanelShellIntegrationSchema().apiName, "ini-panel-shell-integration");
|
|
assert.equal(isSupportedIniPanelShellIntegrationManifest(shellIntegrationManifest), true);
|
|
assert.equal(createIniPanelShellIntegrationReadiness(shellIntegrationManifest).ready, true);
|
|
assert.equal(createIniPanelShellIntegrationWorkflowPlan({
|
|
manifest: shellIntegrationManifest,
|
|
}).ready, true);
|
|
assert.equal(
|
|
createIniPanelShellWorkflowOverviewContract().methodNames.includes("getWorkflowOverviewApiSurfaceInventory"),
|
|
true,
|
|
);
|
|
|
|
const shellViewModel = createIniPanelShellViewModel();
|
|
assert.equal(
|
|
shellViewModel.launchApiManifest.methods.includes("mountWorkflowOverviewEmbeddingMountState"),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
shellViewModel.launchApiManifest.methods.includes("getShellSessionReadinessWorkflowReport"),
|
|
true,
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellSessionReadinessWorkflowReport().apiName,
|
|
"ini-panel-shell-session-readiness-workflow-report",
|
|
);
|
|
assert.equal(
|
|
createIniPanelShellApiSurfaceInventory().apiName,
|
|
"ini-panel-shell-api-surface-inventory",
|
|
);
|
|
assert.equal(shellViewModel.shellApiSurfaceInventory.ready, true);
|
|
assert.equal(
|
|
shellViewModel.shellSessionHandoffWorkflowSummary.rows.find(
|
|
({ id }) => id === "persistence-summary",
|
|
)?.value,
|
|
"waiting: 5 missing",
|
|
);
|
|
assert.equal(
|
|
shellViewModel.shellSessionHandoffWorkflowSummary.rows.find(
|
|
({ id }) => id === "api-surface-inventory",
|
|
)?.value,
|
|
"ready: 6 rows",
|
|
);
|
|
assert.equal(
|
|
shellViewModel.mountWorkflowOverviewEmbeddingMountState,
|
|
mountIniPanelShellWorkflowOverviewEmbeddingMountState,
|
|
);
|
|
|
|
const blockedMount = mountIniPanelShellWorkflowOverviewEmbeddingMountState({ documentRef: null });
|
|
assert.equal(blockedMount.apiName, "ini-panel-shell-workflow-overview-embedding-mount-dom-mount");
|
|
assert.equal(blockedMount.ready, false);
|
|
assert.deepEqual(blockedMount.domReadiness.missing, ["document", "mount", "status", "rows"]);
|
|
|
|
assert.match(sdkReadmeText, /OPFS\/session persistence/);
|
|
assert.match(sdkReadmeText, /INI panel shell handoff/);
|
|
assert.match(sdkReadmeText, /workflow overview embedding/);
|
|
assert.match(trackerText, /SDK\/API surface/);
|
|
|
|
console.log("sdk_surface_node_smoke=ok");
|