Makelore 2.0 initial clean snapshot
This commit is contained in:
113
tests/unit/python-runtime.test.ts
Normal file
113
tests/unit/python-runtime.test.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { delimiter, dirname, join } from 'node:path';
|
||||
import { afterEach, describe, expect, it } from 'vitest';
|
||||
import { prependPythonToPath, resolvePythonRuntime } from '@electron/utils/python-runtime';
|
||||
|
||||
const temporaryDirectories: string[] = [];
|
||||
|
||||
async function createFile(path: string): Promise<string> {
|
||||
await mkdir(dirname(path), { recursive: true });
|
||||
await writeFile(path, 'python');
|
||||
return path;
|
||||
}
|
||||
|
||||
async function temporaryDirectory(prefix: string): Promise<string> {
|
||||
const directory = await mkdtemp(join(tmpdir(), prefix));
|
||||
temporaryDirectories.push(directory);
|
||||
return directory;
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(temporaryDirectories.splice(0).map((directory) => rm(directory, { recursive: true, force: true })));
|
||||
});
|
||||
|
||||
describe('managed Python runtime resolution', () => {
|
||||
it('prefers an explicit existing interpreter in development', async () => {
|
||||
const root = await temporaryDirectory('niancode-python-configured-');
|
||||
const configuredPath = await createFile(join(root, 'custom', 'python.exe'));
|
||||
|
||||
expect(resolvePythonRuntime({
|
||||
isPackaged: false,
|
||||
resourcesPath: root,
|
||||
appPath: root,
|
||||
platform: 'win32',
|
||||
arch: 'x64',
|
||||
configuredPath,
|
||||
})).toEqual({
|
||||
binDir: dirname(configuredPath),
|
||||
executable: configuredPath,
|
||||
source: 'configured',
|
||||
});
|
||||
});
|
||||
|
||||
it('resolves the packaged Windows interpreter', async () => {
|
||||
const resourcesPath = await temporaryDirectory('niancode-python-packaged-win-');
|
||||
const executable = await createFile(join(resourcesPath, 'python', 'python.exe'));
|
||||
|
||||
expect(resolvePythonRuntime({
|
||||
isPackaged: true,
|
||||
resourcesPath,
|
||||
appPath: resourcesPath,
|
||||
platform: 'win32',
|
||||
arch: 'x64',
|
||||
})).toEqual({ executable, binDir: dirname(executable), source: 'bundled' });
|
||||
});
|
||||
|
||||
it('resolves the packaged Unix interpreter', async () => {
|
||||
const resourcesPath = await temporaryDirectory('niancode-python-packaged-unix-');
|
||||
const executable = await createFile(join(resourcesPath, 'python', 'bin', 'python3'));
|
||||
|
||||
expect(resolvePythonRuntime({
|
||||
isPackaged: true,
|
||||
resourcesPath,
|
||||
appPath: resourcesPath,
|
||||
platform: 'darwin',
|
||||
arch: 'arm64',
|
||||
})).toEqual({ executable, binDir: dirname(executable), source: 'bundled' });
|
||||
});
|
||||
|
||||
it('fails closed when a packaged runtime is missing', async () => {
|
||||
const resourcesPath = await temporaryDirectory('niancode-python-packaged-missing-');
|
||||
|
||||
expect(() => resolvePythonRuntime({
|
||||
isPackaged: true,
|
||||
resourcesPath,
|
||||
appPath: resourcesPath,
|
||||
platform: 'linux',
|
||||
arch: 'x64',
|
||||
})).toThrow(`Bundled Python runtime is missing: ${join(resourcesPath, 'python', 'bin', 'python3')}`);
|
||||
});
|
||||
|
||||
it('falls back to a system command only in development', async () => {
|
||||
const root = await temporaryDirectory('niancode-python-development-');
|
||||
|
||||
expect(resolvePythonRuntime({
|
||||
isPackaged: false,
|
||||
resourcesPath: root,
|
||||
appPath: root,
|
||||
platform: 'linux',
|
||||
arch: 'x64',
|
||||
})).toEqual({ executable: 'python3', binDir: '', source: 'system' });
|
||||
});
|
||||
|
||||
it('prepends the managed bin directory without mutating the input environment', () => {
|
||||
const environment = { PATH: 'existing-bin', KEEP: 'yes' };
|
||||
const runtime = { executable: 'C:\\NianCode\\python\\python.exe', binDir: 'C:\\NianCode\\python', source: 'bundled' as const };
|
||||
|
||||
expect(prependPythonToPath(environment, runtime)).toEqual({
|
||||
PATH: `${runtime.binDir}${delimiter}existing-bin`,
|
||||
KEEP: 'yes',
|
||||
NIANCODE_PYTHON_PATH: runtime.executable,
|
||||
});
|
||||
expect(environment).toEqual({ PATH: 'existing-bin', KEEP: 'yes' });
|
||||
});
|
||||
|
||||
it('preserves the Windows Path key casing', () => {
|
||||
const runtime = { executable: 'C:\\NianCode\\python\\python.exe', binDir: 'C:\\NianCode\\python', source: 'bundled' as const };
|
||||
const result = prependPythonToPath({ Path: 'existing-bin' }, runtime, 'win32');
|
||||
|
||||
expect(result.Path).toBe(`${runtime.binDir}${delimiter}existing-bin`);
|
||||
expect(result).not.toHaveProperty('PATH');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user