mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-11-11 08:37:35 +00:00
* docs: align resolution architecture and roadmap * docs: add language ingestion gap inventories * test: audit receiver gap targets and coverage Check exact declaration IDs, expose the Dart await wrong-owner edge, and execute previously excluded C++, Rust, PHP, Dart and Vue shapes. Refresh the baseline and all language inventories from fresh measurements; call-drop counts remain unchanged. * docs: focus roadmap and shorten project README Keep the resolution roadmap limited to future work and acceptance criteria. Move detailed editor, CLI, MCP, deployment and wiki instructions into linked guides, preserve their command examples, and correct stale onboarding claims. * docs: correct setup and audit descriptions --------- Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
79 lines
2.7 KiB
TypeScript
79 lines
2.7 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { classify } from '../../bench/receiver-resolution/measure.mjs';
|
|
|
|
const expectedTarget = 'Method:models.dart:User.save#0';
|
|
const wrongTarget = 'Method:models.dart:Address.save#0';
|
|
const caller = 'Function:main.dart:awaitParen';
|
|
const corpus = {
|
|
ext: '.dart',
|
|
shapes: [
|
|
{
|
|
id: 'awaitParen',
|
|
member: 'save',
|
|
body: '(await svc.getUserAsync()).save();',
|
|
expectedTarget,
|
|
},
|
|
],
|
|
};
|
|
|
|
function result(targets: string[], outcomes: Record<string, unknown>[] = []) {
|
|
const nodes = new Map([
|
|
[caller, { properties: { name: 'awaitParen', filePath: 'main.dart' } }],
|
|
[expectedTarget, { properties: { name: 'save', filePath: 'models.dart' } }],
|
|
[wrongTarget, { properties: { name: 'save', filePath: 'models.dart' } }],
|
|
]);
|
|
return {
|
|
graph: {
|
|
getNode: (id: string) => nodes.get(id),
|
|
iterRelationships: () =>
|
|
targets.map((targetId) => ({ type: 'CALLS', sourceId: caller, targetId })),
|
|
},
|
|
resolutionOutcomes: outcomes,
|
|
};
|
|
}
|
|
|
|
function drop(filePath = 'main.dart', siteKind = 'call') {
|
|
return {
|
|
kind: 'suppressed',
|
|
reason: 'receiver-unresolved',
|
|
name: 'save',
|
|
shapeId: 'awaitParen',
|
|
filePath,
|
|
siteKind,
|
|
};
|
|
}
|
|
|
|
describe('receiver measurement target and drop identity', () => {
|
|
it('does not report a same-named method on the wrong owner as resolved', () => {
|
|
expect(classify(corpus, result([wrongTarget]))[0].state).toBe('WRONG-TARGET');
|
|
});
|
|
|
|
it('reports an extra wrong target even when the expected method also resolves', () => {
|
|
expect(classify(corpus, result([expectedTarget, wrongTarget]))[0].state).toBe('WRONG-TARGET');
|
|
});
|
|
|
|
it('resolves only the expected declaration', () => {
|
|
expect(classify(corpus, result([expectedTarget]))[0].state).toBe('RESOLVES');
|
|
});
|
|
|
|
it('keeps untyped controls unresolved and rejects a guessed edge', () => {
|
|
const untyped = { ...corpus, shapes: [{ ...corpus.shapes[0], expectedTarget: null }] };
|
|
expect(classify(untyped, result([], [drop()]))[0].state).toBe('VISIBLE-GAP');
|
|
expect(classify(untyped, result([expectedTarget]))[0].state).toBe('WRONG-TARGET');
|
|
});
|
|
|
|
it('does not borrow a drop from another file at the same shape line', () => {
|
|
expect(classify(corpus, result([], [drop('models.dart')]))[0].state).toBe('INVISIBLE-GAP');
|
|
});
|
|
|
|
it('does not treat a property-read drop as a missing call diagnostic', () => {
|
|
expect(classify(corpus, result([], [drop('main.dart', 'read')]))[0].state).toBe(
|
|
'INVISIBLE-GAP',
|
|
);
|
|
});
|
|
|
|
it('distinguishes an observed call drop from an unrecorded call', () => {
|
|
expect(classify(corpus, result([], [drop()]))[0].state).toBe('VISIBLE-GAP');
|
|
expect(classify(corpus, result([]))[0].state).toBe('INVISIBLE-GAP');
|
|
});
|
|
});
|