From d72ac59068f3baabbeeac9e252147fc81e11570a Mon Sep 17 00:00:00 2001 From: Ben Vinegar Date: Sun, 22 Mar 2026 09:45:04 -0400 Subject: [PATCH] Expand prebuilt helper edge coverage --- scripts/prebuilt-package-helpers.ts | 17 +++++++---- test/prebuilt-package-helpers.test.ts | 43 +++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/scripts/prebuilt-package-helpers.ts b/scripts/prebuilt-package-helpers.ts index 330f9cd5..bff1a323 100644 --- a/scripts/prebuilt-package-helpers.ts +++ b/scripts/prebuilt-package-helpers.ts @@ -47,16 +47,16 @@ export function getPlatformPackageSpecByName(packageName: string) { return PLATFORM_PACKAGE_MATRIX.find((candidate) => candidate.packageName === packageName); } -/** Return the Hunk package spec that matches the current machine. */ -export function getHostPlatformPackageSpec() { - const normalizedPlatform = normalizeHostPlatform(os.platform()); +/** Resolve the published package spec for a given Node platform/architecture pair. */ +export function getPlatformPackageSpecForHost(platform: NodeJS.Platform, arch: NodeJS.Architecture) { + const normalizedPlatform = normalizeHostPlatform(platform); if (!normalizedPlatform) { - throw new Error(`Unsupported host platform for prebuilt packaging: ${os.platform()}`); + throw new Error(`Unsupported host platform for prebuilt packaging: ${platform}`); } - const normalizedArch = normalizeHostArch(os.arch()); + const normalizedArch = normalizeHostArch(arch); if (!normalizedArch) { - throw new Error(`Unsupported host architecture for prebuilt packaging: ${os.arch()}`); + throw new Error(`Unsupported host architecture for prebuilt packaging: ${arch}`); } const spec = PLATFORM_PACKAGE_MATRIX.find((candidate) => candidate.os === normalizedPlatform && candidate.cpu === normalizedArch); @@ -67,6 +67,11 @@ export function getHostPlatformPackageSpec() { return spec; } +/** Return the Hunk package spec that matches the current machine. */ +export function getHostPlatformPackageSpec() { + return getPlatformPackageSpecForHost(os.platform(), os.arch()); +} + /** Build the optional dependency map for the top-level hunkdiff package. */ export function buildOptionalDependencyMap(version: string, specs: readonly PlatformPackageSpec[] = PLATFORM_PACKAGE_MATRIX) { return Object.fromEntries(specs.map((spec) => [spec.packageName, version])); diff --git a/test/prebuilt-package-helpers.test.ts b/test/prebuilt-package-helpers.test.ts index e5bb48da..1a75e324 100644 --- a/test/prebuilt-package-helpers.test.ts +++ b/test/prebuilt-package-helpers.test.ts @@ -3,8 +3,13 @@ import { PLATFORM_PACKAGE_MATRIX, binaryFilenameForSpec, buildOptionalDependencyMap, + getHostPlatformPackageSpec, getPlatformPackageSpecByName, + getPlatformPackageSpecForHost, + normalizeHostArch, + normalizeHostPlatform, sortPlatformPackageSpecs, + type PlatformPackageSpec, } from "../scripts/prebuilt-package-helpers"; describe("prebuilt package helpers", () => { @@ -22,12 +27,50 @@ describe("prebuilt package helpers", () => { } }); + test("binaryFilenameForSpec adds .exe for windows packages", () => { + const windowsSpec: PlatformPackageSpec = { + packageName: "hunkdiff-windows-x64", + os: "windows", + cpu: "x64", + binaryName: "hunk", + binaryRelativePath: "bin/hunk.exe", + }; + + expect(binaryFilenameForSpec(windowsSpec)).toBe("hunk.exe"); + }); + + test("normalizeHostPlatform and normalizeHostArch reject unsupported values", () => { + expect(normalizeHostPlatform("linux")).toBe("linux"); + expect(normalizeHostPlatform("win32")).toBe("windows"); + expect(normalizeHostPlatform("freebsd" as NodeJS.Platform)).toBeUndefined(); + + expect(normalizeHostArch("x64")).toBe("x64"); + expect(normalizeHostArch("arm64")).toBe("arm64"); + expect(normalizeHostArch("ia32" as NodeJS.Architecture)).toBeUndefined(); + }); + test("getPlatformPackageSpecByName returns known package specs", () => { expect(getPlatformPackageSpecByName("hunkdiff-linux-x64")?.cpu).toBe("x64"); expect(getPlatformPackageSpecByName("hunkdiff-darwin-arm64")?.os).toBe("darwin"); expect(getPlatformPackageSpecByName("hunkdiff-does-not-exist")).toBeUndefined(); }); + test("getPlatformPackageSpecForHost resolves supported combinations and rejects unsupported ones", () => { + expect(getPlatformPackageSpecForHost("linux", "x64").packageName).toBe("hunkdiff-linux-x64"); + expect(getPlatformPackageSpecForHost("darwin", "arm64").packageName).toBe("hunkdiff-darwin-arm64"); + expect(() => getPlatformPackageSpecForHost("freebsd" as NodeJS.Platform, "x64")).toThrow( + "Unsupported host platform for prebuilt packaging: freebsd", + ); + expect(() => getPlatformPackageSpecForHost("linux", "ia32" as NodeJS.Architecture)).toThrow( + "Unsupported host architecture for prebuilt packaging: ia32", + ); + expect(() => getPlatformPackageSpecForHost("linux", "arm64")).toThrow("No published prebuilt package spec matches linux/arm64"); + }); + + test("getHostPlatformPackageSpec resolves the current machine", () => { + expect(getHostPlatformPackageSpec()).toEqual(getPlatformPackageSpecForHost(process.platform, process.arch)); + }); + test("sortPlatformPackageSpecs keeps package publish order stable", () => { const reversed = [...PLATFORM_PACKAGE_MATRIX].reverse(); expect(sortPlatformPackageSpecs(reversed).map((spec) => spec.packageName)).toEqual([