| 1 | import assert from "node:assert/strict"; |
| 2 | import { readFileSync } from "node:fs"; |
| 3 | import test from "node:test"; |
| 4 | import { isolatedGroups, selectPackages, testArgs } from "./windows-go-tests.mjs"; |
| 5 | import { windowsPRContractArgs, windowsPRContractGroups } from "./windows-pr-contract-tests.mjs"; |
| 6 | |
| 7 | const packages = ["reasonix/cmd/reasonix", "reasonix/internal/agent", "reasonix/internal/agent/testutil", |
| 8 | "reasonix/internal/acp", "reasonix/internal/agentpreset", "reasonix/internal/boot", "reasonix/internal/bot", "reasonix/internal/control", |
| 9 | "reasonix/internal/control/child", "reasonix/internal/extension/sidecar", "reasonix/internal/proc", |
| 10 | "reasonix/internal/serve", "reasonix/internal/session", "reasonix/internal/worktree", |
| 11 | "reasonix/internal/lsp", "reasonix/internal/fileops", "reasonix/internal/newpackage", "reasonix/internal/projectiondb", |
| 12 | "reasonix/internal/sessioncatalog", "reasonix/internal/sqliteuri", "reasonix/internal/topicstate", |
| 13 | "reasonix/internal/winaclresidue", "reasonix/tools/repolint"]; |
| 14 | |
| 15 | test("the full Windows groups cover every package exactly once, including new packages", () => { |
| 16 | const grouped = ["full", ...isolatedGroups].flatMap(group => selectPackages(packages, group)); |
| 17 | assert.deepEqual(grouped.toSorted(), packages.toSorted()); |
| 18 | assert.equal(new Set(grouped).size, grouped.length); |
| 19 | assert.ok(selectPackages(packages, "full").includes("reasonix/internal/agentpreset")); |
| 20 | }); |
| 21 | |
| 22 | test("PR smoke keeps platform coverage without duplicating isolated suites", () => { |
| 23 | assert.deepEqual(selectPackages(packages, "smoke"), [ |
| 24 | "reasonix/cmd/reasonix", "reasonix/internal/extension/sidecar", "reasonix/internal/proc", "reasonix/internal/lsp", |
| 25 | "reasonix/internal/fileops", |
| 26 | "reasonix/internal/projectiondb", "reasonix/internal/sessioncatalog", "reasonix/internal/sqliteuri", |
| 27 | "reasonix/internal/topicstate", "reasonix/internal/winaclresidue", |
| 28 | ]); |
| 29 | for (const group of isolatedGroups) { |
| 30 | assert.deepEqual(testArgs(packages, group).slice(0, 4), ["test", "-p", "1", "-timeout=8m"]); |
| 31 | } |
| 32 | assert.equal(testArgs(packages, "bot")[4], "-json"); |
| 33 | assert.equal(testArgs(packages, "acp").includes("-json"), false); |
| 34 | assert.deepEqual(testArgs(packages, "full").slice(0, 4), ["test", "-p", "4", "-timeout=8m"]); |
| 35 | assert.throws(() => testArgs(packages, "typo"), /Unknown/); |
| 36 | assert.throws(() => testArgs([], "full"), /Empty/); |
| 37 | }); |
| 38 | |
| 39 | test("CI invokes every isolated group and both residual entrypoints", () => { |
| 40 | const source = readFileSync(new URL("../.github/workflows/ci.yml", import.meta.url), "utf8"); |
| 41 | for (const group of ["full", "smoke", "control"]) { |
| 42 | assert.match(source, new RegExp(`run: node scripts/windows-go-tests\\.mjs ${group}\\n`)); |
| 43 | } |
| 44 | const isolated = source.match(/\n windows-isolated:\n([\s\S]*?)(?=\n [a-z][a-z0-9-]*:|$)/)?.[1]; |
| 45 | assert.ok(isolated); |
| 46 | const matrix = isolated.match(/group: \[([^\]]+)\]/)[1].split(",").map(value => value.trim()); |
| 47 | assert.deepEqual([...matrix, "control"].toSorted(), isolatedGroups.toSorted()); |
| 48 | assert.match(isolated, /- name: test\n(?: #.*\n)* timeout-minutes: 15\n/); |
| 49 | assert.match(isolated, /run: node scripts\/windows-go-tests\.mjs \$\{\{ matrix.group \}\}/); |
| 50 | assert.match(isolated, /fail-fast: false/); |
| 51 | assert.match(isolated, /actions\/setup-node@v7/); |
| 52 | }); |
| 53 | |
| 54 | test("Windows PR contract selector covers shell identity, lifecycle and cancellation regressions", () => { |
| 55 | const source = readFileSync(new URL("../.github/workflows/ci.yml", import.meta.url), "utf8"); |
| 56 | assert.match(source, /run: node scripts\/windows-pr-contract-tests\.mjs/); |
| 57 | const selected = new Set(windowsPRContractGroups.flatMap(group => group.tests)); |
| 58 | for (const required of [ |
| 59 | "TestWorkspacePassesBashTimeout", |
| 60 | "TestBashSchemaUnchangedWithSessionTemp", |
| 61 | "TestBashUnsupportedOSSandboxUsesToolLayerPermissionBoundary", |
| 62 | "TestOSSandboxSupportedPerPlatform", |
| 63 | "TestE2EApprovalRoundTrip", |
| 64 | "TestE2ECancelMidTurn", |
| 65 | "TestBotGatewayStopWaitsForDispatchHandler", |
| 66 | "TestBotGatewayStopWaitsForTurn", |
| 67 | "TestBotGatewayStopBeforeTurnCancelPublication", |
| 68 | ]) { |
| 69 | assert.equal(selected.has(required), true, `${required} is missing from the Windows PR contract`); |
| 70 | } |
| 71 | for (const group of windowsPRContractGroups) { |
| 72 | const args = windowsPRContractArgs(group); |
| 73 | assert.equal(args.at(-1), group.package); |
| 74 | for (const name of group.tests) assert.match(args[3], new RegExp(`\\b${name}\\b`)); |
| 75 | } |
| 76 | assert.deepEqual(windowsPRContractArgs(windowsPRContractGroups[0], { fullBuiltin: true }), ["test", "-timeout=5m", "./internal/tool/builtin"]); |
| 77 | }); |
| 78 |