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.
86 lines
3.4 KiB
JavaScript
86 lines
3.4 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* Parity test: `capability-validator.cjs`'s install-time `KEBAB_RE` grammar
|
|
* check on `taskContentResolver.trackerPrefix` (`validateTaskContentResolver`)
|
|
* MUST agree with `task-content-resolution.cts`'s resolve-time re-validation
|
|
* inside `parseResolverDeclaration` (exercised here via `findResolver`) on
|
|
* every `trackerPrefix` value.
|
|
*
|
|
* This is the "Generative Fix Divergence" guard CLAUDE.md requires whenever
|
|
* two surfaces share a rule with no single source of truth: the grammar is
|
|
* duplicated as a literal regex in both files (see `task-content-
|
|
* resolution.cts`'s `TRACKER_PREFIX_RE` docstring for why it is not a shared
|
|
* import), so this test is what actually keeps them from drifting apart. If a
|
|
* future change to either regex loosens or tightens it without mirroring the
|
|
* change in the other file, this test fails.
|
|
*/
|
|
|
|
const { test, describe } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
const { validateTaskContentResolver } = require('../msd-core/bin/lib/capability-validator.cjs');
|
|
const { findResolver } = require('../msd-core/bin/lib/task-content-resolution.cjs');
|
|
const { TASK_RESOLVER_INVOKE_TIMEOUT_MS } = require('./helpers/timeouts.cjs');
|
|
|
|
function validInvoke() {
|
|
return { binary: 'bd', args: ['show', '{{id}}', '--json'], timeoutMs: TASK_RESOLVER_INVOKE_TIMEOUT_MS };
|
|
}
|
|
|
|
function featureCapWithResolver(trackerPrefix) {
|
|
return {
|
|
id: 'demo',
|
|
role: 'feature',
|
|
taskContentResolver: { trackerPrefix, invoke: validInvoke() },
|
|
};
|
|
}
|
|
|
|
/** True when the validator accepts this trackerPrefix (no trackerPrefix-naming error). */
|
|
function validatorAccepts(trackerPrefix) {
|
|
const cap = featureCapWithResolver(trackerPrefix);
|
|
const errs = validateTaskContentResolver(cap);
|
|
return !errs.some((e) => e.includes('trackerPrefix'));
|
|
}
|
|
|
|
/** True when the resolve-time seam accepts this trackerPrefix (finds a match, not `null`). */
|
|
function resolverAccepts(trackerPrefix) {
|
|
const capabilities = [featureCapWithResolver(trackerPrefix)];
|
|
const result = findResolver(trackerPrefix, capabilities);
|
|
return result !== null && result !== 'ambiguous';
|
|
}
|
|
|
|
const TABLE = [
|
|
{ trackerPrefix: 'beads', valid: true },
|
|
{ trackerPrefix: 'my-tracker', valid: true },
|
|
{ trackerPrefix: 'Beads', valid: false },
|
|
{ trackerPrefix: 'has_underscore', valid: false },
|
|
{ trackerPrefix: 'UPPER', valid: false },
|
|
{ trackerPrefix: '', valid: false },
|
|
{ trackerPrefix: '1leading-digit', valid: false },
|
|
];
|
|
|
|
describe('trackerPrefix grammar parity — capability-validator.cjs vs task-content-resolution.cts', () => {
|
|
for (const { trackerPrefix, valid } of TABLE) {
|
|
test(`'${trackerPrefix}' — validator and resolver agree (expected valid: ${valid})`, () => {
|
|
const validatorResult = validatorAccepts(trackerPrefix);
|
|
const resolverResult = resolverAccepts(trackerPrefix);
|
|
assert.strictEqual(
|
|
validatorResult,
|
|
valid,
|
|
`validator disagreed with expected table value for '${trackerPrefix}'`,
|
|
);
|
|
assert.strictEqual(
|
|
resolverResult,
|
|
valid,
|
|
`resolver disagreed with expected table value for '${trackerPrefix}'`,
|
|
);
|
|
assert.strictEqual(
|
|
validatorResult,
|
|
resolverResult,
|
|
`PARITY BREAK: validator and resolver disagree for trackerPrefix '${trackerPrefix}' ` +
|
|
`(validator: ${validatorResult}, resolver: ${resolverResult})`,
|
|
);
|
|
});
|
|
}
|
|
});
|