// Tests for the correction-tracking heuristic — should not flood the // memories table with whitespace-only or single-word fixes on long // outputs, but must capture all real edits. import { describe, expect, it } from 'vitest'; import { isMeaningfulChange } from './correction-tracker'; describe('isMeaningfulChange', () => { it('returns false for empty strings', () => { expect(isMeaningfulChange('', 'anything')).toBe(false); expect(isMeaningfulChange('anything', '')).toBe(false); }); it('returns false when the trimmed text is identical', () => { expect(isMeaningfulChange('hello', 'hello')).toBe(false); expect(isMeaningfulChange('hello\n', ' hello ')).toBe(false); }); it('returns true for short edits even with small word/char diffs', () => { // The 100-char threshold guards against noise on LONG outputs only. // Short edits always count. expect(isMeaningfulChange('hi', 'hi.')).toBe(true); expect(isMeaningfulChange('hi', 'hello')).toBe(true); }); it('rejects single-word, ≤20-char edits on long original output', () => { const long = 'Patient is a 5-year-old male presenting with fever for two days. ' + 'No respiratory symptoms. No GI symptoms. Vitals stable. Exam unremarkable. ' + 'Plan: supportive care, return precautions reviewed.'; // Same length, swap one word — wordDiff=0, charDiff=0 → noise, skip. expect(isMeaningfulChange(long, long.replace('male', 'mail'))).toBe(false); // Same length, swap one word for similar length — still noise, skip. expect(isMeaningfulChange(long, long.replace('two days', 'one day '))).toBe(false); }); it('accepts multi-word edits even on long output', () => { const long = 'Patient is a 5-year-old male presenting with fever for two days. ' + 'No respiratory symptoms. No GI symptoms. Vitals stable. Exam unremarkable. ' + 'Plan: supportive care, return precautions reviewed.'; // Inserting a sentence is a real edit — track it. const edited = long + ' Will follow up in 48 hours if symptoms persist.'; expect(isMeaningfulChange(long, edited)).toBe(true); }); it('accepts single-word edits when the char diff is large enough', () => { const long = 'a'.repeat(150); // 30-char insertion — over the 20-char noise floor. expect(isMeaningfulChange(long, long + 'x'.repeat(30))).toBe(true); }); });