import { describe, expect, it } from 'vitest'; import { deriveInterestBerthLabel } from '@/lib/templates/interest-berth-label'; describe('deriveInterestBerthLabel', () => { it('returns null for empty / nullish input', () => { expect(deriveInterestBerthLabel(undefined)).toBeNull(); expect(deriveInterestBerthLabel(null)).toBeNull(); expect(deriveInterestBerthLabel([])).toBeNull(); expect(deriveInterestBerthLabel([null, undefined, ''])).toBeNull(); }); it('renders a single berth verbatim', () => { expect(deriveInterestBerthLabel(['A1'])).toBe('A1'); }); it('collapses consecutive runs into hyphenated ranges', () => { expect(deriveInterestBerthLabel(['A1', 'A2', 'A3'])).toBe('A1-A3'); }); it('joins non-consecutive berths with comma', () => { expect(deriveInterestBerthLabel(['A1', 'A3'])).toBe('A1, A3'); }); it('mixes ranges + standalone segments', () => { expect(deriveInterestBerthLabel(['A1', 'A2', 'B5', 'B6', 'B7'])).toBe('A1-A2, B5-B7'); }); it('treats a fully consecutive run as one segment regardless of length', () => { // 20 berths but one segment - should NOT trigger the over-cap fallback. const moorings = Array.from({ length: 20 }, (_, i) => `A${i + 1}`); expect(deriveInterestBerthLabel(moorings)).toBe('A1-A20'); }); it('falls back to "first + N more" when post-collapse segment count exceeds 5', () => { // Six standalone berths, all non-consecutive → 6 segments → fallback. expect(deriveInterestBerthLabel(['A1', 'A3', 'A5', 'A7', 'A9', 'A11'])).toBe('A1 + 5 more'); }); it('keeps the compact form when post-collapse segments are <=5', () => { // 5 standalone berths → 5 segments → still rendered in full. expect(deriveInterestBerthLabel(['A1', 'A3', 'A5', 'A7', 'A9'])).toBe('A1, A3, A5, A7, A9'); }); it('ignores blank / nullish entries while preserving the rest', () => { expect(deriveInterestBerthLabel(['A1', null, '', undefined, 'A3'])).toBe('A1, A3'); }); });