fix: Windows test compatibility — resolve paths and normalize mock keys

This commit is contained in:
iliya 2026-03-01 09:32:07 +02:00
parent d8655df838
commit bfb4be1ef8
3 changed files with 16 additions and 10 deletions

View file

@ -505,7 +505,7 @@ export class ProjectFileService {
const newPath = path.join(normalizedDest, path.basename(normalizedSrc)); const newPath = path.join(normalizedDest, path.basename(normalizedSrc));
// 8. Prevent parent → child move (moving dir into itself) // 8. Prevent parent → child move (moving dir into itself)
if (normalizedDest.startsWith(normalizedSrc + '/') || normalizedDest === normalizedSrc) { if (normalizedDest.startsWith(normalizedSrc + path.sep) || normalizedDest === normalizedSrc) {
throw new Error('Cannot move a directory into itself'); throw new Error('Cannot move a directory into itself');
} }

View file

@ -29,7 +29,7 @@ import { isBinaryFile } from 'isbinaryfile';
import { FileSearchService } from '@main/services/editor/FileSearchService'; import { FileSearchService } from '@main/services/editor/FileSearchService';
const PROJECT_ROOT = '/test/project'; const PROJECT_ROOT = path.resolve('/test/project');
describe('FileSearchService', () => { describe('FileSearchService', () => {
let service: FileSearchService; let service: FileSearchService;
@ -40,6 +40,12 @@ describe('FileSearchService', () => {
}); });
function mockFileSystem(files: Record<string, string>) { function mockFileSystem(files: Record<string, string>) {
// Normalize keys so lookups work on Windows (backslash vs forward slash)
const normalizedFiles: Record<string, string> = {};
for (const [key, value] of Object.entries(files)) {
normalizedFiles[path.normalize(key)] = value;
}
const entries = Object.keys(files).map((filePath) => { const entries = Object.keys(files).map((filePath) => {
const name = path.basename(filePath); const name = path.basename(filePath);
return { name, isFile: () => true, isDirectory: () => false }; return { name, isFile: () => true, isDirectory: () => false };
@ -49,15 +55,15 @@ describe('FileSearchService', () => {
vi.mocked(isBinaryFile).mockResolvedValue(false); vi.mocked(isBinaryFile).mockResolvedValue(false);
vi.mocked(fs.stat).mockImplementation(async (filePath: unknown) => { vi.mocked(fs.stat).mockImplementation(async (filePath: unknown) => {
const p = String(filePath); const p = path.normalize(String(filePath));
const content = files[p]; const content = normalizedFiles[p];
if (content === undefined) throw new Error('ENOENT'); if (content === undefined) throw new Error('ENOENT');
return { size: content.length } as never; return { size: content.length } as never;
}); });
vi.mocked(fs.readFile).mockImplementation(async (filePath: unknown) => { vi.mocked(fs.readFile).mockImplementation(async (filePath: unknown) => {
const p = String(filePath); const p = path.normalize(String(filePath));
const content = files[p]; const content = normalizedFiles[p];
if (content === undefined) throw new Error('ENOENT'); if (content === undefined) throw new Error('ENOENT');
return content as never; return content as never;
}); });

View file

@ -55,7 +55,7 @@ import { ProjectFileService } from '../../../../src/main/services/editor/Project
// Setup // Setup
// ============================================================================= // =============================================================================
const PROJECT_ROOT = '/Users/test/my-project'; const PROJECT_ROOT = path.resolve('/Users/test/my-project');
let service: ProjectFileService; let service: ProjectFileService;
const mockLstat = vi.mocked(fs.lstat); const mockLstat = vi.mocked(fs.lstat);
@ -219,7 +219,7 @@ describe('ProjectFileService.readDir', () => {
mockRealpath.mockImplementation(async (p) => { mockRealpath.mockImplementation(async (p) => {
const name = path.basename(String(p)); const name = path.basename(String(p));
if (name === 'safe-link') return PROJECT_ROOT + '/actual-dir'; if (name === 'safe-link') return path.join(PROJECT_ROOT, 'actual-dir');
return '/etc/shadow'; // escapes project return '/etc/shadow'; // escapes project
}); });
@ -559,8 +559,8 @@ describe('ProjectFileService.deleteFile', () => {
// ============================================================================= // =============================================================================
describe('ProjectFileService.moveFile', () => { describe('ProjectFileService.moveFile', () => {
const SRC_DIR = PROJECT_ROOT + '/src'; const SRC_DIR = path.join(PROJECT_ROOT, 'src');
const DEST_DIR = PROJECT_ROOT + '/lib'; const DEST_DIR = path.join(PROJECT_ROOT, 'lib');
beforeEach(() => { beforeEach(() => {
mockRename.mockResolvedValue(undefined); mockRename.mockResolvedValue(undefined);