@afokapu/atdd-bun 0.10.17 → 0.10.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -319,3 +319,36 @@ export function writeReport(violations) {
319
319
  writeFileSync(rp, JSON.stringify({ violations }, null, 2), "utf8");
320
320
  process.exit(0);
321
321
  }
322
+
323
+ // A route whose train passes through a wagon with no source yet is pending: the plan promises it, and nothing exists to
324
+ // drive yet. The route rules skip it until every wagon on its train has source, then judge it. Derived from the plan and
325
+ // the source tree, never declared, so it cannot be used to park a route; topology keeps reporting the missing source.
326
+ const pendingCache = new Map();
327
+ export function unbuiltWagons(croot, trainId) {
328
+ if (!trainId) return [];
329
+ let byTrain = pendingCache.get(croot);
330
+ if (!byTrain) {
331
+ byTrain = new Map();
332
+ let sourceRoot = "src/wagons";
333
+ try { sourceRoot = Bun.YAML.parse(readText(join(croot, "atdd-bun.yaml")))?.topology?.source_root || sourceRoot; } catch { /* default layout */ }
334
+ const hasSource = (wagon) => [...walkFiles(join(croot, sourceRoot, wagon), isTs)].some((f) => !/\.(test|spec)\.[cm]?[jt]sx?$/.test(f));
335
+ (function rec(dir) {
336
+ let entries;
337
+ try { entries = readdirSync(dir).sort(); } catch { return; }
338
+ for (const name of entries) {
339
+ const full = join(dir, name);
340
+ let st;
341
+ try { st = statSync(full); } catch { continue; }
342
+ if (st.isDirectory()) { if (name !== "_interlockings") rec(full); continue; }
343
+ if (!/\.ya?ml$/.test(name)) continue;
344
+ let doc;
345
+ try { doc = Bun.YAML.parse(readText(full)); } catch { continue; }
346
+ if (!doc || typeof doc.train_id !== "string" || !Array.isArray(doc.sequence)) continue;
347
+ const wagons = new Set(doc.sequence.flatMap((step) => [step?.from, step?.to]).filter((end) => typeof end === "string" && end.startsWith("wagon:")).map((end) => end.slice(6).trim()));
348
+ byTrain.set(doc.train_id, [...wagons].filter((wagon) => !hasSource(wagon)));
349
+ }
350
+ })(join(croot, PLAN_ROOT));
351
+ pendingCache.set(croot, byTrain);
352
+ }
353
+ return byTrain.get(trainId) ?? [];
354
+ }
@@ -18,6 +18,7 @@ import {
18
18
  rel,
19
19
  mk,
20
20
  writeReport,
21
+ unbuiltWagons,
21
22
  } from "../_shared/interlocking.mjs";
22
23
 
23
24
  const RULE = "tester.bun.interlocking-route-coverage";
