

























@@ -39,6 +39,14 @@ const nonBooleanConfigCases = [
3939},
4040];
414142+function issuePaths(issues: Array<{ path: string }>): string[] {
43+return issues.map((issue) => issue.path);
44+}
45+46+function issueMessages(issues: Array<{ message: string }>): string[] {
47+return issues.map((issue) => issue.message);
48+}
49+4250describe("boolean config validation", () => {
4351it.each(nonBooleanConfigCases)("rejects non-boolean values for $name", ({ config }) => {
4452const result = OpenClawSchema.safeParse(config);
@@ -986,8 +994,10 @@ describe("config strict validation", () => {
986994const snap = await readConfigFileSnapshot();
987995988996expect(snap.valid).toBe(false);
989-expect(snap.issues.some((issue) => issue.message.includes('"memorySearch"'))).toBe(true);
990-expect(snap.legacyIssues.some((issue) => issue.path === "memorySearch")).toBe(true);
997+expect(issueMessages(snap.issues)).toEqual(
998+expect.arrayContaining([expect.stringContaining('"memorySearch"')]),
999+);
1000+expect(issuePaths(snap.legacyIssues)).toContain("memorySearch");
9911001expect((snap.sourceConfig as { memorySearch?: unknown }).memorySearch).toMatchObject({
9921002provider: "local",
9931003fallback: "none",
@@ -1009,8 +1019,10 @@ describe("config strict validation", () => {
10091019const snap = await readConfigFileSnapshot();
1010102010111021expect(snap.valid).toBe(false);
1012-expect(snap.issues.some((issue) => issue.message.includes('"heartbeat"'))).toBe(true);
1013-expect(snap.legacyIssues.some((issue) => issue.path === "heartbeat")).toBe(true);
1022+expect(issueMessages(snap.issues)).toEqual(
1023+expect.arrayContaining([expect.stringContaining('"heartbeat"')]),
1024+);
1025+expect(issuePaths(snap.legacyIssues)).toContain("heartbeat");
10141026expect((snap.sourceConfig as { heartbeat?: unknown }).heartbeat).toMatchObject({
10151027every: "30m",
10161028model: "anthropic/claude-3-5-haiku-20241022",
@@ -1032,8 +1044,10 @@ describe("config strict validation", () => {
10321044const snap = await readConfigFileSnapshot();
1033104510341046expect(snap.valid).toBe(false);
1035-expect(snap.issues.some((issue) => issue.message.includes('"heartbeat"'))).toBe(true);
1036-expect(snap.legacyIssues.some((issue) => issue.path === "heartbeat")).toBe(true);
1047+expect(issueMessages(snap.issues)).toEqual(
1048+expect.arrayContaining([expect.stringContaining('"heartbeat"')]),
1049+);
1050+expect(issuePaths(snap.legacyIssues)).toContain("heartbeat");
10371051expect((snap.sourceConfig as { heartbeat?: unknown }).heartbeat).toMatchObject({
10381052showOk: true,
10391053showAlerts: false,
@@ -1057,7 +1071,7 @@ describe("config strict validation", () => {
10571071};
10581072const issues = findLegacyConfigIssues(raw);
105910731060-expect(issues.some((issue) => issue.path === "messages.tts")).toBe(true);
1074+expect(issuePaths(issues)).toContain("messages.tts");
10611075expect(raw.messages.tts.elevenlabs).toEqual({
10621076apiKey: "test-key",
10631077voiceId: "voice-1",
@@ -1088,12 +1102,12 @@ describe("config strict validation", () => {
10881102const snap = await readConfigFileSnapshot();
1089110310901104expect(snap.valid).toBe(false);
1091-expect(snap.issues.some((issue) => issue.path === "agents.defaults.sandbox")).toBe(true);
1092-expect(snap.issues.some((issue) => issue.path === "agents.list.0.sandbox")).toBe(true);
1093-expect(snap.legacyIssues.some((issue) => issue.path === "agents.defaults.sandbox")).toBe(
1094-true,
1105+expect(issuePaths(snap.issues)).toEqual(
1106+expect.arrayContaining(["agents.defaults.sandbox", "agents.list.0.sandbox"]),
1107+);
1108+expect(issuePaths(snap.legacyIssues)).toEqual(
1109+expect.arrayContaining(["agents.defaults.sandbox", "agents.list"]),
10951110);
1096-expect(snap.legacyIssues.some((issue) => issue.path === "agents.list")).toBe(true);
10971111expect(snap.sourceConfig.agents?.defaults?.sandbox).toEqual({ perSession: true });
10981112expect(snap.sourceConfig.agents?.list?.[0]?.sandbox).toEqual({ perSession: false });
10991113});
@@ -1111,7 +1125,7 @@ describe("config strict validation", () => {
11111125const snap = await readConfigFileSnapshot();
11121126expect(snap.valid).toBe(false);
11131127expect(snap.legacyIssues).toHaveLength(0);
1114-expect(snap.issues.some((issue) => issue.path === "gateway.bind")).toBe(true);
1128+expect(issuePaths(snap.issues)).toContain("gateway.bind");
11151129} finally {
11161130if (prev === undefined) {
11171131delete process.env.OPENCLAW_BIND;
@@ -1130,8 +1144,8 @@ describe("config strict validation", () => {
1130114411311145const snap = await readConfigFileSnapshot();
11321146expect(snap.valid).toBe(false);
1133-expect(snap.issues.some((issue) => issue.path === "gateway.bind")).toBe(true);
1134-expect(snap.legacyIssues.some((issue) => issue.path === "gateway.bind")).toBe(true);
1147+expect(issuePaths(snap.issues)).toContain("gateway.bind");
1148+expect(issuePaths(snap.legacyIssues)).toContain("gateway.bind");
11351149});
11361150});
11371151});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。