Files
brain/tools/observer-chain-map-checker.test.mjs
T

47 lines
1.6 KiB
JavaScript

import { describe, it, expect } from 'vitest';
import { parseChainsFromMd, checkSync } from './observer-chain-map-checker.mjs';
const SAMPLE_MD = [
'| # | Цепочка | Зачем |',
'|---|---|---|',
'| L1 | `discovery-interview` (FEATURE) → `brainstorming` | text |',
'| L2 | `audit-portal` | text |',
'| L13 | `billing-audit` (#62) + `Pest` | text |',
].join('\n');
describe('parseChainsFromMd', () => {
it('extracts the set of L-numbers from the table', () => {
expect(parseChainsFromMd(SAMPLE_MD)).toEqual(new Set(['L1', 'L2', 'L13']));
});
});
describe('checkSync', () => {
it('passes when JSON L-numbers subset of md and md subset of json-union', () => {
const mdSet = new Set(['L1', 'L2', 'L13']);
const jsonMap = { a: ['L1'], b: ['L2'], c: ['L13'] };
expect(checkSync(jsonMap, mdSet).ok).toBe(true);
});
it('fails when JSON references a chain absent from md', () => {
const mdSet = new Set(['L1', 'L2']);
const jsonMap = { a: ['L1'], b: ['L99'] };
const res = checkSync(jsonMap, mdSet);
expect(res.ok).toBe(false);
expect(res.jsonOnly).toContain('L99');
});
it('fails when md has a chain not covered by any JSON entry', () => {
const mdSet = new Set(['L1', 'L2', 'L14']);
const jsonMap = { a: ['L1'], b: ['L2'] };
const res = checkSync(jsonMap, mdSet);
expect(res.ok).toBe(false);
expect(res.mdOnly).toContain('L14');
});
it('ignores the _note metadata key in the JSON map', () => {
const mdSet = new Set(['L1']);
const jsonMap = { _note: 'meta', a: ['L1'] };
expect(checkSync(jsonMap, mdSet).ok).toBe(true);
});
});