import { accessSync, constants, mkdtempSync, rmSync, writeFileSync } from 'node:fs' import * as os from 'node:os' import * as path from 'node:path' import { afterEach, describe, expect, it } from 'vitest' import { DEFAULT_COMMIT_PROFILE_NAME, resolveCommitProfileForRun, seedCommitProfilePath, } from './commitProfile' const tempDirs: string[] = [] afterEach(() => { while (tempDirs.length > 0) { const dir = tempDirs.pop() if (dir) rmSync(dir, { recursive: true, force: true }) } }) function tempDir(): string { const dir = mkdtempSync(path.join(os.tmpdir(), 'commit-profile-')) tempDirs.push(dir) return dir } describe('seedCommitProfilePath', () => { it('key 缺失时预填 deepseek-v4-pro 的 path', () => { const profiles = [ { name: 'grok-4.5', path: '/p/grok-4.5.json' }, { name: DEFAULT_COMMIT_PROFILE_NAME, path: '/p/deepseek-v4-pro.json' }, ] expect(seedCommitProfilePath(undefined, profiles)).toBe('/p/deepseek-v4-pro.json') }) it('key 缺失且无 deepseek 时返回空串', () => { expect(seedCommitProfilePath(undefined, [{ name: 'grok-4.5', path: '/p/g.json' }])).toBe('') }) it('key 已存在为空串时尊重用户清空', () => { expect(seedCommitProfilePath('', [{ name: DEFAULT_COMMIT_PROFILE_NAME, path: '/p/d.json' }])).toBe('') }) it('key 已存在为 path 时原样返回', () => { expect(seedCommitProfilePath('/custom/x.json', [{ name: DEFAULT_COMMIT_PROFILE_NAME, path: '/p/d.json' }])).toBe('/custom/x.json') }) }) describe('resolveCommitProfileForRun', () => { it('空串 → empty', () => { expect(resolveCommitProfileForRun(' ', p => p, () => true)).toEqual({ ok: false, reason: 'empty' }) }) it('文件不可读 → unreadable', () => { const dir = tempDir() const missing = path.join(dir, 'gone.json') const result = resolveCommitProfileForRun( missing, p => p, (p) => { try { accessSync(p, constants.R_OK) return true } catch { return false } }, ) expect(result).toEqual({ ok: false, reason: 'unreadable', profilePath: missing }) }) it('可读 path → ok', () => { const dir = tempDir() const file = path.join(dir, 'deepseek-v4-pro.json') writeFileSync(file, '{}') const result = resolveCommitProfileForRun( file, p => p, (p) => { try { accessSync(p, constants.R_OK) return true } catch { return false } }, ) expect(result).toEqual({ ok: true, profilePath: file }) }) it('经 resolvePath remap 后再检查可读', () => { const dir = tempDir() const local = path.join(dir, 'deepseek-v4-pro.json') writeFileSync(local, '{}') const foreign = '/Users/other/.claude/profiles/deepseek-v4-pro.json' const result = resolveCommitProfileForRun( foreign, () => local, (p) => { try { accessSync(p, constants.R_OK) return true } catch { return false } }, ) expect(result).toEqual({ ok: true, profilePath: local }) }) })