227 lines · 7.3 KB · TypeScript
RawDownload
import { describe, it, expect, beforeEach, afterEach } from 'vitest';import { LessonsManager } from '../tools/prr/state/lessons.js';import * as fs from 'fs';import * as path from 'path'; describe('normalizeLessonText', () => {  let lessonsManager: LessonsManager;  const testDir = '/tmp/test-lessons-normalize';   beforeEach(() => {    if (!fs.existsSync(testDir)) {      fs.mkdirSync(testDir, { recursive: true });    }    lessonsManager = new LessonsManager('test-owner', 'test-repo', 'test-branch');  });   afterEach(() => {    if (fs.existsSync(testDir)) {      fs.rmSync(testDir, { recursive: true, force: true });    }  });   // Helper to access private method  const normalize = (text: string): string | null => {    return (lessonsManager as any).normalizeLessonText(text);  };   describe('code fence removal', () => {    it('removes code fences', () => {      expect(normalize('```typescript\nsome code\n```')).toBeNull();    });     it('removes inline code backticks', () => {      expect(normalize('use `const` instead')).toBeNull();    });  });   describe('markdown header removal', () => {    it('removes markdown headers', () => {      expect(normalize('### Important Note')).toBeNull();    });     it('removes multiple header levels', () => {      expect(normalize('# Title')).toBeNull();      expect(normalize('## Subtitle')).toBeNull();    });  });   describe('bold line removal', () => {    it('removes bold markers', () => {      expect(normalize('**important text**')).toBeNull();    });  });   describe('list numbering and bullets', () => {    it('removes numbered list prefixes', () => {      expect(normalize('1. First item')).toBeNull();      expect(normalize('42. Some item')).toBeNull();    });     it('removes bullet points', () => {      expect(normalize('- bullet item')).toBeNull();      expect(normalize('* star item')).toBeNull();    });  });   describe('comment token removal', () => {    it('removes single-line comment tokens', () => {      expect(normalize('// this is a comment')).toBeNull();    });     it('removes multi-line comment tokens', () => {      expect(normalize('/* block comment */')).toBeNull();      expect(normalize('* continuation')).toBeNull();    });  });   describe('access modifier removal', () => {    it('removes public/private/protected', () => {      expect(normalize('public method()')).toBeNull();      expect(normalize('private field')).toBeNull();      expect(normalize('protected value')).toBeNull();    });  });   describe('declaration keyword removal', () => {    it('removes class/interface/type keywords', () => {      expect(normalize('class MyClass')).toBeNull();      expect(normalize('interface IFace')).toBeNull();      expect(normalize('type MyType')).toBeNull();    });     it('removes const/let/var keywords', () => {      expect(normalize('const value')).toBeNull();      expect(normalize('let variable')).toBeNull();      expect(normalize('var old')).toBeNull();    });     it('removes import/export keywords', () => {      expect(normalize('import something')).toBeNull();      expect(normalize('export default')).toBeNull();    });  });   describe('(inferred) removal', () => {    it('removes (inferred) markers', () => {      expect(normalize('(inferred) some text')).toBeNull();      expect(normalize('text (inferred) more')).toBeNull();    });  });   describe('file extension suffix stripping', () => {    it('strips common file extensions from paths', () => {      const result = normalize('Fix issue in file.ts');      expect(result).not.toContain('.ts:');    });     it('handles .js, .md, .json, .yml extensions', () => {      expect(normalize('edit config.json carefully before release')).toBeTruthy();      expect(normalize('update readme.md with release steps')).toBeTruthy();    });  });   describe('trailing type/line-number patterns', () => {    it('strips trailing line numbers like a:123', () => {      const result = normalize('file.ts:123');      expect(result).toBeNull();    });     it('strips file:line patterns', () => {      const result = normalize('src/index.ts:45');      expect(result).toBeNull();    });  });   describe('made no changes normalization', () => {    it('normalizes "tool made no changes"', () => {      const result = normalize('tool made no changes without explanation');      expect(result).toBe('tool made no changes without explanation');    });     it('normalizes "fixer made no changes"', () => {      const result = normalize('fixer made no changes without explanation');      expect(result).toBe('fixer made no changes without explanation');    });     it('normalizes with "trying different approach"', () => {      const result = normalize('tool made no changes - trying different approach');      expect(result).toBe('tool made no changes - trying different approach');    });     it('normalizes runner-prefixed variants', () => {      const result = normalize('claude-code made no changes without explanation');      expect(result).toBe('tool made no changes without explanation');    });     it('collapses numeric prefixes', () => {      const result = normalize('42 made no changes');      expect(result).toBe('tool made no changes');    });  });   describe('truncated and Fix for cases returning null', () => {    it('returns null for "chars truncated"', () => {      expect(normalize('500 chars truncated')).toBeNull();      expect(normalize('some text chars truncated here')).toBeNull();    });     it('returns null for "Fix for file:null"', () => {      expect(normalize('Fix for src/file.ts:null')).toBeNull();    });     it('returns null for "Fix for file:undefined"', () => {      expect(normalize('Fix for src/file.ts:undefined')).toBeNull();    });     it('returns null for "Fix for file:123"', () => {      expect(normalize('Fix for src/file.ts:123')).toBeNull();    });     it('returns null for "Fix for file" without line', () => {      expect(normalize('Fix for src/file.ts')).toBeNull();    });     it('returns null for bare numbers', () => {      expect(normalize('123')).toBeNull();      expect(normalize('42.')).toBeNull();    });  });   describe('trimming and cleanup', () => {    it('trims trailing colons', () => {      const result = normalize('Always document decisions:');      expect(result).toBe('Always document decisions');    });     it('trims trailing dashes', () => {      const result = normalize('Always document decisions -');      expect(result).toBe('Always document decisions');    });     it('returns null for empty result', () => {      expect(normalize('')).toBeNull();      expect(normalize('   ')).toBeNull();    });  });   describe('combined/edge inputs', () => {    it('handles multiple transformations in sequence', () => {      const input = '### **1. // public class MyClass**';      const result = normalize(input);      expect(result).toBeNull();    });     it('handles nested patterns', () => {      const input = '```ts\n// private const value\n```';      const result = normalize(input);      expect(result).toBeNull();    });     it('preserves meaningful content after all transformations', () => {      const input = 'Always validate user input before processing';      const result = normalize(input);      expect(result).toBe('Always validate user input before processing');    });  });});

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t