import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { ICON_PATHS, ICON_LABELS, BUTTON_ICON_GROUPS, ALL_ICON_GROUPS } from '../public/assets/icons.js'; const read = path => readFileSync(new URL(path, import.meta.url), 'utf8'); test('the editor draws the same icons the website renders and the server allows', () => { // Drei Listen, ein Satz: die Zeichnungen der Website (Twig), die Vorschau im Editor und die // erlaubten Namen im Validator. Weicht eine ab, zeigt die Auswahl ein anderes Symbol als die // Seite - oder bietet eins an, das der Server beim Speichern ablehnt. const twig = read('../templates/blocks/icon.html.twig'); const website = Object.fromEntries([...twig.matchAll(/^\s{4}'?([a-z-]+)'?: '([^']+)',?$/gm)].map(([, name, path]) => [name, path])); assert.deepEqual(ICON_PATHS, website); const validator = read('../src/Content/DocumentValidator.php'); const allowed = [...validator.match(/public const ICONS = \[([^\]]+)\]/)[1].matchAll(/'([a-z-]+)'/g)].map(([, name]) => name); assert.deepEqual(Object.keys(ICON_PATHS).sort(), [...allowed].sort()); }); test('every icon has a German name and the pickers offer each icon exactly once', () => { assert.deepEqual(Object.keys(ICON_LABELS).sort(), Object.keys(ICON_PATHS).sort()); const button = BUTTON_ICON_GROUPS.flatMap(([, names]) => names); assert.equal(new Set(button).size, button.length, 'Ein Symbol steht doppelt in der Button-Auswahl.'); for (const name of button) assert.ok(ICON_PATHS[name], `${name} hat keine Zeichnung.`); // Der bisherige Pfeil steht vorn: er ist das, was ein Button ohne eigene Wahl trägt. assert.equal(button[0], 'arrow-up-right'); const all = ALL_ICON_GROUPS.flatMap(([, names]) => names); assert.deepEqual([...all].sort(), Object.keys(ICON_PATHS).sort(), 'Symbol und Symbolkarte bieten jedes Symbol genau einmal an.'); });