1import test from 'node:test'2import assert from 'node:assert/strict'3import { diagramTypes } from '../src/diagram-types.js'4import {5 launcherCatalog,6 launcherCatalogGroups,7 launcherEntryFor,8 filterLauncherCatalog,9} from '../src/launcher-catalog.js'1011test('launcher groups cover every diagram type exactly once in the source order', () => {12 const groupedIds = launcherCatalogGroups.flatMap(group => group.items.map(item => item.id))13 assert.equal(launcherCatalog.length, 32)14 assert.equal(groupedIds.length, diagramTypes.length)15 assert.equal(new Set(groupedIds).size, groupedIds.length)16 assert.deepEqual(new Set(groupedIds), new Set(diagramTypes.map(type => type.id)))17 assert.deepEqual(launcherCatalog.map(item => item.id), diagramTypes.map(type => type.id))18 assert.deepEqual(launcherCatalogGroups.map(group => [group.label, group.items.length]), [19 ['Flow & sequence', 7],20 ['Architecture', 6],21 ['Data & charts', 5],22 ['Network & hardware', 7],23 ['Drawing & ASCII', 7],24 ])25})2627test('catalog entries are normalized with group and format metadata', () => {28 for (const entry of launcherCatalog) {29 assert.equal(typeof entry.id, 'string')30 assert.equal(typeof entry.label, 'string')31 assert.equal(typeof entry.description, 'string')32 assert.ok(entry.description.length > 0)33 assert.equal(typeof entry.groupId, 'string')34 assert.equal(typeof entry.groupLabel, 'string')35 assert.ok(Array.isArray(entry.extensions))36 }37 assert.equal(launcherEntryFor('not-a-format'), null)38 assert.equal(launcherEntryFor('wireviz').groupLabel, 'Network & hardware')39})4041test('catalog filtering is case-insensitive across id, label, description, and extension', () => {42 assert.deepEqual(filterLauncherCatalog('PLANTUML').map(entry => entry.id), ['plantuml', 'c4plantuml'])43 assert.deepEqual(filterLauncherCatalog('wIrInG').map(entry => entry.id), ['wireviz'])44 assert.deepEqual(filterLauncherCatalog('.yaml').map(entry => entry.id), ['wireviz'])45 assert.deepEqual(filterLauncherCatalog(' '), launcherCatalog)46})