mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
### What does this PR do? ### How did you verify your code works? --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
741 lines
21 KiB
TypeScript
741 lines
21 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { execSync } from "child_process";
|
|
import { promises as fs } from "fs";
|
|
import { bunEnv, bunExe, isWindows, tempDir } from "harness";
|
|
import { join } from "path";
|
|
|
|
// Helper to ensure executable cleanup
|
|
function cleanup(outfile: string) {
|
|
return {
|
|
[Symbol.asyncDispose]: async () => {
|
|
try {
|
|
await fs.rm(outfile, { force: true });
|
|
} catch {}
|
|
},
|
|
};
|
|
}
|
|
|
|
describe.skipIf(!isWindows).concurrent("Windows compile metadata", () => {
|
|
describe("CLI flags", () => {
|
|
test("all metadata flags via CLI", async () => {
|
|
using dir = tempDir("windows-metadata-cli", {
|
|
"app.js": `console.log("Test app with metadata");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "app-with-metadata.exe");
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"My Application",
|
|
"--windows-publisher",
|
|
"Test Company Inc",
|
|
"--windows-version",
|
|
"1.2.3.4",
|
|
"--windows-description",
|
|
"A test application with metadata",
|
|
"--windows-copyright",
|
|
"Copyright © 2024 Test Company Inc",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
|
|
|
expect(exitCode).toBe(0);
|
|
expect(stderr).toBe("");
|
|
|
|
// Verify executable was created
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
|
|
// Verify metadata using PowerShell
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toBe("My Application");
|
|
expect(getMetadata("CompanyName")).toBe("Test Company Inc");
|
|
expect(getMetadata("FileDescription")).toBe("A test application with metadata");
|
|
expect(getMetadata("LegalCopyright")).toBe("Copyright © 2024 Test Company Inc");
|
|
expect(getMetadata("ProductVersion")).toBe("1.2.3.4");
|
|
expect(getMetadata("FileVersion")).toBe("1.2.3.4");
|
|
});
|
|
|
|
test("partial metadata flags", async () => {
|
|
using dir = tempDir("windows-metadata-partial", {
|
|
"app.js": `console.log("Partial metadata test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "app-partial.exe");
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"Simple App",
|
|
"--windows-version",
|
|
"2.0.0.0",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toBe("Simple App");
|
|
expect(getMetadata("ProductVersion")).toBe("2.0.0.0");
|
|
expect(getMetadata("FileVersion")).toBe("2.0.0.0");
|
|
});
|
|
|
|
test("windows flags without --compile should error", async () => {
|
|
using dir = tempDir("windows-no-compile", {
|
|
"app.js": `console.log("test");`,
|
|
});
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [bunExe(), "build", join(String(dir), "app.js"), "--windows-title", "Should Fail"],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
|
|
|
|
expect(exitCode).not.toBe(0);
|
|
expect(stderr).toContain("--windows-title requires --compile");
|
|
});
|
|
|
|
test("windows flags with non-Windows target should error", async () => {
|
|
using dir = tempDir("windows-wrong-target", {
|
|
"app.js": `console.log("test");`,
|
|
});
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
"--target",
|
|
"bun-linux-x64",
|
|
join(String(dir), "app.js"),
|
|
"--windows-title",
|
|
"Should Fail",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
|
|
|
|
expect(exitCode).not.toBe(0);
|
|
// Windows flags require a Windows compile target
|
|
expect(stderr.toLowerCase()).toContain("windows compile target");
|
|
});
|
|
});
|
|
|
|
describe("Bun.build() API", () => {
|
|
test("all metadata via Bun.build()", async () => {
|
|
using dir = tempDir("windows-metadata-api", {
|
|
"app.js": `console.log("API metadata test");`,
|
|
});
|
|
|
|
const result = await Bun.build({
|
|
entrypoints: [join(String(dir), "app.js")],
|
|
outdir: String(dir),
|
|
compile: {
|
|
target: "bun-windows-x64",
|
|
outfile: "app-api.exe",
|
|
windows: {
|
|
title: "API App",
|
|
publisher: "API Company",
|
|
version: "3.0.0.0",
|
|
description: "Built with Bun.build API",
|
|
copyright: "© 2024 API Company",
|
|
},
|
|
},
|
|
});
|
|
|
|
expect(result.success).toBe(true);
|
|
expect(result.outputs.length).toBe(1);
|
|
|
|
const outfile = result.outputs[0].path;
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toBe("API App");
|
|
expect(getMetadata("CompanyName")).toBe("API Company");
|
|
expect(getMetadata("FileDescription")).toBe("Built with Bun.build API");
|
|
expect(getMetadata("LegalCopyright")).toBe("© 2024 API Company");
|
|
expect(getMetadata("ProductVersion")).toBe("3.0.0.0");
|
|
});
|
|
|
|
test("partial metadata via Bun.build()", async () => {
|
|
using dir = tempDir("windows-metadata-api-partial", {
|
|
"app.js": `console.log("Partial API test");`,
|
|
});
|
|
|
|
const result = await Bun.build({
|
|
entrypoints: [join(String(dir), "app.js")],
|
|
outdir: String(dir),
|
|
compile: {
|
|
target: "bun-windows-x64",
|
|
outfile: "partial-api.exe",
|
|
windows: {
|
|
title: "Partial App",
|
|
version: "1.0.0.0",
|
|
},
|
|
},
|
|
});
|
|
|
|
expect(result.success).toBe(true);
|
|
|
|
const outfile = result.outputs[0].path;
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toBe("Partial App");
|
|
expect(getMetadata("ProductVersion")).toBe("1.0.0.0");
|
|
});
|
|
|
|
test("relative outdir with compile", async () => {
|
|
using dir = tempDir("windows-relative-outdir", {
|
|
"app.js": `console.log("Relative outdir test");`,
|
|
});
|
|
|
|
const result = await Bun.build({
|
|
entrypoints: [join(String(dir), "app.js")],
|
|
outdir: "./out",
|
|
compile: {
|
|
target: "bun-windows-x64",
|
|
outfile: "relative.exe",
|
|
windows: {
|
|
title: "Relative Path App",
|
|
},
|
|
},
|
|
});
|
|
|
|
expect(result.success).toBe(true);
|
|
expect(result.outputs.length).toBe(1);
|
|
|
|
// Should not crash with assertion error
|
|
const exists = await Bun.file(result.outputs[0].path).exists();
|
|
expect(exists).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("Version string formats", () => {
|
|
const testVersionFormats = [
|
|
{ input: "1", expected: "1.0.0.0" },
|
|
{ input: "1.2", expected: "1.2.0.0" },
|
|
{ input: "1.2.3", expected: "1.2.3.0" },
|
|
{ input: "1.2.3.4", expected: "1.2.3.4" },
|
|
{ input: "10.20.30.40", expected: "10.20.30.40" },
|
|
{ input: "999.999.999.999", expected: "999.999.999.999" },
|
|
];
|
|
|
|
test.each(testVersionFormats)("version format: $input", async ({ input, expected }) => {
|
|
using dir = tempDir(`windows-version-${input.replace(/\./g, "-")}`, {
|
|
"app.js": `console.log("Version test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "version-test.exe");
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-version",
|
|
input,
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const version = execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.ProductVersion"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
|
|
expect(version).toBe(expected);
|
|
});
|
|
|
|
test("invalid version format should error gracefully", async () => {
|
|
using dir = tempDir("windows-invalid-version", {
|
|
"app.js": `console.log("Invalid version test");`,
|
|
});
|
|
|
|
const invalidVersions = [
|
|
"not.a.version",
|
|
"1.2.3.4.5",
|
|
"1.-2.3.4",
|
|
"65536.0.0.0", // > 65535
|
|
"",
|
|
];
|
|
|
|
for (const version of invalidVersions) {
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
join(String(dir), "test.exe"),
|
|
"--windows-version",
|
|
version,
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).not.toBe(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("Original Filename removal", () => {
|
|
test("Original Filename field should be empty", async () => {
|
|
using dir = tempDir("windows-original-filename", {
|
|
"app.js": `console.log("Original filename test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "test-original.exe");
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"Test Application",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
// Check that Original Filename is empty (not "bun.exe")
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
const originalFilename = getMetadata("OriginalFilename");
|
|
expect(originalFilename).toBe("");
|
|
expect(originalFilename).not.toBe("bun.exe");
|
|
});
|
|
|
|
test("Original Filename should be empty even with all metadata set", async () => {
|
|
using dir = tempDir("windows-original-filename-full", {
|
|
"app.js": `console.log("Full metadata test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "full-metadata.exe");
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"Complete App",
|
|
"--windows-publisher",
|
|
"Test Publisher",
|
|
"--windows-version",
|
|
"5.4.3.2",
|
|
"--windows-description",
|
|
"Application with full metadata",
|
|
"--windows-copyright",
|
|
"© 2024 Test",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
// Verify all custom metadata is set correctly
|
|
expect(getMetadata("ProductName")).toBe("Complete App");
|
|
expect(getMetadata("CompanyName")).toBe("Test Publisher");
|
|
expect(getMetadata("FileDescription")).toBe("Application with full metadata");
|
|
expect(getMetadata("ProductVersion")).toBe("5.4.3.2");
|
|
|
|
// But Original Filename should still be empty
|
|
const originalFilename = getMetadata("OriginalFilename");
|
|
expect(originalFilename).toBe("");
|
|
expect(originalFilename).not.toBe("bun.exe");
|
|
});
|
|
});
|
|
|
|
describe("Edge cases", () => {
|
|
test("long strings in metadata", async () => {
|
|
using dir = tempDir("windows-long-strings", {
|
|
"app.js": `console.log("Long strings test");`,
|
|
});
|
|
|
|
const longString = Buffer.alloc(255, "A").toString();
|
|
const outfile = join(String(dir), "long-strings.exe");
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
longString,
|
|
"--windows-description",
|
|
longString,
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
});
|
|
|
|
test("special characters in metadata", async () => {
|
|
using dir = tempDir("windows-special-chars", {
|
|
"app.js": `console.log("Special chars test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "special-chars.exe");
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"App™ with® Special© Characters",
|
|
"--windows-publisher",
|
|
"Company & Co.",
|
|
"--windows-description",
|
|
"Test \"quotes\" and 'apostrophes'",
|
|
"--windows-copyright",
|
|
"© 2024 <Company>",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toContain("App");
|
|
expect(getMetadata("CompanyName")).toContain("Company & Co.");
|
|
});
|
|
|
|
test("unicode in metadata", async () => {
|
|
using dir = tempDir("windows-unicode", {
|
|
"app.js": `console.log("Unicode test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "unicode.exe");
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"アプリケーション",
|
|
"--windows-publisher",
|
|
"会社名",
|
|
"--windows-description",
|
|
"Émoji test 🚀 🎉",
|
|
"--windows-copyright",
|
|
"© 2024 世界",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
});
|
|
|
|
test("empty strings in metadata", async () => {
|
|
using dir = tempDir("windows-empty-strings", {
|
|
"app.js": `console.log("Empty strings test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "empty.exe");
|
|
await using _cleanup = cleanup(outfile);
|
|
|
|
// Empty strings should be treated as not provided
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-title",
|
|
"",
|
|
"--windows-description",
|
|
"",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("Combined with other compile options", () => {
|
|
test("metadata with --windows-hide-console", async () => {
|
|
using dir = tempDir("windows-metadata-hide-console", {
|
|
"app.js": `console.log("Hidden console test");`,
|
|
});
|
|
|
|
const outfile = join(String(dir), "hidden-with-metadata.exe");
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-hide-console",
|
|
"--windows-title",
|
|
"Hidden Console App",
|
|
"--windows-version",
|
|
"1.0.0.0",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toBe("Hidden Console App");
|
|
expect(getMetadata("ProductVersion")).toBe("1.0.0.0");
|
|
});
|
|
|
|
test("metadata with --windows-icon", async () => {
|
|
// Create a simple .ico file (minimal valid ICO header)
|
|
const icoHeader = Buffer.from([
|
|
0x00,
|
|
0x00, // Reserved
|
|
0x01,
|
|
0x00, // Type (1 = ICO)
|
|
0x01,
|
|
0x00, // Count (1 image)
|
|
0x10, // Width (16)
|
|
0x10, // Height (16)
|
|
0x00, // Color count
|
|
0x00, // Reserved
|
|
0x01,
|
|
0x00, // Color planes
|
|
0x20,
|
|
0x00, // Bits per pixel
|
|
0x68,
|
|
0x01,
|
|
0x00,
|
|
0x00, // Size
|
|
0x16,
|
|
0x00,
|
|
0x00,
|
|
0x00, // Offset
|
|
]);
|
|
|
|
using dir = tempDir("windows-metadata-icon", {
|
|
"app.js": `console.log("Icon test");`,
|
|
"icon.ico": icoHeader,
|
|
});
|
|
|
|
const outfile = join(String(dir), "icon-with-metadata.exe");
|
|
|
|
await using proc = Bun.spawn({
|
|
cmd: [
|
|
bunExe(),
|
|
"build",
|
|
"--compile",
|
|
join(String(dir), "app.js"),
|
|
"--outfile",
|
|
outfile,
|
|
"--windows-icon",
|
|
join(String(dir), "icon.ico"),
|
|
"--windows-title",
|
|
"App with Icon",
|
|
"--windows-version",
|
|
"2.0.0.0",
|
|
],
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
|
|
|
// Icon might fail but metadata should still work
|
|
const exists = await Bun.file(outfile).exists();
|
|
expect(exists).toBe(true);
|
|
|
|
const getMetadata = (field: string) => {
|
|
try {
|
|
return execSync(`powershell -Command "(Get-ItemProperty '${outfile}').VersionInfo.${field}"`, {
|
|
encoding: "utf8",
|
|
}).trim();
|
|
} catch {
|
|
return "";
|
|
}
|
|
};
|
|
|
|
expect(getMetadata("ProductName")).toBe("App with Icon");
|
|
expect(getMetadata("ProductVersion")).toBe("2.0.0.0");
|
|
});
|
|
});
|
|
});
|
|
|
|
// Test for non-Windows platforms
|