























11// Onboard skills tests cover skill setup prompts, package manager config, and skip behavior.
2-import { afterEach, describe, expect, it, vi } from "vitest";
2+import { beforeEach, describe, expect, it, vi } from "vitest";
33import type { OpenClawConfig } from "../config/config.js";
44import type { RuntimeEnv } from "../runtime.js";
55import type { WizardPrompter } from "../wizard/prompts.js";
@@ -143,16 +143,30 @@ const runtime: RuntimeEnv = {
143143}) as RuntimeEnv["exit"],
144144};
145145146+const supportsHomebrewPrompt = process.platform === "darwin" || process.platform === "linux";
147+148+async function withPlatform<T>(platform: NodeJS.Platform, fn: () => Promise<T>): Promise<T> {
149+const originalPlatformDescriptor = Object.getOwnPropertyDescriptor(process, "platform")!;
150+Object.defineProperty(process, "platform", {
151+configurable: true,
152+value: platform,
153+});
154+try {
155+return await fn();
156+} finally {
157+Object.defineProperty(process, "platform", originalPlatformDescriptor);
158+}
159+}
160+146161describe("setupSkills", () => {
147-afterEach(() => {
162+beforeEach(() => {
163+vi.clearAllMocks();
148164mocks.isContainerEnvironment.mockReset();
149165mocks.resolveBrewExecutable.mockReset();
150166});
151167152168it("hides brew-only installs in Linux containers when brew is missing", async () => {
153-const originalPlatformDescriptor = Object.getOwnPropertyDescriptor(process, "platform")!;
154-Object.defineProperty(process, "platform", { value: "linux", configurable: true });
155-try {
169+await withPlatform("linux", async () => {
156170mockMissingBrewStatus([
157171createBundledSkill({
158172name: "video-frames",
@@ -173,15 +187,11 @@ describe("setupSkills", () => {
173187expect(
174188notes.find((n) => n.message.includes("No missing skill dependencies to install")),
175189).toBeUndefined();
176-} finally {
177-Object.defineProperty(process, "platform", originalPlatformDescriptor);
178-}
190+});
179191});
180192181193it("keeps brew-only installs visible when Linuxbrew is resolved off PATH", async () => {
182-const originalPlatformDescriptor = Object.getOwnPropertyDescriptor(process, "platform")!;
183-Object.defineProperty(process, "platform", { value: "linux", configurable: true });
184-try {
194+await withPlatform("linux", async () => {
185195mockMissingBrewStatus([
186196createBundledSkill({
187197name: "video-frames",
@@ -202,13 +212,11 @@ describe("setupSkills", () => {
202212);
203213expect(notes.find((n) => n.title === "Container skill installs")).toBeUndefined();
204214expect(notes.find((n) => n.title === "Homebrew recommended")).toBeUndefined();
205-} finally {
206-Object.defineProperty(process, "platform", originalPlatformDescriptor);
207-}
215+});
208216});
209217210218it("does not recommend Homebrew when user skips installing brew-backed deps", async () => {
211-if (process.platform === "win32") {
219+if (!supportsHomebrewPrompt) {
212220return;
213221}
214222@@ -247,7 +255,7 @@ describe("setupSkills", () => {
247255});
248256249257it("recommends Homebrew when user selects a brew-backed install and brew is missing", async () => {
250-if (process.platform === "win32") {
258+if (!supportsHomebrewPrompt) {
251259return;
252260}
253261@@ -279,4 +287,24 @@ describe("setupSkills", () => {
279287expect(emptyStateNote?.message).toContain("openclaw skills list --verbose");
280288expect(emptyStateNote?.message).toContain("openclaw skills check");
281289});
290+291+it("does not recommend Homebrew on FreeBSD", async () => {
292+await withPlatform("freebsd", async () => {
293+mockMissingBrewStatus([
294+createBundledSkill({
295+name: "video-frames",
296+description: "ffmpeg",
297+bins: ["ffmpeg"],
298+installLabel: "Install ffmpeg (brew)",
299+}),
300+]);
301+302+const { prompter, notes } = createPrompter({ multiselect: ["video-frames"] });
303+await setupSkills({} as OpenClawConfig, "/tmp/ws", runtime, prompter);
304+305+const brewNote = notes.find((n) => n.title === "Homebrew recommended");
306+expect(brewNote).toBeUndefined();
307+expect(mocks.detectBinary).not.toHaveBeenCalledWith("brew");
308+});
309+});
282310});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。