





















@@ -19,11 +19,14 @@ vi.mock("../../logger.js", () => ({
1919logWarn: (...args: unknown[]) => logWarnMock(...args),
2020}));
212122-const { createRuntimeConfig } = await import("./runtime-config.js");
22+const { withPluginRuntimePluginScope } = await import("./gateway-request-scope.js");
23+const { createRuntimeConfig, resetRuntimeConfigDeprecationWarningStateForTest } =
24+await import("./runtime-config.js");
2325const deprecatedConfigCode = "runtime-config-load-write";
24262527describe("createRuntimeConfig", () => {
2628beforeEach(() => {
29+resetRuntimeConfigDeprecationWarningStateForTest();
2730getRuntimeConfigMock.mockReset();
2831mutateConfigFileMock.mockReset();
2932replaceConfigFileMock.mockReset();
@@ -46,6 +49,40 @@ describe("createRuntimeConfig", () => {
4649);
4750});
485152+it("attributes deprecated loadConfig warnings to the active plugin scope", () => {
53+const runtimeConfig = { plugins: { entries: {} } };
54+getRuntimeConfigMock.mockReturnValue(runtimeConfig);
55+const configApi = createRuntimeConfig();
56+57+const loaded = withPluginRuntimePluginScope(
58+{ pluginId: "legacy-plugin", pluginSource: "/plugins/legacy-plugin/index.js" },
59+() => configApi.loadConfig(),
60+);
61+62+expect(loaded).toBe(runtimeConfig);
63+expect(logWarnMock).toHaveBeenCalledWith(
64+`plugin "legacy-plugin" runtime config.loadConfig() is deprecated (${deprecatedConfigCode}); use config.current(). Source: /plugins/legacy-plugin/index.js`,
65+);
66+});
67+68+it("keeps deprecated loadConfig warning attribution per plugin", () => {
69+const configApi = createRuntimeConfig();
70+71+withPluginRuntimePluginScope({ pluginId: "first" }, () => configApi.loadConfig());
72+withPluginRuntimePluginScope({ pluginId: "first" }, () => configApi.loadConfig());
73+withPluginRuntimePluginScope({ pluginId: "second" }, () => configApi.loadConfig());
74+75+expect(logWarnMock).toHaveBeenCalledTimes(2);
76+expect(logWarnMock).toHaveBeenNthCalledWith(
77+1,
78+`plugin "first" runtime config.loadConfig() is deprecated (${deprecatedConfigCode}); use config.current().`,
79+);
80+expect(logWarnMock).toHaveBeenNthCalledWith(
81+2,
82+`plugin "second" runtime config.loadConfig() is deprecated (${deprecatedConfigCode}); use config.current().`,
83+);
84+});
85+4986it("routes deprecated writeConfigFile through replaceConfigFile with afterWrite", async () => {
5087const configApi = createRuntimeConfig();
5188const nextConfig = { plugins: { entries: {} } } as OpenClawConfig;
@@ -62,6 +99,25 @@ describe("createRuntimeConfig", () => {
6299});
63100});
64101102+it("attributes deprecated writeConfigFile warnings to the active plugin scope", async () => {
103+const configApi = createRuntimeConfig();
104+const nextConfig = { plugins: { entries: {} } } as OpenClawConfig;
105+106+await withPluginRuntimePluginScope(
107+{ pluginId: "legacy-plugin", pluginSource: "/plugins/legacy-plugin/index.js" },
108+async () => await configApi.writeConfigFile(nextConfig),
109+);
110+111+expect(logWarnMock).toHaveBeenCalledWith(
112+`plugin "legacy-plugin" runtime config.writeConfigFile() is deprecated (${deprecatedConfigCode}); use config.mutateConfigFile(...) or config.replaceConfigFile(...). Source: /plugins/legacy-plugin/index.js`,
113+);
114+expect(replaceConfigFileMock).toHaveBeenCalledWith({
115+ nextConfig,
116+afterWrite: { mode: "auto" },
117+writeOptions: undefined,
118+});
119+});
120+65121it("preserves explicit afterWrite intent for deprecated writeConfigFile", async () => {
66122const configApi = createRuntimeConfig();
67123const nextConfig = { plugins: { entries: {} } } as OpenClawConfig;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。