|
|
@@ -1,10 +1,22 @@
|
|
|
-import { describe, expect, it } from "vitest"
|
|
|
+import { afterEach, describe, expect, it, vi } from "vitest"
|
|
|
+
|
|
|
+const invokeMock = vi.hoisted(() => vi.fn().mockResolvedValue(undefined))
|
|
|
+
|
|
|
+vi.mock("@tauri-apps/api/core", () => ({ invoke: invokeMock }))
|
|
|
+vi.mock("./platform", () => ({ isTauri: () => true }))
|
|
|
+
|
|
|
import {
|
|
|
formatReasoningReplayRiskForError,
|
|
|
isReasoningContentRequiredError,
|
|
|
+ logReasoningReplay,
|
|
|
summarizeReasoningReplayRisk,
|
|
|
} from "./reasoning-replay-debug"
|
|
|
|
|
|
+afterEach(() => {
|
|
|
+ invokeMock.mockClear()
|
|
|
+ vi.restoreAllMocks()
|
|
|
+})
|
|
|
+
|
|
|
describe("reasoning replay debug", () => {
|
|
|
it("detects the DeepSeek/Kimi reasoning_content 400 message", () => {
|
|
|
expect(isReasoningContentRequiredError(
|
|
|
@@ -42,4 +54,21 @@ describe("reasoning replay debug", () => {
|
|
|
expect(formatReasoningReplayRiskForError(summary)).toContain("missing=1")
|
|
|
expect(formatReasoningReplayRiskForError(summary)).toContain("reasoning=MISSING")
|
|
|
})
|
|
|
+
|
|
|
+ it("forwards collection diagnostics without using the frontend error channel", async () => {
|
|
|
+ vi.spyOn(console, "warn").mockImplementation(() => {})
|
|
|
+
|
|
|
+ logReasoningReplay("stream.collected", {
|
|
|
+ model: "deepseek/deepseek-v4-flash",
|
|
|
+ contentCharsEmitted: 499,
|
|
|
+ reasoningCharsObserved: 469,
|
|
|
+ })
|
|
|
+
|
|
|
+ await vi.waitFor(() => {
|
|
|
+ expect(invokeMock).toHaveBeenCalledWith("log_diagnostic", {
|
|
|
+ message: expect.stringContaining("[reasoning-replay] stream.collected"),
|
|
|
+ })
|
|
|
+ })
|
|
|
+ expect(invokeMock).not.toHaveBeenCalledWith("log_error", expect.anything())
|
|
|
+ })
|
|
|
})
|