"use strict"; const test = require("node:test"); const assert = require("node:assert/strict"); const fs = require("node:fs"); const path = require("node:path"); const root = path.resolve(__dirname, "..", ".."); const app = fs.readFileSync(path.join(root, "Web", "app.js"), "utf8"); const index = fs.readFileSync(path.join(root, "Web", "index.html"), "utf8"); const styles = fs.readFileSync(path.join(root, "Web", "styles.css"), "utf8"); function functionBody(source, name, nextName) { const start = source.indexOf(`function ${name}`); const end = source.indexOf(`function ${nextName}`, start + 1); assert.ok(start >= 0, `${name} must exist`); assert.ok(end > start, `${nextName} must follow ${name}`); return source.slice(start, end); } test("stock source list exposes explicit original-style multi-selection controls", () => { const moduleOffset = index.indexOf('src="legacy-batch-selection-workflow.js"'); const appOffset = index.indexOf('src="app.js"'); assert.ok(moduleOffset >= 0 && moduleOffset < appOffset); for (const id of [ "stockCutSelectionCount", "stockCutBatchAdd", "stockCutSelectionClear" ]) { assert.match(index, new RegExp(`id="${id}"`, "u")); } assert.match(index, /aria-multiselectable="true"/u); assert.match(styles, /\.stock-cut-row\.selected/u); }); test("stock gestures use Ctrl Shift selection and materialize a complete batch before push", () => { assert.match(app, /MbnLegacyBatchSelectionWorkflow/u); assert.match(app, /applyPointerSelection\([\s\S]*ctrlKey[\s\S]*shiftKey/u); const batch = functionBody(app, "addStockCuts", "renderGlobalCandleOptions"); const materialize = batch.indexOf("materializeAtomicBatch"); const commit = batch.indexOf("state.playlist.push(...entries)"); assert.ok(materialize >= 0 && commit > materialize); assert.match(batch, /isStockCutAllowed/u); }); test("fixed source section supports ordered all-or-nothing child addition", () => { const batch = functionBody(app, "addFixedActions", "renderFixedWorkflow"); const materialize = batch.indexOf("materializeAtomicBatch"); const commit = batch.indexOf("state.playlist.push(...entries)"); assert.ok(materialize >= 0 && commit > materialize); assert.match(batch, /action\?\.available === false/u); assert.match(app, /legacy-fixed-batch-add/u); assert.match(app, /sectionActions/u); });