mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-08 03:08:13 +00:00
Lands the authoritative data model and constants for the pure scope-based resolution RFC (#909) as Ring 1, part 1. No runtime behavior changes — types + constants only. New in gitnexus-shared/src/scope-resolution/: - types.ts — Scope, ScopeKind, ScopeId, DefId, Range, Capture, BindingRef, ImportEdge, TypeRef, Resolution, ResolutionEvidence, Reference, ReferenceIndex, LookupParams, RegistryContributor - evidence-weights.ts — EvidenceWeights constant map + typeBindingWeightAtDepth (RFC Appendix A) - origin-priority.ts — ORIGIN_PRIORITY constant map for deterministic tie-breaks (RFC Appendix B) - language-classification.ts — LanguageClassification type + LanguageClassifications map (production × 14, experimental × 2 for vue/cobol; governs Ring 4 DAG-retirement gate) - symbol-definition.ts — SymbolDefinition moved from gitnexus/src/core/ingestion/model/symbol-table.ts so scope-resolution types can reference it from the shared package Consumer updates: - symbol-table.ts: removes local SymbolDefinition declaration; imports from gitnexus-shared - model/index.ts: drops SymbolDefinition from barrel re-export per "direct imports from gitnexus-shared" convention (see gitnexus-shared feedback in project memory) - 9 source files + 5 test files: import SymbolDefinition directly from 'gitnexus-shared' Verification: - gitnexus-shared builds clean (tsc) - gitnexus builds clean (scripts/build.js) - 131/132 unit test files pass; 3767 tests green - Zero behavior changes; SymbolDefinition shape unchanged Blocks: #911 (LanguageProvider hook interface extensions) and all of Ring 2 (#912-#925). Closes part of #909.
74 lines
2.9 KiB
TypeScript
74 lines
2.9 KiB
TypeScript
/**
|
|
* Unit tests for FieldRegistry (SM-20).
|
|
*
|
|
* FieldRegistry is the simplest of the three owner-scoped registries —
|
|
* one flat Map keyed on `ownerNodeId\0fieldName`. These tests pin the
|
|
* basic register/lookup/clear contract and the owner-scope isolation.
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { createFieldRegistry } from '../../../src/core/ingestion/model/field-registry.js';
|
|
import type { SymbolDefinition } from 'gitnexus-shared';
|
|
import { makeDef as makeBaseDef } from './helpers.js';
|
|
|
|
const makeDef = (overrides: Partial<SymbolDefinition> = {}): SymbolDefinition =>
|
|
makeBaseDef({ nodeId: 'prop:test', type: 'Property', ...overrides });
|
|
|
|
describe('FieldRegistry', () => {
|
|
it('lookupFieldByOwner returns undefined when the registry is empty', () => {
|
|
const reg = createFieldRegistry();
|
|
expect(reg.lookupFieldByOwner('class:User', 'name')).toBeUndefined();
|
|
});
|
|
|
|
it('register + lookup round-trips the exact def reference', () => {
|
|
const reg = createFieldRegistry();
|
|
const def = makeDef({ nodeId: 'prop:User.name', declaredType: 'string' });
|
|
|
|
reg.register('class:User', 'name', def);
|
|
|
|
expect(reg.lookupFieldByOwner('class:User', 'name')).toBe(def);
|
|
});
|
|
|
|
it('isolates fields by ownerNodeId — same field name on two classes does not collide', () => {
|
|
const reg = createFieldRegistry();
|
|
const userName = makeDef({ nodeId: 'prop:User.name' });
|
|
const orderName = makeDef({ nodeId: 'prop:Order.name' });
|
|
|
|
reg.register('class:User', 'name', userName);
|
|
reg.register('class:Order', 'name', orderName);
|
|
|
|
expect(reg.lookupFieldByOwner('class:User', 'name')?.nodeId).toBe('prop:User.name');
|
|
expect(reg.lookupFieldByOwner('class:Order', 'name')?.nodeId).toBe('prop:Order.name');
|
|
});
|
|
|
|
it('last-wins on duplicate (ownerNodeId, fieldName) — registry is flat, not an overload list', () => {
|
|
const reg = createFieldRegistry();
|
|
const first = makeDef({ nodeId: 'prop:User.name#first' });
|
|
const second = makeDef({ nodeId: 'prop:User.name#second' });
|
|
|
|
reg.register('class:User', 'name', first);
|
|
reg.register('class:User', 'name', second);
|
|
|
|
expect(reg.lookupFieldByOwner('class:User', 'name')?.nodeId).toBe('prop:User.name#second');
|
|
});
|
|
|
|
it('clear() empties the registry', () => {
|
|
const reg = createFieldRegistry();
|
|
reg.register('class:User', 'name', makeDef());
|
|
reg.register('class:Order', 'total', makeDef());
|
|
|
|
reg.clear();
|
|
|
|
expect(reg.lookupFieldByOwner('class:User', 'name')).toBeUndefined();
|
|
expect(reg.lookupFieldByOwner('class:Order', 'total')).toBeUndefined();
|
|
});
|
|
|
|
it('allows re-registration after clear', () => {
|
|
const reg = createFieldRegistry();
|
|
reg.register('class:User', 'name', makeDef({ nodeId: 'prop:first' }));
|
|
reg.clear();
|
|
reg.register('class:User', 'name', makeDef({ nodeId: 'prop:second' }));
|
|
|
|
expect(reg.lookupFieldByOwner('class:User', 'name')?.nodeId).toBe('prop:second');
|
|
});
|
|
});
|