91ded23462
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
71 lines
4.5 KiB
JavaScript
71 lines
4.5 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { applyResults, applyHarvest } from './secretary-apply.mjs';
|
|
|
|
describe('applyResults', () => {
|
|
const base = () => ({ hidden: [], nextSvId: 1, candidates: [] });
|
|
|
|
it('новая ветка из диагностики получает id+паспорт; догадка+блокер→важное', () => {
|
|
const p = applyResults(base(), 13, { new: [{ text: 'x', lens: 'Л4', опора: 'догадка', тяжесть: 'блокер' }] }, { dropped: [] }, { forks: [] }, { tend: [] });
|
|
expect(p.hidden[0].id).toBe('СВ-1');
|
|
expect(p.hidden[0].опора).toBe('догадка');
|
|
expect(p.hidden[0].тяжесть).toBe('важное'); // зажим: догадка не блокер
|
|
});
|
|
|
|
it('брошенное ловцом → ветка lens=брош', () => {
|
|
const p = applyResults(base(), 13, { new: [] }, { dropped: [{ text: 'parked', цитата: 'q' }] }, { forks: [] }, { tend: [] });
|
|
expect(p.hidden[0].lens).toBe('брош');
|
|
});
|
|
|
|
it('кандидаты накапливаются (ход рождения), без дублей', () => {
|
|
let p = applyResults(base(), 13, { new: [] }, { dropped: [] }, { forks: [{ branch: 'idea-1' }] }, { tend: [] });
|
|
p = applyResults(p, 15, { new: [] }, { dropped: [] }, { forks: [{ branch: 'idea-1' }, { branch: 'idea-2' }] }, { tend: [] });
|
|
expect(p.candidates.map((c) => c.branch)).toEqual(['idea-1', 'idea-2']);
|
|
expect(p.candidates.find((c) => c.branch === 'idea-1').born).toBe(13);
|
|
});
|
|
|
|
it('садовник закрывает ветку через применение', () => {
|
|
const proto = { hidden: [{ id: 'СВ-1', status: 'открыт' }], nextSvId: 2, candidates: [] };
|
|
const p = applyResults(proto, 15, { new: [] }, { dropped: [] }, { forks: [] }, { tend: [{ id: 'СВ-1', action: 'close', proof: 'есть' }] });
|
|
expect(p.hidden[0].status).toBe('закрыт');
|
|
});
|
|
|
|
it('вход не мутируется', () => {
|
|
const proto = base();
|
|
applyResults(proto, 13, { new: [{ text: 'x', lens: 'Л1' }] }, { dropped: [] }, { forks: [] }, { tend: [] });
|
|
expect(proto.hidden).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe('applyHarvest (рождение+заточка+полнота кандидатов)', () => {
|
|
const base = (over) => ({ hidden: [], candidates: [], nextSvId: 1, nextKdId: 1,
|
|
decisions: [], alternatives: [], consequences: [], will: [], open: [], doneNext: [], history: [], ...over });
|
|
it('форк рождает кандидата с темой/важностью/id', () => {
|
|
const out = applyHarvest(base(), 1, { new: [] }, { dropped: [] },
|
|
{ forks: [{ branch: 'идея', title: 'т', тема: 'поиск', важность: 'medium' }] });
|
|
expect(out.candidates[0]).toMatchObject({ id: 'КД-1', тема: 'поиск', важность: 'medium', status: 'жив' });
|
|
});
|
|
it('диаг-ветка несёт title/тема/важность', () => {
|
|
const out = applyHarvest(base(), 1, { new: [{ text: 'дыра', lens: 'Л1', title: 'к', тема: 'поиск', важность: 'high' }] },
|
|
{ dropped: [] }, { forks: [] });
|
|
expect(out.hidden[0]).toMatchObject({ тема: 'поиск', важность: 'high', title: 'к' });
|
|
});
|
|
it('mutate точит кандидата → наследник с lineage', () => {
|
|
const p = base({ candidates: [{ id: 'КД-1', branch: 'старо', status: 'жив' }], nextKdId: 2 });
|
|
const out = applyHarvest(p, 2, { new: [] }, { dropped: [] },
|
|
{ forks: [], mutate: [{ id: 'КД-1', newText: 'остро', newTitle: 'острее', why: 'ход заточил' }] });
|
|
expect(out.candidates.find((c) => c.id === 'КД-1').status).toBe('мутировал');
|
|
expect(out.candidates.at(-1).lineage).toContain('КД-1');
|
|
});
|
|
it('gap рождает кандидата high+gap', () => {
|
|
const out = applyHarvest(base(), 3, { new: [] }, { dropped: [] },
|
|
{ forks: [], gaps: [{ тема: 'тесты', title: 'нет тестов', why: 'пласт отсутствует' }] });
|
|
expect(out.candidates.at(-1)).toMatchObject({ важность: 'high', gap: true });
|
|
});
|
|
it('gap дедуп по теме — не плодит дубль уже существующей темы', () => {
|
|
const p = base({ candidates: [{ id: 'КД-1', branch: 'x', тема: 'тесты' }], nextKdId: 2 });
|
|
const out = applyHarvest(p, 3, { new: [] }, { dropped: [] },
|
|
{ forks: [], gaps: [{ тема: 'тесты', title: 'дубль', why: 'w' }] });
|
|
expect(out.candidates.filter((c) => c.gap).length).toBe(0);
|
|
});
|
|
});
|