- .archify content is YAML (JSON still accepted); converted to JSON for the renderer - Archify Diagram custom editor is the default for *.archify; Show Source opens the YAML beside it - YAML syntax errors and validation problems mapped to YAML lines - yamlValidation for schema completion with redhat.vscode-yaml - scripts/to-yaml.mjs converts existing .archify files
77 lines
3.3 KiB
TypeScript
77 lines
3.3 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import fs from 'node:fs';
|
|
import os from 'node:os';
|
|
import path from 'node:path';
|
|
import { test } from 'node:test';
|
|
import { readDiagramSource } from '../src/detect';
|
|
import { renderDiagram, renderToFile, RuntimeOptions, validate } from '../src/renderer';
|
|
|
|
const root = path.resolve(__dirname, '..', '..');
|
|
const fixtures = path.join(root, 'test', 'fixtures');
|
|
const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'archify-ext-test-'));
|
|
|
|
function runtime(extra: Partial<RuntimeOptions> = {}): RuntimeOptions {
|
|
return {
|
|
cliPath: path.join(root, 'vendor', 'archify', 'bin', 'archify.mjs'),
|
|
nodePath: process.execPath,
|
|
runAsNode: false,
|
|
workDir,
|
|
...extra,
|
|
};
|
|
}
|
|
|
|
function load(name: string) {
|
|
const text = fs.readFileSync(path.join(fixtures, name), 'utf8');
|
|
const source = readDiagramSource(text, name);
|
|
assert.ok(source, `${name} is a diagram source`);
|
|
return source;
|
|
}
|
|
|
|
for (const name of fs.readdirSync(fixtures).filter((file) => !file.startsWith('mco-'))) {
|
|
test(`renders ${name}`, async () => {
|
|
const result = await renderDiagram(runtime(), load(name), 'strict');
|
|
assert.equal(result.error, undefined);
|
|
assert.ok(result.ok);
|
|
assert.match(result.html ?? '', /<meta name="generator" content="archify/);
|
|
assert.equal(result.evidenceNotice, undefined);
|
|
});
|
|
}
|
|
|
|
test('reports schema problems with JSON pointer paths', async () => {
|
|
const text = JSON.stringify({ schema_version: 1, diagram_type: 'architecture', meta: { title: 'x' }, components: [{ id: 'a' }] });
|
|
const result = await validate(runtime(), 'architecture', text);
|
|
assert.equal(result.ok, false);
|
|
assert.ok(result.diagnostics.some((d) => d.subject?.path === '/components/0' && d.severity === 'error'));
|
|
});
|
|
|
|
test('render failure returns the CLI error', async () => {
|
|
const text = JSON.stringify({ schema_version: 1, diagram_type: 'architecture', meta: {}, components: [] });
|
|
const result = await renderDiagram(runtime(), { type: 'architecture', diagram: JSON.parse(text), format: 'json', json: text }, 'fallback');
|
|
assert.equal(result.ok, false);
|
|
assert.match(result.error ?? '', /schema validation failed/);
|
|
});
|
|
|
|
test('unverifiable source evidence falls back to a render without source links', async () => {
|
|
// This checkout's origin is not mco-org/mco, so verification must fail.
|
|
const source = load('mco-runtime.architecture.json');
|
|
const strict = await renderDiagram(runtime({ repoRoot: root }), source, 'strict');
|
|
assert.equal(strict.ok, false);
|
|
const fallback = await renderDiagram(runtime({ repoRoot: root }), source, 'fallback');
|
|
assert.ok(fallback.ok, fallback.error);
|
|
assert.match(fallback.evidenceNotice ?? '', /Source links are hidden/);
|
|
const noRoot = await renderDiagram(runtime(), source, 'fallback');
|
|
assert.ok(noRoot.ok);
|
|
assert.match(noRoot.evidenceNotice ?? '', /not inside a Git checkout/);
|
|
});
|
|
|
|
test('renders to a chosen file', async () => {
|
|
const output = path.join(workDir, 'exported.html');
|
|
const result = await renderToFile(runtime(), load('event-stream.dataflow.json'), output);
|
|
assert.ok(result.ok, result.error);
|
|
assert.ok(fs.statSync(output).size > 10_000);
|
|
});
|
|
|
|
test('scratch directories are cleaned up', () => {
|
|
assert.deepEqual(fs.readdirSync(workDir).filter((entry) => entry.startsWith('run-')), []);
|
|
});
|