@@ -34,6 +35,7 @@ for (const scanRoot of roots) {
34
35
  for (const { file, rec } of records) {
35
36
  for (const route of rec.routes) {
36
37
  if (isRouteCovered(route, e2eTexts)) continue;
38
+ if (unbuiltWagons(croot, route.trainId).length) continue; // pending: a wagon on its train has no source yet
37
39
  const cat =
38
40
  route.category !== null
39
41
  ? `category "${route.category}"`
@@ -16,7 +16,7 @@
16
16
  // suite green. The runtime obeyed the new plan; no test looked.
17
17
  import {
18
18
  parseJsonEnv, readText, findConsumerRoots, interlockingFiles, e2eFiles,
19
- parseInterlocking, tokenCovered, rel, mk, PLAN_ROOT,
19
+ parseInterlocking, tokenCovered, rel, mk, PLAN_ROOT, unbuiltWagons,
20
20
  } from "../_shared/interlocking.mjs";
21
21
  import { writeFileSync, readdirSync, statSync } from "node:fs";
22
22
  import { join } from "node:path";
@@ -88,6 +88,7 @@ export function scanExecution(scanRoot) {
88
88
  const anchor = files.length ? rel(files[0].file, croot) : "e2e/";
89
89
  for (const trainId of [...trainsReachableFromRoutes(records)].sort()) {
90
90
  if (!declaresASequence(croot, trainId)) continue; // nothing declared to exercise
91
+ if (unbuiltWagons(croot, trainId).length) continue; // pending: a wagon on it has no source yet
91
92
  if (trainSequenceCovered(trainId, texts)) continue;
92
93
  violations.push(
93
94
  mk(RULE_SEQUENCE, anchor, 1, 0,
package/integrity.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.10.17",
2
+ "version": "0.10.18",
3
3
  "files": {
4
4
  "HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
5
5
  "PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
@@ -379,14 +379,14 @@
379
379
  "detectors/bun_interlocking_binding/fixtures/dirty_transcribed_runtime/server.ts": "d5bc34c5b1b2b0a511e0c4604ce6f9c77491dca9aee994be720540f3052babc1",
380
380
  "detectors/bun_interlocking_binding/fixtures/dirty_transcribed_runtime/src/trains/interlocking.ts": "9bcfdb4ecff6efd1f658b9fd587342615179924e25468c75daa07c2626d4d8ab",
381
381
  "detectors/bun_interlocking_binding/fixtures/dirty_transcribed_runtime/src/trains/runner.ts": "0e4b885e50f12cc2a8c8f6740bf83e7b2e7137a28e1e143586e9a8550ea5bd45",
382
- "detectors/bun_interlocking_coverage/_shared/interlocking.mjs": "6a3440e53ba13948edfbb1ef8de4c01e4fd022ad6f9d44739f814220cc583417",
382
+ "detectors/bun_interlocking_coverage/_shared/interlocking.mjs": "f1dcc2a23e1656da7ab5b231ad9cd15466144a13f56aa0e15cbfa97ca098eb8d",
383
383
  "detectors/bun_interlocking_coverage/atdd.implementation.yaml": "f160517a8138ba3ca05e3d130e6fbfb796e643376f25743fdef4fc210196525b",
384
384
  "detectors/bun_interlocking_coverage/checks/_map.json": "0a218ea319cc6258af7bd721c2154cb9561fe67e80d80ef32d08fc77bc9403c3",
385
385
  "detectors/bun_interlocking_coverage/checks/interlocking_production_runner.mjs": "136eb0955052f2485740adfb888f5ba6f1414dcdb53d505034b8db40420a611a",
386
- "detectors/bun_interlocking_coverage/checks/interlocking_route_coverage.mjs": "55716c706818d3f724cdd5f1f16a67b92dacdc4bb4a2d23a037039ddd869acea",
386
+ "detectors/bun_interlocking_coverage/checks/interlocking_route_coverage.mjs": "b91b7920064faa412056edb8a743dfab4fcf11778fc0af02ac6e1d5db1c88212",
387
387
  "detectors/bun_interlocking_coverage/checks/interlocking_smoke_coverage.mjs": "ea4b0155c4f151a36979d850aa2482901b37eacc0fe01cecc0a736089a3e15ce",
388
388
  "detectors/bun_interlocking_coverage/checks/interlocking_trace_binds.mjs": "61dcb8a8d04e9764aab7920f346bd3684fc98e2c294aa5c58eefec555145a1d0",
389
- "detectors/bun_interlocking_coverage/checks/interlocking_train_sequence.mjs": "ab00524af6cce2a95c3a1232f2e6304c761533c2ac3f42d34683b2c0dc5f9c6a",
389
+ "detectors/bun_interlocking_coverage/checks/interlocking_train_sequence.mjs": "7a38ce0b8bd5b4342a7bae09776b9638dc3ed51635322055a4fb0f0e6940af77",
390
390
  "detectors/bun_interlocking_coverage/detect.mjs": "a124418dc29aaf8fda9cd09427230d25768206b3f563d516774667e8cf75b66e",
391
391
  "detectors/bun_interlocking_coverage/fixtures/clean/interlocking_production_runner/e2e/interlockings/match-resolution/routes.test.ts": "ba6ea85b3fbe15e3c49332da3ad2921a0ff3436a6fe3b5a5035fb35fdc874720",
392
392
  "detectors/bun_interlocking_coverage/fixtures/clean/interlocking_production_runner/e2e/interlockings/match-resolution/trace.test.ts": "aee4ea93ceb8636846344e915cd7e66f7e8f99ba08596f83266590fa2b9ff58e",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afokapu/atdd-bun",
3
- "version": "0.10.17",
3
+ "version": "0.10.18",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/afokapu/atdd-bun.git"