cloud-drive-renamer/tests/unit/last-rename-operation.test.ts
Zain bf75cdcb10 feat: 为批量重命名面板增加撤销最近一次操作功能
- 在平台适配器中统一暴露 getCurrentDirectoryKey() 方法,用于确定当前目录范围
- 新增 LastRenameOperation 数据模型和核心操作函数,支持单条撤销记录的创建、合并和范围校验
- 在 file-selector-panel 中集成撤销逻辑,支持执行后保存记录、retry 成功后合并记录以及撤销操作
- 在 config-panel 底部操作区新增撤销按钮,根据当前目录范围动态显示/隐藏
- 添加多语言支持,包含撤销相关文案
- 添加单元测试和集成测试,确保撤销功能的正确性和稳定性
2026-03-18 23:14:53 +08:00

75 行
2.9 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
createLastRenameOperation,
isLastRenameOperationInScope,
mergeLastRenameOperation,
retainFailedUndoItems,
} from '../../src/core/last-rename-operation';
describe('last rename operation helpers', () => {
it('creates a last rename operation from success results', () => {
const operation = createLastRenameOperation('quark', 'dir-1', [
{ fileId: '1', original: 'old-a.txt', renamed: 'new-a.txt', index: 0 },
]);
expect(operation).not.toBeNull();
expect(operation?.platform).toBe('quark');
expect(operation?.directoryKey).toBe('dir-1');
expect(operation?.items).toEqual([
{ fileId: '1', original: 'old-a.txt', renamed: 'new-a.txt', index: 0 },
]);
expect(typeof operation?.createdAt).toBe('number');
expect(typeof operation?.updatedAt).toBe('number');
});
it('returns null when creating from empty success results', () => {
expect(createLastRenameOperation('quark', 'dir-1', [])).toBeNull();
});
it('merges retry success items into the existing operation', () => {
const existing = createLastRenameOperation('quark', 'dir-1', [
{ fileId: '1', original: 'old-a.txt', renamed: 'new-a.txt', index: 0 },
]);
const merged = mergeLastRenameOperation(existing, 'quark', 'dir-1', [
{ fileId: '2', original: 'old-b.txt', renamed: 'new-b.txt', index: 1 },
]);
expect(merged).not.toBeNull();
expect(merged?.items.map((item) => item.fileId)).toEqual(['1', '2']);
expect(merged?.createdAt).toBe(existing?.createdAt);
expect((merged?.updatedAt ?? 0) >= (existing?.updatedAt ?? 0)).toBe(true);
});
it('checks whether an operation is still in the current scope', () => {
const operation = createLastRenameOperation('baidu', '/video/season1', [
{ fileId: '9', original: 'ep01.mkv', renamed: 'S01E01.mkv', index: 0 },
]);
expect(isLastRenameOperationInScope(operation, 'baidu', '/video/season1')).toBe(true);
expect(isLastRenameOperationInScope(operation, 'baidu', '/video/season2')).toBe(false);
expect(isLastRenameOperationInScope(operation, 'quark', '/video/season1')).toBe(false);
});
it('retains only failed undo items', () => {
const operation = createLastRenameOperation('quark', 'dir-1', [
{ fileId: '1', original: 'old-a.txt', renamed: 'new-a.txt', index: 0 },
{ fileId: '2', original: 'old-b.txt', renamed: 'new-b.txt', index: 1 },
]);
const next = retainFailedUndoItems(operation, new Set(['2']));
expect(next?.items).toEqual([
{ fileId: '2', original: 'old-b.txt', renamed: 'new-b.txt', index: 1 },
]);
});
it('returns null when no failed undo items remain', () => {
const operation = createLastRenameOperation('quark', 'dir-1', [
{ fileId: '1', original: 'old-a.txt', renamed: 'new-a.txt', index: 0 },
]);
expect(retainFailedUndoItems(operation, new Set())).toBeNull();
});
});