aeb81abfa2
Pure regex/JSON, 0 LLM calls. 5 Vitest tests GREEN (23/23 total). Per ADR-011 + spec §6.2. Smoke run on real repo surfaces ~150 «drifts» — these are **historical 'наследие' entries** in headers (CLAUDE.md / Pravila / Tooling / PSR_v1), not actual current cross-ref mismatches. Each of these 4 files has a multi-line «v2.X наследие:» / «v1.Y наследие:» chain in its top header describing past sub-versions; my 50-line scan picks them all up. CONCERN: mechanism is correct (test fixtures pass), but real-world needs refinement before lefthook wiring (C5). Options for follow-up: - Scope match to explicit «§0 cross-refs» table marker. - Distinguish «current cross-ref» from «historical наследие mention» by surrounding markup. - Restrict regex to cross-ref tables (markdown | columns) only. Until refined: C2 will be wired in C5 with caveat (WARN-only, or disabled) to avoid blocking every commit on pre-existing 'наследие' entries. Extracted Tooling Прил. Н version via **Версия:** pattern (file-level v8.3 wrapper at line 1 was misleading — Прил. Н is v2.17 at line 4). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
46 lines
1.5 KiB
JavaScript
46 lines
1.5 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { extractVersion, extractCrossRefs, detectMismatches } from './cross-ref-checker.mjs';
|
|
|
|
describe('extractVersion', () => {
|
|
it('extracts version from header', () => {
|
|
const text = '# Pravila v1.30 от 18.05.2026';
|
|
expect(extractVersion(text)).toBe('1.30');
|
|
});
|
|
|
|
it('returns null if no version', () => {
|
|
expect(extractVersion('# Untitled')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('extractCrossRefs', () => {
|
|
it('extracts cross-refs like "Pravila v1.29"', () => {
|
|
const text = 'See Pravila v1.29 and Tooling v2.15.';
|
|
const refs = extractCrossRefs(text);
|
|
expect(refs).toContainEqual({ name: 'Pravila', version: '1.29' });
|
|
expect(refs).toContainEqual({ name: 'Tooling', version: '2.15' });
|
|
});
|
|
});
|
|
|
|
describe('detectMismatches', () => {
|
|
it('detects when fileA references fileB v1.29 but fileB header is v1.30', () => {
|
|
const files = {
|
|
'A.md': '# A v1.0 — cross-refs: Pravila v1.29',
|
|
'docs/Pravila_raboty_Claude_v1_1.md': '# Pravila v1.30',
|
|
};
|
|
const m = detectMismatches(files);
|
|
expect(m).toHaveLength(1);
|
|
expect(m[0].from).toBe('A.md');
|
|
expect(m[0].to).toBe('Pravila');
|
|
expect(m[0].expected).toBe('1.30');
|
|
expect(m[0].found).toBe('1.29');
|
|
});
|
|
|
|
it('passes when in sync', () => {
|
|
const files = {
|
|
'A.md': '# A v1.0 — Pravila v1.30',
|
|
'docs/Pravila_raboty_Claude_v1_1.md': '# Pravila v1.30',
|
|
};
|
|
expect(detectMismatches(files)).toHaveLength(0);
|
|
});
|
|
});
|