import { describe, expect, it } from 'vitest' import { buildChangedTree } from './changedTree' describe('改动的文件树', () => { // 原型「审查 · 改动的文件」里的 6 个文件(schemas.py 是改名的,算修改) const files = [ { path: 'backend/src/luffy_agent/user/routes.py', change: 'M' }, { path: 'backend/tests/user/test_avatar.py', change: 'A' }, { path: 'backend/src/luffy_agent/core/storage.py', change: 'M' }, { path: 'backend/src/luffy_agent/user/legacy_profile.py', change: 'D' }, { path: 'backend/src/luffy_agent/user/services.py', change: 'M' }, { path: 'backend/src/luffy_agent/user/schemas.py', change: 'M' }, ] as const const tree = buildChangedTree(files) const names = (dir: string): string[] => (tree.get(dir) ?? []).map(entry => entry.name) it('目录层级照留,每层只有通往改动的文件的目录', () => { expect(names('')).toEqual(['backend']) expect(names('backend')).toEqual(['src', 'tests']) expect(names('backend/src')).toEqual(['luffy_agent']) expect(names('backend/src/luffy_agent')).toEqual(['core', 'user']) expect(names('backend/src/luffy_agent/core')).toEqual(['storage.py']) expect(names('backend/tests/user')).toEqual(['test_avatar.py']) }) it('同一层里的文件按名字排,带着各自的改动和相对根目录的路径', () => { expect(tree.get('backend/src/luffy_agent/user')).toEqual([ { name: 'legacy_profile.py', path: 'backend/src/luffy_agent/user/legacy_profile.py', isDirectory: false, change: 'D' }, { name: 'routes.py', path: 'backend/src/luffy_agent/user/routes.py', isDirectory: false, change: 'M' }, { name: 'schemas.py', path: 'backend/src/luffy_agent/user/schemas.py', isDirectory: false, change: 'M' }, { name: 'services.py', path: 'backend/src/luffy_agent/user/services.py', isDirectory: false, change: 'M' }, ]) }) it('目录没有改动,路径相对根目录', () => { expect(tree.get('backend')).toEqual([ { name: 'src', path: 'backend/src', isDirectory: true }, { name: 'tests', path: 'backend/tests', isDirectory: true }, ]) }) it('目录在前、文件在后,名字不区分大小写,和普通的树一样', () => { const mixed = buildChangedTree([ { path: 'README.md', change: 'M' }, { path: 'src/a.ts', change: 'A' }, { path: 'Docs/b.md', change: 'A' }, { path: 'package.json', change: 'M' }, ]) expect(mixed.get('')?.map(entry => entry.name)).toEqual(['Docs', 'src', 'package.json', 'README.md']) }) it('文件换成同名目录(删掉 a、新加 a/b)两项都留着', () => { const replaced = buildChangedTree([{ path: 'a', change: 'D' }, { path: 'a/b', change: 'A' }]) expect(replaced.get('')).toEqual([ { name: 'a', path: 'a', isDirectory: true }, { name: 'a', path: 'a', isDirectory: false, change: 'D' }, ]) expect(replaced.get('a')?.map(entry => entry.change)).toEqual(['A']) }) it('没有改动的文件时根下面是空的', () => { expect(buildChangedTree([]).get('')).toEqual([]) }) })