183 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| #!/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 !');
 |