import assert from 'node:assert/strict' import test from 'node:test' import { collectFencedLines, findFencedBlockEnd, findFencedBlockStart, findFencedBlockStartBy, parseBookmarkMeta, parseMediaMeta, parseSignupMeta } from '../lib/markdown-fenced-meta.js' test('fenced 블록 시작과 종료 줄을 찾는다', () => { const lines = [ '이전', ':::gallery', '![a](/a.webp)', ':::', '다음' ] assert.equal(findFencedBlockStart(lines, 2, ':::gallery'), 1) assert.equal(findFencedBlockEnd(lines, 1), 3) }) test('닫힘 표식 너머의 fenced 블록 시작은 현재 블록으로 보지 않는다', () => { const lines = [ ':::gallery', '![a](/a.webp)', ':::', '본문' ] assert.equal(findFencedBlockStart(lines, 3, ':::gallery'), -1) }) test('조건 기반 fenced 블록 시작 줄을 찾는다', () => { const lines = [ ':::callout emoji=none bg=blue', '본문', ':::' ] assert.equal(findFencedBlockStartBy(lines, 1, (line) => line.startsWith(':::callout')), 0) }) test('fenced 블록 닫힘 표식까지의 본문과 다음 줄을 수집한다', () => { assert.deepEqual(collectFencedLines([ ':::bookmark', 'https://example.com', 'Example', ':::', '다음 문단' ], 1), { contentLines: ['https://example.com', 'Example'], endLine: 3, nextIndex: 4 }) }) test('닫힘 표식이 없는 fenced 블록도 마지막 본문 범위를 반환한다', () => { assert.deepEqual(collectFencedLines([ ':::video', '/uploads/video.mp4' ], 1), { contentLines: ['/uploads/video.mp4'], endLine: 1, nextIndex: 2 }) }) test('북마크 메타는 key=value와 순차 본문을 모두 파싱한다', () => { assert.deepEqual(parseBookmarkMeta([ 'https://example.com/post', '예시 제목', '예시 설명' ].join('\n')), { url: 'https://example.com/post', title: '예시 제목', description: '예시 설명', thumbnail: '' }) assert.deepEqual(parseBookmarkMeta([ 'url=https://example.com', 'title=제목', 'desc=설명', 'image=/thumb.webp' ].join('\n')), { url: 'https://example.com', title: '제목', description: '설명', thumbnail: '/thumb.webp' }) }) test('회원가입 메타는 기본값을 유지하며 전달된 필드만 바꾼다', () => { assert.deepEqual(parseSignupMeta('title=구독\nbutton=시작하기'), { title: '구독', description: '새 글이 올라오면 받아보실 수 있어요.', button: '시작하기', placeholder: 'you@example.com' }) }) test('미디어 메타는 key=value와 순차 본문을 모두 파싱한다', () => { assert.deepEqual(parseMediaMeta([ '/uploads/video.mp4', '영상 제목', '영상 설명' ].join('\n')), { url: '/uploads/video.mp4', title: '영상 제목', description: '영상 설명', poster: '', caption: '', fileName: '', size: '' }) assert.deepEqual(parseMediaMeta([ 'src=/uploads/audio.mp3', 'title=오디오', 'thumbnail=/poster.webp', 'caption=캡션', 'filename=sound.mp3', 'size=3MB' ].join('\n')), { url: '/uploads/audio.mp3', title: '오디오', description: '', poster: '/poster.webp', caption: '캡션', fileName: 'sound.mp3', size: '3MB' }) })