fix(ci): resolve mock.module() cross-file leakage in test suite

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-04 02:35:23 +09:00
parent 673b107f53
commit 6acca09bd0
15 changed files with 130 additions and 66 deletions
@@ -1,13 +1,19 @@
import { afterAll, describe, expect, it, mock } from "bun:test"
import { afterEach, describe, expect, it, spyOn } from "bun:test"
import type { LoadedSkill } from "../../features/opencode-skill-loader"
import * as shared from "../../shared"
import * as slashcommand from "../../tools/slashcommand"
import { executeSlashCommand } from "./executor"
mock.module("../../shared", () => ({
resolveCommandsInText: async (content: string) => content,
resolveFileReferencesInText: async (content: string) => content,
}))
let resolveCommandsInTextSpy: { mockRestore: () => void } | undefined
let resolveFileReferencesInTextSpy: { mockRestore: () => void } | undefined
let discoverCommandsSyncSpy: { mockRestore: () => void } | undefined
mock.module("../../tools/slashcommand", () => ({
discoverCommandsSync: () => [
function setupExecutorSpies(): void {
resolveCommandsInTextSpy = spyOn(shared, "resolveCommandsInText")
.mockImplementation(async (content: string) => content)
resolveFileReferencesInTextSpy = spyOn(shared, "resolveFileReferencesInText")
.mockImplementation(async (content: string) => content)
discoverCommandsSyncSpy = spyOn(slashcommand, "discoverCommandsSync").mockReturnValue([
{
name: "shadowed",
metadata: { name: "shadowed", description: "builtin" },
@@ -20,18 +26,19 @@ mock.module("../../tools/slashcommand", () => ({
content: "project template",
scope: "project",
},
],
}))
])
}
mock.module("../../features/opencode-skill-loader", () => ({
discoverAllSkills: async (): Promise<LoadedSkill[]> => [],
}))
function restoreExecutorSpies(): void {
resolveCommandsInTextSpy?.mockRestore()
resolveFileReferencesInTextSpy?.mockRestore()
discoverCommandsSyncSpy?.mockRestore()
resolveCommandsInTextSpy = undefined
resolveFileReferencesInTextSpy = undefined
discoverCommandsSyncSpy = undefined
}
afterAll(() => {
mock.restore()
})
const { executeSlashCommand } = await import("./executor")
afterEach(restoreExecutorSpies)
function createRestrictedSkill(): LoadedSkill {
return {
@@ -49,6 +56,7 @@ function createRestrictedSkill(): LoadedSkill {
describe("executeSlashCommand resolution semantics", () => {
it("returns project command when project and builtin names collide", async () => {
//#given
setupExecutorSpies()
const parsed = {
command: "shadowed",
args: "",
@@ -67,6 +75,7 @@ describe("executeSlashCommand resolution semantics", () => {
it("blocks slash skill invocation when invoking agent is missing", async () => {
//#given
setupExecutorSpies()
const parsed = {
command: "restricted-skill",
args: "",
@@ -83,6 +92,7 @@ describe("executeSlashCommand resolution semantics", () => {
it("allows slash skill invocation when invoking agent matches restriction", async () => {
//#given
setupExecutorSpies()
const parsed = {
command: "restricted-skill",
args: "",