Files
superwork/vscode/src/codeReader/explorer/fileEntries.test.ts
T

82 lines
4.0 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { createExcludeMatcher, entryContext, sortEntries } from './fileEntries'
const dir = (name: string): { name: string, isDirectory: boolean } => ({ name, isDirectory: true })
const file = (name: string): { name: string, isDirectory: boolean } => ({ name, isDirectory: false })
describe('文件树排序', () => {
it('目录在前、文件在后,名字不区分大小写', () => {
const sorted = sortEntries([file('b.ts'), dir('src'), file('A.ts'), dir('Docs'), file('a.md')])
expect(sorted.map(e => e.name)).toEqual(['Docs', 'src', 'a.md', 'A.ts', 'b.ts'])
})
it('名字里的数字按数值比', () => {
expect(sortEntries([file('item10.ts'), file('item2.ts'), file('item1.ts')]).map(e => e.name))
.toEqual(['item1.ts', 'item2.ts', 'item10.ts'])
})
it('只差大小写的名字次序稳定,不依赖输入顺序', () => {
const a = sortEntries([file('readme.md'), file('README.md')]).map(e => e.name)
const b = sortEntries([file('README.md'), file('readme.md')]).map(e => e.name)
expect(a).toEqual(b)
})
})
describe('行的 contextValue', () => {
it('工作区根、目录、文件各一种,菜单按它挂「添加注释」', () => {
expect(entryContext({ isDirectory: true, isRoot: true })).toBe('root')
expect(entryContext({ isDirectory: true, isRoot: false })).toBe('folder')
expect(entryContext({ isDirectory: false, isRoot: false })).toBe('file')
})
it('文件行可以带标记(「更改」区能暂存的 file unstaged),目录、根不带', () => {
expect(entryContext({ isDirectory: false, isRoot: false }, 'unstaged')).toBe('file unstaged')
expect(entryContext({ isDirectory: true, isRoot: false }, 'unstaged')).toBe('folder')
expect(entryContext({ isDirectory: true, isRoot: true }, 'unstaged')).toBe('root')
})
it('删掉的文件行最后带 deleted(菜单按它不挂「打开更改」),改了、新加的不带', () => {
expect(entryContext({ isDirectory: false, isRoot: false, change: 'D' })).toBe('file deleted')
expect(entryContext({ isDirectory: false, isRoot: false, change: 'D' }, 'unstaged')).toBe('file unstaged deleted')
expect(entryContext({ isDirectory: false, isRoot: false, change: 'M' }, 'unstaged')).toBe('file unstaged')
expect(entryContext({ isDirectory: false, isRoot: false, change: 'A' })).toBe('file')
})
})
describe('files.exclude', () => {
const none = new Set<string>()
it('默认的排除项(.git、.DS_Store 等)在任意层级都生效', () => {
const excluded = createExcludeMatcher({ '**/.git': true, '**/.DS_Store': true, '**/node_modules': true })
expect(excluded('.git', none)).toBe(true)
expect(excluded('packages/app/.DS_Store', none)).toBe(true)
expect(excluded('node_modules', none)).toBe(true)
expect(excluded('src/.gitignore', none)).toBe(false)
expect(excluded('src/index.ts', none)).toBe(false)
})
it('值为 false 的规则不排除;没有配置时什么都不排除', () => {
expect(createExcludeMatcher({ '**/dist': false })('dist', none)).toBe(false)
expect(createExcludeMatcher(undefined)('dist', none)).toBe(false)
})
it('不带 **/ 的规则只匹配工作区根下的路径', () => {
const excluded = createExcludeMatcher({ build: true })
expect(excluded('build', none)).toBe(true)
expect(excluded('src/build', none)).toBe(false)
})
it('* 也匹配点开头的名字,花括号展开可用', () => {
const excluded = createExcludeMatcher({ '**/*.{log,tmp}': true })
expect(excluded('.debug.log', none)).toBe(true)
expect(excluded('.github/x.tmp', none)).toBe(true)
expect(excluded('x.ts', none)).toBe(false)
})
it('when 条件:有同名的兄弟文件才排除', () => {
const excluded = createExcludeMatcher({ '**/*.js': { when: '$(basename).ts' } })
expect(excluded('src/app.js', new Set(['app.js', 'app.ts']))).toBe(true)
expect(excluded('src/tool.js', new Set(['tool.js', 'app.ts']))).toBe(false)
})
})