// @vitest-environment node import { afterEach, describe, expect, it } from 'vitest'; import fs from 'fs-extra'; import afterPackModule from '../scripts/after-pack.cjs'; const afterPackTestApi = afterPackModule.__test__ as { resolveBundledRuntimeTarget(context: { electronPlatformName: string; arch: string | number }): string; copyBundledRuntimeBinaries( context: { electronPlatformName: string; arch: string | number; appOutDir: string }, overrides?: { sourceRoot?: string; resourcesDir?: string; destRoot?: string; requiredFiles?: string[]; } ): Promise; }; const tempDirs: string[] = []; function joinPath(...parts: string[]): string { return parts .filter(Boolean) .join('/') .replace(/\/+/g, '/'); } async function createTempDir(prefix: string): Promise { const dir = joinPath( process.cwd().replace(/\\/g, '/'), '.tmp-vitest', `${prefix}${Date.now()}-${Math.random().toString(36).slice(2, 10)}`, ); await fs.ensureDir(dir); tempDirs.push(dir); return dir; } describe('after-pack bundled runtime binaries', () => { afterEach(async () => { await Promise.all(tempDirs.splice(0).map((dir) => fs.remove(dir))); }); it('resolves electron-builder platform and arch to the runtime binary target', () => { expect(afterPackTestApi.resolveBundledRuntimeTarget({ electronPlatformName: 'win', arch: 1, })).toBe('win32-x64'); expect(afterPackTestApi.resolveBundledRuntimeTarget({ electronPlatformName: 'mac', arch: 'arm64', })).toBe('darwin-arm64'); }); it('copies required runtime binaries into the packaged resources/bin directory', async () => { const sourceRoot = await createTempDir('after-pack-source-'); const resourcesDir = await createTempDir('after-pack-resources-'); await fs.writeFile(joinPath(sourceRoot, 'uv.exe'), 'uv-binary', 'utf8'); await fs.writeFile(joinPath(sourceRoot, 'node.exe'), 'node-binary', 'utf8'); await afterPackTestApi.copyBundledRuntimeBinaries( { electronPlatformName: 'win', arch: 'x64', appOutDir: resourcesDir, }, { sourceRoot, resourcesDir, requiredFiles: ['uv.exe', 'node.exe'], }, ); expect(await fs.readFile(joinPath(resourcesDir, 'bin', 'uv.exe'), 'utf8')).toBe('uv-binary'); expect(await fs.readFile(joinPath(resourcesDir, 'bin', 'node.exe'), 'utf8')).toBe('node-binary'); }); it('fails packaging when required runtime binaries are still missing', async () => { const sourceRoot = await createTempDir('after-pack-missing-source-'); const resourcesDir = await createTempDir('after-pack-missing-resources-'); await fs.writeFile(joinPath(sourceRoot, 'node.exe'), 'node-binary', 'utf8'); await expect(afterPackTestApi.copyBundledRuntimeBinaries( { electronPlatformName: 'win', arch: 'x64', appOutDir: resourcesDir, }, { sourceRoot, resourcesDir, requiredFiles: ['uv.exe', 'node.exe'], }, )).rejects.toThrow('Missing required bundled runtime binaries'); }); });