import assert from 'node:assert/strict'; import { test } from 'node:test'; import { hasSourceEvidence, isArchifyHtml, readDiagramSource, stripSourceEvidence, typeFromFilename } from '../src/detect'; import { pointerSegments, rangeForPointer, rangeForPointerYaml, yamlSyntaxProblems } from '../src/jsonPointer'; test('reads diagram_type from content', () => { const source = readDiagramSource('{"schema_version":1,"diagram_type":"sequence","meta":{}}', 'plain.json'); assert.equal(source?.type, 'sequence'); }); test('falls back to the file name for unparseable sources', () => { assert.equal(readDiagramSource('{"diagram_type": ', 'x.workflow.json')?.type, 'workflow'); assert.equal(readDiagramSource('{"name":"pkg"}', 'package.json'), undefined); assert.equal(typeFromFilename('/a/b/Web.Architecture.json'), 'architecture'); }); test('recognizes Archify HTML by its generator meta', () => { assert.ok(isArchifyHtml('
')); assert.ok(!isArchifyHtml('')); }); test('strips source evidence without touching the original', () => { const diagram = { meta: { title: 't', repository: { url: 'https://github.com/a/b', revision: 'x' } }, components: [{ id: 'a', sources: [{ path: 'src/a.ts' }] }, { id: 'b' }], }; assert.ok(hasSourceEvidence('architecture', diagram)); const stripped = stripSourceEvidence('architecture', diagram); assert.ok(!hasSourceEvidence('architecture', stripped)); assert.ok(diagram.meta.repository, 'original keeps its repository'); assert.deepEqual((stripped.components as unknown[])[1], { id: 'b' }); }); test('json pointer segments decode escapes and indexes', () => { assert.deepEqual(pointerSegments('/components/0/a~1b~0c'), ['components', 0, 'a/b~c']); assert.deepEqual(pointerSegments(''), []); }); test('json pointer ranges point at keys for containers and values for leaves', () => { const text = '{\n "meta": { "title": "x" },\n "components": [ { "id": "a" } ]\n}'; const meta = rangeForPointer(text, '/meta'); assert.equal(text.slice(meta.start, meta.end), '"meta"'); const title = rangeForPointer(text, '/meta/title'); assert.equal(text.slice(title.start, title.end), '"x"'); const item = rangeForPointer(text, '/components/0'); assert.equal(text.slice(item.start, item.end), '{'); const missing = rangeForPointer(text, '/components/0/label'); assert.equal(text.slice(missing.start, missing.end), '{', 'falls back to the nearest existing ancestor'); }); test('.archify files are diagram sources typed by their content', async () => { const { diagramBaseName, isArchifyFile, isDiagramFileName } = await import('../src/detect'); assert.ok(isArchifyFile('/w/My Platform.archify')); assert.ok(isDiagramFileName('/w/x.ARCHIFY')); assert.ok(isDiagramFileName('/w/x.workflow.json')); assert.ok(!isDiagramFileName('/w/archify.json')); assert.equal(diagramBaseName('/w/web.archify'), 'web'); assert.equal(diagramBaseName('/w/web.architecture.json'), 'web.architecture'); assert.equal(readDiagramSource('{"diagram_type":"lifecycle"}', 'run.archify')?.type, 'lifecycle'); assert.equal(readDiagramSource('{"title":"no type yet"}', 'run.archify'), undefined); const yaml = readDiagramSource('schema_version: 1\ndiagram_type: sequence\nmeta:\n title: T\n', 'flow.archify'); assert.equal(yaml?.type, 'sequence'); assert.equal(yaml?.format, 'yaml'); assert.deepEqual(JSON.parse(yaml!.json), { schema_version: 1, diagram_type: 'sequence', meta: { title: 'T' } }); assert.equal(readDiagramSource('diagram_type: [unclosed', 'bad.archify'), undefined); }); test('yaml pointer ranges match the json behaviour', () => { const text = 'meta:\n title: x\ncomponents:\n - id: a\n label: A\n'; const meta = rangeForPointerYaml(text, '/meta'); assert.equal(text.slice(meta.start, meta.end), 'meta'); const title = rangeForPointerYaml(text, '/meta/title'); assert.equal(text.slice(title.start, title.end), 'x'); const item = rangeForPointerYaml(text, '/components/0'); assert.equal(text.slice(item.start, item.end), 'i', 'first character of the item'); const label = rangeForPointerYaml(text, '/components/0/label'); assert.equal(text.slice(label.start, label.end), 'A'); const missing = rangeForPointerYaml(text, '/components/0/type'); assert.equal(text.slice(missing.start, missing.end), 'i', 'falls back to the nearest existing ancestor'); }); test('yaml syntax problems carry offsets', () => { assert.deepEqual(yamlSyntaxProblems('a: 1\nb: 2\n'), []); const problems = yamlSyntaxProblems('a: [1, 2\nb: 3\n'); assert.ok(problems.length > 0); assert.ok(problems[0].start >= 0 && problems[0].end > problems[0].start); });