import { accessSync, constants, mkdtempSync, mkdirSync, 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 { getProfilesDir, resolveProfilePath, setProfilesDirOverride, } from './profiles' const originalEnv = process.env.SUPERPOWERS_PROFILES_DIR afterEach(() => { setProfilesDirOverride(undefined) if (originalEnv === undefined) delete process.env.SUPERPOWERS_PROFILES_DIR else process.env.SUPERPOWERS_PROFILES_DIR = originalEnv }) describe('getProfilesDir', () => { it('env SUPERPOWERS_PROFILES_DIR 优先', () => { const dir = mkdtempSync(path.join(os.tmpdir(), 'profiles-env-')) try { process.env.SUPERPOWERS_PROFILES_DIR = dir setProfilesDirOverride('~/ignored') expect(getProfilesDir()).toBe(path.resolve(dir)) } finally { rmSync(dir, { recursive: true, force: true }) } }) it('settings override 支持 ~ 并优先于 auto', () => { delete process.env.SUPERPOWERS_PROFILES_DIR const dir = mkdtempSync(path.join(os.tmpdir(), 'profiles-override-')) try { const tildePath = dir.replace(os.homedir(), '~') setProfilesDirOverride(tildePath) expect(getProfilesDir()).toBe(path.resolve(dir)) } finally { rmSync(dir, { recursive: true, force: true }) } }) it('空 override 时优先 cruldra-profile 真实源(若可读)', () => { delete process.env.SUPERPOWERS_PROFILES_DIR setProfilesDirOverride(undefined) const preferred = path.join(os.homedir(), 'Sources', 'cruldra-profile', 'claude-config', 'profiles') try { accessSync(preferred, constants.R_OK) } catch { // 本机无该目录则跳过(CI / 其它机器) return } expect(getProfilesDir()).toBe(preferred) }) }) describe('resolveProfilePath', () => { it('空值回退默认 profile 路径', () => { delete process.env.SUPERPOWERS_PROFILES_DIR const dir = mkdtempSync(path.join(os.tmpdir(), 'profiles-default-')) try { writeFileSync(path.join(dir, 'offical.json'), '{}') setProfilesDirOverride(dir) expect(resolveProfilePath(undefined)).toBe(path.join(dir, 'offical.json')) expect(resolveProfilePath('')).toBe(path.join(dir, 'offical.json')) } finally { rmSync(dir, { recursive: true, force: true }) } }) it('可读绝对路径原样返回', () => { delete process.env.SUPERPOWERS_PROFILES_DIR const dir = mkdtempSync(path.join(os.tmpdir(), 'profiles-readable-')) try { const file = path.join(dir, 'grok-4.5.json') writeFileSync(file, '{}') setProfilesDirOverride(dir) expect(resolveProfilePath(file)).toBe(file) } finally { rmSync(dir, { recursive: true, force: true }) } }) it('跨机绝对路径按 basename remap 到本机 profiles 目录', () => { delete process.env.SUPERPOWERS_PROFILES_DIR const dir = mkdtempSync(path.join(os.tmpdir(), 'profiles-remap-')) try { writeFileSync(path.join(dir, 'grok-4.5.json'), '{}') setProfilesDirOverride(dir) const foreign = '/Users/cruldra/.claude/profile-settings/grok-4.5.json' expect(resolveProfilePath(foreign)).toBe(path.join(dir, 'grok-4.5.json')) } finally { rmSync(dir, { recursive: true, force: true }) } }) it('无法 remap 时返回原路径', () => { delete process.env.SUPERPOWERS_PROFILES_DIR const dir = mkdtempSync(path.join(os.tmpdir(), 'profiles-miss-')) try { mkdirSync(dir, { recursive: true }) setProfilesDirOverride(dir) const foreign = '/Users/cruldra/.claude/profile-settings/missing-model.json' expect(resolveProfilePath(foreign)).toBe(foreign) } finally { rmSync(dir, { recursive: true, force: true }) } }) })