#!/usr/bin/env node /** * Tests unitaires pour markdown-frontmatter.mjs * Valide toutes les règles métier YAML */ import assert from 'assert'; import { rewriteTagsFrontmatter, extractTagsFromFrontmatter } from './markdown-frontmatter.mjs'; function test(name, fn) { try { fn(); console.log(`✅ ${name}`); } catch (error) { console.error(`❌ ${name}`); console.error(error); process.exit(1); } } console.log('🧪 Tests markdown-frontmatter\n'); // Test 1: Création de front-matter si absent test('Crée front-matter avec tags si absent', () => { const input = 'Hello world'; const result = rewriteTagsFrontmatter(input, ['tag1', 'tag2']); assert.ok(result.includes('---')); assert.ok(result.includes('tags:')); assert.ok(result.includes(' - tag1')); assert.ok(result.includes(' - tag2')); assert.ok(result.includes('Hello world')); }); // Test 2: Pas de front-matter si tags vide test('Ne crée pas de front-matter si tags vide et pas de FM existant', () => { const input = 'Hello world'; const result = rewriteTagsFrontmatter(input, []); assert.strictEqual(result, 'Hello world'); }); // Test 3: Suppression de la clé tags si liste vide test('Supprime la clé tags si liste vide', () => { const input = `--- title: Test tags: - old-tag --- Content`; const result = rewriteTagsFrontmatter(input, []); assert.ok(result.includes('title: Test')); assert.ok(!result.includes('tags:')); assert.ok(!result.includes('old-tag')); }); // Test 4: Déduplique les tags (case-insensitive) test('Déduplique les tags (case-insensitive)', () => { const input = 'Hello'; const result = rewriteTagsFrontmatter(input, ['Tag', 'tag', 'TAG', 'other']); const tags = extractTagsFromFrontmatter(result); assert.strictEqual(tags.length, 2); assert.ok(tags.includes('Tag')); // Première occurrence préservée assert.ok(tags.includes('other')); }); // Test 5: Normalise les espaces test('Normalise les espaces dans les tags', () => { const input = 'Hello'; const result = rewriteTagsFrontmatter(input, [' tag with spaces ']); const tags = extractTagsFromFrontmatter(result); assert.strictEqual(tags.length, 1); assert.strictEqual(tags[0], 'tag with spaces'); }); // Test 6: Préserve les autres propriétés test('Préserve les autres propriétés du front-matter', () => { const input = `--- title: My Note author: John date: 2024-01-01 tags: - old --- Content`; const result = rewriteTagsFrontmatter(input, ['new']); assert.ok(result.includes('title: My Note')); assert.ok(result.includes('author: John')); assert.ok(result.includes('date: 2024-01-01')); assert.ok(result.includes(' - new')); assert.ok(!result.includes(' - old')); }); // Test 7: Pas de lignes vides dans le front-matter test('Pas de lignes vides dans le front-matter', () => { const input = `--- title: Test tags: - old --- Content`; const result = rewriteTagsFrontmatter(input, ['new']); const fmMatch = result.match(/^---\n([\s\S]*?)\n---/); assert.ok(fmMatch); const fm = fmMatch[1]; assert.ok(!fm.includes('\n\n')); // Pas de double saut de ligne }); // Test 8: Supprime le front-matter si vide après suppression des tags test('Supprime le front-matter si vide après suppression des tags', () => { const input = `--- tags: - only-tag --- Content`; const result = rewriteTagsFrontmatter(input, []); assert.strictEqual(result, 'Content'); assert.ok(!result.includes('---')); }); // Test 9: Gère les tags inline (format [tag1, tag2]) test('Remplace les tags inline par format liste', () => { const input = `--- title: Test tags: [old1, old2] --- Content`; const result = rewriteTagsFrontmatter(input, ['new1', 'new2']); assert.ok(result.includes(' - new1')); assert.ok(result.includes(' - new2')); assert.ok(!result.includes('[old1, old2]')); }); // Test 10: Extraction des tags test('Extrait correctement les tags du front-matter', () => { const input = `--- title: Test tags: - tag1 - tag2 - tag3 --- Content`; const tags = extractTagsFromFrontmatter(input); assert.strictEqual(tags.length, 3); assert.deepStrictEqual(tags, ['tag1', 'tag2', 'tag3']); }); // Test 11: Extraction des tags inline test('Extrait les tags inline', () => { const input = `--- tags: [tag1, tag2, tag3] --- Content`; const tags = extractTagsFromFrontmatter(input); assert.strictEqual(tags.length, 3); assert.deepStrictEqual(tags, ['tag1', 'tag2', 'tag3']); }); // Test 12: Gère les caractères spéciaux test('Gère les tags avec caractères spéciaux', () => { const input = 'Content'; const result = rewriteTagsFrontmatter(input, ['tag-with-dash', 'tag_with_underscore', 'tag/with/slash']); const tags = extractTagsFromFrontmatter(result); assert.strictEqual(tags.length, 3); assert.ok(tags.includes('tag-with-dash')); assert.ok(tags.includes('tag_with_underscore')); assert.ok(tags.includes('tag/with/slash')); }); // Test 13: Gère les BOM et line endings test('Normalise BOM et line endings', () => { const input = '\uFEFFContent\r\nwith\r\nCRLF'; const result = rewriteTagsFrontmatter(input, ['tag']); assert.ok(!result.includes('\uFEFF')); assert.ok(!result.includes('\r')); }); console.log('\n✅ Tous les tests passent !');