mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* test: strengthen e2e PR coverage * fix: address e2e PR feedback Generated-By: looper 0.6.1 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Generated-By: looper 0.6.1 (runner=fixer, agent=opencode) * ci: cache Windows packaged smoke builds * test: fake additional agent runtimes * fix: address e2e PR feedback Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Route tools-pack mac starts through a launch-time packaged config override so portable packaged smoke runs keep using the namespace runtime root that inspect and logs expect. Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Fall back to the packaged app's embedded config when the build output config is missing so installed mac starts still work. Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: align packaged mac PR smoke with tools-pack runtime mode Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Keep blake3-wasm out of the packaged mac daemon prebundle so the standalone runtime loads the Cloudflare asset hasher from node_modules instead of crashing in ESM. Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix: address e2e PR feedback Skip the portable mac launch override when the bundled packaged config is missing so installed fallback app targets can still boot with packaged defaults. Add a regression test covering the missing-config start path. Generated-By: looper 0.6.2 (runner=fixer, agent=opencode) * fix(pack): remove duplicate mac prebundle dependency key
138 lines
5.6 KiB
TypeScript
138 lines
5.6 KiB
TypeScript
import { chmod, mkdtemp, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import type { ToolPackConfig } from "../src/config.js";
|
|
import { resolveMacPaths } from "../src/mac/paths.js";
|
|
|
|
const requestJsonIpc = vi.fn(async () => ({ state: "running" }));
|
|
const resolveAppIpcPath = vi.fn(() => "/tmp/open-design/ipc/test/desktop.sock");
|
|
const createSidecarLaunchEnv = vi.fn(({ extraEnv }: { extraEnv: NodeJS.ProcessEnv }) => extraEnv);
|
|
const spawnBackgroundProcess = vi.fn(async ({ env }: { env: NodeJS.ProcessEnv }) => ({ env, pid: 1234 }));
|
|
|
|
vi.mock("@open-design/sidecar", () => ({
|
|
createSidecarLaunchEnv,
|
|
requestJsonIpc,
|
|
resolveAppIpcPath,
|
|
}));
|
|
|
|
vi.mock("@open-design/platform", () => ({
|
|
collectProcessTreePids: vi.fn(),
|
|
createProcessStampArgs: vi.fn(() => []),
|
|
listProcessSnapshots: vi.fn(async () => []),
|
|
matchesStampedProcess: vi.fn(() => false),
|
|
readLogTail: vi.fn(async () => []),
|
|
spawnBackgroundProcess,
|
|
stopProcesses: vi.fn(async () => []),
|
|
}));
|
|
|
|
const { startPackedMacApp } = await import("../src/mac/lifecycle.js");
|
|
|
|
function makeConfig(root: string, overrides: Partial<ToolPackConfig> = {}): ToolPackConfig {
|
|
return {
|
|
containerized: false,
|
|
electronBuilderCliPath: "/x/electron-builder/cli.js",
|
|
electronDistPath: "/x/electron/dist",
|
|
electronVersion: "41.3.0",
|
|
macCompression: "normal",
|
|
namespace: "local-test",
|
|
platform: "mac",
|
|
portable: true,
|
|
removeData: false,
|
|
removeLogs: false,
|
|
removeProductUserData: false,
|
|
removeSidecars: false,
|
|
roots: {
|
|
output: {
|
|
appBuilderRoot: join(root, ".tmp", "tools-pack", "out", "mac", "namespaces", "local-test", "builder"),
|
|
namespaceRoot: join(root, ".tmp", "tools-pack", "out", "mac", "namespaces", "local-test"),
|
|
platformRoot: join(root, ".tmp", "tools-pack", "out", "mac"),
|
|
root: join(root, ".tmp", "tools-pack", "out"),
|
|
},
|
|
runtime: {
|
|
namespaceBaseRoot: join(root, ".tmp", "tools-pack", "runtime", "mac", "namespaces"),
|
|
namespaceRoot: join(root, ".tmp", "tools-pack", "runtime", "mac", "namespaces", "local-test"),
|
|
},
|
|
cacheRoot: join(root, ".tmp", "tools-pack", "cache"),
|
|
toolPackRoot: join(root, ".tmp", "tools-pack"),
|
|
},
|
|
silent: true,
|
|
signed: false,
|
|
to: "app",
|
|
webOutputMode: "standalone",
|
|
workspaceRoot: root,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.clearAllMocks();
|
|
requestJsonIpc.mockResolvedValue({ state: "running" });
|
|
});
|
|
|
|
describe("startPackedMacApp", () => {
|
|
it("skips the launch override when the bundled config is missing", async () => {
|
|
const root = await mkdtemp(join(tmpdir(), "open-design-tools-pack-mac-lifecycle-"));
|
|
try {
|
|
const config = makeConfig(root);
|
|
const paths = resolveMacPaths(config);
|
|
const executablePath = join(paths.installedAppPath, "Contents", "MacOS", "Open Design");
|
|
|
|
await mkdir(join(paths.installedAppPath, "Contents", "MacOS"), { recursive: true });
|
|
await writeFile(executablePath, "#!/bin/sh\nexit 0\n", "utf8");
|
|
await chmod(executablePath, 0o755);
|
|
|
|
const result = await startPackedMacApp(config);
|
|
const launchConfigPath = join(config.roots.runtime.namespaceRoot, "open-design-config.json");
|
|
const launchEnv = spawnBackgroundProcess.mock.calls[0]?.[0]?.env as NodeJS.ProcessEnv | undefined;
|
|
|
|
expect(result.source).toBe("installed");
|
|
expect(result.status?.state).toBe("running");
|
|
expect(launchEnv?.OD_PACKAGED_CONFIG_PATH).toBeUndefined();
|
|
await expect(readFile(launchConfigPath, "utf8")).rejects.toMatchObject({ code: "ENOENT" });
|
|
} finally {
|
|
await rm(root, { force: true, recursive: true });
|
|
}
|
|
});
|
|
|
|
it("passes a launch override config path for portable mac starts", async () => {
|
|
const root = await mkdtemp(join(tmpdir(), "open-design-tools-pack-mac-lifecycle-"));
|
|
try {
|
|
const config = makeConfig(root);
|
|
const paths = resolveMacPaths(config);
|
|
const executablePath = join(paths.installedAppPath, "Contents", "MacOS", "Open Design");
|
|
const bundledConfigPath = join(paths.installedAppPath, "Contents", "Resources", "open-design-config.json");
|
|
|
|
await mkdir(join(paths.installedAppPath, "Contents", "MacOS"), { recursive: true });
|
|
await mkdir(join(paths.installedAppPath, "Contents", "Resources"), { recursive: true });
|
|
await writeFile(executablePath, "#!/bin/sh\nexit 0\n", "utf8");
|
|
await chmod(executablePath, 0o755);
|
|
await writeFile(
|
|
bundledConfigPath,
|
|
`${JSON.stringify({
|
|
appVersion: "1.2.3",
|
|
daemonCliEntryRelative: "open-design/bin/od",
|
|
namespace: config.namespace,
|
|
nodeCommandRelative: "open-design/bin/node",
|
|
}, null, 2)}\n`,
|
|
"utf8",
|
|
);
|
|
|
|
const result = await startPackedMacApp(config);
|
|
const launchConfigPath = join(config.roots.runtime.namespaceRoot, "open-design-config.json");
|
|
const launchEnv = spawnBackgroundProcess.mock.calls[0]?.[0]?.env as NodeJS.ProcessEnv | undefined;
|
|
|
|
expect(result.source).toBe("installed");
|
|
expect(result.status?.state).toBe("running");
|
|
expect(launchEnv?.OD_PACKAGED_CONFIG_PATH).toBe(launchConfigPath);
|
|
await expect(readFile(launchConfigPath, "utf8")).resolves.toContain(
|
|
`"namespaceBaseRoot": ${JSON.stringify(config.roots.runtime.namespaceBaseRoot)}`,
|
|
);
|
|
await expect(readFile(launchConfigPath, "utf8")).resolves.toContain('"appVersion": "1.2.3"');
|
|
} finally {
|
|
await rm(root, { force: true, recursive: true });
|
|
}
|
|
});
|
|
});
|