import { describe, it, expect } from 'vitest'; import { readFileSync } from 'node:fs'; import { givenTokens, loadInitialInputs } from './registry-initial-inputs.mjs'; import { findHoles, normToken } from './coverage-machine.mjs'; import { loadRegistry } from './skill-contract-registry.mjs'; const VOCAB = 'docs/registry/capability-vocabulary.json'; const raw = JSON.parse(readFileSync(VOCAB, 'utf8')); describe('registry-initial-inputs — данности задачи (D1)', () => { it('givenTokens возвращает ровно токены category:"given"', () => { const given = givenTokens(raw); expect(Array.isArray(given)).toBe(true); expect(given.length).toBeGreaterThan(50); // в словаре v0.6.0 их ~117 const set = new Set(given); for (const t of raw.tokens) { if (t.category === 'given') expect(set.has(t.token)).toBe(true); else expect(set.has(t.token)).toBe(false); } }); it('givenTokens на пустом/битом словаре → [] (без броска)', () => { expect(givenTokens(null)).toEqual([]); expect(givenTokens(undefined)).toEqual([]); expect(givenTokens({})).toEqual([]); expect(givenTokens({ tokens: [] })).toEqual([]); }); it('loadInitialInputs читает словарь и совпадает с givenTokens', () => { const fromFile = loadInitialInputs({ path: VOCAB }); expect(fromFile).toEqual(givenTokens(raw)); }); it('данности не считаются дырами и сокращают findHoles на полном наборе', () => { const reg = loadRegistry({ dir: 'docs/registry/contracts' }); const given = givenTokens(raw); const givenSet = new Set(given.map(normToken)); const without = findHoles(reg.contracts); const withInputs = findHoles(reg.contracts, { initialInputs: given }); for (const h of withInputs) { expect(givenSet.has(normToken(h.need))).toBe(false); } expect(withInputs.length).toBeLessThan(without.length); }); });