eigent/test/unit/electron/main/processUtilsDemo.test.ts
Tong Chen af93bb3065
feat: Add Lint & Format (#878)
Co-authored-by: a7m-1st <Ahmed.jimi.awelkeir500@gmail.com>
Co-authored-by: eigent-ai <camel@eigent.ai>
Co-authored-by: Wendong-Fan <133094783+Wendong-Fan@users.noreply.github.com>
Co-authored-by: Wendong-Fan <w3ndong.fan@gmail.com>
2026-02-01 23:16:18 +08:00

218 lines
8.1 KiB
TypeScript

// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
/**
* Simple demonstration test for the new process utilities mocking
* This shows how to test the functions from process.ts with our enhanced mocks
*/
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import {
createElectronAppMock,
createFileSystemMock,
createLogMock,
createOsMock,
createPathMock,
createProcessMock,
createProcessUtilsMock,
setupMockEnvironment,
} from '../../../mocks/environmentMocks';
// Set up vi.mock calls at the top level to avoid hoisting issues
vi.mock('fs', () => createFileSystemMock());
vi.mock('child_process', () => createProcessMock());
vi.mock('os', () => ({ default: createOsMock() }));
vi.mock('path', () => ({ default: createPathMock() }));
vi.mock('electron', () => ({
app: createElectronAppMock(),
BrowserWindow: vi.fn(),
}));
vi.mock('electron-log', () => ({ default: createLogMock() }));
vi.mock('../../../../electron/main/utils/process', () =>
createProcessUtilsMock()
);
describe('Process Utils Mocking Demo', () => {
let mockEnv: ReturnType<typeof setupMockEnvironment>;
beforeEach(() => {
mockEnv = setupMockEnvironment();
});
afterEach(() => {
mockEnv.reset();
});
describe('Binary Path Functions', () => {
it('should return correct binary paths based on platform', async () => {
// Test Windows binary naming
mockEnv.mockState.system.platform = 'win32';
const uvBinaryName = await mockEnv.processUtilsMock.getBinaryName('uv');
expect(uvBinaryName).toBe('uv.exe');
const uvBinaryPath = await mockEnv.processUtilsMock.getBinaryPath('uv');
expect(uvBinaryPath).toContain('.eigent/bin');
expect(uvBinaryPath).toContain('uv.exe');
});
it('should return correct binary paths for macOS', async () => {
mockEnv.scenarios.macOSEnvironment();
const uvBinaryName = await mockEnv.processUtilsMock.getBinaryName('uv');
expect(uvBinaryName).toBe('uv');
const uvBinaryPath = await mockEnv.processUtilsMock.getBinaryPath('uv');
expect(uvBinaryPath).toContain('.eigent/bin');
expect(uvBinaryPath).toContain('/uv');
expect(uvBinaryPath).not.toContain('.exe');
});
});
describe('Directory Path Functions', () => {
it('should return correct backend path for development mode', () => {
mockEnv.mockState.app.isPackaged = false;
const backendPath = mockEnv.processUtilsMock.getBackendPath();
expect(backendPath).toContain('/backend');
expect(backendPath).not.toContain('resources');
});
it('should return correct backend path for packaged app', () => {
mockEnv.scenarios.packagedApp();
const backendPath = mockEnv.processUtilsMock.getBackendPath();
expect(backendPath).toContain('backend');
// In packaged mode, it should use resources path
expect(mockEnv.mockState.app.isPackaged).toBe(true);
});
it('should return correct cache paths', () => {
const cachePath = mockEnv.processUtilsMock.getCachePath('models');
expect(cachePath).toContain('.eigent/cache/models');
});
it('should return correct venv paths', () => {
const venvPath = mockEnv.processUtilsMock.getVenvPath('1.0.0');
expect(venvPath).toContain('.eigent/venvs/backend-1.0.0');
});
});
describe('Binary Existence Checking', () => {
it('should correctly check binary existence', async () => {
// Set up scenario where uv exists but bun doesn't
mockEnv.mockState.filesystem.binariesExist = { uv: true, bun: false };
const uvExists = await mockEnv.processUtilsMock.isBinaryExists('uv');
const bunExists = await mockEnv.processUtilsMock.isBinaryExists('bun');
expect(uvExists).toBe(true);
expect(bunExists).toBe(false);
});
});
describe('Old Venv Cleanup', () => {
it('should cleanup old venvs correctly', async () => {
// Set up scenario with multiple old venvs
mockEnv.scenarios.multipleOldVenvs('1.0.0');
const initialOldVenvs = [...mockEnv.mockState.filesystem.oldVenvsExist];
expect(initialOldVenvs).toContain('backend-0.9.0');
expect(initialOldVenvs).toContain('backend-0.9.5');
expect(initialOldVenvs).toContain('backend-1.0.1-beta');
// Run cleanup
await mockEnv.processUtilsMock.cleanupOldVenvs('1.0.0');
// Should keep current version but remove others
const remainingVenvs = mockEnv.mockState.filesystem.oldVenvsExist;
console.log(remainingVenvs);
expect(remainingVenvs).toContain('backend-1.0.0');
expect(remainingVenvs).not.toContain('backend-0.9.0');
expect(remainingVenvs).not.toContain('backend-0.9.5');
expect(remainingVenvs).not.toContain('backend-1.0.1-beta');
});
});
describe('Installation Decision Matrix', () => {
it('should correctly determine when installation is needed', () => {
// Test the decision logic that createWindow uses
const checkInstallationNeeded = (mockState: any) => {
const currentVersion = mockState.app.currentVersion;
const versionExists = mockState.filesystem.versionFileExists;
const savedVersion = versionExists
? mockState.filesystem.versionFileContent
: '';
const uvExists = mockState.filesystem.binariesExist['uv'] || false;
const bunExists = mockState.filesystem.binariesExist['bun'] || false;
const installationCompleted = mockState.filesystem.installedLockExists;
return (
!versionExists ||
savedVersion !== currentVersion ||
!uvExists ||
!bunExists ||
!installationCompleted
);
};
// Test fresh install scenario
mockEnv.scenarios.freshInstall();
expect(checkInstallationNeeded(mockEnv.mockState)).toBe(true);
// Test version update scenario
mockEnv.scenarios.versionUpdate('0.9.0', '1.0.0');
expect(checkInstallationNeeded(mockEnv.mockState)).toBe(true);
// Test all good scenario
mockEnv.mockState.filesystem.versionFileExists = true;
mockEnv.mockState.filesystem.versionFileContent = '1.0.0';
mockEnv.mockState.app.currentVersion = '1.0.0';
mockEnv.mockState.filesystem.binariesExist = { uv: true, bun: true };
mockEnv.mockState.filesystem.installedLockExists = true;
expect(checkInstallationNeeded(mockEnv.mockState)).toBe(false);
});
});
describe('File System Operations', () => {
it('should handle directory creation correctly', () => {
// Test .eigent directory creation
mockEnv.scenarios.missingEigentDirectories();
expect(mockEnv.mockState.filesystem.eigentDirExists).toBe(false);
expect(mockEnv.mockState.filesystem.eigentBinDirExists).toBe(false);
// Simulate directory creation
mockEnv.fsMock.mkdirSync('/mock/home/.eigent', { recursive: true });
mockEnv.fsMock.mkdirSync('/mock/home/.eigent/bin', { recursive: true });
expect(mockEnv.mockState.filesystem.eigentDirExists).toBe(true);
expect(mockEnv.mockState.filesystem.eigentBinDirExists).toBe(true);
});
it('should handle file operations correctly', () => {
// Test version file operations
expect(mockEnv.mockState.filesystem.versionFileExists).toBe(true);
// Write new version
mockEnv.fsMock.writeFileSync('/path/to/version.txt', '2.0.0');
expect(mockEnv.mockState.filesystem.versionFileContent).toBe('2.0.0');
// Delete version file
mockEnv.fsMock.unlinkSync('/path/to/version.txt');
expect(mockEnv.mockState.filesystem.versionFileExists).toBe(false);
});
});
});