import { describe, it, expect } from 'vitest'; import { splitMessage } from './utils.js'; describe('splitMessage', () => { it('returns single chunk for empty string', () => { const result = splitMessage('', 100); // empty string never enters the while loop → returns empty array expect(result).toEqual([]); }); it('returns single chunk when text is under maxLength', () => { const result = splitMessage('hello world', 100); expect(result).toEqual(['hello world']); }); it('returns single chunk when text equals maxLength', () => { const text = 'a'.repeat(50); const result = splitMessage(text, 50); expect(result).toEqual([text]); }); it('splits at newline when possible', () => { const text = 'line one\nline two\nline three'; // maxLength 18 → "line one\nline two\n" is 18 chars, lastIndexOf('\n', 18) = 17 const result = splitMessage(text, 18); expect(result).toEqual(['line one\nline two', 'line three']); }); it('splits at space when no newline available', () => { const text = 'word1 word2 word3 word4'; // maxLength 12 → "word1 word2 " lastIndexOf(' ', 12) = 11 const result = splitMessage(text, 12); expect(result[0]).toBe('word1 word2'); expect(result.length).toBeGreaterThanOrEqual(2); }); it('hard-cuts when no whitespace available', () => { const text = 'abcdefghijklmnop'; const result = splitMessage(text, 5); expect(result[0]).toBe('abcde'); expect(result[1]).toBe('fghij'); expect(result[2]).toBe('klmno'); expect(result[3]).toBe('p'); }); it('produces multiple chunks for long text', () => { const text = 'chunk one\nchunk two\nchunk three\nchunk four'; const result = splitMessage(text, 20); expect(result.length).toBeGreaterThan(1); // Every chunk respects the limit for (const chunk of result) { expect(chunk.length).toBeLessThanOrEqual(20); } }); it('preserves all content (joined chunks equal original minus trimmed whitespace)', () => { const text = 'The quick brown fox jumps over the lazy dog. ' + 'Pack my box with five dozen liquor jugs. ' + 'How vexingly quick daft zebras jump.'; const result = splitMessage(text, 30); // Reassemble: since trimStart() removes leading whitespace between chunks, // we verify all words are preserved const originalWords = text.split(/\s+/); const resultWords = result.join(' ').split(/\s+/); expect(resultWords).toEqual(originalWords); }); it('prefers newline split over space split', () => { // Place newline at a good position and space later const text = 'first part\nsecond part of the message'; // maxLength 15: lastIndexOf('\n', 15) = 10, which is >= 15/2 = 7.5 → splits at newline const result = splitMessage(text, 15); expect(result[0]).toBe('first part'); }); it('falls back to space when newline is too early', () => { // Newline at position 2, which is < maxLength/2 for maxLength=14 const text = 'ab\ncdefghij klmnopqrst'; // lastIndexOf('\n', 14) = 2, but 2 < 14/2=7 → falls back to space // lastIndexOf(' ', 14) = 11, which is >= 7 → splits at space const result = splitMessage(text, 14); expect(result[0]).toBe('ab\ncdefghij'); expect(result[1]).toBe('klmnopqrst'); }); });