import { describe, expect, it } from 'vitest'; import { dedupeName, formatNamingDate, formatNamingSequence, resolveNamingTemplate, sanitizeFilename, validateNamingTemplate, } from './naming.js'; describe('sanitizeFilename', () => { it('替换路径分隔符与非法字符,保留中文', () => { expect(sanitizeFilename('素材/标签:01*?.png')).toBe('素材_标签_01__.png'); }); it('去除首尾空格与点,空名回退', () => { expect(sanitizeFilename(' ..脚本草稿 .. ')).toBe('脚本草稿'); expect(sanitizeFilename(' ')).toBe('未命名'); expect(sanitizeFilename('***', { fallback: 'file' })).toBe('file'); }); it('Windows 保留名追加下划线', () => { expect(sanitizeFilename('CON')).toBe('CON_'); expect(sanitizeFilename('lpt1')).toBe('lpt1_'); }); it('超长时保留扩展名', () => { const name = sanitizeFilename(`${'a'.repeat(200)}.png`, { maxLength: 20 }); expect(name).toHaveLength(20); expect(name.endsWith('.png')).toBe(true); }); }); describe('dedupeName(R-01 同名自动加序号)', () => { it('不冲突时原样返回', () => { expect(dedupeName('脚本-01', new Set())).toBe('脚本-01'); }); it('冲突时追加两位序号', () => { const existing = new Set(['素材.png', '素材-02.png']); expect(dedupeName('素材.png', existing)).toBe('素材-03.png'); }); it('带序号的名字基于原始基名递增', () => { const existing = new Set(['素材-02.png', '素材-03.png']); expect(dedupeName('素材-03.png', existing)).toBe('素材-04.png'); }); it('序号耗尽时抛错', () => { const existing = new Set(['a', ...Array.from({ length: 3 }, (_, i) => `a-0${String(i + 2)}`)]); expect(() => dedupeName('a', existing, 3)).toThrow(RangeError); }); }); describe('命名模板(A4-BE-03 / R-01)', () => { const context = { industry: '电商', customer: '花间集', direction: '口播', date: '20261104', sequence: 1, spec: '1080x1920', }; it('默认脚本模板解析为「行业-客户-方向-日期-序号」', () => { expect(resolveNamingTemplate('{行业}-{客户}-{脚本方向}-{日期}-{序号}', context)).toBe( '电商-花间集-口播-20261104-1', ); }); it('序号可先补零后传入', () => { expect( resolveNamingTemplate('{行业}-{客户}-{日期}-{序号}', { ...context, sequence: formatNamingSequence(context.sequence), }), ).toBe('电商-花间集-20261104-01'); }); it('兼容英文 key 与规格后缀', () => { expect(resolveNamingTemplate('{industry}-{customer}-{date}-{seq}-{spec}', context)).toBe( '电商-花间集-20261104-1-1080x1920', ); }); it('未知占位符 / 非法字符 / 空模板被拒绝', () => { expect(validateNamingTemplate('{行业}-{未知}').valid).toBe(false); expect(validateNamingTemplate('{行业}*{客户}').valid).toBe(false); expect(validateNamingTemplate(' ').valid).toBe(false); }); it('缺失占位符值时抛错', () => { expect(() => resolveNamingTemplate('{行业}-{客户}', { ...context, customer: '' })).toThrow( '命名占位符缺少值', ); }); it('超过最大长度抛错', () => { expect(() => resolveNamingTemplate('{客户}', { ...context, customer: '客'.repeat(101) }), ).toThrow('不能超过 100 个字符'); }); it('日期与序号格式化', () => { expect(formatNamingDate(new Date(2026, 10, 4))).toBe('20261104'); expect(formatNamingSequence(7)).toBe('07'); expect(formatNamingSequence(123)).toBe('123'); expect(() => formatNamingSequence(-1)).toThrow(); }); });