镜像自地址
https://github.com/lhly/cloud-drive-renamer.git
已同步 2026-10-21 06:01:51 +08:00
新增 episodeExtract 规则类型,支持从文件名提取季集号并按模板生成新文件名。提取失败的文件会在预览中显示错误信息并自动跳过执行,避免误操作。
- 支持模板变量:{prefix} {season} {episode} {ext}
- 提供 helperPre/helperPost 锚点辅助提取
- 支持集数偏移和自定义前导零位数
- 更新规则工厂、类型定义和国际化配置
- 添加单元测试和设计文档
82 行
2.3 KiB
TypeScript
82 行
2.3 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
||
import { EpisodeExtractRule } from '../../src/rules/episode-extract';
|
||
|
||
describe('EpisodeExtractRule', () => {
|
||
it('应按模板输出剧集命名(含 ext)', () => {
|
||
const rule = new EpisodeExtractRule({
|
||
template: '{prefix}.S{season}E{episode}{ext}',
|
||
prefix: 'My.Show',
|
||
season: 1,
|
||
leadingZeroCount: 3,
|
||
});
|
||
|
||
const result = rule.execute('My.Show.S01E02.1080p.mp4', 0, 1);
|
||
expect(result).toBe('My.Show.S01E002.mp4');
|
||
});
|
||
|
||
it('模板未包含 {ext} 时应自动补扩展名', () => {
|
||
const rule = new EpisodeExtractRule({
|
||
template: '{prefix}.S{season}E{episode}',
|
||
prefix: 'Series',
|
||
season: 2,
|
||
leadingZeroCount: 2,
|
||
});
|
||
|
||
const result = rule.execute('Series.EP7.mkv', 0, 1);
|
||
expect(result).toBe('Series.S02E07.mkv');
|
||
});
|
||
|
||
it('应支持 helperPre/helperPost 提取集数', () => {
|
||
const rule = new EpisodeExtractRule({
|
||
template: '{prefix}-S{season}E{episode}{ext}',
|
||
prefix: 'Drama',
|
||
season: 3,
|
||
helperPre: '第',
|
||
helperPost: '集',
|
||
leadingZeroCount: 3,
|
||
});
|
||
|
||
const result = rule.execute('Drama 第12集 中文字幕.mp4', 0, 1);
|
||
expect(result).toBe('Drama-S03E012.mp4');
|
||
});
|
||
|
||
it('应支持 offset 偏移', () => {
|
||
const rule = new EpisodeExtractRule({
|
||
template: '{prefix}.S{season}E{episode}{ext}',
|
||
prefix: 'Offset',
|
||
season: 1,
|
||
offset: 10,
|
||
leadingZeroCount: 3,
|
||
});
|
||
|
||
const result = rule.execute('Offset EP02.mp4', 0, 1);
|
||
expect(result).toBe('Offset.S01E012.mp4');
|
||
});
|
||
|
||
it('提取失败时应抛出“未识别到集数”错误码,供上层展示友好文案', () => {
|
||
const rule = new EpisodeExtractRule({
|
||
template: '{prefix}.S{season}E{episode}{ext}',
|
||
prefix: 'NoEp',
|
||
season: 1,
|
||
});
|
||
|
||
expect(() => rule.execute('No episode token here.mp4', 0, 1)).toThrow(
|
||
/extract_episode_not_found/
|
||
);
|
||
});
|
||
|
||
it('offset 导致集数无效时应抛出范围错误码', () => {
|
||
const rule = new EpisodeExtractRule({
|
||
template: '{prefix}.S{season}E{episode}{ext}',
|
||
prefix: 'OffsetBad',
|
||
season: 1,
|
||
offset: -10,
|
||
leadingZeroCount: 3,
|
||
});
|
||
|
||
expect(() => rule.execute('OffsetBad EP02.mp4', 0, 1)).toThrow(
|
||
/extract_episode_out_of_range/
|
||
);
|
||
});
|
||
});
|