Files
PromptX/src/tests/issues/platform-folders.e2e.test.js

276 lines
8.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { execSync, spawn } = require('child_process')
const path = require('path')
const fs = require('fs-extra')
const os = require('os')
describe('Platform-Folders 兼容性问题 - E2E Tests', () => {
let tempDir
let originalPlatform
beforeAll(async () => {
// 创建临时目录用于测试
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'promptx-platform-test-'))
originalPlatform = process.platform
})
afterAll(async () => {
if (tempDir) {
await fs.remove(tempDir)
}
// 恢复原始平台
Object.defineProperty(process, 'platform', {
value: originalPlatform
})
})
/**
* 模拟Windows环境
*/
function mockWindowsEnvironment() {
// 模拟Windows平台
Object.defineProperty(process, 'platform', {
value: 'win32',
configurable: true
})
// 模拟Windows环境变量
const originalEnv = { ...process.env }
process.env.APPDATA = 'C:\\Users\\Test\\AppData\\Roaming'
process.env.LOCALAPPDATA = 'C:\\Users\\Test\\AppData\\Local'
process.env.USERPROFILE = 'C:\\Users\\Test'
return () => {
// 恢复环境变量
Object.keys(originalEnv).forEach(key => {
process.env[key] = originalEnv[key]
})
Object.keys(process.env).forEach(key => {
if (!(key in originalEnv)) {
delete process.env[key]
}
})
}
}
/**
* 模拟platform-folders包导入失败
*/
function mockPlatformFoldersFailure() {
const Module = require('module')
const originalRequire = Module.prototype.require
// Mock Module.prototype.require
Module.prototype.require = function(id) {
if (id === 'platform-folders') {
const error = new Error("Cannot find module 'platform-folders'")
error.code = 'MODULE_NOT_FOUND'
throw error
}
return originalRequire.call(this, id)
}
return () => {
Module.prototype.require = originalRequire
}
}
/**
* 模拟NPX环境下的安装问题
*/
function mockNpxEnvironment() {
const originalEnv = { ...process.env }
// 模拟npx环境变量
process.env.npm_execpath = '/usr/local/lib/node_modules/npm/bin/npx-cli.js'
process.env.npm_config_cache = '/tmp/_npx/12345'
process.env.npm_lifecycle_event = undefined
return () => {
Object.keys(originalEnv).forEach(key => {
process.env[key] = originalEnv[key]
})
}
}
describe('Windows环境兼容性测试', () => {
test('应该检测到Windows环境下的platform-folders问题', async () => {
const restoreEnv = mockWindowsEnvironment()
const restoreRequire = mockPlatformFoldersFailure()
try {
// 动态导入UserProtocol测试platform-folders错误处理
const UserProtocol = require('../../lib/core/resource/protocols/UserProtocol')
const userProtocol = new UserProtocol()
// 调用可能触发platform-folders的方法
const result = await userProtocol.getUserDirectory('home')
// 验证fallback机制是否工作
expect(result).toBeDefined()
expect(typeof result).toBe('string')
// 验证是否使用了fallback路径home目录应该存在
expect(result).toBeTruthy()
} catch (error) {
// 如果抛出错误验证错误信息是否包含platform-folders相关内容
expect(error.message).toMatch(/platform-folders|用户目录|配置路径/)
} finally {
restoreEnv()
restoreRequire()
}
})
test('应该在Windows + NPX环境下正常工作无警告', async () => {
const restoreEnv = mockWindowsEnvironment()
const restoreNpx = mockNpxEnvironment()
// 捕获console.warn输出
const originalWarn = console.warn
const warnMessages = []
console.warn = (...args) => {
warnMessages.push(args.join(' '))
}
try {
// 测试在Windows + NPX环境下env-paths正常工作
const UserProtocol = require('../../lib/core/resource/protocols/UserProtocol')
const userProtocol = new UserProtocol()
const documentsPath = await userProtocol.getUserDirectory('documents')
// 验证获取目录成功
expect(documentsPath).toBeDefined()
expect(typeof documentsPath).toBe('string')
expect(documentsPath.length).toBeGreaterThan(0)
// 检查是否有platform-folders相关警告
const hasPlatformFoldersWarning = warnMessages.some(msg =>
msg.includes('platform-folders') ||
msg.includes('不可用使用os.homedir()回退方案')
)
// 使用env-paths后不应该有platform-folders相关警告
expect(hasPlatformFoldersWarning).toBe(false)
console.log('✅ Windows + NPX环境下env-paths工作正常无platform-folders警告')
} finally {
console.warn = originalWarn
restoreEnv()
restoreNpx()
}
})
})
describe('替代方案验证测试', () => {
test('应该验证env-paths作为替代方案可以正常工作', async () => {
// 创建一个模拟的env-paths实现
const mockEnvPaths = (name) => ({
data: path.join(os.homedir(), '.local', 'share', name),
config: path.join(os.homedir(), '.config', name),
cache: path.join(os.homedir(), '.cache', name),
log: path.join(os.homedir(), '.local', 'share', name, 'logs'),
temp: path.join(os.tmpdir(), name)
})
// 验证env-paths风格的路径解析
const paths = mockEnvPaths('promptx')
expect(paths.data).toBeDefined()
expect(paths.config).toBeDefined()
expect(paths.cache).toBeDefined()
expect(typeof paths.data).toBe('string')
expect(paths.data).toContain('promptx')
})
test('应该测试跨平台路径解析的一致性', () => {
// 测试不同平台下的路径格式
const testPlatforms = ['win32', 'darwin', 'linux']
testPlatforms.forEach(platform => {
const originalPlatform = process.platform
Object.defineProperty(process, 'platform', {
value: platform,
configurable: true
})
try {
// 测试路径解析逻辑
const homedir = os.homedir()
const configPath = path.join(homedir, '.config', 'promptx')
expect(configPath).toBeDefined()
expect(path.isAbsolute(configPath)).toBe(true)
// 验证路径包含正确的组件
expect(configPath).toContain('promptx')
} finally {
Object.defineProperty(process, 'platform', {
value: originalPlatform,
configurable: true
})
}
})
})
})
describe('实际CLI命令测试', () => {
test('在模拟的问题环境下CLI应该仍能正常工作', async () => {
const restoreEnv = mockWindowsEnvironment()
try {
// 运行CLI命令验证即使在问题环境下也能工作
const result = execSync('node src/bin/promptx.js hello', {
cwd: process.cwd(),
encoding: 'utf8',
timeout: 10000,
env: process.env
})
// 验证命令执行成功
expect(result).toContain('AI专业角色服务清单')
} catch (error) {
// 如果命令失败检查是否是由于platform-folders问题
const isplatformFoldersError = error.message.includes('platform-folders') ||
error.stderr?.includes('platform-folders')
if (isplatformFoldersError) {
console.log('✅ 成功重现了 platform-folders 问题')
expect(isplatformFoldersError).toBe(true)
} else {
throw error
}
} finally {
restoreEnv()
}
})
})
describe('错误处理和恢复测试', () => {
test('应该测试graceful fallback机制', async () => {
const restoreRequire = mockPlatformFoldersFailure()
try {
// 重新导入模块以测试fallback
const userProtocolPath = path.resolve(__dirname, '../../lib/core/resource/protocols/UserProtocol.js')
delete require.cache[userProtocolPath]
const UserProtocol = require('../../lib/core/resource/protocols/UserProtocol')
const userProtocol = new UserProtocol()
// 测试fallback路径生成
const fallbackPath = await userProtocol.getUserDirectory('home')
expect(fallbackPath).toBeDefined()
expect(typeof fallbackPath).toBe('string')
// 验证fallback路径是合理的home目录应该存在
expect(fallbackPath).toBeTruthy()
} finally {
restoreRequire()
}
})
})
})