205 lines
5.5 KiB
JavaScript
205 lines
5.5 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Unit tests for Excalidraw Obsidian format utilities
|
|
* Run with: node server/excalidraw-obsidian.test.mjs
|
|
*/
|
|
|
|
import assert from 'assert';
|
|
import {
|
|
parseObsidianExcalidrawMd,
|
|
parseFlatJson,
|
|
toObsidianExcalidrawMd,
|
|
extractFrontMatter,
|
|
parseExcalidrawAny,
|
|
isValidExcalidrawScene
|
|
} from './excalidraw-obsidian.mjs';
|
|
|
|
let passed = 0;
|
|
let failed = 0;
|
|
|
|
function test(name, fn) {
|
|
try {
|
|
fn();
|
|
console.log(`✅ ${name}`);
|
|
passed++;
|
|
} catch (error) {
|
|
console.error(`❌ ${name}`);
|
|
console.error(` ${error.message}`);
|
|
failed++;
|
|
}
|
|
}
|
|
|
|
// Sample data
|
|
const sampleScene = {
|
|
elements: [
|
|
{ id: '1', type: 'rectangle', x: 100, y: 100, width: 200, height: 100 }
|
|
],
|
|
appState: { viewBackgroundColor: '#ffffff' },
|
|
files: {}
|
|
};
|
|
|
|
const sampleFrontMatter = `---
|
|
excalidraw-plugin: parsed
|
|
tags: [excalidraw]
|
|
---`;
|
|
|
|
console.log('🧪 Running Excalidraw Obsidian Format Tests\n');
|
|
|
|
// Test: extractFrontMatter
|
|
test('extractFrontMatter - extracts front matter', () => {
|
|
const md = `---
|
|
excalidraw-plugin: parsed
|
|
---
|
|
Content here`;
|
|
const result = extractFrontMatter(md);
|
|
assert.ok(result);
|
|
assert.ok(result.includes('excalidraw-plugin'));
|
|
});
|
|
|
|
test('extractFrontMatter - returns null when no front matter', () => {
|
|
const md = 'Just some content';
|
|
const result = extractFrontMatter(md);
|
|
assert.strictEqual(result, null);
|
|
});
|
|
|
|
// Test: toObsidianExcalidrawMd
|
|
test('toObsidianExcalidrawMd - creates valid markdown', () => {
|
|
const md = toObsidianExcalidrawMd(sampleScene);
|
|
assert.ok(md.includes('---'));
|
|
assert.ok(md.includes('excalidraw-plugin'));
|
|
assert.ok(md.includes('```compressed-json'));
|
|
assert.ok(md.includes('# Excalidraw Data'));
|
|
});
|
|
|
|
test('toObsidianExcalidrawMd - preserves existing front matter', () => {
|
|
const customFrontMatter = `---
|
|
excalidraw-plugin: parsed
|
|
tags: [custom, test]
|
|
---`;
|
|
const md = toObsidianExcalidrawMd(sampleScene, customFrontMatter);
|
|
assert.ok(md.includes('tags: [custom, test]'));
|
|
});
|
|
|
|
// Test: parseObsidianExcalidrawMd round-trip
|
|
test('parseObsidianExcalidrawMd - round-trip conversion', () => {
|
|
const md = toObsidianExcalidrawMd(sampleScene);
|
|
const parsed = parseObsidianExcalidrawMd(md);
|
|
|
|
assert.ok(parsed);
|
|
assert.ok(Array.isArray(parsed.elements));
|
|
assert.strictEqual(parsed.elements.length, 1);
|
|
assert.strictEqual(parsed.elements[0].type, 'rectangle');
|
|
});
|
|
|
|
// Test: parseFlatJson
|
|
test('parseFlatJson - parses valid JSON', () => {
|
|
const json = JSON.stringify(sampleScene);
|
|
const parsed = parseFlatJson(json);
|
|
|
|
assert.ok(parsed);
|
|
assert.ok(Array.isArray(parsed.elements));
|
|
assert.strictEqual(parsed.elements.length, 1);
|
|
});
|
|
|
|
test('parseFlatJson - returns null for invalid JSON', () => {
|
|
const parsed = parseFlatJson('not valid json');
|
|
assert.strictEqual(parsed, null);
|
|
});
|
|
|
|
test('parseFlatJson - returns null for JSON without elements', () => {
|
|
const parsed = parseFlatJson('{"foo": "bar"}');
|
|
assert.strictEqual(parsed, null);
|
|
});
|
|
|
|
// Test: parseExcalidrawAny
|
|
test('parseExcalidrawAny - parses Obsidian format', () => {
|
|
const md = toObsidianExcalidrawMd(sampleScene);
|
|
const parsed = parseExcalidrawAny(md);
|
|
|
|
assert.ok(parsed);
|
|
assert.ok(Array.isArray(parsed.elements));
|
|
});
|
|
|
|
test('parseExcalidrawAny - parses flat JSON', () => {
|
|
const json = JSON.stringify(sampleScene);
|
|
const parsed = parseExcalidrawAny(json);
|
|
|
|
assert.ok(parsed);
|
|
assert.ok(Array.isArray(parsed.elements));
|
|
});
|
|
|
|
test('parseExcalidrawAny - returns null for invalid content', () => {
|
|
const parsed = parseExcalidrawAny('invalid content');
|
|
assert.strictEqual(parsed, null);
|
|
});
|
|
|
|
// Test: isValidExcalidrawScene
|
|
test('isValidExcalidrawScene - validates correct structure', () => {
|
|
assert.strictEqual(isValidExcalidrawScene(sampleScene), true);
|
|
});
|
|
|
|
test('isValidExcalidrawScene - rejects invalid structure', () => {
|
|
assert.strictEqual(isValidExcalidrawScene({}), false);
|
|
assert.strictEqual(isValidExcalidrawScene({ elements: 'not an array' }), false);
|
|
assert.strictEqual(isValidExcalidrawScene(null), false);
|
|
});
|
|
|
|
// Test: Empty scene handling
|
|
test('toObsidianExcalidrawMd - handles empty scene', () => {
|
|
const emptyScene = { elements: [], appState: {}, files: {} };
|
|
const md = toObsidianExcalidrawMd(emptyScene);
|
|
const parsed = parseObsidianExcalidrawMd(md);
|
|
|
|
assert.ok(parsed);
|
|
assert.ok(Array.isArray(parsed.elements));
|
|
assert.strictEqual(parsed.elements.length, 0);
|
|
});
|
|
|
|
// Test: Large scene handling
|
|
test('toObsidianExcalidrawMd - handles large scene', () => {
|
|
const largeScene = {
|
|
elements: Array.from({ length: 100 }, (_, i) => ({
|
|
id: `${i}`,
|
|
type: 'rectangle',
|
|
x: i * 10,
|
|
y: i * 10,
|
|
width: 50,
|
|
height: 50
|
|
})),
|
|
appState: {},
|
|
files: {}
|
|
};
|
|
|
|
const md = toObsidianExcalidrawMd(largeScene);
|
|
const parsed = parseObsidianExcalidrawMd(md);
|
|
|
|
assert.ok(parsed);
|
|
assert.strictEqual(parsed.elements.length, 100);
|
|
});
|
|
|
|
// Test: Special characters in scene
|
|
test('toObsidianExcalidrawMd - handles special characters', () => {
|
|
const sceneWithSpecialChars = {
|
|
elements: [
|
|
{ id: '1', type: 'text', text: 'Hello "World" & <test>' }
|
|
],
|
|
appState: {},
|
|
files: {}
|
|
};
|
|
|
|
const md = toObsidianExcalidrawMd(sceneWithSpecialChars);
|
|
const parsed = parseObsidianExcalidrawMd(md);
|
|
|
|
assert.ok(parsed);
|
|
assert.strictEqual(parsed.elements[0].text, 'Hello "World" & <test>');
|
|
});
|
|
|
|
// Summary
|
|
console.log('\n━'.repeat(30));
|
|
console.log(`✅ Passed: ${passed}`);
|
|
console.log(`❌ Failed: ${failed}`);
|
|
console.log('━'.repeat(30));
|
|
|
|
process.exit(failed > 0 ? 1 : 0);
|