test: add pickAsset unit tests for architecture-aware signal-cli install
This commit is contained in:
committed by
Peter Steinberger
parent
eb4a0a84f2
commit
771c7ba14e
128
src/commands/signal-install.test.ts
Normal file
128
src/commands/signal-install.test.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { ReleaseAsset } from "./signal-install.js";
|
||||
import { looksLikeArchive, pickAsset } from "./signal-install.js";
|
||||
|
||||
// Realistic asset list modelled after an actual signal-cli GitHub release.
|
||||
const SAMPLE_ASSETS: ReleaseAsset[] = [
|
||||
{
|
||||
name: "signal-cli-0.13.14-Linux-native.tar.gz",
|
||||
browser_download_url: "https://example.com/linux-native.tar.gz",
|
||||
},
|
||||
{
|
||||
name: "signal-cli-0.13.14-Linux-native.tar.gz.asc",
|
||||
browser_download_url: "https://example.com/linux-native.tar.gz.asc",
|
||||
},
|
||||
{
|
||||
name: "signal-cli-0.13.14-macOS-native.tar.gz",
|
||||
browser_download_url: "https://example.com/macos-native.tar.gz",
|
||||
},
|
||||
{
|
||||
name: "signal-cli-0.13.14-macOS-native.tar.gz.asc",
|
||||
browser_download_url: "https://example.com/macos-native.tar.gz.asc",
|
||||
},
|
||||
{
|
||||
name: "signal-cli-0.13.14-Windows-native.zip",
|
||||
browser_download_url: "https://example.com/windows-native.zip",
|
||||
},
|
||||
{
|
||||
name: "signal-cli-0.13.14-Windows-native.zip.asc",
|
||||
browser_download_url: "https://example.com/windows-native.zip.asc",
|
||||
},
|
||||
{ name: "signal-cli-0.13.14.tar.gz", browser_download_url: "https://example.com/jvm.tar.gz" },
|
||||
{
|
||||
name: "signal-cli-0.13.14.tar.gz.asc",
|
||||
browser_download_url: "https://example.com/jvm.tar.gz.asc",
|
||||
},
|
||||
];
|
||||
|
||||
describe("looksLikeArchive", () => {
|
||||
it("recognises .tar.gz", () => {
|
||||
expect(looksLikeArchive("foo.tar.gz")).toBe(true);
|
||||
});
|
||||
|
||||
it("recognises .tgz", () => {
|
||||
expect(looksLikeArchive("foo.tgz")).toBe(true);
|
||||
});
|
||||
|
||||
it("recognises .zip", () => {
|
||||
expect(looksLikeArchive("foo.zip")).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects signature files", () => {
|
||||
expect(looksLikeArchive("foo.tar.gz.asc")).toBe(false);
|
||||
});
|
||||
|
||||
it("rejects unrelated files", () => {
|
||||
expect(looksLikeArchive("README.md")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("pickAsset", () => {
|
||||
describe("linux", () => {
|
||||
it("selects the Linux-native asset on x64", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "linux", "x64");
|
||||
expect(result).toBeDefined();
|
||||
expect(result!.name).toContain("Linux-native");
|
||||
expect(result!.name).toMatch(/\.tar\.gz$/);
|
||||
});
|
||||
|
||||
it("returns undefined on arm64 (triggers brew fallback)", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "linux", "arm64");
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("returns undefined on arm (32-bit)", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "linux", "arm");
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("darwin", () => {
|
||||
it("selects the macOS-native asset", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "darwin", "arm64");
|
||||
expect(result).toBeDefined();
|
||||
expect(result!.name).toContain("macOS-native");
|
||||
});
|
||||
|
||||
it("selects the macOS-native asset on x64", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "darwin", "x64");
|
||||
expect(result).toBeDefined();
|
||||
expect(result!.name).toContain("macOS-native");
|
||||
});
|
||||
});
|
||||
|
||||
describe("win32", () => {
|
||||
it("selects the Windows-native asset", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "win32", "x64");
|
||||
expect(result).toBeDefined();
|
||||
expect(result!.name).toContain("Windows-native");
|
||||
expect(result!.name).toMatch(/\.zip$/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("edge cases", () => {
|
||||
it("returns undefined for an empty asset list", () => {
|
||||
expect(pickAsset([], "linux", "x64")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("skips assets with missing name or url", () => {
|
||||
const partial: ReleaseAsset[] = [
|
||||
{ name: "signal-cli.tar.gz" },
|
||||
{ browser_download_url: "https://example.com/file.tar.gz" },
|
||||
];
|
||||
expect(pickAsset(partial, "linux", "x64")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("falls back to first archive for unknown platform", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "freebsd" as NodeJS.Platform, "x64");
|
||||
expect(result).toBeDefined();
|
||||
expect(result!.name).toMatch(/\.tar\.gz$/);
|
||||
});
|
||||
|
||||
it("never selects .asc signature files", () => {
|
||||
const result = pickAsset(SAMPLE_ASSETS, "linux", "x64");
|
||||
expect(result).toBeDefined();
|
||||
expect(result!.name).not.toMatch(/\.asc$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -9,12 +9,12 @@ import { resolveBrewExecutable } from "../infra/brew.js";
|
||||
import { runCommandWithTimeout } from "../process/exec.js";
|
||||
import { CONFIG_DIR } from "../utils.js";
|
||||
|
||||
type ReleaseAsset = {
|
||||
export type ReleaseAsset = {
|
||||
name?: string;
|
||||
browser_download_url?: string;
|
||||
};
|
||||
|
||||
type NamedAsset = {
|
||||
export type NamedAsset = {
|
||||
name: string;
|
||||
browser_download_url: string;
|
||||
};
|
||||
@@ -31,7 +31,8 @@ export type SignalInstallResult = {
|
||||
error?: string;
|
||||
};
|
||||
|
||||
function looksLikeArchive(name: string): boolean {
|
||||
/** @internal Exported for testing. */
|
||||
export function looksLikeArchive(name: string): boolean {
|
||||
return name.endsWith(".tar.gz") || name.endsWith(".tgz") || name.endsWith(".zip");
|
||||
}
|
||||
|
||||
@@ -43,7 +44,8 @@ function looksLikeArchive(name: string): boolean {
|
||||
* returns `undefined` so the caller can fall back to a different install
|
||||
* strategy (e.g. Homebrew).
|
||||
*/
|
||||
function pickAsset(
|
||||
/** @internal Exported for testing. */
|
||||
export function pickAsset(
|
||||
assets: ReleaseAsset[],
|
||||
platform: NodeJS.Platform,
|
||||
arch: string,
|
||||
|
||||
Reference in New Issue
Block a user