import { describe, it, expect } from 'vitest'; import { formatTable } from '../../src/formatters/table.js'; import type { Column } from '../../src/formatters/table.js'; interface TestRow { name: string; age: number; city: string; } const columns: Column[] = [ { header: 'NAME', key: 'name' }, { header: 'AGE', key: 'age', align: 'right' }, { header: 'CITY', key: 'city' }, ]; describe('formatTable', () => { it('returns empty message for no rows', () => { expect(formatTable([], columns)).toBe('No results found.'); }); it('formats a single row', () => { const rows = [{ name: 'Alice', age: 30, city: 'NYC' }]; const result = formatTable(rows, columns); const lines = result.split('\n'); expect(lines).toHaveLength(3); // header, separator, data expect(lines[0]).toContain('NAME'); expect(lines[0]).toContain('AGE'); expect(lines[0]).toContain('CITY'); expect(lines[2]).toContain('Alice'); expect(lines[2]).toContain('NYC'); }); it('right-aligns numeric columns', () => { const rows = [{ name: 'Bob', age: 5, city: 'LA' }]; const result = formatTable(rows, columns); const lines = result.split('\n'); // AGE column should be right-aligned: " 5" or "5" padded const ageLine = lines[2]; // The age value should have leading space(s) for right alignment expect(ageLine).toMatch(/\s+5/); }); it('auto-sizes columns to content', () => { const rows = [ { name: 'A', age: 1, city: 'X' }, { name: 'LongName', age: 100, city: 'LongCityName' }, ]; const result = formatTable(rows, columns); const lines = result.split('\n'); // Header should be at least as wide as longest data expect(lines[0]).toContain('NAME'); expect(lines[2]).toContain('A'); expect(lines[3]).toContain('LongName'); expect(lines[3]).toContain('LongCityName'); }); it('truncates long values when width is fixed', () => { const narrowCols: Column[] = [ { header: 'NAME', key: 'name', width: 5 }, ]; const rows = [{ name: 'VeryLongName', age: 0, city: '' }]; const result = formatTable(rows, narrowCols); const lines = result.split('\n'); // Should be truncated with ellipsis expect(lines[2].trim().length).toBeLessThanOrEqual(5); expect(lines[2]).toContain('\u2026'); }); it('supports function-based column keys', () => { const fnCols: Column[] = [ { header: 'INFO', key: (row) => `${row.name} (${row.age})` }, ]; const rows = [{ name: 'Eve', age: 25, city: 'SF' }]; const result = formatTable(rows, fnCols); expect(result).toContain('Eve (25)'); }); it('handles separator line matching column widths', () => { const rows = [{ name: 'Test', age: 1, city: 'Here' }]; const result = formatTable(rows, columns); const lines = result.split('\n'); const separator = lines[1]; // Separator should consist of dashes and spaces expect(separator).toMatch(/^[-\s]+$/); }); });