Skip to content

Commit 96f175d

Browse files
committed
test: simplify Vitest 4 mock typings
1 parent c3ba738 commit 96f175d

4 files changed

Lines changed: 172 additions & 167 deletions

File tree

packages/cloud/src/__mocks__/vscode.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
type VscodeWindowMock = {
2-
showInformationMessage: (message: string) => void
3-
showErrorMessage: (message: string) => void
4-
}
1+
import type * as vscode from "vscode"
52

6-
type VscodeEnvMock = {
7-
openExternal: (uri: unknown) => Promise<void>
8-
}
3+
type VscodeWindowMock = Pick<typeof vscode.window, "showInformationMessage" | "showErrorMessage">
94

10-
type VscodeCommandsMock = {
11-
executeCommand: (command: string, ...args: unknown[]) => Promise<unknown>
12-
}
5+
type VscodeEnvMock = Pick<typeof vscode.env, "openExternal">
6+
7+
type VscodeCommandsMock = Pick<typeof vscode.commands, "executeCommand">
138

149
export const window: VscodeWindowMock = {
1510
showInformationMessage: vi.fn(),

packages/cloud/src/__tests__/CloudSettingsService.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ExtensionContext } from "vscode"
22
import type { Mock } from "vitest"
33

4-
import type { OrganizationSettings, AuthService } from "@roo-code/types"
4+
import type { OrganizationSettings, AuthService, AuthServiceEvents } from "@roo-code/types"
55

