ci: restore mock.module() overrides in afterAll to prevent cross-file pollution
Add afterAll hooks that restore original module implementations after mock.module() overrides. This prevents mock state from leaking across test files when bun runs them in the same process. Pattern: capture original module with await import() before mocking, restore in afterAll.
This commit is contained in:
parent
945329e261
commit
271929a9e4
@ -1,6 +1,10 @@
|
|||||||
import { afterEach, describe, expect, it, mock } from "bun:test"
|
import { afterEach, afterAll, describe, expect, it, mock } from "bun:test"
|
||||||
import type { DoctorResult } from "./types"
|
import type { DoctorResult } from "./types"
|
||||||
|
|
||||||
|
const realFormatDefault = await import("./format-default")
|
||||||
|
const realFormatStatus = await import("./format-status")
|
||||||
|
const realFormatVerbose = await import("./format-verbose")
|
||||||
|
|
||||||
function createDoctorResult(): DoctorResult {
|
function createDoctorResult(): DoctorResult {
|
||||||
return {
|
return {
|
||||||
results: [
|
results: [
|
||||||
@ -44,6 +48,12 @@ describe("formatter", () => {
|
|||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("./format-default", () => ({ ...realFormatDefault }))
|
||||||
|
mock.module("./format-status", () => ({ ...realFormatStatus }))
|
||||||
|
mock.module("./format-verbose", () => ({ ...realFormatVerbose }))
|
||||||
|
})
|
||||||
|
|
||||||
describe("formatDoctorOutput", () => {
|
describe("formatDoctorOutput", () => {
|
||||||
it("dispatches to default formatter for default mode", async () => {
|
it("dispatches to default formatter for default mode", async () => {
|
||||||
//#given
|
//#given
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
import { afterEach, describe, expect, it, mock } from "bun:test"
|
import { afterEach, afterAll, describe, expect, it, mock } from "bun:test"
|
||||||
import type { CheckDefinition, CheckResult, DoctorResult, SystemInfo, ToolsSummary } from "./types"
|
import type { CheckDefinition, CheckResult, DoctorResult, SystemInfo, ToolsSummary } from "./types"
|
||||||
|
|
||||||
|
const realChecks = await import("./checks")
|
||||||
|
const realFormatter = await import("./formatter")
|
||||||
|
|
||||||
function createSystemInfo(): SystemInfo {
|
function createSystemInfo(): SystemInfo {
|
||||||
return {
|
return {
|
||||||
opencodeVersion: "1.0.200",
|
opencodeVersion: "1.0.200",
|
||||||
@ -47,6 +50,11 @@ describe("runner", () => {
|
|||||||
mock.restore()
|
mock.restore()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("./checks", () => ({ ...realChecks }))
|
||||||
|
mock.module("./formatter", () => ({ ...realFormatter }))
|
||||||
|
})
|
||||||
|
|
||||||
describe("runCheck", () => {
|
describe("runCheck", () => {
|
||||||
it("returns fail result with issue when check throws", async () => {
|
it("returns fail result with issue when check throws", async () => {
|
||||||
//#given
|
//#given
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import { describe, it, expect, beforeEach, afterEach, mock } from "bun:test"
|
import { describe, it, expect, beforeEach, afterEach, afterAll, mock } from "bun:test"
|
||||||
|
|
||||||
|
const realMcpOauthProvider = await import("../../features/mcp-oauth/provider")
|
||||||
|
|
||||||
const mockLogin = mock(() => Promise.resolve({ accessToken: "test-token", expiresAt: 1710000000 }))
|
const mockLogin = mock(() => Promise.resolve({ accessToken: "test-token", expiresAt: 1710000000 }))
|
||||||
|
|
||||||
@ -11,6 +13,10 @@ mock.module("../../features/mcp-oauth/provider", () => ({
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("../../features/mcp-oauth/provider", () => ({ ...realMcpOauthProvider }))
|
||||||
|
})
|
||||||
|
|
||||||
const { login } = await import("./login")
|
const { login } = await import("./login")
|
||||||
|
|
||||||
describe("login command", () => {
|
describe("login command", () => {
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import { describe, it, expect, mock, spyOn, beforeEach, afterEach } from "bun:test"
|
import { describe, it, expect, mock, spyOn, beforeEach, afterEach, afterAll } from "bun:test"
|
||||||
import type { RunResult } from "./types"
|
import type { RunResult } from "./types"
|
||||||
import { createJsonOutputManager } from "./json-output"
|
import { createJsonOutputManager } from "./json-output"
|
||||||
import { resolveSession } from "./session-resolver"
|
import { resolveSession } from "./session-resolver"
|
||||||
import { executeOnCompleteHook } from "./on-complete-hook"
|
import { executeOnCompleteHook } from "./on-complete-hook"
|
||||||
import type { OpencodeClient } from "./types"
|
import type { OpencodeClient } from "./types"
|
||||||
|
|
||||||
|
const realSdk = await import("@opencode-ai/sdk")
|
||||||
|
const realPortUtils = await import("../../shared/port-utils")
|
||||||
|
|
||||||
const mockServerClose = mock(() => {})
|
const mockServerClose = mock(() => {})
|
||||||
const mockCreateOpencode = mock(() =>
|
const mockCreateOpencode = mock(() =>
|
||||||
Promise.resolve({
|
Promise.resolve({
|
||||||
@ -17,16 +20,23 @@ const mockIsPortAvailable = mock(() => Promise.resolve(true))
|
|||||||
const mockGetAvailableServerPort = mock(() => Promise.resolve({ port: 9999, wasAutoSelected: false }))
|
const mockGetAvailableServerPort = mock(() => Promise.resolve({ port: 9999, wasAutoSelected: false }))
|
||||||
|
|
||||||
mock.module("@opencode-ai/sdk", () => ({
|
mock.module("@opencode-ai/sdk", () => ({
|
||||||
|
...realSdk,
|
||||||
createOpencode: mockCreateOpencode,
|
createOpencode: mockCreateOpencode,
|
||||||
createOpencodeClient: mockCreateOpencodeClient,
|
createOpencodeClient: mockCreateOpencodeClient,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
mock.module("../../shared/port-utils", () => ({
|
mock.module("../../shared/port-utils", () => ({
|
||||||
|
...realPortUtils,
|
||||||
isPortAvailable: mockIsPortAvailable,
|
isPortAvailable: mockIsPortAvailable,
|
||||||
getAvailableServerPort: mockGetAvailableServerPort,
|
getAvailableServerPort: mockGetAvailableServerPort,
|
||||||
DEFAULT_SERVER_PORT: 4096,
|
DEFAULT_SERVER_PORT: 4096,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("@opencode-ai/sdk", () => ({ ...realSdk }))
|
||||||
|
mock.module("../../shared/port-utils", () => ({ ...realPortUtils }))
|
||||||
|
})
|
||||||
|
|
||||||
const { createServerConnection } = await import("./server-connection")
|
const { createServerConnection } = await import("./server-connection")
|
||||||
|
|
||||||
interface MockWriteStream {
|
interface MockWriteStream {
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
import { describe, it, expect, mock, beforeEach, afterEach } from "bun:test"
|
import { describe, it, expect, mock, beforeEach, afterEach, afterAll } from "bun:test"
|
||||||
|
|
||||||
|
const realSdk = await import("@opencode-ai/sdk")
|
||||||
|
const realPortUtils = await import("../../shared/port-utils")
|
||||||
|
|
||||||
const originalConsole = globalThis.console
|
const originalConsole = globalThis.console
|
||||||
|
|
||||||
@ -15,16 +18,23 @@ const mockGetAvailableServerPort = mock(() => Promise.resolve({ port: 4096, wasA
|
|||||||
const mockConsoleLog = mock(() => {})
|
const mockConsoleLog = mock(() => {})
|
||||||
|
|
||||||
mock.module("@opencode-ai/sdk", () => ({
|
mock.module("@opencode-ai/sdk", () => ({
|
||||||
|
...realSdk,
|
||||||
createOpencode: mockCreateOpencode,
|
createOpencode: mockCreateOpencode,
|
||||||
createOpencodeClient: mockCreateOpencodeClient,
|
createOpencodeClient: mockCreateOpencodeClient,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
mock.module("../../shared/port-utils", () => ({
|
mock.module("../../shared/port-utils", () => ({
|
||||||
|
...realPortUtils,
|
||||||
isPortAvailable: mockIsPortAvailable,
|
isPortAvailable: mockIsPortAvailable,
|
||||||
getAvailableServerPort: mockGetAvailableServerPort,
|
getAvailableServerPort: mockGetAvailableServerPort,
|
||||||
DEFAULT_SERVER_PORT: 4096,
|
DEFAULT_SERVER_PORT: 4096,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("@opencode-ai/sdk", () => ({ ...realSdk }))
|
||||||
|
mock.module("../../shared/port-utils", () => ({ ...realPortUtils }))
|
||||||
|
})
|
||||||
|
|
||||||
const { createServerConnection } = await import("./server-connection")
|
const { createServerConnection } = await import("./server-connection")
|
||||||
|
|
||||||
describe("createServerConnection", () => {
|
describe("createServerConnection", () => {
|
||||||
|
|||||||
@ -6,15 +6,20 @@ import { tmpdir } from "os"
|
|||||||
const TEST_DIR = join(tmpdir(), "mcp-loader-test-" + Date.now())
|
const TEST_DIR = join(tmpdir(), "mcp-loader-test-" + Date.now())
|
||||||
const TEST_HOME = join(TEST_DIR, "home")
|
const TEST_HOME = join(TEST_DIR, "home")
|
||||||
|
|
||||||
|
const realOs = await import("os")
|
||||||
|
const realShared = await import("../../shared")
|
||||||
|
|
||||||
describe("getSystemMcpServerNames", () => {
|
describe("getSystemMcpServerNames", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
mkdirSync(TEST_DIR, { recursive: true })
|
mkdirSync(TEST_DIR, { recursive: true })
|
||||||
mkdirSync(TEST_HOME, { recursive: true })
|
mkdirSync(TEST_HOME, { recursive: true })
|
||||||
mock.module("os", () => ({
|
mock.module("os", () => ({
|
||||||
|
...realOs,
|
||||||
homedir: () => TEST_HOME,
|
homedir: () => TEST_HOME,
|
||||||
tmpdir,
|
tmpdir,
|
||||||
}))
|
}))
|
||||||
mock.module("../../shared", () => ({
|
mock.module("../../shared", () => ({
|
||||||
|
...realShared,
|
||||||
getClaudeConfigDir: () => join(TEST_HOME, ".claude"),
|
getClaudeConfigDir: () => join(TEST_HOME, ".claude"),
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
@ -22,6 +27,9 @@ describe("getSystemMcpServerNames", () => {
|
|||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mock.restore()
|
mock.restore()
|
||||||
rmSync(TEST_DIR, { recursive: true, force: true })
|
rmSync(TEST_DIR, { recursive: true, force: true })
|
||||||
|
|
||||||
|
mock.module("os", () => ({ ...realOs }))
|
||||||
|
mock.module("../../shared", () => ({ ...realShared }))
|
||||||
})
|
})
|
||||||
|
|
||||||
it("returns empty set when no .mcp.json files exist", async () => {
|
it("returns empty set when no .mcp.json files exist", async () => {
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
import { describe, it, expect, beforeEach, afterEach, mock, spyOn } from "bun:test"
|
import { describe, it, expect, beforeEach, afterEach, mock, spyOn, afterAll } from "bun:test"
|
||||||
import { SkillMcpManager } from "./manager"
|
import { SkillMcpManager } from "./manager"
|
||||||
import type { SkillMcpClientInfo, SkillMcpServerContext } from "./types"
|
import type { SkillMcpClientInfo, SkillMcpServerContext } from "./types"
|
||||||
import type { ClaudeCodeMcpServer } from "../claude-code-mcp-loader/types"
|
import type { ClaudeCodeMcpServer } from "../claude-code-mcp-loader/types"
|
||||||
|
|
||||||
|
const realStreamableHttp = await import(
|
||||||
|
"@modelcontextprotocol/sdk/client/streamableHttp.js"
|
||||||
|
)
|
||||||
|
const realMcpOauthProvider = await import("../mcp-oauth/provider")
|
||||||
|
|
||||||
// Mock the MCP SDK transports to avoid network calls
|
// Mock the MCP SDK transports to avoid network calls
|
||||||
const mockHttpConnect = mock(() => Promise.reject(new Error("Mocked HTTP connection failure")))
|
const mockHttpConnect = mock(() => Promise.reject(new Error("Mocked HTTP connection failure")))
|
||||||
const mockHttpClose = mock(() => Promise.resolve())
|
const mockHttpClose = mock(() => Promise.resolve())
|
||||||
@ -37,6 +42,13 @@ mock.module("../mcp-oauth/provider", () => ({
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("@modelcontextprotocol/sdk/client/streamableHttp.js", () => ({
|
||||||
|
...realStreamableHttp,
|
||||||
|
}))
|
||||||
|
mock.module("../mcp-oauth/provider", () => ({ ...realMcpOauthProvider }))
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
import { describe, test, expect, mock, beforeEach } from 'bun:test'
|
import { describe, test, expect, mock, beforeEach, afterAll } from 'bun:test'
|
||||||
import type { TmuxConfig } from '../../config/schema'
|
import type { TmuxConfig } from '../../config/schema'
|
||||||
import type { WindowState, PaneAction } from './types'
|
import type { WindowState, PaneAction } from './types'
|
||||||
import type { ActionResult, ExecuteContext } from './action-executor'
|
import type { ActionResult, ExecuteContext } from './action-executor'
|
||||||
import type { TmuxUtilDeps } from './manager'
|
import type { TmuxUtilDeps } from './manager'
|
||||||
|
|
||||||
|
const realPaneStateQuerier = await import('./pane-state-querier')
|
||||||
|
const realActionExecutor = await import('./action-executor')
|
||||||
|
const realSharedTmux = await import('../../shared/tmux')
|
||||||
|
|
||||||
type ExecuteActionsResult = {
|
type ExecuteActionsResult = {
|
||||||
success: boolean
|
success: boolean
|
||||||
spawnedPaneId?: string
|
spawnedPaneId?: string
|
||||||
@ -71,6 +75,12 @@ mock.module('../../shared/tmux', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module('./pane-state-querier', () => ({ ...realPaneStateQuerier }))
|
||||||
|
mock.module('./action-executor', () => ({ ...realActionExecutor }))
|
||||||
|
mock.module('../../shared/tmux', () => ({ ...realSharedTmux }))
|
||||||
|
})
|
||||||
|
|
||||||
const trackedSessions = new Set<string>()
|
const trackedSessions = new Set<string>()
|
||||||
|
|
||||||
function createMockContext(overrides?: {
|
function createMockContext(overrides?: {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { describe, test, expect, mock, beforeEach } from "bun:test"
|
import { describe, test, expect, mock, beforeEach, afterAll } from "bun:test"
|
||||||
import { truncateUntilTargetTokens } from "./storage"
|
import { truncateUntilTargetTokens } from "./storage"
|
||||||
import * as storage from "./storage"
|
import * as storage from "./storage"
|
||||||
|
|
||||||
@ -11,6 +11,10 @@ mock.module("./storage", () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("./storage", () => ({ ...storage }))
|
||||||
|
})
|
||||||
|
|
||||||
describe("truncateUntilTargetTokens", () => {
|
describe("truncateUntilTargetTokens", () => {
|
||||||
const sessionID = "test-session"
|
const sessionID = "test-session"
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,11 @@
|
|||||||
import { describe, it, expect, mock, beforeEach } from "bun:test"
|
import { describe, it, expect, mock, beforeEach, afterAll } from "bun:test"
|
||||||
|
|
||||||
|
const realChecker = await import("../checker")
|
||||||
|
const realVersionChannel = await import("../version-channel")
|
||||||
|
const realCache = await import("../cache")
|
||||||
|
const realConfigManager = await import("../../../cli/config-manager")
|
||||||
|
const realUpdateToasts = await import("./update-toasts")
|
||||||
|
const realLogger = await import("../../../shared/logger")
|
||||||
|
|
||||||
// Mock modules before importing
|
// Mock modules before importing
|
||||||
const mockFindPluginEntry = mock(() => null as any)
|
const mockFindPluginEntry = mock(() => null as any)
|
||||||
@ -39,6 +46,15 @@ mock.module("../../../shared/logger", () => ({
|
|||||||
log: () => {},
|
log: () => {},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("../checker", () => ({ ...realChecker }))
|
||||||
|
mock.module("../version-channel", () => ({ ...realVersionChannel }))
|
||||||
|
mock.module("../cache", () => ({ ...realCache }))
|
||||||
|
mock.module("../../../cli/config-manager", () => ({ ...realConfigManager }))
|
||||||
|
mock.module("./update-toasts", () => ({ ...realUpdateToasts }))
|
||||||
|
mock.module("../../../shared/logger", () => ({ ...realLogger }))
|
||||||
|
})
|
||||||
|
|
||||||
const { runBackgroundUpdateCheck } = await import("./background-update-check")
|
const { runBackgroundUpdateCheck } = await import("./background-update-check")
|
||||||
|
|
||||||
describe("runBackgroundUpdateCheck", () => {
|
describe("runBackgroundUpdateCheck", () => {
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { describe, it, expect, mock, beforeEach } from "bun:test"
|
import { describe, it, expect, mock, beforeEach, afterAll } from "bun:test"
|
||||||
import type { ClaudeHooksConfig } from "./types"
|
import type { ClaudeHooksConfig } from "./types"
|
||||||
import type { StopContext } from "./stop"
|
import type { StopContext } from "./stop"
|
||||||
|
|
||||||
|
const realCommandExecutor = await import("../../shared/command-executor")
|
||||||
|
const realLogger = await import("../../shared/logger")
|
||||||
|
|
||||||
const mockExecuteHookCommand = mock(() =>
|
const mockExecuteHookCommand = mock(() =>
|
||||||
Promise.resolve({ exitCode: 0, stdout: "", stderr: "" })
|
Promise.resolve({ exitCode: 0, stdout: "", stderr: "" })
|
||||||
)
|
)
|
||||||
@ -17,6 +20,11 @@ mock.module("../../shared/logger", () => ({
|
|||||||
getLogFilePath: () => "/tmp/test.log",
|
getLogFilePath: () => "/tmp/test.log",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("../../shared/command-executor", () => ({ ...realCommandExecutor }))
|
||||||
|
mock.module("../../shared/logger", () => ({ ...realLogger }))
|
||||||
|
})
|
||||||
|
|
||||||
const { executeStopHooks } = await import("./stop")
|
const { executeStopHooks } = await import("./stop")
|
||||||
|
|
||||||
function createStopContext(overrides?: Partial<StopContext>): StopContext {
|
function createStopContext(overrides?: Partial<StopContext>): StopContext {
|
||||||
|
|||||||
@ -1,10 +1,19 @@
|
|||||||
import { describe, test, expect, mock } from "bun:test"
|
import { describe, test, expect, mock, afterAll } from "bun:test"
|
||||||
import { chmodSync, mkdtempSync, writeFileSync } from "node:fs"
|
import { chmodSync, mkdtempSync, writeFileSync } from "node:fs"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import { tmpdir } from "node:os"
|
import { tmpdir } from "node:os"
|
||||||
|
|
||||||
import type { PendingCall } from "./types"
|
import type { PendingCall } from "./types"
|
||||||
|
|
||||||
|
const realCli = await import("./cli")
|
||||||
|
const cliTsHref = new URL("./cli.ts", import.meta.url).href
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("./cli", () => ({ ...realCli }))
|
||||||
|
mock.module("./cli.ts", () => ({ ...realCli }))
|
||||||
|
mock.module(cliTsHref, () => ({ ...realCli }))
|
||||||
|
})
|
||||||
|
|
||||||
function createMockInput() {
|
function createMockInput() {
|
||||||
return {
|
return {
|
||||||
session_id: "test",
|
session_id: "test",
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import { describe, it, expect, mock, beforeEach } from "bun:test"
|
import { describe, it, expect, mock, beforeEach, afterAll } from "bun:test"
|
||||||
|
|
||||||
|
const realCliRunner = await import("./cli-runner")
|
||||||
|
|
||||||
const processApplyPatchEditsWithCli = mock(async () => {})
|
const processApplyPatchEditsWithCli = mock(async () => {})
|
||||||
|
|
||||||
@ -10,6 +12,10 @@ mock.module("./cli-runner", () => ({
|
|||||||
processApplyPatchEditsWithCli,
|
processApplyPatchEditsWithCli,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("./cli-runner", () => ({ ...realCliRunner }))
|
||||||
|
})
|
||||||
|
|
||||||
const { createCommentCheckerHooks } = await import("./hook")
|
const { createCommentCheckerHooks } = await import("./hook")
|
||||||
|
|
||||||
describe("comment-checker apply_patch integration", () => {
|
describe("comment-checker apply_patch integration", () => {
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
import { describe, expect, it, mock } from "bun:test"
|
import { describe, expect, it, mock, afterAll } from "bun:test"
|
||||||
|
|
||||||
|
const realSystemDirective = await import("../../shared/system-directive")
|
||||||
|
|
||||||
mock.module("../../shared/system-directive", () => ({
|
mock.module("../../shared/system-directive", () => ({
|
||||||
createSystemDirective: (type: string) => `[DIRECTIVE:${type}]`,
|
createSystemDirective: (type: string) => `[DIRECTIVE:${type}]`,
|
||||||
@ -14,6 +16,10 @@ mock.module("../../shared/system-directive", () => ({
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("../../shared/system-directive", () => ({ ...realSystemDirective }))
|
||||||
|
})
|
||||||
|
|
||||||
import { createCompactionContextInjector } from "./index"
|
import { createCompactionContextInjector } from "./index"
|
||||||
import { TaskHistory } from "../../features/background-agent/task-history"
|
import { TaskHistory } from "../../features/background-agent/task-history"
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, it, mock } from "bun:test";
|
import { afterEach, beforeEach, describe, expect, it, mock, afterAll } from "bun:test";
|
||||||
import * as fs from "node:fs";
|
import * as fs from "node:fs";
|
||||||
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
||||||
import * as os from "node:os";
|
import * as os from "node:os";
|
||||||
@ -6,6 +6,10 @@ import { tmpdir } from "node:os";
|
|||||||
import { join } from "node:path";
|
import { join } from "node:path";
|
||||||
import { RULES_INJECTOR_STORAGE } from "./constants";
|
import { RULES_INJECTOR_STORAGE } from "./constants";
|
||||||
|
|
||||||
|
const realNodeFs = await import("node:fs");
|
||||||
|
const realNodeOs = await import("node:os");
|
||||||
|
const realMatcher = await import("./matcher");
|
||||||
|
|
||||||
type StatSnapshot = { mtimeMs: number; size: number };
|
type StatSnapshot = { mtimeMs: number; size: number };
|
||||||
|
|
||||||
let trackedRulePath = "";
|
let trackedRulePath = "";
|
||||||
@ -56,6 +60,12 @@ mock.module("./matcher", () => ({
|
|||||||
isDuplicateByContentHash: (hash: string, cache: Set<string>) => cache.has(hash),
|
isDuplicateByContentHash: (hash: string, cache: Set<string>) => cache.has(hash),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("node:fs", () => ({ ...realNodeFs }));
|
||||||
|
mock.module("node:os", () => ({ ...realNodeOs }));
|
||||||
|
mock.module("./matcher", () => ({ ...realMatcher }));
|
||||||
|
});
|
||||||
|
|
||||||
function createOutput(): { title: string; output: string; metadata: unknown } {
|
function createOutput(): { title: string; output: string; metadata: unknown } {
|
||||||
return { title: "tool", output: "", metadata: {} };
|
return { title: "tool", output: "", metadata: {} };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,9 @@ import { mkdtempSync, rmSync, writeFileSync } from "node:fs"
|
|||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import { tmpdir } from "node:os"
|
import { tmpdir } from "node:os"
|
||||||
|
|
||||||
import { describe, it, expect, spyOn, mock, beforeEach, afterEach } from "bun:test"
|
import { describe, it, expect, spyOn, mock, beforeEach, afterEach, afterAll } from "bun:test"
|
||||||
|
|
||||||
|
const realJsonRpcNode = await import("vscode-jsonrpc/node")
|
||||||
|
|
||||||
mock.module("vscode-jsonrpc/node", () => ({
|
mock.module("vscode-jsonrpc/node", () => ({
|
||||||
createMessageConnection: () => {
|
createMessageConnection: () => {
|
||||||
@ -12,6 +14,10 @@ mock.module("vscode-jsonrpc/node", () => ({
|
|||||||
StreamMessageWriter: function StreamMessageWriter() {},
|
StreamMessageWriter: function StreamMessageWriter() {},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("vscode-jsonrpc/node", () => ({ ...realJsonRpcNode }))
|
||||||
|
})
|
||||||
|
|
||||||
import { LSPClient, lspManager, validateCwd } from "./client"
|
import { LSPClient, lspManager, validateCwd } from "./client"
|
||||||
import type { ResolvedServer } from "./types"
|
import type { ResolvedServer } from "./types"
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import { describe, test, expect, beforeEach, afterEach, mock } from "bun:test"
|
import { describe, test, expect, beforeEach, afterEach, afterAll, mock } from "bun:test"
|
||||||
import { mkdirSync, writeFileSync, rmSync, existsSync } from "node:fs"
|
import { mkdirSync, writeFileSync, rmSync, existsSync } from "node:fs"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import { tmpdir } from "node:os"
|
import { tmpdir } from "node:os"
|
||||||
import { randomUUID } from "node:crypto"
|
import { randomUUID } from "node:crypto"
|
||||||
|
|
||||||
|
const realConstants = await import("./constants")
|
||||||
|
|
||||||
const TEST_DIR = join(tmpdir(), `omo-test-session-manager-${randomUUID()}`)
|
const TEST_DIR = join(tmpdir(), `omo-test-session-manager-${randomUUID()}`)
|
||||||
const TEST_MESSAGE_STORAGE = join(TEST_DIR, "message")
|
const TEST_MESSAGE_STORAGE = join(TEST_DIR, "message")
|
||||||
const TEST_PART_STORAGE = join(TEST_DIR, "part")
|
const TEST_PART_STORAGE = join(TEST_DIR, "part")
|
||||||
@ -26,6 +28,10 @@ mock.module("./constants", () => ({
|
|||||||
TOOL_NAME_PREFIX: "session_",
|
TOOL_NAME_PREFIX: "session_",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("./constants", () => ({ ...realConstants }))
|
||||||
|
})
|
||||||
|
|
||||||
const { getAllSessions, getMessageDir, sessionExists, readSessionMessages, readSessionTodos, getSessionInfo } =
|
const { getAllSessions, getMessageDir, sessionExists, readSessionMessages, readSessionTodos, getSessionInfo } =
|
||||||
await import("./storage")
|
await import("./storage")
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { describe, it, expect, beforeEach, mock, spyOn } from "bun:test"
|
import { describe, it, expect, beforeEach, mock, spyOn, afterAll } from "bun:test"
|
||||||
import type { ToolContext } from "@opencode-ai/plugin/tool"
|
import type { ToolContext } from "@opencode-ai/plugin/tool"
|
||||||
import * as fs from "node:fs"
|
import * as fs from "node:fs"
|
||||||
import { createSkillTool } from "./tools"
|
import { createSkillTool } from "./tools"
|
||||||
@ -8,6 +8,8 @@ import type { Tool as McpTool } from "@modelcontextprotocol/sdk/types.js"
|
|||||||
|
|
||||||
const originalReadFileSync = fs.readFileSync.bind(fs)
|
const originalReadFileSync = fs.readFileSync.bind(fs)
|
||||||
|
|
||||||
|
const realNodeFs = await import("node:fs")
|
||||||
|
|
||||||
mock.module("node:fs", () => ({
|
mock.module("node:fs", () => ({
|
||||||
...fs,
|
...fs,
|
||||||
readFileSync: (path: string, encoding?: string) => {
|
readFileSync: (path: string, encoding?: string) => {
|
||||||
@ -21,6 +23,10 @@ Test skill body content`
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
mock.module("node:fs", () => ({ ...realNodeFs }))
|
||||||
|
})
|
||||||
|
|
||||||
function createMockSkill(name: string, options: { agent?: string } = {}): LoadedSkill {
|
function createMockSkill(name: string, options: { agent?: string } = {}): LoadedSkill {
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user