'use strict'; /** * Unit tests for plan-document.cjs * * Module: gsd-core/bin/lib/plan-document.cjs * * Covers the `tracker-id` attribute (ADR-3646 Phase 1, #3970) added to the * `` element grammar, plus regression coverage proving the addition * does not alter pre-existing task-parsing behaviour. * * Matrix rows referenced below are from * .gsd/phase/feat-3970-task-content-resolution-seam/50-test-matrix.md */ const { describe, test } = require('node:test'); const assert = require('node:assert/strict'); const { parsePlanDocument } = require('../gsd-core/bin/lib/plan-document.cjs'); describe('plan-document: tracker-id attribute', () => { test('row 1 — no tracker-id attribute yields trackerId: null', () => { const doc = parsePlanDocument(` Do a thing `); assert.equal(doc.tasks.length, 1); assert.equal(doc.tasks[0].trackerId, null); }); test('row 2 — tracker-id is read verbatim, never split', () => { const doc = parsePlanDocument(` Do a thing `); assert.equal(doc.tasks.length, 1); assert.equal(doc.tasks[0].trackerId, 'beads:GSD-42'); }); test('row 3 — tracker-id="" (empty string) normalises to null', () => { const doc = parsePlanDocument(` Do a thing `); assert.equal(doc.tasks.length, 1); assert.equal(doc.tasks[0].trackerId, null); }); test('row 4 — checkpoint tasks never read tracker-id, even when present', () => { const doc = parsePlanDocument(` Ship it `); assert.equal(doc.tasks.length, 1); assert.equal(doc.tasks[0].kind, 'checkpoint'); assert.equal(doc.tasks[0].trackerId, null); }); }); describe('plan-document: regression — legacy behaviour unchanged', () => { test('legacy `## Task N` markdown fallback still parses with trackerId: null', () => { const doc = parsePlanDocument(` ## Task 1: Do a thing Some body text. ## Task 2: Do another thing `); assert.equal(doc.tasks.length, 2); for (const t of doc.tasks) { assert.equal(t.kind, 'auto'); assert.equal(t.type, null); assert.equal(t.trackerId, null); assert.deepEqual(t.plannedFiles, []); assert.deepEqual(t.acceptanceCriteria, []); assert.equal(t.done, null); } assert.equal(doc.tasks[0].name, 'Task 1: Do a thing'); assert.equal(doc.tasks[1].name, 'Task 2: Do another thing'); }); test('ordinary task with name/files/acceptance_criteria still parses correctly alongside trackerId', () => { const doc = parsePlanDocument(` Implement the seam src/a.cts, src/b.cts - criterion one - criterion two Merged. `); assert.equal(doc.tasks.length, 1); const t = doc.tasks[0]; assert.equal(t.kind, 'auto'); assert.equal(t.type, 'auto'); assert.equal(t.name, 'Implement the seam'); assert.deepEqual(t.plannedFiles, ['src/a.cts', 'src/b.cts']); assert.deepEqual(t.acceptanceCriteria, ['criterion one', 'criterion two']); assert.equal(t.done, 'Merged.'); assert.equal(t.trackerId, 'beads:GSD-7'); }); });