import { describe, expect, it } from 'vitest'; import { slugify } from '@/lib/utils'; import { excerptFromBody, extractHeadings, filterPublished, isPublished, readingMinutes } from '@/lib/content'; describe('slugify (frontmatter slug)', () => { it('produces a url-safe slug', () => { expect(slugify('Hello, World!')).toBe('hello-world'); expect(slugify(' Already-slug ')).toBe('already-slug'); expect(slugify('Prisma + Next.js: a guide')).toBe('prisma-next-js-a-guide'); }); }); describe('readingMinutes', () => { it('never returns less than one minute', () => { expect(readingMinutes('short')).toBe(1); }); it('rounds to the nearest minute at ~200 words per minute', () => { const body = Array.from({ length: 600 }, () => 'word').join(' '); expect(readingMinutes(body)).toBe(3); }); }); describe('draft filtering', () => { it('keeps only published items', () => { const items = [ { slug: 'a', status: 'published' }, { slug: 'b', status: 'draft' }, { slug: 'c', status: 'published' }, ]; expect(filterPublished(items).map((i) => i.slug)).toEqual(['a', 'c']); expect(isPublished('published')).toBe(true); expect(isPublished('draft')).toBe(false); }); }); describe('extractHeadings (table of contents)', () => { it('collects h2/h3 headings with anchors', () => { const body = ['# Title', 'intro', '', '## Before you ship', 'text', '', '### Details', 'more'].join('\n'); expect(extractHeadings(body)).toEqual([ { id: 'before-you-ship', text: 'Before you ship', level: 2 }, { id: 'details', text: 'Details', level: 3 }, ]); }); it('de-duplicates repeated heading anchors', () => { const body = ['## Setup', 'a', '', '## Setup', 'b'].join('\n'); expect(extractHeadings(body).map((h) => h.id)).toEqual(['setup', 'setup-1']); }); }); describe('excerptFromBody', () => { it('strips markdown and truncates', () => { const excerpt = excerptFromBody('# Title\n\nSome **bold** text with `code`.'); expect(excerpt).toBe('Title Some bold text with code.'); }); });