import assert from 'node:assert/strict'; import test from 'node:test'; import type { HelpSectionId } from './helpSections'; import { buildHelpLinkCatalog, findHelpLinkRanges, splitHelpTextWithLinks } from './helpLinkify'; const RU_TITLES: Record = { overview: 'Обзор приложения', license: 'Лицензия и первый запуск', projects: 'Проекты', scenes: 'Сцены', graph: 'Граф сцен', sideStorylines: 'Побочные сюжетные линии', sceneProps: 'Свойства сцены', sceneEditor: 'Редактор сцены', grid: 'Генератор сетки', traps: 'Ловушки', tokens: 'Неигровые токены', campaignAudio: 'Аудио игры', materials: 'Материалы', players: 'Игроки', npcs: 'НПС', session: 'Запуск сессии', controlPanel: 'Пульт управления', transitions: 'Переходы между сценами', music: 'Музыка на пульте', effects: 'Эффекты поля и действий', presentation: 'Экран презентации', importExport: 'Импорт и экспорт', settings: 'Настройки, язык и обновления', }; void test('findHelpLinkRanges: «Ловушки» и алиас «Эффекты»', () => { const catalog = buildHelpLinkCatalog((id) => RU_TITLES[id]); const text = 'см. «Ловушки» и кистью (см. «Эффекты»). Также разделы «Генератор сетки», «Неигровые токены».'; const ranges = findHelpLinkRanges(text, catalog); assert.deepEqual( ranges.map((r) => r.id), ['traps', 'effects', 'grid', 'tokens'], ); }); void test('findHelpLinkRanges: длинный title предпочитается короткому алиасу', () => { const catalog = buildHelpLinkCatalog((id) => RU_TITLES[id]); const text = 'Откройте «Редактор сцены» и «Генератор сетки».'; const ranges = findHelpLinkRanges(text, catalog); assert.equal(ranges.length, 2); assert.equal(ranges[0]?.id, 'sceneEditor'); assert.equal(ranges[1]?.id, 'grid'); }); void test('splitHelpTextWithLinks: EN see Scene editor / Traps', () => { const getTitle = (id: HelpSectionId): string => { const map: Partial> = { sceneEditor: 'Scene editor', traps: 'Traps', tokens: 'Non-player tokens', grid: 'Grid generator', effects: 'Field and action effects', controlPanel: 'Control panel', }; return map[id] ?? id; }; const catalog = buildHelpLinkCatalog(getTitle); const parts = splitHelpTextWithLinks( 'For details, see Grid generator, Traps, and Non-player tokens. Also see Effects.', catalog, ); const links = parts.filter((p) => p.type === 'link'); assert.deepEqual( links.map((p) => (p.type === 'link' ? p.id : null)), ['grid', 'traps', 'tokens', 'effects'], ); }); void test('findHelpLinkRanges: полное «Пульт управления» не режется до «Пульт»', () => { const catalog = buildHelpLinkCatalog((id) => RU_TITLES[id]); const ranges = findHelpLinkRanges('см. «Пульт управления»', catalog); assert.equal(ranges.length, 1); assert.equal(ranges[0]?.id, 'controlPanel'); assert.equal(ranges[0]?.text, '«Пульт управления»'); });