Skip to content

fix(tests): resolve Windows test failures and upgrade prek#13619

Merged
kangfenmao merged 5 commits intomainfrom
fix/windows-test-failures
Mar 19, 2026
Merged

fix(tests): resolve Windows test failures and upgrade prek#13619
kangfenmao merged 5 commits intomainfrom
fix/windows-test-failures

Conversation

@GeorgeDong32
Copy link
Collaborator

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 commit and regular git commit to fail on Windows, while working fine on macOS and Linux.

Changes

Dependencies

  • @j178/prek: v0.2.28 → v0.3.4

This upgrade fixes the Windows command lookup bug (#1383) that caused pre-commit hooks to fail.

Test Fixes

  • 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)
  • Use path.normalize() for cross-platform path comparison in BaseService test

Test Plan

  • pnpm test:main - 33 test files passed, 575 tests passed
  • pnpm lint - passed
  • Pre-commit hook working on Windows

Refs

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.
Copy link
Collaborator Author

@GeorgeDong32 GeorgeDong32 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  1. Short-term: Current skip logic can be retained (tests will still be skipped on Windows CI)
  2. Medium-term: Refactor tests using Solution 1 or Solution 3 to enable running on all platforms
  3. 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 专用测试

🎯 建议行动

  1. 短期:当前 skip 逻辑可以保留(测试在 Windows CI 上仍会 skip)
  2. 中期:采用方案一或方案三重构测试,使所有平台都能运行
  3. 长期:建立 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.
@kangfenmao kangfenmao merged commit 24645d3 into main Mar 19, 2026
7 checks passed
@kangfenmao kangfenmao deleted the fix/windows-test-failures branch March 19, 2026 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants