test(plugin): update plugin config and registry tests
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
+18
-10
@@ -3,7 +3,7 @@ import { chmodSync, existsSync, mkdtempSync, mkdirSync, readFileSync, rmSync, wr
|
|||||||
import { tmpdir } from "node:os"
|
import { tmpdir } from "node:os"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import * as shared from "./shared"
|
import * as shared from "./shared"
|
||||||
import { loadPluginConfig, mergeConfigs, parseConfigPartially } from "./plugin-config";
|
import { mergeConfigs, parseConfigPartially } from "./plugin-config";
|
||||||
import { OhMyOpenCodeConfigSchema, type OhMyOpenCodeConfig } from "./config";
|
import { OhMyOpenCodeConfigSchema, type OhMyOpenCodeConfig } from "./config";
|
||||||
|
|
||||||
const tempDirs: string[] = []
|
const tempDirs: string[] = []
|
||||||
@@ -12,6 +12,10 @@ function createConfig(config: Partial<OhMyOpenCodeConfig>): OhMyOpenCodeConfig {
|
|||||||
return OhMyOpenCodeConfigSchema.parse(config)
|
return OhMyOpenCodeConfigSchema.parse(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function importFreshPluginConfigModule(): Promise<typeof import("./plugin-config")> {
|
||||||
|
return import(`./plugin-config?test=${Date.now()}-${Math.random()}`)
|
||||||
|
}
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mock.restore()
|
mock.restore()
|
||||||
|
|
||||||
@@ -297,7 +301,7 @@ describe("parseConfigPartially", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("loadPluginConfig", () => {
|
describe("loadPluginConfig", () => {
|
||||||
it("should only honor mcp_env_allowlist from user config", () => {
|
it("should only honor mcp_env_allowlist from user config", async () => {
|
||||||
// given
|
// given
|
||||||
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-"))
|
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-"))
|
||||||
const userConfigDir = join(rootDir, "user-config")
|
const userConfigDir = join(rootDir, "user-config")
|
||||||
@@ -317,16 +321,17 @@ describe("loadPluginConfig", () => {
|
|||||||
JSON.stringify({ mcp_env_allowlist: ["PROJECT_TOKEN"] })
|
JSON.stringify({ mcp_env_allowlist: ["PROJECT_TOKEN"] })
|
||||||
)
|
)
|
||||||
|
|
||||||
spyOn(shared, "getOpenCodeConfigDir").mockReturnValue(userConfigDir)
|
process.env.OPENCODE_CONFIG_DIR = userConfigDir
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
const { loadPluginConfig } = await importFreshPluginConfigModule()
|
||||||
const config = loadPluginConfig(projectDir, {})
|
const config = loadPluginConfig(projectDir, {})
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(config.mcp_env_allowlist).toEqual(["USER_ONLY_TOKEN"])
|
expect(config.mcp_env_allowlist).toEqual(["USER_ONLY_TOKEN"])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should ignore edits to the renamed legacy backup after migration", () => {
|
it("should ignore edits to the renamed legacy backup after migration", async () => {
|
||||||
// given
|
// given
|
||||||
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-legacy-"))
|
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-legacy-"))
|
||||||
const userConfigDir = join(rootDir, "user-config")
|
const userConfigDir = join(rootDir, "user-config")
|
||||||
@@ -341,9 +346,10 @@ describe("loadPluginConfig", () => {
|
|||||||
mkdirSync(projectConfigDir, { recursive: true })
|
mkdirSync(projectConfigDir, { recursive: true })
|
||||||
writeFileSync(legacyConfigPath, JSON.stringify({ agents: { oracle: { model: "openai/gpt-5.4" } } }))
|
writeFileSync(legacyConfigPath, JSON.stringify({ agents: { oracle: { model: "openai/gpt-5.4" } } }))
|
||||||
|
|
||||||
spyOn(shared, "getOpenCodeConfigDir").mockReturnValue(userConfigDir)
|
process.env.OPENCODE_CONFIG_DIR = userConfigDir
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
const { loadPluginConfig } = await importFreshPluginConfigModule()
|
||||||
loadPluginConfig(projectDir, {})
|
loadPluginConfig(projectDir, {})
|
||||||
writeFileSync(backupConfigPath, JSON.stringify({ agents: { oracle: { model: "openai/gpt-5-nano" } } }))
|
writeFileSync(backupConfigPath, JSON.stringify({ agents: { oracle: { model: "openai/gpt-5-nano" } } }))
|
||||||
const reloadedConfig = loadPluginConfig(projectDir, {})
|
const reloadedConfig = loadPluginConfig(projectDir, {})
|
||||||
@@ -355,7 +361,7 @@ describe("loadPluginConfig", () => {
|
|||||||
expect(reloadedConfig.agents?.oracle?.model).toBe("openai/gpt-5.4")
|
expect(reloadedConfig.agents?.oracle?.model).toBe("openai/gpt-5.4")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should still load config from legacy path when migration fails", () => {
|
it("should still load config from legacy path when migration fails", async () => {
|
||||||
// given - legacy config exists but canonical path is not writable
|
// given - legacy config exists but canonical path is not writable
|
||||||
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-fail-"))
|
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-fail-"))
|
||||||
const userConfigDir = join(rootDir, "user-config")
|
const userConfigDir = join(rootDir, "user-config")
|
||||||
@@ -374,12 +380,13 @@ describe("loadPluginConfig", () => {
|
|||||||
chmodSync(projectConfigDir, 0o555)
|
chmodSync(projectConfigDir, 0o555)
|
||||||
}
|
}
|
||||||
|
|
||||||
spyOn(shared, "getOpenCodeConfigDir").mockReturnValue(userConfigDir)
|
process.env.OPENCODE_CONFIG_DIR = userConfigDir
|
||||||
|
|
||||||
// when
|
// when
|
||||||
let config: OhMyOpenCodeConfig
|
let config: OhMyOpenCodeConfig
|
||||||
try {
|
try {
|
||||||
config = loadPluginConfig(projectDir, {})
|
const fresh = await importFreshPluginConfigModule()
|
||||||
|
config = fresh.loadPluginConfig(projectDir, {})
|
||||||
} finally {
|
} finally {
|
||||||
// Restore permissions for cleanup
|
// Restore permissions for cleanup
|
||||||
if (process.platform !== "win32") {
|
if (process.platform !== "win32") {
|
||||||
@@ -391,7 +398,7 @@ describe("loadPluginConfig", () => {
|
|||||||
expect(config.agents?.oracle?.model).toBe("openai/gpt-5.4")
|
expect(config.agents?.oracle?.model).toBe("openai/gpt-5.4")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should load migrated legacy project config on the first load", () => {
|
it("should load migrated legacy project config on the first load", async () => {
|
||||||
// given
|
// given
|
||||||
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-first-load-"))
|
const rootDir = mkdtempSync(join(tmpdir(), "omo-plugin-config-first-load-"))
|
||||||
const userConfigDir = join(rootDir, "user-config")
|
const userConfigDir = join(rootDir, "user-config")
|
||||||
@@ -405,9 +412,10 @@ describe("loadPluginConfig", () => {
|
|||||||
mkdirSync(projectConfigDir, { recursive: true })
|
mkdirSync(projectConfigDir, { recursive: true })
|
||||||
writeFileSync(legacyConfigPath, JSON.stringify({ agents: { oracle: { model: "openai/gpt-5.4" } } }))
|
writeFileSync(legacyConfigPath, JSON.stringify({ agents: { oracle: { model: "openai/gpt-5.4" } } }))
|
||||||
|
|
||||||
spyOn(shared, "getOpenCodeConfigDir").mockReturnValue(userConfigDir)
|
process.env.OPENCODE_CONFIG_DIR = userConfigDir
|
||||||
|
|
||||||
// when
|
// when
|
||||||
|
const { loadPluginConfig } = await importFreshPluginConfigModule()
|
||||||
const config = loadPluginConfig(projectDir, {})
|
const config = loadPluginConfig(projectDir, {})
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, mock, spyOn, test } from "bun:test"
|
import { beforeEach, describe, expect, mock, spyOn, test } from "bun:test"
|
||||||
import { tool } from "@opencode-ai/plugin"
|
import { tool } from "@opencode-ai/plugin"
|
||||||
|
|
||||||
import type { OhMyOpenCodeConfig } from "../config"
|
import type { OhMyOpenCodeConfig } from "../config"
|
||||||
@@ -25,7 +25,12 @@ const syncSessionCreatedCallbacks: Array<
|
|||||||
((event: { sessionID: string; parentID: string; title: string }) => Promise<void>) | undefined
|
((event: { sessionID: string; parentID: string; title: string }) => Promise<void>) | undefined
|
||||||
> = []
|
> = []
|
||||||
|
|
||||||
mock.module("../tools", () => ({
|
const trackedPaneBySession = new Map<string, string>()
|
||||||
|
let dispatchOpenClawEvent: ReturnType<typeof spyOn>
|
||||||
|
|
||||||
|
const { createToolRegistry, trimToolsToCap } = await import("./tool-registry")
|
||||||
|
|
||||||
|
const toolFactories: NonNullable<Parameters<typeof createToolRegistry>[0]["toolFactories"]> = {
|
||||||
builtinTools: { bash: fakeTool, read: fakeTool },
|
builtinTools: { bash: fakeTool, read: fakeTool },
|
||||||
createBackgroundTools: mock(() => ({})),
|
createBackgroundTools: mock(() => ({})),
|
||||||
createCallOmoAgent: mock(() => fakeTool),
|
createCallOmoAgent: mock(() => fakeTool),
|
||||||
@@ -47,12 +52,7 @@ mock.module("../tools", () => ({
|
|||||||
createTaskList: mock(() => fakeTool),
|
createTaskList: mock(() => fakeTool),
|
||||||
createTaskUpdateTool: mock(() => fakeTool),
|
createTaskUpdateTool: mock(() => fakeTool),
|
||||||
createHashlineEditTool: mock(() => fakeTool),
|
createHashlineEditTool: mock(() => fakeTool),
|
||||||
}))
|
}
|
||||||
|
|
||||||
const trackedPaneBySession = new Map<string, string>()
|
|
||||||
|
|
||||||
const { createToolRegistry, trimToolsToCap } = await import("./tool-registry")
|
|
||||||
const dispatchOpenClawEvent = spyOn(openclawRuntimeDispatch, "dispatchOpenClawEvent")
|
|
||||||
|
|
||||||
function createPluginConfig(overrides: Partial<OhMyOpenCodeConfig> = {}): OhMyOpenCodeConfig {
|
function createPluginConfig(overrides: Partial<OhMyOpenCodeConfig> = {}): OhMyOpenCodeConfig {
|
||||||
return {
|
return {
|
||||||
@@ -65,6 +65,11 @@ function createPluginConfig(overrides: Partial<OhMyOpenCodeConfig> = {}): OhMyOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
dispatchOpenClawEvent = spyOn(openclawRuntimeDispatch, "dispatchOpenClawEvent")
|
||||||
|
syncSessionCreatedCallbacks.length = 0
|
||||||
|
})
|
||||||
|
|
||||||
describe("#given tool trimming prioritization", () => {
|
describe("#given tool trimming prioritization", () => {
|
||||||
test("#when max_tools trims a hashline edit registration named edit #then edit is removed before higher-priority tools", () => {
|
test("#when max_tools trims a hashline edit registration named edit #then edit is removed before higher-priority tools", () => {
|
||||||
const filteredTools = {
|
const filteredTools = {
|
||||||
@@ -100,6 +105,7 @@ describe("#given task_system configuration", () => {
|
|||||||
disabledSkills: new Set(),
|
disabledSkills: new Set(),
|
||||||
},
|
},
|
||||||
availableCategories: [],
|
availableCategories: [],
|
||||||
|
toolFactories,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(result.taskSystemEnabled).toBe(false)
|
expect(result.taskSystemEnabled).toBe(false)
|
||||||
@@ -129,6 +135,7 @@ describe("#given task_system configuration", () => {
|
|||||||
disabledSkills: new Set(),
|
disabledSkills: new Set(),
|
||||||
},
|
},
|
||||||
availableCategories: [],
|
availableCategories: [],
|
||||||
|
toolFactories,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(result.taskSystemEnabled).toBe(true)
|
expect(result.taskSystemEnabled).toBe(true)
|
||||||
@@ -168,6 +175,7 @@ describe("#given tmux integration is disabled", () => {
|
|||||||
},
|
},
|
||||||
availableCategories: [],
|
availableCategories: [],
|
||||||
interactiveBashEnabled: true,
|
interactiveBashEnabled: true,
|
||||||
|
toolFactories,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(result.filteredTools).toHaveProperty("interactive_bash")
|
expect(result.filteredTools).toHaveProperty("interactive_bash")
|
||||||
@@ -201,6 +209,7 @@ describe("#given tmux integration is disabled", () => {
|
|||||||
},
|
},
|
||||||
availableCategories: [],
|
availableCategories: [],
|
||||||
interactiveBashEnabled: false,
|
interactiveBashEnabled: false,
|
||||||
|
toolFactories,
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(result.filteredTools).not.toHaveProperty("interactive_bash")
|
expect(result.filteredTools).not.toHaveProperty("interactive_bash")
|
||||||
@@ -246,6 +255,7 @@ describe("#given openclaw is enabled for sync task sessions", () => {
|
|||||||
disabledSkills: new Set(),
|
disabledSkills: new Set(),
|
||||||
},
|
},
|
||||||
availableCategories: [],
|
availableCategories: [],
|
||||||
|
toolFactories,
|
||||||
})
|
})
|
||||||
|
|
||||||
const onSyncSessionCreated = syncSessionCreatedCallbacks[syncSessionCreatedCallbacks.length - 1]
|
const onSyncSessionCreated = syncSessionCreatedCallbacks[syncSessionCreatedCallbacks.length - 1]
|
||||||
|
|||||||
@@ -6,6 +6,12 @@ import { tmpdir } from "node:os"
|
|||||||
import * as dataPathModule from "../shared/data-path"
|
import * as dataPathModule from "../shared/data-path"
|
||||||
import * as sharedModule from "../shared"
|
import * as sharedModule from "../shared"
|
||||||
|
|
||||||
|
let scheduleDeferredModelOverride: (typeof import("./ultrawork-db-model-override"))["scheduleDeferredModelOverride"]
|
||||||
|
|
||||||
|
async function importFreshUltraworkDbModelOverrideModule(): Promise<typeof import("./ultrawork-db-model-override")> {
|
||||||
|
return import(`./ultrawork-db-model-override?test=${Date.now()}-${Math.random()}`)
|
||||||
|
}
|
||||||
|
|
||||||
function flushMicrotasks(depth: number): Promise<void> {
|
function flushMicrotasks(depth: number): Promise<void> {
|
||||||
return new Promise<void>((resolve) => {
|
return new Promise<void>((resolve) => {
|
||||||
let remaining = depth
|
let remaining = depth
|
||||||
@@ -22,6 +28,11 @@ function flushWithTimeout(): Promise<void> {
|
|||||||
return new Promise<void>((resolve) => setTimeout(resolve, 10))
|
return new Promise<void>((resolve) => setTimeout(resolve, 10))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function settleDeferredModelOverrideWork(): Promise<void> {
|
||||||
|
await flushMicrotasks(12)
|
||||||
|
await flushWithTimeout()
|
||||||
|
}
|
||||||
|
|
||||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
return typeof value === "object" && value !== null
|
return typeof value === "object" && value !== null
|
||||||
}
|
}
|
||||||
@@ -32,7 +43,7 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
let logSpy: ReturnType<typeof spyOn>
|
let logSpy: ReturnType<typeof spyOn>
|
||||||
let getDataDirSpy: ReturnType<typeof spyOn>
|
let getDataDirSpy: ReturnType<typeof spyOn>
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
tempDir = mkdtempSync(join(tmpdir(), "ultrawork-db-test-"))
|
tempDir = mkdtempSync(join(tmpdir(), "ultrawork-db-test-"))
|
||||||
const opencodePath = join(tempDir, "opencode")
|
const opencodePath = join(tempDir, "opencode")
|
||||||
mkdirSync(opencodePath, { recursive: true })
|
mkdirSync(opencodePath, { recursive: true })
|
||||||
@@ -50,11 +61,15 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
`)
|
`)
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
getDataDirSpy = spyOn(dataPathModule, "getDataDir").mockReturnValue(tempDir)
|
getDataDirSpy = spyOn(dataPathModule, "getDataDir")
|
||||||
logSpy = spyOn(sharedModule, "log").mockImplementation(() => {})
|
getDataDirSpy.mockReturnValue(tempDir)
|
||||||
|
logSpy = spyOn(sharedModule, "log")
|
||||||
|
logSpy.mockImplementation(() => {})
|
||||||
|
;({ scheduleDeferredModelOverride } = await importFreshUltraworkDbModelOverrideModule())
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(async () => {
|
||||||
|
await settleDeferredModelOverrideWork()
|
||||||
getDataDirSpy?.mockRestore()
|
getDataDirSpy?.mockRestore()
|
||||||
logSpy?.mockRestore()
|
logSpy?.mockRestore()
|
||||||
rmSync(tempDir, { recursive: true, force: true })
|
rmSync(tempDir, { recursive: true, force: true })
|
||||||
@@ -95,7 +110,6 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
insertMessage("msg_001", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
insertMessage("msg_001", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const { scheduleDeferredModelOverride } = await import("./ultrawork-db-model-override")
|
|
||||||
scheduleDeferredModelOverride(
|
scheduleDeferredModelOverride(
|
||||||
"msg_001",
|
"msg_001",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
@@ -112,7 +126,6 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
insertMessage("msg_002", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
insertMessage("msg_002", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const { scheduleDeferredModelOverride } = await import("./ultrawork-db-model-override")
|
|
||||||
scheduleDeferredModelOverride(
|
scheduleDeferredModelOverride(
|
||||||
"msg_002",
|
"msg_002",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
@@ -129,7 +142,6 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
//#given no message inserted
|
//#given no message inserted
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const { scheduleDeferredModelOverride } = await import("./ultrawork-db-model-override")
|
|
||||||
scheduleDeferredModelOverride(
|
scheduleDeferredModelOverride(
|
||||||
"msg_nonexistent",
|
"msg_nonexistent",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
@@ -148,7 +160,6 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
insertMessage("msg_003", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
insertMessage("msg_003", { providerID: "anthropic", modelID: "claude-sonnet-4-6" })
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const { scheduleDeferredModelOverride } = await import("./ultrawork-db-model-override")
|
|
||||||
scheduleDeferredModelOverride(
|
scheduleDeferredModelOverride(
|
||||||
"msg_003",
|
"msg_003",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
@@ -167,7 +178,6 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
getDataDirSpy.mockReturnValue("/nonexistent/path/that/does/not/exist")
|
getDataDirSpy.mockReturnValue("/nonexistent/path/that/does/not/exist")
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const { scheduleDeferredModelOverride } = await import("./ultrawork-db-model-override")
|
|
||||||
scheduleDeferredModelOverride(
|
scheduleDeferredModelOverride(
|
||||||
"msg_004",
|
"msg_004",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
@@ -188,7 +198,6 @@ describe("scheduleDeferredModelOverride", () => {
|
|||||||
chmodSync(corruptedDbPath, 0o000)
|
chmodSync(corruptedDbPath, 0o000)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const { scheduleDeferredModelOverride } = await import("./ultrawork-db-model-override")
|
|
||||||
scheduleDeferredModelOverride(
|
scheduleDeferredModelOverride(
|
||||||
"msg_corrupt",
|
"msg_corrupt",
|
||||||
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
{ providerID: "anthropic", modelID: "claude-opus-4-6" },
|
||||||
|
|||||||
@@ -1,14 +1,29 @@
|
|||||||
import { describe, expect, test, beforeEach, afterEach, spyOn } from "bun:test"
|
import { describe, expect, test, beforeEach, afterEach, spyOn } from "bun:test"
|
||||||
import {
|
|
||||||
applyUltraworkModelOverrideOnMessage,
|
|
||||||
resolveUltraworkOverride,
|
|
||||||
detectUltrawork,
|
|
||||||
} from "./ultrawork-model-override"
|
|
||||||
import * as sharedModule from "../shared"
|
import * as sharedModule from "../shared"
|
||||||
import * as dbOverrideModule from "./ultrawork-db-model-override"
|
import * as dbOverrideModule from "./ultrawork-db-model-override"
|
||||||
import * as sessionStateModule from "../features/claude-code-session-state"
|
import * as sessionStateModule from "../features/claude-code-session-state"
|
||||||
|
|
||||||
|
let resolveUltraworkOverride: (typeof import("./ultrawork-model-override"))["resolveUltraworkOverride"]
|
||||||
|
let detectUltrawork: (typeof import("./ultrawork-model-override"))["detectUltrawork"]
|
||||||
|
let applyUltraworkModelOverrideOnMessage: (typeof import("./ultrawork-model-override"))["applyUltraworkModelOverrideOnMessage"]
|
||||||
|
|
||||||
|
async function importFreshUltraworkModelOverrideModule(): Promise<typeof import("./ultrawork-model-override")> {
|
||||||
|
return import(`./ultrawork-model-override?test=${Date.now()}-${Math.random()}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadFreshUltraworkModelOverrideModule(): Promise<void> {
|
||||||
|
;({
|
||||||
|
resolveUltraworkOverride,
|
||||||
|
detectUltrawork,
|
||||||
|
applyUltraworkModelOverrideOnMessage,
|
||||||
|
} = await importFreshUltraworkModelOverrideModule())
|
||||||
|
}
|
||||||
|
|
||||||
describe("detectUltrawork", () => {
|
describe("detectUltrawork", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await loadFreshUltraworkModelOverrideModule()
|
||||||
|
})
|
||||||
|
|
||||||
test("should detect ultrawork keyword", () => {
|
test("should detect ultrawork keyword", () => {
|
||||||
expect(detectUltrawork("ultrawork do something")).toBe(true)
|
expect(detectUltrawork("ultrawork do something")).toBe(true)
|
||||||
})
|
})
|
||||||
@@ -41,6 +56,10 @@ describe("detectUltrawork", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("resolveUltraworkOverride", () => {
|
describe("resolveUltraworkOverride", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
await loadFreshUltraworkModelOverrideModule()
|
||||||
|
})
|
||||||
|
|
||||||
function createOutput(text: string, agentName?: string) {
|
function createOutput(text: string, agentName?: string) {
|
||||||
return {
|
return {
|
||||||
message: {
|
message: {
|
||||||
@@ -203,7 +222,8 @@ describe("resolveUltraworkOverride", () => {
|
|||||||
//#given
|
//#given
|
||||||
const config = createConfig("sisyphus", { model: "anthropic/claude-opus-4-6", variant: "max" })
|
const config = createConfig("sisyphus", { model: "anthropic/claude-opus-4-6", variant: "max" })
|
||||||
const output = createOutput("ultrawork do something")
|
const output = createOutput("ultrawork do something")
|
||||||
const getSessionAgentSpy = spyOn(sessionStateModule, "getSessionAgent").mockReturnValue("sisyphus")
|
const getSessionAgentSpy = spyOn(sessionStateModule, "getSessionAgent")
|
||||||
|
getSessionAgentSpy.mockReturnValue("sisyphus")
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const result = resolveUltraworkOverride(config, undefined, output, "ses_test")
|
const result = resolveUltraworkOverride(config, undefined, output, "ses_test")
|
||||||
@@ -220,9 +240,12 @@ describe("applyUltraworkModelOverrideOnMessage", () => {
|
|||||||
let logSpy: ReturnType<typeof spyOn>
|
let logSpy: ReturnType<typeof spyOn>
|
||||||
let dbOverrideSpy: ReturnType<typeof spyOn>
|
let dbOverrideSpy: ReturnType<typeof spyOn>
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
logSpy = spyOn(sharedModule, "log").mockImplementation(() => {})
|
logSpy = spyOn(sharedModule, "log")
|
||||||
dbOverrideSpy = spyOn(dbOverrideModule, "scheduleDeferredModelOverride").mockImplementation(() => {})
|
logSpy.mockImplementation(() => {})
|
||||||
|
dbOverrideSpy = spyOn(dbOverrideModule, "scheduleDeferredModelOverride")
|
||||||
|
dbOverrideSpy.mockImplementation(() => {})
|
||||||
|
await loadFreshUltraworkModelOverrideModule()
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user