/** * 04-finder: Finder 历史导航、文件操作、废纸篓 * 原测试: Playwright browser → 改为 FS composable 层测试 */ import { describe, it, expect, beforeEach } from 'vitest' import { fs } from '../../src/composables/useFS' describe('04-finder — 访达核心', () => { beforeEach(() => { localStorage.clear(); (fs as any).root = null; fs.init() }) // ===== 路径导航 ===== it('list Desktop 返回 ≥2 项目(welcome.txt + Sample Folder)', () => { const items = fs.list(fs.HOME + '/Desktop') expect(items.length).toBeGreaterThanOrEqual(2) }) it('baseName 提取文件名', () => { expect(fs.baseName('/a/b/c.txt')).toBe('c.txt') }) it('dirName 提取目录', () => { expect(fs.dirName('/a/b/c.txt')).toBe('/a/b') }) it('join 拼接路径', () => { expect(fs.join('/a', 'b/', '/c')).toBe('/a/b/c') }) it('normalize 规范化', () => { expect(fs.normalize('/a/./b/../c')).toBe('/a/c') }) // ===== 选择与类型 ===== it('iconFor 文件夹返回 folder 图标', () => { expect(fs.iconFor(fs.HOME + '/Desktop')).toContain('folder') }) it('iconFor 文本文件返回 txt 图标', () => { expect(fs.iconFor(fs.HOME + '/Desktop/welcome.txt')).toContain('txt') }) it('kindOf 文件夹返回"文件夹"', () => { expect(fs.kindOf(fs.HOME + '/Desktop')).toBe('文件夹') }) it('kindOf 文本返回"纯文本"', () => { expect(fs.kindOf(fs.HOME + '/Desktop/welcome.txt')).toBe('纯文本') }) // ===== 重命名 ===== it('rename 后旧名消失新名存在', () => { fs.write(fs.HOME + '/rn-old.txt', 'x') fs.rename(fs.HOME + '/rn-old.txt', 'rn-new.txt') expect(fs.exists(fs.HOME + '/rn-old.txt')).toBe(false) expect(fs.exists(fs.HOME + '/rn-new.txt')).toBe(true) fs.remove(fs.HOME + '/rn-new.txt') }) // ===== 复制/移动 ===== it('copy 复制文件到目标目录', () => { const np = fs.copy(fs.HOME + '/Desktop/welcome.txt', fs.HOME + '/Documents') expect(np).toContain('Documents') expect(fs.exists(np)).toBe(true) fs.remove(np) }) it('move 移动文件并删除源', () => { fs.write(fs.HOME + '/mv-src.txt', 'x') fs.move(fs.HOME + '/mv-src.txt', fs.HOME + '/Documents') expect(fs.exists(fs.HOME + '/mv-src.txt')).toBe(false) expect(fs.exists(fs.HOME + '/Documents/mv-src.txt')).toBe(true) fs.remove(fs.HOME + '/Documents/mv-src.txt') }) it('move 到自身抛错', () => { expect(() => fs.move(fs.HOME + '/Desktop', fs.HOME + '/Desktop')).toThrow() }) // ===== 废纸篓 ===== it('trash + restore 完整流程', () => { fs.write(fs.HOME + '/Documents/trash-me.txt', 'restore me') const orig = fs.HOME + '/Documents/trash-me.txt' fs.trash(orig) expect(fs.exists(orig)).toBe(false) // 已移走 fs.restore('trash-me.txt') expect(fs.exists(orig)).toBe(true) // 已还原 fs.remove(orig) }) it('emptyTrash 清空废纸篓', () => { fs.write(fs.HOME + '/empty-me.txt', '') fs.trash(fs.HOME + '/empty-me.txt') expect(fs.list(fs.TRASH).length).toBeGreaterThan(0) fs.emptyTrash() expect(fs.list(fs.TRASH).length).toBe(0) }) // ===== 搜索 ===== it('search 按名称找到文件', () => { const r = fs.search('welcome') expect(r.length).toBeGreaterThanOrEqual(1) expect(r.some((x: any) => x.path.includes('welcome'))).toBe(true) }) it('search 限制最多 40 条', () => { for (let i = 0; i < 50; i++) fs.write(fs.HOME + '/st-' + i + '.txt', '') const r = fs.search('st-', fs.HOME) expect(r.length).toBeLessThanOrEqual(40) for (let i = 0; i < 50; i++) fs.remove(fs.HOME + '/st-' + i + '.txt') }) // ===== uniqueName ===== it('uniqueName 冲突时自动编号', () => { const name = fs.uniqueName(fs.HOME + '/Desktop', 'welcome.txt') expect(name).not.toBe('welcome.txt') expect(name).toContain('welcome') }) // ===== 边界情况 ===== it('write 到同名目录抛错', () => { fs.mkdir(fs.HOME + '/crash-test') expect(() => fs.write(fs.HOME + '/crash-test', '')).toThrow('同名文件夹') fs.remove(fs.HOME + '/crash-test') }) it('read 不存在文件抛错', () => { expect(() => fs.read('/no')).toThrow() }) it('read 目录抛错', () => { expect(() => fs.read(fs.HOME)).toThrow('不是文本文件') }) it('mkdir 已存在目录且 recursive 不抛错', () => { fs.mkdir(fs.HOME + '/exist-test', { recursive: true, silent: true }) expect(fs.isDir(fs.HOME + '/exist-test')).toBe(true) // recursive 已存在不应抛错 expect(() => fs.mkdir(fs.HOME + '/exist-test', { recursive: true })).not.toThrow() fs.remove(fs.HOME + '/exist-test') }) })