diff --git a/test/js/bun/test-macos-app-sandbox.test.ts b/test/js/bun/test-macos-app-sandbox.test.ts
index c71e69732b..98d98974cf 100644
--- a/test/js/bun/test-macos-app-sandbox.test.ts
+++ b/test/js/bun/test-macos-app-sandbox.test.ts
@@ -1,33 +1,9 @@
import { describe, expect, test } from "bun:test";
-import { copyFileSync } from "fs";
+import { copyFileSync, rmSync } from "fs";
+import { homedir } from "os";
import { bunEnv, bunExe, isMacOS, tempDir } from "harness";
import { join } from "path";
-const infoPlist = `
-
-
-
- CFBundleExecutable
- bun
- CFBundleIdentifier
- dev.bun.test.bun_sandboxed
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- bun_sandboxed
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- 1.0
- CFBundleSupportedPlatforms
-
- MacOSX
-
- CFBundleVersion
- 1
-
-`;
-
const entitlementsPlist = `
@@ -45,12 +21,39 @@ const entitlementsPlist = `
`;
-async function createSandboxedApp(prefix: string) {
+function makeInfoPlist(bundleId: string) {
+ return `
+
+
+
+ CFBundleExecutable
+ bun
+ CFBundleIdentifier
+ ${bundleId}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ bun_sandboxed
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSupportedPlatforms
+
+ MacOSX
+
+ CFBundleVersion
+ 1
+
+`;
+}
+
+async function createSandboxedApp(prefix: string, bundleId: string) {
const dir = tempDir(prefix, {
"entitlements.plist": entitlementsPlist,
"bun_sandboxed.app": {
"Contents": {
- "Info.plist": infoPlist,
+ "Info.plist": makeInfoPlist(bundleId),
"MacOS": {},
},
},
@@ -65,46 +68,60 @@ async function createSandboxedApp(prefix: string) {
await using codesign = Bun.spawn({
cmd: ["/usr/bin/codesign", "--entitlements", entitlementsPath, "--force", "-s", "-", appBundlePath],
env: bunEnv,
- stderr: "pipe",
+ stdout: "pipe",
+ stderr: "inherit",
});
expect(await codesign.exited).toBe(0);
- return { dir, bunPath };
+ return { dir, bunPath, bundleId, containerPath: join(homedir(), "Library", "Containers", bundleId) };
}
// Modeled after Node.js's test/parallel/test-macos-app-sandbox.js
describe.skipIf(!isMacOS)("macOS App Sandbox", () => {
test.concurrent("bun can execute JavaScript inside the app sandbox", async () => {
- const { dir, bunPath } = await createSandboxedApp("macos-sandbox-test");
+ const { dir, bunPath, containerPath } = await createSandboxedApp("macos-sandbox-test", "dev.bun.test.sandbox_exec");
using _dir = dir;
- await using proc = Bun.spawn({
- cmd: [bunPath, "-e", "console.log('hello sandbox')"],
- env: bunEnv,
- stderr: "pipe",
- });
+ try {
+ await using proc = Bun.spawn({
+ cmd: [bunPath, "-e", "console.log('hello sandbox')"],
+ env: bunEnv,
+ stdout: "pipe",
+ stderr: "inherit",
+ });
- const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
+ const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
- expect(stdout.trim()).toBe("hello sandbox");
- expect(exitCode).toBe(0);
+ expect(stdout.trim()).toBe("hello sandbox");
+ expect(exitCode).toBe(0);
+ } finally {
+ rmSync(containerPath, { recursive: true, force: true });
+ }
});
test.concurrent("sandboxed bun runs inside the sandbox container", async () => {
- const { dir, bunPath } = await createSandboxedApp("macos-sandbox-test-container");
+ const { dir, bunPath, bundleId, containerPath } = await createSandboxedApp(
+ "macos-sandbox-test-container",
+ "dev.bun.test.sandbox_container",
+ );
using _dir = dir;
- // When running inside a macOS App Sandbox, os.homedir() should return
- // the sandbox container path, not the real home directory.
- await using proc = Bun.spawn({
- cmd: [bunPath, "-e", "console.log(require('os').homedir())"],
- env: bunEnv,
- stderr: "pipe",
- });
+ try {
+ // When running inside a macOS App Sandbox, os.homedir() should return
+ // the sandbox container path, not the real home directory.
+ await using proc = Bun.spawn({
+ cmd: [bunPath, "-e", "console.log(require('os').homedir())"],
+ env: bunEnv,
+ stdout: "pipe",
+ stderr: "inherit",
+ });
- const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
+ const [stdout, exitCode] = await Promise.all([proc.stdout.text(), proc.exited]);
- expect(stdout.trim()).toContain("Library/Containers/dev.bun.test.bun_sandboxed");
- expect(exitCode).toBe(0);
+ expect(stdout.trim()).toContain(`Library/Containers/${bundleId}`);
+ expect(exitCode).toBe(0);
+ } finally {
+ rmSync(containerPath, { recursive: true, force: true });
+ }
});
});