fix(tests): resolve Windows test failures and upgrade prek#13619
fix(tests): resolve Windows test failures and upgrade prek#13619kangfenmao merged 5 commits intomainfrom
Conversation
Fix cross-platform test compatibility issues: - Use path.join() for platform-independent path construction in DxtService tests - Skip path-matching tests on Windows due to path format differences - Adjust configManager.set call count expectations based on platform - Fix execFileSync mock expectation to use expect.any(Object) Affected test files: - src/main/services/__tests__/DxtService.test.ts - src/main/services/__tests__/BackupManager.deleteTempBackup.test.ts - src/main/utils/__tests__/process.test.ts
Fix Windows command lookup bug and improve cross-platform compatibility. Changes: - Upgrade @j178/prek from v0.2.28 to v0.3.4 - This fixes Windows-specific pre-commit hook issues Refs: j178/prek#1383
Fix BaseService test that failed on Windows due to path.normalize converting forward slashes to backslashes on Windows. The test now uses path.normalize() in the expected value to ensure cross-platform compatibility.
There was a problem hiding this comment.
Note
This review was translated by Claude.
Code Review: Skipped Tests in BackupManager.test.ts
🔍 Problem Analysis
There is a logic error in the current test file that prevents tests from being skipped correctly on Windows:
// Problematic code (lines 103-104, 243-244)
describe('Normal Operations', () => {
const itFn = process.platform === 'win32' ? it.skip : it // ❌ Evaluated at definition time
itFn('should delete valid file in allowed directory', async () => { ... })
})Root Cause: itFn is evaluated during the test definition phase, while the process.platform mock in beforeEach only takes effect during the test execution phase. Therefore, itFn always makes judgments based on the actual platform, causing tests to be incorrectly skipped on Windows.
💡 Suggested Solutions
Solution 1: Mock the path Module (Recommended)
Force all tests to use POSIX path format to completely eliminate platform differences:
vi.mock('path', () => ({
...jest.requireActual('path'),
posix: jest.requireActual('path').posix,
// Force use of POSIX methods
join: (...args) => args.join('/'),
normalize: (p) => p.replace(/\\/+/g, '/'),
resolve: (...args) => args.join('/'),
sep: '/'
}))Solution 2: Use describe.skipIf + Platform-Agnostic Assertions
Refer to the correct usage in src/main/utils/__tests__/process.test.ts:
describe.skipIf(process.platform === 'win32')('POSIX-only path tests', () => {
it('should handle path correctly', () => {
// Use path.join() to construct cross-platform paths
const testPath = path.join('/tmp', 'cherry-studio', 'lan-transfer', 'file.zip')
expect(result).toBe(true)
})
})Solution 3: Platform-Agnostic Test Assertions
it('should delete valid file in allowed directory', async () => {
// Use path.join to construct test path
const validPath = path.join(app.getPath('temp'), 'cherry-studio', 'lan-transfer', 'backup.zip')
vi.mocked(fs.pathExists).mockResolvedValue(true as never)
vi.mocked(fs.remove).mockResolvedValue(undefined as never)
const result = await backupManager.deleteLanTransferBackup({} as any, validPath)
expect(result).toBe(true)
})📋 Other Findings
| File | Status | Notes |
|---|---|---|
DxtService.test.ts |
✅ Correctly uses path.join() |
No skipped tests |
BaseService.test.ts |
✅ Correctly uses path.normalize() |
Cross-platform compatible |
process.test.ts |
✅ Correctly uses describe.skipIf |
Windows-specific tests |
🎯 Suggested Actions
- Short-term: Current skip logic can be retained (tests will still be skipped on Windows CI)
- Medium-term: Refactor tests using Solution 1 or Solution 3 to enable running on all platforms
- Long-term: Establish CI platform matrix to ensure test coverage for macOS/Linux/Windows
Overall Assessment: Comprehensive safety test coverage, only need to improve cross-platform testing strategy.
Original Content
Code Review: Skipped Tests in BackupManager.test.ts
🔍 问题分析
当前测试文件中存在一个逻辑错误,导致 Windows 上的测试被 skip 后无法正确执行:
// 问题代码 (lines 103-104, 243-244)
describe('Normal Operations', () => {
const itFn = process.platform === 'win32' ? it.skip : it // ❌ 在定义时求值
itFn('should delete valid file in allowed directory', async () => { ... })
})根本原因:itFn 在测试定义阶段就被求值,而 beforeEach 中的 process.platform mock 只在测试执行阶段生效。因此 itFn 始终基于真实平台做判断,导致 Windows 上测试被错误地 skip。
💡 建议方案
方案一:Mock path 模块(推荐)
强制所有测试使用 POSIX 路径格式,彻底消除平台差异:
vi.mock('path', () => ({
...jest.requireActual('path'),
posix: jest.requireActual('path').posix,
// 强制使用 POSIX 方法
join: (...args) => args.join('/'),
normalize: (p) => p.replace(/\\/+/g, '/'),
resolve: (...args) => args.join('/'),
sep: '/'
}))方案二:使用 describe.skipIf + 平台无关断言
参考 src/main/utils/__tests__/process.test.ts 的正确用法:
describe.skipIf(process.platform === 'win32')('POSIX-only path tests', () => {
it('should handle path correctly', () => {
// 使用 path.join() 构造跨平台路径
const testPath = path.join('/tmp', 'cherry-studio', 'lan-transfer', 'file.zip')
expect(result).toBe(true)
})
})方案三:平台无关的测试断言
it('should delete valid file in allowed directory', async () => {
// 使用 path.join 构造测试路径
const validPath = path.join(app.getPath('temp'), 'cherry-studio', 'lan-transfer', 'backup.zip')
vi.mocked(fs.pathExists).mockResolvedValue(true as never)
vi.mocked(fs.remove).mockResolvedValue(undefined as never)
const result = await backupManager.deleteLanTransferBackup({} as any, validPath)
expect(result).toBe(true)
})📋 其他发现
| 文件 | 状态 | 备注 |
|---|---|---|
DxtService.test.ts |
✅ 正确使用 path.join() |
无 skipped tests |
BaseService.test.ts |
✅ 正确使用 path.normalize() |
跨平台兼容 |
process.test.ts |
✅ 正确使用 describe.skipIf |
Windows 专用测试 |
🎯 建议行动
- 短期:当前 skip 逻辑可以保留(测试在 Windows CI 上仍会 skip)
- 中期:采用方案一或方案三重构测试,使所有平台都能运行
- 长期:建立 CI 平台矩阵,确保 macOS/Linux/Windows 都有测试覆盖
总体评价:安全测试覆盖全面,仅需改进跨平台测试策略。
Mock path module in BackupManager tests to force POSIX path behavior across all platforms. This eliminates the need to skip tests on Windows. Changes: - Replace process.platform mocking with comprehensive path module mock - Force all path operations to use forward slashes (POSIX style) - Handle path.resolve specially to avoid Windows drive letter prefix - Remove all it.skip for path-matching tests This approach (suggested in code review) ensures tests run on all platforms without skipping any functionality.
Fix lint error: import() type annotations are forbidden. Use type-only import syntax instead.
Summary
Fix Windows test failures and upgrade prek dependency to resolve git hook issues on Windows.
Problem
On Windows, the pre-commit hook was failing due to a bug in prek v0.2.28 where command lookup didn't work correctly with Windows paths. This caused
but commitand regulargit committo fail on Windows, while working fine on macOS and Linux.Changes
Dependencies
@j178/prek: v0.2.28 → v0.3.4This upgrade fixes the Windows command lookup bug (#1383) that caused pre-commit hooks to fail.
Test Fixes
path.join()for platform-independent path construction in DxtService testsconfigManager.setcall count expectations based on platformexecFileSyncmock expectation to useexpect.any(Object)path.normalize()for cross-platform path comparison in BaseService testTest Plan
pnpm test:main- 33 test files passed, 575 tests passedpnpm lint- passedRefs