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.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* stateReplaceField / stateExtractField / stateReplaceFieldWithFallback
|
||||
* (issue #2880, ADR-2143 §3/§4). These lock byte-identical behaviour across
|
||||
* the migration of the table branch off a hand-rolled whole-document regex
|
||||
* onto a line-scan + byte-range splice (see gsd-core/bin/lib/state-document.cjs
|
||||
* onto a line-scan + byte-range splice (see msd-core/bin/lib/state-document.cjs
|
||||
* locateFieldRow). Any future re-implementation of the table branch must keep
|
||||
* every assertion below true.
|
||||
*/
|
||||
@@ -21,7 +21,7 @@ const {
|
||||
stateReplaceField,
|
||||
stateExtractField,
|
||||
stateReplaceFieldWithFallback,
|
||||
} = require('../gsd-core/bin/lib/state-document.cjs');
|
||||
} = require('../msd-core/bin/lib/state-document.cjs');
|
||||
|
||||
describe('stateReplaceField — table branch (characterization, #2880)', () => {
|
||||
test('replaces a two-cell row in place', () => {
|
||||
@@ -184,7 +184,7 @@ describe('stateReplaceField — empty field preserves the following line (#4010)
|
||||
});
|
||||
|
||||
test('E2E: transitionCore update of an empty field preserves the next line (ADR-3180 Decision 4(c))', () => {
|
||||
const { transitionCore } = require('../gsd-core/bin/lib/state-transition.cjs');
|
||||
const { transitionCore } = require('../msd-core/bin/lib/state-transition.cjs');
|
||||
const content = '## Current Position\n\n**Status:**\n**Current Plan:** 2 of 5';
|
||||
const result = transitionCore(content, { kind: 'update', field: 'Status', value: 'Executing Phase 5' });
|
||||
assert.equal(result.content, '## Current Position\n\n**Status:** Executing Phase 5\n**Current Plan:** 2 of 5');
|
||||
@@ -660,13 +660,13 @@ const { test, describe, beforeEach, afterEach } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
describe('#2828 — total_phases uses the roadmap count on a flat unmilestoned roadmap', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-2828-');
|
||||
tmpDir = createTempProject('msd-2828-');
|
||||
const planningDir = path.join(tmpDir, '.planning');
|
||||
// Flat unmilestoned roadmap with 6 phases (no versioned milestone heading).
|
||||
fs.writeFileSync(
|
||||
@@ -712,7 +712,7 @@ describe('#2828 — total_phases uses the roadmap count on a flat unmilestoned r
|
||||
test('state sync writes progress.total_phases === 6 (roadmap count), not 1 (phase-dir count) (#2828)', () => {
|
||||
// `state sync` derives progress.total_phases from the disk-scan cache (the read path
|
||||
// #2828 fixes) and writes it to STATE.md frontmatter. Pre-fix this wrote 1.
|
||||
const result = runGsdTools(['state', 'sync'], tmpDir);
|
||||
const result = runMsdTools(['state', 'sync'], tmpDir);
|
||||
assert.ok(result.success, `state sync failed: ${result.error}`);
|
||||
|
||||
const stateMd = fs.readFileSync(path.join(tmpDir, '.planning', 'STATE.md'), 'utf8');
|
||||
@@ -774,7 +774,7 @@ describe('#2828 — total_phases uses the roadmap count on a flat unmilestoned r
|
||||
* behavior verified to already hold today (see phase-log for the manual CLI
|
||||
* probes that established each expected value before this file was written).
|
||||
*
|
||||
* Rows and naming follow `.gsd/phase/fix-3185-state-writer-phase-count/50-test-matrix.md`
|
||||
* Rows and naming follow `.msd/phase/fix-3185-state-writer-phase-count/50-test-matrix.md`
|
||||
* verbatim (row numbers refer to that matrix, not the 8-row table in
|
||||
* `40-design.md`).
|
||||
*
|
||||
@@ -793,7 +793,7 @@ const { test, describe, beforeEach, afterEach } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Fixture builders
|
||||
@@ -830,7 +830,7 @@ function seedNamedPhaseDir(tmpDir, dirName, planBase) {
|
||||
function buildStateMd({ milestone = 'v1.0', milestoneName = 'Test', totalPhases, currentPhase = '01', eol = '\n' }) {
|
||||
const lines = [
|
||||
'---',
|
||||
'gsd_state_version: 1.0',
|
||||
'msd_state_version: 1.0',
|
||||
`milestone: ${milestone}`,
|
||||
`milestone_name: ${milestoneName}`,
|
||||
`current_phase: "${currentPhase}"`,
|
||||
@@ -843,7 +843,7 @@ function buildStateMd({ milestone = 'v1.0', milestoneName = 'Test', totalPhases,
|
||||
' percent: 0',
|
||||
'---',
|
||||
'',
|
||||
'# GSD State',
|
||||
'# MSD State',
|
||||
'',
|
||||
'## Current Position',
|
||||
'',
|
||||
@@ -856,13 +856,13 @@ function buildStateMd({ milestone = 'v1.0', milestoneName = 'Test', totalPhases,
|
||||
|
||||
/** Invoke `state record-session` (the #3204 entry point) then read back `state json --raw`. */
|
||||
function recordSessionAndReadTotalPhases(tmpDir) {
|
||||
const recordResult = runGsdTools(
|
||||
const recordResult = runMsdTools(
|
||||
['state', 'record-session', '--stopped-at', 'Phase 1, Plan 1', '--resume-file', 'none'],
|
||||
tmpDir,
|
||||
);
|
||||
assert.ok(recordResult.success, `state record-session failed: ${recordResult.error}`);
|
||||
|
||||
const jsonResult = runGsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
const jsonResult = runMsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
assert.ok(jsonResult.success, `state json --raw failed: ${jsonResult.error}`);
|
||||
return JSON.parse(jsonResult.output);
|
||||
}
|
||||
@@ -1095,7 +1095,7 @@ describe('#3204 buildStateFrontmatter total_phases — negative space / boundari
|
||||
`#3642: a single non-matching section must not leak its phases into the asserted milestone's total; stored 99 expected, got ${out.progress && out.progress.total_phases}`,
|
||||
);
|
||||
// The clobber must also be SURFACED, not silent: drive the seam directly
|
||||
// (runGsdTools discards stderr on success) and require the #3642 warning
|
||||
// (runMsdTools discards stderr on success) and require the #3642 warning
|
||||
// naming the asserted milestone.
|
||||
const { runNode } = require('./helpers/process-seam.cjs');
|
||||
const { TOOLS_PATH, TEST_ENV_BASE } = require('./helpers.cjs');
|
||||
@@ -1525,7 +1525,7 @@ describe('#3185 buildStateFrontmatter total_phases — directory-enumeration ind
|
||||
const roadmap = ['# Roadmap', '', '## Phase 1: One', '## Phase 2: Two', '## Phase 3: Three', ''].join('\n');
|
||||
fs.writeFileSync(path.join(tmpDir, '.planning', 'ROADMAP.md'), roadmap);
|
||||
const sessionState = [
|
||||
'# GSD State',
|
||||
'# MSD State',
|
||||
'',
|
||||
'## Session',
|
||||
'',
|
||||
@@ -1543,14 +1543,14 @@ describe('#3185 buildStateFrontmatter total_phases — directory-enumeration ind
|
||||
seedPhaseDirs(tmpDir, [1, 2, 3]);
|
||||
|
||||
const statePath = path.join(tmpDir, '.planning', 'STATE.md');
|
||||
const pinnedEnv = { GSD_TEST_MODE: '1', GSD_NOW_MS: '1600000000000' };
|
||||
const pinnedEnv = { MSD_TEST_MODE: '1', MSD_NOW_MS: '1600000000000' };
|
||||
const args = ['state', 'record-session', '--stopped-at', 'Phase 1, Plan 1', '--resume-file', 'none'];
|
||||
|
||||
const first = runGsdTools(args, tmpDir, pinnedEnv);
|
||||
const first = runMsdTools(args, tmpDir, pinnedEnv);
|
||||
assert.ok(first.success, `first record-session failed: ${first.error}`);
|
||||
const afterFirst = fs.readFileSync(statePath, 'utf8');
|
||||
|
||||
const second = runGsdTools(args, tmpDir, pinnedEnv);
|
||||
const second = runMsdTools(args, tmpDir, pinnedEnv);
|
||||
assert.ok(second.success, `second record-session failed: ${second.error}`);
|
||||
const afterSecond = fs.readFileSync(statePath, 'utf8');
|
||||
|
||||
@@ -1586,7 +1586,7 @@ describe('#3355 phase-dir dedup — collision tie-break must not consult mtime',
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-3355-');
|
||||
tmpDir = createTempProject('msd-3355-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -1619,7 +1619,7 @@ describe('#3355 phase-dir dedup — collision tie-break must not consult mtime',
|
||||
}
|
||||
|
||||
function readProgress() {
|
||||
const result = runGsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
const result = runMsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
assert.ok(result.success, `state json --raw failed: ${result.error}`);
|
||||
return JSON.parse(result.output).progress;
|
||||
}
|
||||
@@ -1632,7 +1632,7 @@ describe('#3355 phase-dir dedup — collision tie-break must not consult mtime',
|
||||
// utimes to whole ms), so the flip uses a margin guaranteed to register
|
||||
// everywhere — pre-fix, the mtime-newer duplicate then won the dedup
|
||||
// regardless of repository content. `_diskScanCache` is process-local
|
||||
// and runGsdTools spawns a fresh node per call, so each read below is a
|
||||
// and runMsdTools spawns a fresh node per call, so each read below is a
|
||||
// cold scan exactly like a fresh checkout.
|
||||
const base = new Date('2026-01-01T00:00:00.000Z');
|
||||
const margin = new Date(base.getTime() + 1500);
|
||||
@@ -1656,7 +1656,7 @@ describe('#3355 phase-dir dedup — collision tie-break must not consult mtime',
|
||||
);
|
||||
|
||||
// The collision must be surfaced: stderr warning naming BOTH dirs
|
||||
// (runGsdTools discards stderr on success, so drive the seam directly).
|
||||
// (runMsdTools discards stderr on success, so drive the seam directly).
|
||||
const rec = runNode(
|
||||
[TOOLS_PATH, 'state', 'json', '--raw'],
|
||||
{ cwd: tmpDir, env: { ...process.env, ...TEST_ENV_BASE }, timeoutMs: LOOP_HOOK_POINT_CLI_TIMEOUT_MS },
|
||||
@@ -1723,7 +1723,7 @@ describe('#3354 buildStateFrontmatter total_phases — milestoned-but-unbounded
|
||||
);
|
||||
seedPhaseDirs(tmpDir, [1, 2, 3, 4]);
|
||||
|
||||
// Drive the mutating command with stderr captured (runGsdTools discards
|
||||
// Drive the mutating command with stderr captured (runMsdTools discards
|
||||
// stderr on success). The warning is asserted on THIS invocation.
|
||||
const rec = runNode(
|
||||
[TOOLS_PATH, 'state', 'record-session', '--stopped-at', 'Phase 1, Plan 1', '--resume-file', 'none'],
|
||||
@@ -1736,7 +1736,7 @@ describe('#3354 buildStateFrontmatter total_phases — milestoned-but-unbounded
|
||||
`#3354: expected a stderr warning naming the unbounded milestone token 'v1.0', got stderr=${JSON.stringify(rec.stderr)}`,
|
||||
);
|
||||
|
||||
const jsonResult = runGsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
const jsonResult = runMsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
assert.ok(jsonResult.success, `state json --raw failed: ${jsonResult.error}`);
|
||||
const out = JSON.parse(jsonResult.output);
|
||||
|
||||
@@ -1759,14 +1759,14 @@ describe('#3354 buildStateFrontmatter total_phases — milestoned-but-unbounded
|
||||
path.join(tmpDir, '.planning', 'STATE.md'),
|
||||
[
|
||||
'---',
|
||||
'gsd_state_version: 1.0',
|
||||
'msd_state_version: 1.0',
|
||||
'milestone: v1.0',
|
||||
'milestone_name: Unbounded',
|
||||
'current_phase: "01"',
|
||||
'status: executing',
|
||||
'---',
|
||||
'',
|
||||
'# GSD State',
|
||||
'# MSD State',
|
||||
'',
|
||||
'## Current Position',
|
||||
'',
|
||||
@@ -1777,13 +1777,13 @@ describe('#3354 buildStateFrontmatter total_phases — milestoned-but-unbounded
|
||||
);
|
||||
seedPhaseDirs(tmpDir, [1, 2, 3, 4]);
|
||||
|
||||
const recordResult = runGsdTools(
|
||||
const recordResult = runMsdTools(
|
||||
['state', 'record-session', '--stopped-at', 'Phase 1, Plan 1', '--resume-file', 'none'],
|
||||
tmpDir,
|
||||
);
|
||||
assert.ok(recordResult.success, `state record-session failed: ${recordResult.error}`);
|
||||
|
||||
const jsonResult = runGsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
const jsonResult = runMsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
assert.ok(jsonResult.success, `state json --raw failed: ${jsonResult.error}`);
|
||||
const out = JSON.parse(jsonResult.output);
|
||||
|
||||
@@ -1909,7 +1909,7 @@ describe('#3573 total_phases — roadmap absent with an asserted milestone', ()
|
||||
const rec = recordSession(tmpDir);
|
||||
assert.ok(rec.exitCode === 0, `state record-session failed: ${rec.stderr}`);
|
||||
|
||||
const jsonResult = runGsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
const jsonResult = runMsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
assert.ok(jsonResult.success, `state json --raw failed: ${jsonResult.error}`);
|
||||
const out = JSON.parse(jsonResult.output);
|
||||
assert.strictEqual(
|
||||
@@ -1977,7 +1977,7 @@ describe('#3573 total_phases — roadmap absent with an asserted milestone', ()
|
||||
// resyncing write, silently clobbering stored values under the exact
|
||||
// condition #3354 established the scan is untrustworthy for. Extend the
|
||||
// withhold-then-fall-back-to-stored pattern to all three siblings.
|
||||
// Matrix: .gsd/bug/fix-4094-milestone-withhold-all-counters/50-test-matrix.md
|
||||
// Matrix: .msd/bug/fix-4094-milestone-withhold-all-counters/50-test-matrix.md
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('#4094 milestone-unbounded withhold — all four progress counters', () => {
|
||||
@@ -1988,10 +1988,10 @@ describe('#4094 milestone-unbounded withhold — all four progress counters', ()
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runNode } = require('./helpers/process-seam.cjs');
|
||||
const { TOOLS_PATH, TEST_ENV_BASE } = require('./helpers.cjs');
|
||||
const { splitLines } = require('../gsd-core/bin/lib/text-lines.cjs');
|
||||
const { splitLines } = require('../msd-core/bin/lib/text-lines.cjs');
|
||||
|
||||
/** Seed `.planning/phases/<padded>-phase-<n>` — local copy (the block-scoped seeder at the top of this file is not reachable from here). */
|
||||
function seedPhaseDirs(dir, nums) {
|
||||
@@ -2034,7 +2034,7 @@ describe('#4094 milestone-unbounded withhold — all four progress counters', ()
|
||||
const { totalPhases, completedPhases, totalPlans, completedPlans } = counters;
|
||||
const fm = [
|
||||
'---',
|
||||
'gsd_state_version: 1.0',
|
||||
'msd_state_version: 1.0',
|
||||
`milestone: ${milestone}`,
|
||||
'milestone_name: Unbounded',
|
||||
'current_phase: "01"',
|
||||
@@ -2050,7 +2050,7 @@ describe('#4094 milestone-unbounded withhold — all four progress counters', ()
|
||||
fm.push('progress:');
|
||||
for (const [k, v] of rows) fm.push(` ${k}: ${v}`);
|
||||
}
|
||||
fm.push('---', '', '# GSD State', '', '## Current Position', '', '**Current Phase:** 01', '**Status:** Executing', '');
|
||||
fm.push('---', '', '# MSD State', '', '## Current Position', '', '**Current Phase:** 01', '**Status:** Executing', '');
|
||||
return fm.join('\n');
|
||||
}
|
||||
|
||||
@@ -2078,7 +2078,7 @@ describe('#4094 milestone-unbounded withhold — all four progress counters', ()
|
||||
}
|
||||
|
||||
function stateJson(dir) {
|
||||
const jsonResult = runGsdTools(['state', 'json', '--raw'], dir);
|
||||
const jsonResult = runMsdTools(['state', 'json', '--raw'], dir);
|
||||
assert.ok(jsonResult.success, `state json --raw failed: ${jsonResult.error}`);
|
||||
return JSON.parse(jsonResult.output);
|
||||
}
|
||||
@@ -2308,7 +2308,7 @@ describe('#4094 milestone-unbounded withhold — all four progress counters', ()
|
||||
// unbounded branch's flat test, so the single-section shape takes the #3354
|
||||
// withhold (stored value preserved + warning) instead of substituting the
|
||||
// whole-document count. Controls pin what must NOT change.
|
||||
// Matrix: .gsd/bug/fix-3642-milestone-sectioning-leak/50-test-matrix.md
|
||||
// Matrix: .msd/bug/fix-3642-milestone-sectioning-leak/50-test-matrix.md
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
@@ -2316,7 +2316,7 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { runMsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
|
||||
// Compact local builders (this file's sections are deliberately
|
||||
// self-contained; the #3204 suite's identical builders live in its own
|
||||
@@ -2333,7 +2333,7 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
function stateMd({ milestone, totalPhases }) {
|
||||
return [
|
||||
'---',
|
||||
'gsd_state_version: 1.0',
|
||||
'msd_state_version: 1.0',
|
||||
`milestone: ${milestone}`,
|
||||
'milestone_name: M',
|
||||
'current_phase: "01"',
|
||||
@@ -2346,7 +2346,7 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
' percent: 0',
|
||||
'---',
|
||||
'',
|
||||
'# GSD State',
|
||||
'# MSD State',
|
||||
'',
|
||||
'## Current Position',
|
||||
'',
|
||||
@@ -2357,12 +2357,12 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
}
|
||||
|
||||
function writeTotalAfterRecord(tmpDir) {
|
||||
const recordResult = runGsdTools(
|
||||
const recordResult = runMsdTools(
|
||||
['state', 'record-session', '--stopped-at', 'Phase 1, Plan 1', '--resume-file', 'none'],
|
||||
tmpDir,
|
||||
);
|
||||
assert.ok(recordResult.success, `state record-session failed: ${recordResult.error}`);
|
||||
const jsonResult = runGsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
const jsonResult = runMsdTools(['state', 'json', '--raw'], tmpDir);
|
||||
assert.ok(jsonResult.success, `state json --raw failed: ${jsonResult.error}`);
|
||||
return Number(JSON.parse(jsonResult.output).progress.total_phases);
|
||||
}
|
||||
@@ -2370,7 +2370,7 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
let tmpDir;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = createTempProject('gsd-3642-');
|
||||
tmpDir = createTempProject('msd-3642-');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -2405,7 +2405,7 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
});
|
||||
|
||||
test('seam pins: hasAnyMilestoneSection counts >=1; hasMilestoneSectioning stays >=2', () => {
|
||||
const roadmapParser = require(path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'roadmap-parser.cjs'));
|
||||
const roadmapParser = require(path.join(__dirname, '..', 'msd-core', 'bin', 'lib', 'roadmap-parser.cjs'));
|
||||
assert.strictEqual(typeof roadmapParser.hasAnyMilestoneSection, 'function',
|
||||
'hasAnyMilestoneSection must be exported for buildStateFrontmatter (#3642)');
|
||||
const one = ['# Roadmap', '', '## v2.0', '## Phase 1: One'].join('\n');
|
||||
@@ -2431,7 +2431,7 @@ describe('#3642 — single-section leak controls and seam pins', () => {
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
describe('#4186: normalizeStateStatus anchored status vocabulary — substring traps', () => {
|
||||
const { normalizeStateStatus } = require('../gsd-core/bin/lib/state-document.cjs');
|
||||
const { normalizeStateStatus } = require('../msd-core/bin/lib/state-document.cjs');
|
||||
|
||||
// Row 1 — the failing-first regression: a `.planning/` path inside Italian
|
||||
// prose must NOT land on `planning` (the trigger word lives in the
|
||||
@@ -2494,7 +2494,7 @@ describe('#4186: normalizeStateStatus anchored status vocabulary — substring t
|
||||
});
|
||||
|
||||
describe('#4186: normalizeStateStatus anchored status vocabulary — documented vocabulary still normalizes', () => {
|
||||
const { normalizeStateStatus } = require('../gsd-core/bin/lib/state-document.cjs');
|
||||
const { normalizeStateStatus } = require('../msd-core/bin/lib/state-document.cjs');
|
||||
|
||||
test('rows 13-15: variable handler-written phase statuses (case/whitespace variants)', () => {
|
||||
assert.strictEqual(normalizeStateStatus('Executing Phase 5', null), 'executing');
|
||||
|
||||
Reference in New Issue
Block a user