82 lines
4.6 KiB
JavaScript
82 lines
4.6 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import { renderFluffy, renderDoc } from './secretary-render-fluffy.mjs';
|
|
|
|
const base = () => ({ subject: 'дело', status: 'открыто', decisions: [], will: [], open: [], consequences: [], doneNext: [], hidden: [], acceptance: [], tails: [], candidates: [], steps: [] });
|
|
|
|
describe('renderFluffy', () => {
|
|
it('пустой протокол не падает, даёт заголовок и секции', () => {
|
|
const md = renderFluffy(base());
|
|
expect(md).toContain('# 📋 Протокол: дело');
|
|
expect(md).toContain('## 🌳 Ствол');
|
|
expect(md).toContain('## 🧭 Шаги');
|
|
});
|
|
it('живое решение наверху, зачёркнутое — в свёрнутом блоке, оба со ссылкой', () => {
|
|
const p = base();
|
|
p.decisions = [{ text: 'живое', why: 'потому', struck: false, turns: [5] }, { text: 'старое', struck: true, turns: [3] }];
|
|
const md = renderFluffy(p);
|
|
expect(md).toMatch(/- живое — потому.*ходы\/turn-5\.log/);
|
|
expect(md).toContain('<details><summary>▸ решённое в стволе');
|
|
expect(md).toMatch(/~~старое~~.*ходы\/turn-3\.log/);
|
|
});
|
|
it('живая ветка: глиф состояния + паспорт + источник born→lastTouch', () => {
|
|
const p = base();
|
|
p.hidden = [{ id: 'СВ-7', lens: 'Л6', status: 'сужен', text: 'граф хрупкость', опора: 'догадка', тяжесть: 'мелочь', born: 12, lastTouch: 15 }];
|
|
const md = renderFluffy(p);
|
|
expect(md).toContain('## 🌿 Живые ветки');
|
|
expect(md).toMatch(/✂️ сужен/);
|
|
expect(md).toMatch(/догадка · мелочь/);
|
|
expect(md).toMatch(/turn-12\.log.*turn-15\.log/);
|
|
});
|
|
it('закрытая ветка уходит в свёрнутые «решённые» с пруфом', () => {
|
|
const p = base();
|
|
p.hidden = [{ id: 'СВ-5', lens: 'Л4', status: 'закрыт', text: 'без пруфа', proof: 'код:107', born: 12, lastTouch: 13 }];
|
|
const md = renderFluffy(p);
|
|
expect(md).toContain('✅ решённые ветки');
|
|
expect(md).toMatch(/~~без пруфа~~.*пруф: код:107/);
|
|
});
|
|
it('кандидаты: релевантные наверху, low — свёрнуты, все с источником', () => {
|
|
const p = base();
|
|
p.candidates = [
|
|
{ branch: 'сильная', опора: 'внутр', релевантность: 'medium', born: 15 },
|
|
{ branch: 'слабая', trigger: 'цитата', опора: 'догадка', релевантность: 'low', born: 15 },
|
|
];
|
|
const md = renderFluffy(p);
|
|
expect(md).toMatch(/- сильная `внутр · medium`.*turn-15\.log/);
|
|
expect(md).toContain('▸ свёрнуто 1 слабых');
|
|
expect(md).toMatch(/- слабая .*turn-15\.log/);
|
|
});
|
|
it('горящие Л8/Л9 показаны с источником', () => {
|
|
const p = base();
|
|
p.acceptance = [{ text: 'не проверено', born: 3, done: false }];
|
|
p.tails = [{ text: 'не убрано', born: 3, done: false }];
|
|
const md = renderFluffy(p);
|
|
expect(md).toContain('## 🔥 Горит');
|
|
expect(md).toMatch(/Приёмка \(Л8\):.*не проверено.*turn-3\.log/);
|
|
expect(md).toMatch(/Хвост \(Л9\):.*не убрано/);
|
|
});
|
|
it('шаги со ссылкой на файл хода', () => {
|
|
const p = base();
|
|
p.steps = [{ turn: 15, text: 'Ход 15 — я: …' }];
|
|
const md = renderFluffy(p);
|
|
expect(md).toMatch(/- \[Ход 15\]\(ходы\/turn-15\.log\) — Ход 15/);
|
|
});
|
|
it('ветка без паспорта рисует «—»', () => {
|
|
const p = base();
|
|
p.hidden = [{ id: 'СВ-1', lens: 'Л1', status: 'открыт', text: 'старая', born: 3 }];
|
|
const md = renderFluffy(p);
|
|
expect(md).toMatch(/🌿 открыт \| — \|/);
|
|
});
|
|
});
|
|
|
|
describe('renderDoc — развилка по флагу', () => {
|
|
const proto = { subject: 'дело', status: 'открыто', decisions: [{ text: 'A', struck: false }], will: [], open: [], consequences: [], doneNext: [], hidden: [], acceptance: [], tails: [], candidates: [], steps: [] };
|
|
it('флаг ON → пушистый рендер (🌳 Ствол)', () => {
|
|
expect(renderDoc(proto, {}, { SECRETARY_FLUFFY: '1' })).toContain('## 🌳 Ствол');
|
|
});
|
|
it('флаг OFF (по умолчанию) → старый renderProtocol (## Решения, без 🌳)', () => {
|
|
const md = renderDoc(proto, {}, {});
|
|
expect(md).toContain('## Решения');
|
|
expect(md).not.toContain('🌳');
|
|
});
|
|
});
|