This commit is contained in:
180
app/scripts/bundle-runtimes.test.ts
Normal file
180
app/scripts/bundle-runtimes.test.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import path from 'node:path';
|
||||
import {
|
||||
getNodeDownloadUrl,
|
||||
getPythonDownloadUrl,
|
||||
getResourcePaths,
|
||||
getBundleStatus,
|
||||
parseVersion,
|
||||
isValidVersion,
|
||||
} from './bundle-utils.js';
|
||||
|
||||
// ─── getNodeDownloadUrl ──────────────────────────────────────────────────────
|
||||
|
||||
describe('getNodeDownloadUrl', () => {
|
||||
it('returns Windows x64 URL by default', () => {
|
||||
const url = getNodeDownloadUrl('20.11.1');
|
||||
expect(url).toBe('https://nodejs.org/dist/v20.11.1/win-x64/node.exe');
|
||||
});
|
||||
|
||||
it('returns Windows arm64 URL', () => {
|
||||
const url = getNodeDownloadUrl('20.11.1', 'win32', 'arm64');
|
||||
expect(url).toBe('https://nodejs.org/dist/v20.11.1/win-arm64/node.exe');
|
||||
});
|
||||
|
||||
it('returns macOS tar.gz URL', () => {
|
||||
const url = getNodeDownloadUrl('20.11.1', 'darwin', 'x64');
|
||||
expect(url).toContain('darwin-x64.tar.gz');
|
||||
});
|
||||
|
||||
it('returns Linux tar.xz URL', () => {
|
||||
const url = getNodeDownloadUrl('20.11.1', 'linux', 'x64');
|
||||
expect(url).toContain('linux-x64.tar.xz');
|
||||
});
|
||||
|
||||
it('includes the version in the URL', () => {
|
||||
const url = getNodeDownloadUrl('18.19.0');
|
||||
expect(url).toContain('v18.19.0');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── getPythonDownloadUrl ────────────────────────────────────────────────────
|
||||
|
||||
describe('getPythonDownloadUrl', () => {
|
||||
it('returns Windows amd64 embed URL by default', () => {
|
||||
const url = getPythonDownloadUrl('3.11.8');
|
||||
expect(url).toBe(
|
||||
'https://www.python.org/ftp/python/3.11.8/python-3.11.8-embed-amd64.zip',
|
||||
);
|
||||
});
|
||||
|
||||
it('returns Windows arm64 URL', () => {
|
||||
const url = getPythonDownloadUrl('3.11.8', 'win32', 'arm64');
|
||||
expect(url).toContain('embed-arm64.zip');
|
||||
});
|
||||
|
||||
it('returns macOS pkg URL', () => {
|
||||
const url = getPythonDownloadUrl('3.11.8', 'darwin', 'x64');
|
||||
expect(url).toContain('macos11.pkg');
|
||||
});
|
||||
|
||||
it('returns Linux source URL', () => {
|
||||
const url = getPythonDownloadUrl('3.11.8', 'linux', 'x64');
|
||||
expect(url).toContain('Python-3.11.8.tar.xz');
|
||||
});
|
||||
|
||||
it('includes the version in the URL', () => {
|
||||
const url = getPythonDownloadUrl('3.12.1');
|
||||
expect(url).toContain('3.12.1');
|
||||
});
|
||||
});
|
||||
|
||||
// ─── getResourcePaths ────────────────────────────────────────────────────────
|
||||
|
||||
describe('getResourcePaths', () => {
|
||||
it('returns correct Windows paths when platform is win32', () => {
|
||||
const dir = '/app/src-tauri/resources';
|
||||
const paths = getResourcePaths(dir, 'win32');
|
||||
|
||||
expect(paths.node).toBe(path.join(dir, 'node', 'node.exe'));
|
||||
expect(paths.python).toBe(path.join(dir, 'python', 'python.exe'));
|
||||
expect(paths.litellm).toBe(
|
||||
path.join(dir, 'python', 'Lib', 'site-packages', 'litellm'),
|
||||
);
|
||||
});
|
||||
|
||||
it('handles Windows-style paths', () => {
|
||||
const dir = 'C:\\Users\\user\\app\\resources';
|
||||
const paths = getResourcePaths(dir, 'win32');
|
||||
|
||||
expect(paths.node).toContain('node.exe');
|
||||
expect(paths.python).toContain('python.exe');
|
||||
expect(paths.litellm).toContain('litellm');
|
||||
});
|
||||
|
||||
it('returns correct Unix paths when platform is darwin', () => {
|
||||
const dir = '/app/src-tauri/resources';
|
||||
const paths = getResourcePaths(dir, 'darwin');
|
||||
|
||||
expect(paths.node).toBe(path.join(dir, 'node', 'bin', 'node'));
|
||||
expect(paths.python).toBe(path.join(dir, 'python', 'bin', 'python3'));
|
||||
expect(paths.litellm).toBe(
|
||||
path.join(dir, 'python', 'lib', 'python3.11', 'site-packages', 'litellm'),
|
||||
);
|
||||
});
|
||||
|
||||
it('returns correct Unix paths when platform is linux', () => {
|
||||
const dir = '/app/src-tauri/resources';
|
||||
const paths = getResourcePaths(dir, 'linux');
|
||||
|
||||
expect(paths.node).toBe(path.join(dir, 'node', 'bin', 'node'));
|
||||
expect(paths.python).toBe(path.join(dir, 'python', 'bin', 'python3'));
|
||||
expect(paths.litellm).toBe(
|
||||
path.join(dir, 'python', 'lib', 'python3.11', 'site-packages', 'litellm'),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── getBundleStatus ─────────────────────────────────────────────────────────
|
||||
|
||||
describe('getBundleStatus', () => {
|
||||
it('reports all missing when nothing exists', () => {
|
||||
const mockExists = () => false;
|
||||
const status = getBundleStatus('/fake/dir', mockExists);
|
||||
|
||||
expect(status.nodeReady).toBe(false);
|
||||
expect(status.pythonReady).toBe(false);
|
||||
expect(status.litellmReady).toBe(false);
|
||||
});
|
||||
|
||||
it('reports all ready when all exist', () => {
|
||||
const mockExists = () => true;
|
||||
const status = getBundleStatus('/fake/dir', mockExists);
|
||||
|
||||
expect(status.nodeReady).toBe(true);
|
||||
expect(status.pythonReady).toBe(true);
|
||||
expect(status.litellmReady).toBe(true);
|
||||
});
|
||||
|
||||
it('reports partial status correctly', () => {
|
||||
const paths = getResourcePaths('/fake/dir', process.platform);
|
||||
const existingPaths = new Set([paths.node, paths.python]);
|
||||
const mockExists = (p: string) => existingPaths.has(p);
|
||||
|
||||
const status = getBundleStatus('/fake/dir', mockExists);
|
||||
|
||||
expect(status.nodeReady).toBe(true);
|
||||
expect(status.pythonReady).toBe(true);
|
||||
expect(status.litellmReady).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── parseVersion ────────────────────────────────────────────────────────────
|
||||
|
||||
describe('parseVersion', () => {
|
||||
it('parses a standard semver string', () => {
|
||||
const v = parseVersion('20.11.1');
|
||||
expect(v).toEqual({ major: 20, minor: 11, patch: 1 });
|
||||
});
|
||||
|
||||
it('parses a version with zeros', () => {
|
||||
const v = parseVersion('3.0.0');
|
||||
expect(v).toEqual({ major: 3, minor: 0, patch: 0 });
|
||||
});
|
||||
});
|
||||
|
||||
// ─── isValidVersion ──────────────────────────────────────────────────────────
|
||||
|
||||
describe('isValidVersion', () => {
|
||||
it('accepts a valid version', () => {
|
||||
expect(isValidVersion('20.11.1')).toBe(true);
|
||||
expect(isValidVersion('3.11.8')).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects invalid versions', () => {
|
||||
expect(isValidVersion('20.11')).toBe(false);
|
||||
expect(isValidVersion('abc')).toBe(false);
|
||||
expect(isValidVersion('20.11.1.2')).toBe(false);
|
||||
expect(isValidVersion('')).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user