mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
test(group/sync): cover manifest links producing cross-links
Add a unit test that asserts config.links entries produce contract pairs and a manifest cross-link (matchType: 'manifest') via syncGroup. Also refactors the manifest extraction call to sit outside the else/try block so it runs regardless of extractorOverride arity — makes the code testable without mocked DB pools and ensures links work when callers supply a zero-arity override (e.g. in tests or programmatic usage).
This commit is contained in:
parent
a18fea0d95
commit
3212ffcb04
2 changed files with 56 additions and 15 deletions
|
|
@ -154,20 +154,6 @@ export async function syncGroup(config: GroupConfig, opts?: SyncOptions): Promis
|
|||
}
|
||||
}
|
||||
|
||||
// Process manifest links while DB pools are still open.
|
||||
// ManifestExtractor is fully implemented but was never wired into this
|
||||
// pipeline — config.links were parsed and validated but silently dropped.
|
||||
if (config.links.length > 0) {
|
||||
const manifestEx = new ManifestExtractor();
|
||||
const manifestResult = await manifestEx.extractFromManifest(config.links, dbExecutors);
|
||||
autoContracts.push(...manifestResult.contracts);
|
||||
manifestCrossLinks = manifestResult.crossLinks;
|
||||
if (opts?.verbose) {
|
||||
console.log(
|
||||
` manifest: ${manifestCrossLinks.length} cross-links from ${config.links.length} declared links`,
|
||||
);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
for (const id of [...new Set(openPoolIds)]) {
|
||||
await closeLbug(id).catch(() => {});
|
||||
|
|
@ -175,6 +161,24 @@ export async function syncGroup(config: GroupConfig, opts?: SyncOptions): Promis
|
|||
}
|
||||
}
|
||||
|
||||
// Process manifest links declared in group.yaml.
|
||||
// ManifestExtractor is fully implemented but was never wired into this
|
||||
// pipeline — config.links were parsed and validated but silently dropped.
|
||||
// Placed after the DB try/finally: resolveSymbol falls back to synthetic
|
||||
// UIDs when dbExecutors is undefined or a pool is closed, so cross-links
|
||||
// are always generated regardless of whether real DB executors are available.
|
||||
if (config.links.length > 0) {
|
||||
const manifestEx = new ManifestExtractor();
|
||||
const manifestResult = await manifestEx.extractFromManifest(config.links, dbExecutors);
|
||||
autoContracts.push(...manifestResult.contracts);
|
||||
manifestCrossLinks = manifestResult.crossLinks;
|
||||
if (opts?.verbose) {
|
||||
console.log(
|
||||
` manifest: ${manifestCrossLinks.length} cross-links from ${config.links.length} declared links`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const { matched, unmatched } = runExactMatch(autoContracts);
|
||||
const crossLinks: CrossLink[] = [...matched, ...manifestCrossLinks];
|
||||
const allContracts: StoredContract[] = autoContracts;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import * as fs from 'node:fs';
|
|||
import * as path from 'node:path';
|
||||
import * as os from 'node:os';
|
||||
import { syncGroup, stableRepoPoolId } from '../../../src/core/group/sync.js';
|
||||
import type { GroupConfig, StoredContract, RepoHandle } from '../../../src/core/group/types.js';
|
||||
import type { GroupConfig, StoredContract, RepoHandle, GroupManifestLink } from '../../../src/core/group/types.js';
|
||||
import type { RegistryEntry } from '../../../src/storage/repo-manager.js';
|
||||
|
||||
describe('syncGroup', () => {
|
||||
|
|
@ -202,6 +202,43 @@ describe('syncGroup', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('manifest links in config.links produce cross-links with matchType manifest', async () => {
|
||||
const links: GroupManifestLink[] = [
|
||||
{
|
||||
from: 'app/consumer',
|
||||
to: 'app/provider',
|
||||
type: 'http',
|
||||
contract: 'GET::/api/orders',
|
||||
role: 'consumer',
|
||||
},
|
||||
];
|
||||
|
||||
const config: GroupConfig = {
|
||||
version: 1,
|
||||
name: 'test',
|
||||
description: '',
|
||||
repos: { 'app/consumer': 'consumer-repo', 'app/provider': 'provider-repo' },
|
||||
links,
|
||||
packages: {},
|
||||
detect: { http: true, grpc: false, topics: false, shared_libs: false, embedding_fallback: false },
|
||||
matching: { bm25_threshold: 0.7, embedding_threshold: 0.65, max_candidates_per_step: 3 },
|
||||
};
|
||||
|
||||
const result = await syncGroup(config, {
|
||||
extractorOverride: async () => [],
|
||||
skipWrite: true,
|
||||
});
|
||||
|
||||
// ManifestExtractor should inject 2 contracts (provider + consumer) and 1 cross-link
|
||||
expect(result.contracts).toHaveLength(2);
|
||||
const manifestLinks = result.crossLinks.filter((cl) => cl.matchType === 'manifest');
|
||||
expect(manifestLinks).toHaveLength(1);
|
||||
expect(manifestLinks[0].contractId).toBe('http::GET::/api/orders');
|
||||
expect(manifestLinks[0].from.repo).toBe('app/consumer');
|
||||
expect(manifestLinks[0].to.repo).toBe('app/provider');
|
||||
expect(manifestLinks[0].confidence).toBe(1.0);
|
||||
});
|
||||
|
||||
it('writes registry to groupDir when skipWrite is false', async () => {
|
||||
const tmpDir = path.join(os.tmpdir(), `gitnexus-sync-write-${Date.now()}`);
|
||||
fs.mkdirSync(tmpDir, { recursive: true });
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue