fix(opencode): normalize tool paths across platforms (#2459)

Normalize backslash paths for OpenCode formatting and add branch coverage for GitHub coordination behavior.
This commit is contained in:
Alexis D. 2026-07-26 12:13:49 +02:00 committed by GitHub
parent 5a4777777d
commit 71438391e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 805 additions and 1 deletions

View file

@ -0,0 +1,268 @@
/**
* Targeted branch coverage tests for uncovered paths in:
* scripts/lib/github-coordination/parsing.js
* scripts/lib/github-coordination/state.js
*
* Run with: node tests/lib/github-coordination-branches.test.js
*/
'use strict';
const assert = require('assert');
const {
normalizeBodyForComparison,
parseStringList,
mergeIssueBody,
} = require('../../scripts/lib/github-coordination/parsing');
const {
assertIssueClaimable,
buildIssueStateFromAction,
defaultCoordinationState,
desiredLabelsForState,
mapStateToWorkItemStatus,
verifyDependenciesClosed,
} = require('../../scripts/lib/github-coordination/state');
function test(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (err) {
console.log(`${name}`);
console.log(` Error: ${err.message}`);
return false;
}
}
let passed = 0;
let failed = 0;
console.log('\n=== parsing.js — uncovered branches ===\n');
console.log('normalizeBodyForComparison:');
if (test('handles null body (uses empty string fallback)', () => {
const result = normalizeBodyForComparison(null);
assert.strictEqual(result, '');
})) passed++; else failed++;
if (test('handles undefined body', () => {
const result = normalizeBodyForComparison(undefined);
assert.strictEqual(result, '');
})) passed++; else failed++;
if (test('normalizes lastSyncAt timestamps in body text', () => {
const body = 'before "lastSyncAt": "2024-01-01T00:00:00.000Z", after';
const result = normalizeBodyForComparison(body);
assert.ok(result.includes('"lastSyncAt": NORMALIZED'));
assert.ok(!result.includes('2024-01-01'));
})) passed++; else failed++;
console.log('\nparseStringList:');
if (test('returns empty array for null', () => {
assert.deepStrictEqual(parseStringList(null), []);
})) passed++; else failed++;
if (test('returns empty array for undefined', () => {
assert.deepStrictEqual(parseStringList(undefined), []);
})) passed++; else failed++;
if (test('returns empty array for empty string', () => {
assert.deepStrictEqual(parseStringList(''), []);
})) passed++; else failed++;
if (test('splits a comma-separated string into trimmed parts', () => {
assert.deepStrictEqual(parseStringList('a, b , c'), ['a', 'b', 'c']);
})) passed++; else failed++;
if (test('filters out empty parts from double-commas', () => {
assert.deepStrictEqual(parseStringList('a,,b'), ['a', 'b']);
})) passed++; else failed++;
console.log('\nmergeIssueBody — empty body branch:');
if (test('returns rendered state when issue body is empty string', () => {
const state = { status: 'available', schemaVersion: 'v1', kind: 'epic', owner: null, branch: null, validation: 'pending', review: 'not-requested', project: { state: 'backlog', fields: {} }, dependencies: [], tasks: [], labels: [], lastAction: 'sync' };
const result = mergeIssueBody({ body: '' }, state);
assert.ok(result.includes('ecc-coordination:start'));
})) passed++; else failed++;
if (test('returns rendered state when issue body is null', () => {
const state = { status: 'available', schemaVersion: 'v1', kind: 'epic', owner: null, branch: null, validation: 'pending', review: 'not-requested', project: { state: 'backlog', fields: {} }, dependencies: [], tasks: [], labels: [], lastAction: 'sync' };
const result = mergeIssueBody({ body: null }, state);
assert.ok(result.includes('ecc-coordination:start'));
})) passed++; else failed++;
console.log('\n=== state.js — uncovered branches ===\n');
console.log('buildIssueStateFromAction — options absent (false branches):');
const baseIssue = { number: 1, labels: [], body: '' };
const baseState = {
schemaVersion: 'v1', kind: 'epic', status: 'available', owner: null,
branch: null, validation: 'pending', review: 'not-requested',
project: { state: 'backlog', fields: {} }, dependencies: [], tasks: [],
labels: [], lastAction: 'sync', lastActionAt: null, lastSyncAt: null, notes: null
};
if (test('buildIssueStateFromAction with no options — does not set owner/branch/etc', () => {
const result = buildIssueStateFromAction(baseIssue, baseState, 'sync');
assert.strictEqual(result.lastAction, 'sync');
assert.strictEqual(result.owner, null);
assert.strictEqual(result.branch, null);
})) passed++; else failed++;
if (test('buildIssueStateFromAction with empty options — all conditional branches skip', () => {
const result = buildIssueStateFromAction(baseIssue, { ...baseState }, 'sync', {});
assert.ok(typeof result.lastAction === 'string');
})) passed++; else failed++;
if (test('buildIssueStateFromAction — currentState.dependencies not array → re-extracted', () => {
const issue = { number: 1, labels: [], body: 'Depends on #5 and #6' };
const result = buildIssueStateFromAction(issue, { ...baseState, dependencies: 'not-array' }, 'sync');
assert.ok(Array.isArray(result.dependencies));
})) passed++; else failed++;
if (test('buildIssueStateFromAction — currentState.tasks not array → re-extracted', () => {
const issue = { number: 1, labels: [], body: '## Tasks\n- [ ] Step 1\n- [x] Step 2' };
const result = buildIssueStateFromAction(issue, { ...baseState, tasks: 'not-array' }, 'sync');
assert.ok(Array.isArray(result.tasks));
})) passed++; else failed++;
console.log('\ndesiredLabelsForState — uncovered status/review/validation branches:');
if (test('includes published label for status "published"', () => {
const labels = desiredLabelsForState({ status: 'published' });
assert.ok(labels.includes('coordination:published'));
})) passed++; else failed++;
if (test('includes validated label for validation "passed"', () => {
const labels = desiredLabelsForState({ status: 'available', validation: 'passed' });
assert.ok(labels.includes('coordination:validated'));
})) passed++; else failed++;
if (test('includes review-requested label for review "requested"', () => {
const labels = desiredLabelsForState({ status: 'available', review: 'requested' });
assert.ok(labels.includes('coordination:review-requested'));
})) passed++; else failed++;
if (test('includes review-approved label for review "approved"', () => {
const labels = desiredLabelsForState({ status: 'available', review: 'approved' });
assert.ok(labels.includes('coordination:review-approved'));
})) passed++; else failed++;
if (test('includes review-changes-requested label for review "changes-requested"', () => {
const labels = desiredLabelsForState({ status: 'available', review: 'changes-requested' });
assert.ok(labels.includes('coordination:review-changes-requested'));
})) passed++; else failed++;
console.log('\nmapStateToWorkItemStatus — uncovered switch cases:');
if (test('"validated" → "in-progress"', () => {
assert.strictEqual(mapStateToWorkItemStatus('validated'), 'in-progress');
})) passed++; else failed++;
if (test('"reviewing" → "in-progress"', () => {
assert.strictEqual(mapStateToWorkItemStatus('reviewing'), 'in-progress');
})) passed++; else failed++;
if (test('"changes-requested" → "needs-review"', () => {
assert.strictEqual(mapStateToWorkItemStatus('changes-requested'), 'needs-review');
})) passed++; else failed++;
if (test('"published" → "done"', () => {
assert.strictEqual(mapStateToWorkItemStatus('published'), 'done');
})) passed++; else failed++;
if (test('"unknown-state" → "open" (default)', () => {
assert.strictEqual(mapStateToWorkItemStatus('unknown-state'), 'open');
})) passed++; else failed++;
console.log('\nassertIssueClaimable:');
if (test('throws when issue is not open', () => {
assert.throws(
() => assertIssueClaimable({ number: 1, state: 'closed' }, { status: 'available' }),
/is not open/
);
})) passed++; else failed++;
if (test('throws when issue is already claimed', () => {
assert.throws(
() => assertIssueClaimable({ number: 1, state: 'open' }, { status: 'claimed', owner: 'alice' }),
/already claimed/
);
})) passed++; else failed++;
if (test('does not throw for open, unclaimed issue', () => {
assert.doesNotThrow(() => {
assertIssueClaimable({ number: 1, state: 'open' }, { status: 'available' });
});
})) passed++; else failed++;
console.log('\nverifyDependenciesClosed:');
if (test('returns empty array when dependencyNumbers is not an array', () => {
const result = verifyDependenciesClosed('r/r', null, {}, []);
assert.deepStrictEqual(result, []);
})) passed++; else failed++;
if (test('returns empty array when dependencyNumbers is empty', () => {
const result = verifyDependenciesClosed('r/r', [], {}, []);
assert.deepStrictEqual(result, []);
})) passed++; else failed++;
if (test('returns closed issues when dependency is in closed state', () => {
const issues = [{ number: 5, state: 'closed' }, { number: 6, state: 'open' }];
const result = verifyDependenciesClosed('r/r', [5, 6], {}, issues);
assert.deepStrictEqual(result, [5]);
})) passed++; else failed++;
if (test('warns via stderr and skips when dependency issue is not in allIssues list', () => {
const issues = [{ number: 99, state: 'closed' }];
const originalWrite = process.stderr.write;
let stderrOutput = '';
process.stderr.write = (chunk) => {
stderrOutput += chunk;
return true;
};
let result;
try {
result = verifyDependenciesClosed('r/r', [5], {}, issues);
} finally {
process.stderr.write = originalWrite;
}
assert.deepStrictEqual(result, []);
assert.ok(stderrOutput.includes('dependency issue #5 not found'), `expected stderr warning, got: ${stderrOutput}`);
})) passed++; else failed++;
console.log('\ndefaultCoordinationState — edge branches:');
if (test('owner is null when issue has no author', () => {
const result = defaultCoordinationState({ number: 1, labels: [] });
assert.strictEqual(result.owner, null);
})) passed++; else failed++;
if (test('owner is null when issue.author has no login', () => {
const result = defaultCoordinationState({ number: 1, labels: [], author: {} });
assert.strictEqual(result.owner, null);
})) passed++; else failed++;
if (test('owner is set from issue.author.login', () => {
const result = defaultCoordinationState({ number: 1, labels: [], author: { login: 'alice' } });
assert.strictEqual(result.owner, 'alice');
})) passed++; else failed++;
if (test('handles null issue', () => {
const result = defaultCoordinationState(null);
assert.strictEqual(result.owner, null);
assert.deepStrictEqual(result.dependencies, []);
assert.deepStrictEqual(result.tasks, []);
})) passed++; else failed++;
console.log(`\n Results: ${passed} passed, ${failed} failed`);
if (failed > 0) process.exit(1);

View file

@ -0,0 +1,310 @@
/**
* Tests for scripts/lib/github-coordination/policy.js loadPolicy branch coverage
*
* Run with: node tests/lib/github-coordination-policy.test.js
*/
'use strict';
const assert = require('assert');
const fs = require('fs');
const os = require('os');
const path = require('path');
const {
loadPolicy,
DEFAULT_POLICY,
DEFAULT_LABELS,
DEFAULT_SCHEMA_VERSION,
DEFAULT_SECTION_MARKER,
} = require('../../scripts/lib/github-coordination/policy');
function test(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (err) {
console.log(`${name}`);
console.log(` Error: ${err.message}`);
return false;
}
}
function withTempDir(fn) {
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-policy-test-'));
try {
fn(tmpDir);
} finally {
fs.rmSync(tmpDir, { recursive: true, force: true });
}
}
function writeConfig(tmpDir, content) {
const configDir = path.join(tmpDir, 'config');
fs.mkdirSync(configDir, { recursive: true });
const configPath = path.join(configDir, 'github-native-coordination.json');
fs.writeFileSync(configPath, typeof content === 'string' ? content : JSON.stringify(content));
return configPath;
}
let passed = 0;
let failed = 0;
console.log('\n=== Testing github-coordination/policy.js ===\n');
console.log('loadPolicy — no config file:');
if (test('returns default policy when no config file exists in rootDir', () => {
withTempDir(tmpDir => {
const result = loadPolicy(tmpDir);
assert.strictEqual(result.sourcePath, null);
assert.strictEqual(result.schemaVersion, DEFAULT_SCHEMA_VERSION);
assert.strictEqual(result.sectionMarker, DEFAULT_SECTION_MARKER);
assert.deepStrictEqual(result.labels, DEFAULT_LABELS);
assert.deepStrictEqual(result.review, DEFAULT_POLICY.review);
});
})) passed++; else failed++;
if (test('returns default policy when custom configPath does not exist', () => {
withTempDir(tmpDir => {
const result = loadPolicy(tmpDir, path.join(tmpDir, 'nonexistent.json'));
assert.strictEqual(result.sourcePath, null);
assert.deepStrictEqual(result.review, DEFAULT_POLICY.review);
});
})) passed++; else failed++;
console.log('\nloadPolicy — configPath argument:');
if (test('uses configPath when explicitly provided', () => {
withTempDir(tmpDir => {
const configPath = path.join(tmpDir, 'my-policy.json');
fs.writeFileSync(configPath, JSON.stringify({ schemaVersion: 'custom-v1' }));
const result = loadPolicy(tmpDir, configPath);
assert.strictEqual(result.sourcePath, configPath);
assert.strictEqual(result.schemaVersion, 'custom-v1');
});
})) passed++; else failed++;
if (test('falls back to rootDir config file when configPath is null', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { schemaVersion: 'root-v1' });
const result = loadPolicy(tmpDir, null);
assert.strictEqual(result.schemaVersion, 'root-v1');
assert.ok(result.sourcePath !== null);
});
})) passed++; else failed++;
console.log('\nloadPolicy — invalid JSON:');
if (test('throws on invalid JSON', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, '{ bad json !!!! }');
assert.throws(() => loadPolicy(tmpDir), /Failed to load policy/);
});
})) passed++; else failed++;
console.log('\nloadPolicy — non-object JSON:');
if (test('throws when top-level JSON is null', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, 'null');
assert.throws(() => loadPolicy(tmpDir), /must contain a JSON object/);
});
})) passed++; else failed++;
if (test('throws when top-level JSON is an array', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, '[]');
assert.throws(() => loadPolicy(tmpDir), /must contain a JSON object/);
});
})) passed++; else failed++;
if (test('throws when top-level JSON is a string', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, '"just a string"');
assert.throws(() => loadPolicy(tmpDir), /must contain a JSON object/);
});
})) passed++; else failed++;
console.log('\nloadPolicy — labels merging:');
if (test('merges labels when parsed.labels is a plain object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { labels: { epic: 'my-epic' } });
const result = loadPolicy(tmpDir);
assert.strictEqual(result.labels.epic, 'my-epic');
assert.strictEqual(result.labels.available, DEFAULT_LABELS.available);
});
})) passed++; else failed++;
if (test('falls back to empty labels when parsed.labels is null', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { labels: null });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.labels, DEFAULT_LABELS);
});
})) passed++; else failed++;
if (test('falls back to empty labels when parsed.labels is an array', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { labels: ['a', 'b'] });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.labels, DEFAULT_LABELS);
});
})) passed++; else failed++;
if (test('falls back to empty labels when parsed.labels is a string', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { labels: 'bad' });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.labels, DEFAULT_LABELS);
});
})) passed++; else failed++;
console.log('\nloadPolicy — review merging:');
if (test('merges review when parsed.review is a plain object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { review: { required: false } });
const result = loadPolicy(tmpDir);
assert.strictEqual(result.review.required, false);
assert.strictEqual(result.review.defaultMode, DEFAULT_POLICY.review.defaultMode);
});
})) passed++; else failed++;
if (test('falls back when parsed.review is not an object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { review: 'string' });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.review, DEFAULT_POLICY.review);
});
})) passed++; else failed++;
if (test('falls back when parsed.review is null', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { review: null });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.review, DEFAULT_POLICY.review);
});
})) passed++; else failed++;
if (test('falls back when parsed.review is an array', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { review: [] });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.review, DEFAULT_POLICY.review);
});
})) passed++; else failed++;
console.log('\nloadPolicy — validation merging:');
if (test('merges validation when parsed.validation is a plain object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { validation: { required: false } });
const result = loadPolicy(tmpDir);
assert.strictEqual(result.validation.required, false);
});
})) passed++; else failed++;
if (test('falls back when parsed.validation is not an object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { validation: 42 });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.validation, DEFAULT_POLICY.validation);
});
})) passed++; else failed++;
console.log('\nloadPolicy — branchModel merging:');
if (test('merges branchModel when parsed.branchModel is a plain object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { branchModel: { epicOnly: false, taskBranches: true } });
const result = loadPolicy(tmpDir);
assert.strictEqual(result.branchModel.epicOnly, false);
assert.strictEqual(result.branchModel.taskBranches, true);
});
})) passed++; else failed++;
if (test('falls back when parsed.branchModel is not an object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { branchModel: true });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.branchModel, DEFAULT_POLICY.branchModel);
});
})) passed++; else failed++;
console.log('\nloadPolicy — project merging:');
if (test('merges project when parsed.project is a plain object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: { enabled: true } });
const result = loadPolicy(tmpDir);
assert.strictEqual(result.project.enabled, true);
assert.deepStrictEqual(result.project.fieldNames, DEFAULT_POLICY.project.fieldNames);
});
})) passed++; else failed++;
if (test('falls back when parsed.project is not an object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: 'invalid' });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.project, DEFAULT_POLICY.project);
});
})) passed++; else failed++;
if (test('falls back when parsed.project is null', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: null });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.project, DEFAULT_POLICY.project);
});
})) passed++; else failed++;
console.log('\nloadPolicy — project.fieldNames merging:');
if (test('merges fieldNames when project.fieldNames is a plain object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: { enabled: true, fieldNames: { status: 'MyStatus' } } });
const result = loadPolicy(tmpDir);
assert.strictEqual(result.project.fieldNames.status, 'MyStatus');
assert.strictEqual(result.project.fieldNames.owner, DEFAULT_POLICY.project.fieldNames.owner);
});
})) passed++; else failed++;
if (test('falls back when project.fieldNames is not an object', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: { fieldNames: 'bad' } });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.project.fieldNames, DEFAULT_POLICY.project.fieldNames);
});
})) passed++; else failed++;
if (test('falls back when project.fieldNames is null', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: { fieldNames: null } });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.project.fieldNames, DEFAULT_POLICY.project.fieldNames);
});
})) passed++; else failed++;
if (test('falls back when project.fieldNames is an array', () => {
withTempDir(tmpDir => {
writeConfig(tmpDir, { project: { fieldNames: [] } });
const result = loadPolicy(tmpDir);
assert.deepStrictEqual(result.project.fieldNames, DEFAULT_POLICY.project.fieldNames);
});
})) passed++; else failed++;
console.log('\nloadPolicy — sourcePath:');
if (test('sets sourcePath to the resolved config file path', () => {
withTempDir(tmpDir => {
const configPath = writeConfig(tmpDir, {});
const result = loadPolicy(tmpDir);
assert.strictEqual(result.sourcePath, configPath);
});
})) passed++; else failed++;
console.log(`\n Results: ${passed} passed, ${failed} failed`);
if (failed > 0) process.exit(1);

View file

@ -0,0 +1,208 @@
/**
* Tests for scripts/lib/github-coordination/store.js branch coverage
*
* Run with: node tests/lib/github-coordination-store.test.js
*/
'use strict';
const assert = require('assert');
const {
epicWorkItemId,
upsertCoordinationWorkItem,
openStore,
} = require('../../scripts/lib/github-coordination/store');
const { DEFAULT_SCHEMA_VERSION, DEFAULT_POLICY } = require('../../scripts/lib/github-coordination/policy');
function test(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (err) {
console.log(`${name}`);
console.log(` Error: ${err.message}`);
return false;
}
}
function makeStore() {
const calls = [];
return {
calls,
upsertWorkItem(item) {
calls.push(item);
return item;
},
};
}
let passed = 0;
let failed = 0;
console.log('\n=== Testing github-coordination/store.js ===\n');
console.log('epicWorkItemId:');
if (test('produces a stable ID from repo and issue number', () => {
assert.strictEqual(epicWorkItemId('acme/my-repo', 42), 'github-acme-my-repo-epic-42');
})) passed++; else failed++;
console.log('\nupsertCoordinationWorkItem — null store:');
if (test('returns null when store is null', () => {
const result = upsertCoordinationWorkItem(null, 'r/r', { number: 1 }, {}, 'sync');
assert.strictEqual(result, null);
})) passed++; else failed++;
if (test('returns null when store is undefined', () => {
const result = upsertCoordinationWorkItem(undefined, 'r/r', { number: 1 }, {}, 'sync');
assert.strictEqual(result, null);
})) passed++; else failed++;
console.log('\nupsertCoordinationWorkItem — with store:');
if (test('passes schemaVersion from state when present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { schemaVersion: 'v99', status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].metadata.schemaVersion, 'v99');
})) passed++; else failed++;
if (test('uses DEFAULT_SCHEMA_VERSION when state.schemaVersion is absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].metadata.schemaVersion, DEFAULT_SCHEMA_VERSION);
})) passed++; else failed++;
if (test('sets issueUrl from issue.url when present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, url: 'https://example.com/1', labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].metadata.issueUrl, 'https://example.com/1');
})) passed++; else failed++;
if (test('sets issueUrl to null when issue.url is absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].metadata.issueUrl, null);
})) passed++; else failed++;
if (test('sets issueTitle from issue.title when present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, title: 'My Epic', labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].metadata.issueTitle, 'My Epic');
})) passed++; else failed++;
if (test('sets issueTitle to null when issue.title is absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].metadata.issueTitle, null);
})) passed++; else failed++;
if (test('uses custom policy from options.policy', () => {
const store = makeStore();
const customPolicy = { schemaVersion: 'custom', labels: {}, review: {}, validation: {}, branchModel: {}, project: { enabled: true, fieldNames: {} } };
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync', { policy: customPolicy });
assert.strictEqual(store.calls[0].metadata.projectProjection.enabled, true);
})) passed++; else failed++;
if (test('falls back to DEFAULT_POLICY when options.policy is absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync', {});
assert.strictEqual(store.calls[0].metadata.projectProjection.enabled, DEFAULT_POLICY.project.enabled);
})) passed++; else failed++;
if (test('sets priority high when state.status is blocked', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'blocked' }, 'sync');
assert.strictEqual(store.calls[0].priority, 'high');
})) passed++; else failed++;
if (test('sets priority normal when state.status is not blocked', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].priority, 'normal');
})) passed++; else failed++;
if (test('sets url from issue.url in upsertWorkItem call', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, url: 'https://gh/1', labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].url, 'https://gh/1');
})) passed++; else failed++;
if (test('sets url to null when issue.url absent in upsertWorkItem call', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].url, null);
})) passed++; else failed++;
if (test('uses state.owner when present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available', owner: 'alice' }, 'sync');
assert.strictEqual(store.calls[0].owner, 'alice');
})) passed++; else failed++;
if (test('falls back to issue.author.login when state.owner absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [], author: { login: 'bob' } }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].owner, 'bob');
})) passed++; else failed++;
if (test('sets owner to null when neither state.owner nor author.login present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].owner, null);
})) passed++; else failed++;
if (test('uses options.repoRoot when present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync', { repoRoot: '/my/repo' });
assert.strictEqual(store.calls[0].repoRoot, '/my/repo');
})) passed++; else failed++;
if (test('falls back to process.cwd() when options.repoRoot absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].repoRoot, process.cwd());
})) passed++; else failed++;
if (test('uses options.sessionId when present', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync', { sessionId: 'sess-1' });
assert.strictEqual(store.calls[0].sessionId, 'sess-1');
})) passed++; else failed++;
if (test('sets sessionId to null when options.sessionId absent', () => {
const store = makeStore();
upsertCoordinationWorkItem(store, 'a/b', { number: 1, labels: [] }, { status: 'available' }, 'sync');
assert.strictEqual(store.calls[0].sessionId, null);
})) passed++; else failed++;
console.log('\nopenStore — dbPath: false:');
async function runAsyncTests() {
let asyncPassed = 0;
let asyncFailed = 0;
try {
const result = await openStore({ dbPath: false });
assert.strictEqual(result, null);
console.log(' ✓ returns null when dbPath is false');
asyncPassed++;
} catch (err) {
console.log(' ✗ returns null when dbPath is false');
console.log(` Error: ${err.message}`);
asyncFailed++;
}
const totalPassed = passed + asyncPassed;
const totalFailed = failed + asyncFailed;
console.log(`\n Results: ${totalPassed} passed, ${totalFailed} failed`);
if (totalFailed > 0) process.exit(1);
}
runAsyncTests().catch(err => {
console.error(`Unexpected async test failure: ${err.message}`);
process.exit(1);
});

View file

@ -108,6 +108,24 @@ async function main() {
),
])
tests.push([
"format-code: normalizes Windows backslash paths to forward slashes",
async () => withTempProject(
["tsconfig.json", "src/index.ts"],
async (projectDir) => {
const context = createMockContext(projectDir)
const result = await tools.formatcode.execute(
{ filePath: "src\\index.ts" },
context
)
const parsed = JSON.parse(result)
assert.strictEqual(parsed.success, true)
assert.ok(parsed.command.includes("src/index.ts"), `expected forward slashes in command: ${parsed.command}`)
assert.ok(!parsed.command.includes("src\\index.ts"), `unexpected backslashes in command: ${parsed.command}`)
}
),
])
tests.push([
"format-code: detects Python formatter",
async () => withTempProject(