import { describe, expect, it } from 'vitest'; import { chordProToSvg, parseChordPro } from './chordpro'; const SHEET = `{title: Bühnenlied} {artist: Nadia Morgenstern} {key: C} # internes Kommentar — unsichtbar [C]Hallo du [G]schöne [Am]Welt Ohne Akkorde geht es [F]auch {start_of_chorus} {comment: Refrain} [C]La la [G]la {end_of_chorus}`; describe('chordpro parser + svg formatter (issue #155)', () => { it('parses directives, chords with columns, comments, and chorus', () => { const sheet = parseChordPro(SHEET); expect(sheet.meta).toMatchObject({ title: 'Bühnenlied', subtitle: 'Nadia Morgenstern', key: 'C', }); const first = sheet.lines[0]!; expect(first.lyrics).toBe('Hallo du schöne Welt'); expect(first.chords).toEqual([ { at: 0, chord: 'C' }, { at: 9, chord: 'G' }, { at: 16, chord: 'Am' }, ]); const chorusLine = sheet.lines.find((l) => l.chorus && l.kind === 'pair')!; expect(chorusLine.lyrics).toBe('La la la'); const comment = sheet.lines.find((l) => l.kind === 'comment')!; expect(comment.lyrics).toBe('Refrain'); // `#` lines never show up. expect(sheet.lines.some((l) => l.lyrics.includes('internes'))).toBe(false); }); it('renders a self-contained SVG with title, chords, and umlauts escaped safely', () => { const svg = chordProToSvg(SHEET); expect(svg).toMatch(/^Am'); expect(svg).toContain('Hallo du schöne Welt'); expect(svg).not.toContain(' { const svg = chordProToSvg('{title: }\n[C]a & b < c'); expect(svg).toContain('<img src=x>'); expect(svg).toContain('a & b < c'); }); it('throws on an empty sheet so the plugin can show its hint', () => { expect(() => chordProToSvg(' \n# nur Kommentar')).toThrow(); }); });