Files
msd-core/tests/bug-2660-one-liner-extraction.test.cjs
Tom Boucher 8c3d934a90 refactor(#1294): T-final — delete the core.cjs re-export spine (epic #1267 complete) (#1295)
* refactor(#1294): T-final — delete the core.cjs re-export spine (epic #1267 complete)

After T0–T6 nothing imports core, so retire the spine and its scaffolding:
- delete src/core.cts (and the gitignored gsd-core/bin/lib/core.cjs artifact;
  remove its .gitignore + eslint-ignore entries)
- delete scripts/lint-core-spine-imports.cjs + its allowlist; drop it from the
  package.json lint:ci chain
- regenerate docs/INVENTORY-MANIFEST.json (drops the core.cjs surface)
- sweep stale references: CONTEXT.md glossary back-compat clauses (spine retired,
  callers import the leaf directly), planning-config.md CONFIG_DEFAULTS owner,
  and false present-tense core.cjs claims in leaf-module docstrings

The ADR-857 decomposition is complete: the former Core god-module is fully
dissolved into its leaf modules; no re-export spine remains. No behaviour change.

Closes #1294

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(#1294): migrate the computed-path core.cjs importers the literal grep missed

bin/install.js used require(path.join(_gsdLibDir, 'core.cjs')) (a computed
path, and bin/install.js was never in the convergence lint's scan roots), and
~8 test files referenced core.cjs via path.join/readFileSync/existsSync/FILE_ARG
forms the literal-string migration grep missed. Route install.js's symbols to
their leaves (RUNTIME_PROFILE_MAP->model-catalog, resolveTierEntry/EFFORT_SET->
model-resolver) and repoint/adjust the test references to the leaves. Recovers
the 161 'Cannot find module core.cjs' failures from the spine deletion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 18:50:46 -04:00

83 lines
3.3 KiB
JavaScript

/**
* Bug #2660: `gsd-tools milestone complete <version>` writes MILESTONES.md
* bullets that read "- One-liner:" (the literal label) instead of the prose
* after the label.
*
* Root cause: extractOneLinerFromBody() matches the first **...** span. In
* `**One-liner:** prose`, the first span contains only `One-liner:` so the
* function returns the label instead of the prose after it.
*/
const { describe, test } = require('node:test');
const assert = require('node:assert/strict');
const path = require('path');
const { extractOneLinerFromBody } = require(
path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'core-utils.cjs')
);
describe('bug #2660: extractOneLinerFromBody', () => {
test('a) body-style **One-liner:** label returns prose after the label', () => {
const content =
'# Phase 2 Plan 01: Foundation Summary\n\n**One-liner:** Real prose here.\n';
assert.strictEqual(extractOneLinerFromBody(content), 'Real prose here.');
});
test('b) frontmatter-only one-liner returns null (caller handles frontmatter)', () => {
const content =
'---\none-liner: Set up project\n---\n\n# Phase 1: Foundation Summary\n\nBody prose with no bold line.\n';
assert.strictEqual(extractOneLinerFromBody(content), null);
});
test('c) no one-liner at all returns null', () => {
const content =
'# Phase 1: Foundation Summary\n\nJust some narrative, no bold line.\n';
assert.strictEqual(extractOneLinerFromBody(content), null);
});
test('d) bold spans inside the prose are preserved', () => {
const content =
'# Phase 1: Foundation Summary\n\n**One-liner:** This is **important** stuff.\n';
assert.strictEqual(
extractOneLinerFromBody(content),
'This is **important** stuff.'
);
});
test('e) empty prose after label returns null (no bogus bullet)', () => {
const empty =
'# Phase 1: Foundation Summary\n\n**One-liner:**\n\nRest of body.\n';
const whitespace =
'# Phase 1: Foundation Summary\n\n**One-liner:** \n\nRest of body.\n';
assert.strictEqual(extractOneLinerFromBody(empty), null);
assert.strictEqual(extractOneLinerFromBody(whitespace), null);
});
test('f) legacy bare **prose** format still works (no label, no colon)', () => {
// Preserve pre-existing behavior: SUMMARY files historically used
// `**bold prose**` with no label. See tests/commands.test.cjs:366 and
// tests/milestone.test.cjs:451 — both assert this form.
const content =
'---\nphase: "01"\n---\n\n# Phase 1: Foundation Summary\n\n**JWT auth with refresh rotation using jose library**\n\n## Performance\n';
assert.strictEqual(
extractOneLinerFromBody(content),
'JWT auth with refresh rotation using jose library'
);
});
test('g) other **Label:** prefixes (e.g. Summary:) also capture prose after label', () => {
const content =
'# Phase 1: Foundation Summary\n\n**Summary:** Built the thing.\n';
assert.strictEqual(extractOneLinerFromBody(content), 'Built the thing.');
});
test('h) CRLF line endings (Windows) are handled', () => {
const content =
'---\r\nphase: "01"\r\n---\r\n\r\n# Phase 1: Foundation Summary\r\n\r\n**One-liner:** Windows-authored prose.\r\n';
assert.strictEqual(
extractOneLinerFromBody(content),
'Windows-authored prose.'
);
});
});