61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
/**
|
|
* Unit tests for slugify utility
|
|
*
|
|
* Tests URL/filename-safe slug generation (a-z 0-9 hyphen, max 30 chars).
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { slugify } from '../shared/utils/slug.js';
|
|
|
|
describe('slugify', () => {
|
|
it('should convert to lowercase', () => {
|
|
expect(slugify('Hello World')).toBe('hello-world');
|
|
});
|
|
|
|
it('should replace non-alphanumeric characters with hyphens', () => {
|
|
expect(slugify('foo bar_baz')).toBe('foo-bar-baz');
|
|
});
|
|
|
|
it('should collapse consecutive special characters into single hyphen', () => {
|
|
expect(slugify('foo---bar baz')).toBe('foo-bar-baz');
|
|
});
|
|
|
|
it('should strip leading and trailing hyphens', () => {
|
|
expect(slugify('--hello--')).toBe('hello');
|
|
expect(slugify(' hello ')).toBe('hello');
|
|
});
|
|
|
|
it('should truncate to 30 characters', () => {
|
|
const long = 'a'.repeat(100);
|
|
expect(slugify(long).length).toBeLessThanOrEqual(30);
|
|
});
|
|
|
|
it('should strip CJK characters', () => {
|
|
expect(slugify('タスク指示書')).toBe('');
|
|
});
|
|
|
|
it('should handle mixed ASCII and CJK', () => {
|
|
expect(slugify('Add タスク Feature')).toBe('add-feature');
|
|
});
|
|
|
|
it('should handle numbers', () => {
|
|
expect(slugify('issue 123')).toBe('issue-123');
|
|
});
|
|
|
|
it('should handle empty result after stripping', () => {
|
|
expect(slugify('!@#$%')).toBe('');
|
|
});
|
|
|
|
it('should handle typical GitHub issue titles', () => {
|
|
expect(slugify('Fix: login not working (#42)')).toBe('fix-login-not-working-42');
|
|
});
|
|
|
|
it('should strip trailing hyphen after truncation', () => {
|
|
// 30 chars of slug that ends with a hyphen after slice
|
|
const input = 'abcdefghijklmnopqrstuvwxyz-abc-xyz';
|
|
const result = slugify(input);
|
|
expect(result.length).toBeLessThanOrEqual(30);
|
|
expect(result).not.toMatch(/-$/);
|
|
});
|
|
});
|