import { describe, expect, it, vi } from "vitest"; import { InteractiveMode } from "../../../src/modes/interactive/interactive-mode.ts"; type RebindContext = { session: object; unsubscribe?: () => void; applyRuntimeSettings: () => void; renderCurrentSessionState: () => void; bindCurrentSessionExtensions: () => Promise; subscribeToAgent: () => void; updateAvailableProviderCount: () => Promise; updateEditorBorderColor: () => void; updateTerminalTitle: () => void; }; type InteractiveModePrototype = { rebindCurrentSession(this: RebindContext, options?: { renderBeforeBind?: boolean }): Promise; }; const interactiveModePrototype = InteractiveMode.prototype as unknown as InteractiveModePrototype; describe("overlapping startup and replacement session rebinds", () => { it("does not subscribe from the stale startup rebind", async () => { const startupSession = {}; const replacementSession = {}; let resolveStartupBind!: () => void; let resolveReplacementBind!: () => void; const startupBind = new Promise((resolve) => { resolveStartupBind = resolve; }); const replacementBind = new Promise((resolve) => { resolveReplacementBind = resolve; }); const subscribeToAgent = vi.fn(); const updateTerminalTitle = vi.fn(); let bindCount = 0; const context: RebindContext = { session: startupSession, applyRuntimeSettings: () => {}, renderCurrentSessionState: () => {}, bindCurrentSessionExtensions: () => { bindCount += 1; return bindCount === 1 ? startupBind : replacementBind; }, subscribeToAgent, updateAvailableProviderCount: async () => {}, updateEditorBorderColor: () => {}, updateTerminalTitle, }; const startupRebind = interactiveModePrototype.rebindCurrentSession.call(context); expect(bindCount).toBe(1); context.session = replacementSession; const replacementRebind = interactiveModePrototype.rebindCurrentSession.call(context, { renderBeforeBind: true, }); expect(bindCount).toBe(2); expect(subscribeToAgent).toHaveBeenCalledTimes(1); resolveStartupBind(); await startupRebind; expect(subscribeToAgent).toHaveBeenCalledTimes(1); expect(updateTerminalTitle).not.toHaveBeenCalled(); resolveReplacementBind(); await replacementRebind; expect(subscribeToAgent).toHaveBeenCalledTimes(1); expect(updateTerminalTitle).toHaveBeenCalledTimes(1); }); });