66
import { CloudSettingsService } from "../CloudSettingsService.js"
77
import { RefreshTimer } from "../RefreshTimer.js"
@@ -14,14 +14,14 @@ vi.mock("../config", () => ({
1414

1515
global.fetch = vi.fn()
1616

17-
type AuthStateChangedListener = (data: unknown) => unknown
17+
type AuthStateChangedListener = (data: AuthServiceEvents["auth-state-changed"][0]) => unknown
1818

1919
describe("CloudSettingsService", () => {
2020
let mockContext: ExtensionContext
2121
let mockAuthService: {
22-
getState: Mock<() => string>
22+
getState: Mock<AuthService["getState"]>
2323
getSessionToken: Mock<() => string | undefined | null>
24-
hasActiveSession: Mock<() => boolean>
24+
hasActiveSession: Mock<AuthService["hasActiveSession"]>
2525
on: Mock<(event: string, listener: AuthStateChangedListener) => void>
2626
getStoredOrganizationId: Mock<() => string | null>
2727
}

src/api/providers/__tests__/deepseek.spec.ts

Lines changed: 104 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,128 @@
11
// Mocks must come first, before imports
2-
const mockCreate = vi.fn()
2+
const { mockCreate, constructorMock } = vi.hoisted(() => ({
3+
mockCreate: vi.fn(),
4+
constructorMock: <T>(factory: () => T) =>
5+
vi.fn().mockImplementation(function () {
6+
return factory()
7+
}),
8+
}))
9+
310
vi.mock("openai", () => {
411
return {
512
__esModule: true,
6-
default: vi.fn().mockImplementation(function () {
7-
return {
8-
chat: {
9-
completions: {
10-
create: mockCreate.mockImplementation(async (options) => {
11-
if (!options.stream) {
12-
return {
13-
id: "test-completion",
14-
choices: [
15-
{
16-
message: { role: "assistant", content: "Test response", refusal: null },
17-
finish_reason: "stop",
18-
index: 0,
19-
},
20-
],
21-
usage: {
22-
prompt_tokens: 10,
23-
completion_tokens: 5,
24-
total_tokens: 15,
25-
prompt_tokens_details: {
26-
cache_miss_tokens: 8,
27-
cached_tokens: 2,
28-
},
13+
default: constructorMock(() => ({
14+
chat: {
15+
completions: {
16+
create: mockCreate.mockImplementation(async (options) => {
17+
if (!options.stream) {
18+
return {
19+
id: "test-completion",
20+
choices: [
21+
{
22+
message: { role: "assistant", content: "Test response", refusal: null },
23+
finish_reason: "stop",
24+
index: 0,
2925
},
30-
}
26+
],
27+
usage: {
28+
prompt_tokens: 10,
29+
completion_tokens: 5,
30+
total_tokens: 15,
31+
prompt_tokens_details: {
32+
cache_miss_tokens: 8,
33+
cached_tokens: 2,
34+
},
35+
},
3136
}
37+
}
3238

33-
// Check if this is a reasoning_content test by looking at thinking mode
34-
const isThinkingModel = options.thinking?.type === "enabled"
35-
const isToolCallTest = options.tools?.length > 0
39+
// Check if this is a reasoning_content test by looking at thinking mode
40+
const isThinkingModel = options.thinking?.type === "enabled"
41+
const isToolCallTest = options.tools?.length > 0
3642

37-
// Return async iterator for streaming
38-
return {
39-
[Symbol.asyncIterator]: async function* () {
40-
// For thinking models, emit reasoning_content first
41-
if (isThinkingModel) {
42-
yield {
43-
choices: [
44-
{
45-
delta: { reasoning_content: "Let me think about this..." },
46-
index: 0,
47-
},
48-
],
49-
usage: null,
50-
}
51-
yield {
52-
choices: [
53-
{
54-
delta: { reasoning_content: " I'll analyze step by step." },
55-
index: 0,
56-
},
57-
],
58-
usage: null,
59-
}
43+
// Return async iterator for streaming
44+
return {
45+
[Symbol.asyncIterator]: async function* () {
46+
// For thinking models, emit reasoning_content first
47+
if (isThinkingModel) {
48+
yield {
49+
choices: [
50+
{
51+
delta: { reasoning_content: "Let me think about this..." },
52+
index: 0,
53+
},
54+
],
55+
usage: null,
56+
}
57+
yield {
58+
choices: [
59+
{
60+
delta: { reasoning_content: " I'll analyze step by step." },
61+
index: 0,
62+
},
63+
],
64+
usage: null,
6065
}
66+
}
6167

62-
// For tool call tests with thinking mode, emit tool call
63-
if (isThinkingModel && isToolCallTest) {
64-
yield {
65-
choices: [
66-
{
67-
delta: {
68-
tool_calls: [
69-
{
70-
index: 0,
71-
id: "call_123",
72-
function: {
73-
name: "get_weather",
74-
arguments: '{"location":"SF"}',
75-
},
68+
// For tool call tests with thinking mode, emit tool call
69+
if (isThinkingModel && isToolCallTest) {
70+
yield {
71+
choices: [
72+
{
73+
delta: {
74+
tool_calls: [
75+
{
76+
index: 0,
77+
id: "call_123",
78+
function: {
79+
name: "get_weather",
80+
arguments: '{"location":"SF"}',
7681
},
77-
],
78-
},
79-
index: 0,
80-
},
81-
],
82-
usage: null,
83-
}
84-
} else {
85-
yield {
86-
choices: [
87-
{
88-
delta: { content: "Test response" },
89-
index: 0,
82+
},
83+
],
9084
},
91-
],
92-
usage: null,
93-
}
85+
index: 0,
86+
},
87+
],
88+
usage: null,
9489
}
95-
90+
} else {
9691
yield {
9792
choices: [
9893
{
99-
delta: {},
94+
delta: { content: "Test response" },
10095
index: 0,
101-
finish_reason: isToolCallTest ? "tool_calls" : "stop",
10296
},
10397
],
104-
usage: {
105-
prompt_tokens: 10,
106-
completion_tokens: 5,
107-
total_tokens: 15,
108-
prompt_tokens_details: {
109-
cache_miss_tokens: 8,
110-
cached_tokens: 2,
111-
},
112-
},
98+
usage: null,
11399
}
114-
},
115-
}
116-
}),
117-
},
100+
}
101+
102+
yield {
103+
choices: [
104+
{
105+
delta: {},
106+
index: 0,
107+
finish_reason: isToolCallTest ? "tool_calls" : "stop",
108+
},
109+
],
110+
usage: {
111+
prompt_tokens: 10,
112+
completion_tokens: 5,
113+
total_tokens: 15,
114+
prompt_tokens_details: {
115+
cache_miss_tokens: 8,
116+
cached_tokens: 2,
117+
},
118+
},
119+
}
120+
},
121+
}
122+
}),
118123
},
119-
}
120-
}),
124+
},
125+
})),
121126
}
122127
})
123128

0 commit comments

Comments
 (0)