Files
msd-core/tests/fixtures/index.cjs
Jakub Zych a9a7a328e6 refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
2026-10-06 01:47:40 +02:00

110 lines
4.0 KiB
JavaScript

const fs = require('fs');
const os = require('os');
const path = require('path');
const { gitOrThrow, GIT_FIXTURE_TIMEOUT_MS } = require('../helpers/git-fixture.cjs');
/**
* Create a temp test fixture directory with canonical planning layout.
*
* @param {object} [options]
* @param {string} [options.prefix='msd-test-']
* @param {boolean} [options.git=false] - initialize git repo with initial commit
* @param {boolean} [options.planning=true] - create .planning/phases layout
* @param {boolean} [options.projectDoc=true] - write .planning/PROJECT.md
* @returns {string} absolute fixture directory path
*/
function createFixture(options = {}) {
const {
prefix = 'msd-test-',
git = false,
planning = true,
projectDoc = git,
} = options;
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
if (planning) {
fs.mkdirSync(path.join(tmpDir, '.planning', 'phases'), { recursive: true });
}
if (projectDoc) {
fs.mkdirSync(path.join(tmpDir, '.planning'), { recursive: true });
fs.writeFileSync(
path.join(tmpDir, '.planning', 'PROJECT.md'),
'# Project\n\nTest project.\n'
);
}
if (git) {
// Construction calls (init/config/add/commit), a heavier class than a
// plumbing read — each of `init`/`commit` writes dozens of files, and on
// Windows every spawn is Defender-scanned (#3323).
const gitOpts = { cwd: tmpDir, timeoutMs: GIT_FIXTURE_TIMEOUT_MS };
gitOrThrow(['init'], gitOpts);
gitOrThrow(['config', 'user.email', 'test@test.com'], gitOpts);
gitOrThrow(['config', 'user.name', 'Test'], gitOpts);
gitOrThrow(['config', 'commit.gpgsign', 'false'], gitOpts);
gitOrThrow(['add', '-A'], gitOpts);
// `--allow-empty`: a fixture with `git: true, planning: false,
// projectDoc: false` (e.g. a "greenfield" starting world) stages nothing,
// so a plain `git commit` would fail with "nothing to commit" and the
// caller would never get a usable repo (there'd be no HEAD at all).
gitOrThrow(['commit', '--allow-empty', '-m', 'initial commit'], gitOpts);
}
return tmpDir;
}
/**
* Seed a canonical phase directory with files.
* @param {string} tmpDir
* @param {string} phaseSlug e.g. "03-api"
* @param {Record<string,string>} files map of filename->content
* @returns {string} phase directory path
*/
function seedPhase(tmpDir, phaseSlug, files = {}) {
const phaseDir = path.join(tmpDir, '.planning', 'phases', phaseSlug);
fs.mkdirSync(phaseDir, { recursive: true });
for (const [name, content] of Object.entries(files)) {
fs.writeFileSync(path.join(phaseDir, name), content);
}
return phaseDir;
}
/**
* Seed a canonical workstream tree and optionally set active pointer.
* @param {string} tmpDir
* @param {{name:string, state?:string, roadmap?:string, active?:boolean}} options
* @returns {string} workstream directory path
*/
function seedWorkstream(tmpDir, options) {
const { name, state = '', roadmap = '', active = false } = options || {};
if (!name || /[^a-zA-Z0-9._-]/.test(name) || name.includes('..')) {
throw new Error(`seedWorkstream: invalid name "${name}"`);
}
const wsDir = path.join(tmpDir, '.planning', 'workstreams', name);
fs.mkdirSync(path.join(wsDir, 'phases'), { recursive: true });
if (state) fs.writeFileSync(path.join(wsDir, 'STATE.md'), state);
if (roadmap) fs.writeFileSync(path.join(wsDir, 'ROADMAP.md'), roadmap);
if (active) {
fs.mkdirSync(path.join(tmpDir, '.planning'), { recursive: true });
fs.writeFileSync(path.join(tmpDir, '.planning', 'active-workstream'), `${name}\n`);
}
return wsDir;
}
/**
* Write STATE.md in canonical location.
* @param {string} tmpDir
* @param {string} content
* @returns {string} file path
*/
function writeState(tmpDir, content) {
const statePath = path.join(tmpDir, '.planning', 'STATE.md');
fs.mkdirSync(path.dirname(statePath), { recursive: true });
fs.writeFileSync(statePath, content);
return statePath;
}
module.exports = { createFixture, seedPhase, seedWorkstream, writeState };