Skip to content

Commit 2f26e3b

Browse files
committed
test: make constructor mocks constructable
1 parent 96f175d commit 2f26e3b

151 files changed

Lines changed: 2611 additions & 1925 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,21 @@ describe("CloudService", () => {
147147
backfillMessages: vi.fn().mockResolvedValue(undefined),
148148
}
149149

150-
vi.mocked(WebAuthService).mockImplementation(() => mockAuthService as unknown as WebAuthService)
150+
vi.mocked(WebAuthService).mockImplementation(function () {
151+
return mockAuthService as unknown as WebAuthService
152+
})
151153

152-
vi.mocked(CloudSettingsService).mockImplementation(() => mockSettingsService as unknown as CloudSettingsService)
154+
vi.mocked(CloudSettingsService).mockImplementation(function () {
155+
return mockSettingsService as unknown as CloudSettingsService
156+
})
153157

154-
vi.mocked(CloudShareService).mockImplementation(() => mockShareService as unknown as CloudShareService)
158+
vi.mocked(CloudShareService).mockImplementation(function () {
159+
return mockShareService as unknown as CloudShareService
160+
})
155161

156-
vi.mocked(TelemetryClient).mockImplementation(() => mockTelemetryClient as unknown as TelemetryClient)
162+
vi.mocked(TelemetryClient).mockImplementation(function () {
163+
return mockTelemetryClient as unknown as TelemetryClient
164+
})
157165
})
158166

159167
afterEach(() => {
@@ -417,7 +425,9 @@ describe("CloudService", () => {
417425
})
418426

419427
// Override the mock to return our properly typed instance
420-
vi.mocked(CloudSettingsService).mockImplementation(() => mockCloudSettingsService)
428+
vi.mocked(CloudSettingsService).mockImplementation(function () {
429+
return mockCloudSettingsService
430+
})
421431

422432
const cloudService = await CloudService.createInstance(mockContext)
423433

@@ -450,9 +460,9 @@ describe("CloudService", () => {
450460
}
451461

452462
// Override the mock to return a service that won't pass instanceof check
453-
vi.mocked(CloudSettingsService).mockImplementation(
454-
() => mockStaticSettingsService as unknown as CloudSettingsService,
455-
)
463+
vi.mocked(CloudSettingsService).mockImplementation(function () {
464+
return mockStaticSettingsService as unknown as CloudSettingsService
465+
})
456466

457467
// This should not throw even though the service doesn't pass instanceof check
458468
const _cloudService = await CloudService.createInstance(mockContext)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ describe("CloudShareService", () => {
302302
})
303303

304304
it("should handle errors gracefully", async () => {
305-
;(mockSettingsService.getSettings as any).mockImplementation(() => {
305+
;(mockSettingsService.getSettings as any).mockImplementation(function () {
306306
throw new Error("Settings error")
307307
})
308308

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe("StaticSettingsService", () => {
8181
})
8282

8383
it("should use console.log as default logger for errors", () => {
84-
const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => {})
84+
const consoleSpy = vi.spyOn(console, "log").mockImplementation(function () {})
8585
expect(() => new StaticSettingsService("invalid-base64!@#")).toThrow()
8686

8787
expect(consoleSpy).toHaveBeenCalledWith(

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ describe("TelemetryClient", () => {
5050
json: vi.fn().mockResolvedValue({}),
5151
})
5252

53-
vi.spyOn(console, "info").mockImplementation(() => {})
54-
vi.spyOn(console, "error").mockImplementation(() => {})
53+
vi.spyOn(console, "info").mockImplementation(function () {})
54+
vi.spyOn(console, "error").mockImplementation(function () {})
5555
})
5656

5757
afterEach(() => {

packages/cloud/src/__tests__/WebAuthService.spec.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ describe("WebAuthService", () => {
9797
reset: vi.fn(),
9898
}
9999
const MockedRefreshTimer = vi.mocked(RefreshTimer)
100-
MockedRefreshTimer.mockImplementation(() => mockTimer as unknown as RefreshTimer)
100+
MockedRefreshTimer.mockImplementation(function () {
101+
return mockTimer as unknown as RefreshTimer
102+
})
101103

102104
// Setup config mocks - use production URL by default to maintain existing test behavior
103105
vi.mocked(getClerkBaseUrl).mockReturnValue("https://clerk.roocode.com")
@@ -211,7 +213,7 @@ describe("WebAuthService", () => {
211213
it("should handle credentials change events", async () => {
212214
let onDidChangeCallback: (e: { key: string }) => void
213215

214-
mockContext.secrets.onDidChange.mockImplementation((callback: (e: { key: string }) => void) => {
216+
mockContext.secrets.onDidChange.mockImplementation(function (callback: (e: { key: string }) => void) {
215217
onDidChangeCallback = callback
216218
return { dispose: vi.fn() }
217219
})
@@ -302,7 +304,7 @@ describe("WebAuthService", () => {
302304
})
303305

304306
it("should handle errors during login", async () => {
305-
vi.mocked(crypto.randomBytes).mockImplementation(() => {
307+
vi.mocked(crypto.randomBytes).mockImplementation(function () {
306308
throw new Error("Crypto error")
307309
})
308310

@@ -1190,7 +1192,7 @@ describe("WebAuthService", () => {
11901192

11911193
let onDidChangeCallback: (e: { key: string }) => void
11921194

1193-
mockContext.secrets.onDidChange.mockImplementation((callback: (e: { key: string }) => void) => {
1195+
mockContext.secrets.onDidChange.mockImplementation(function (callback: (e: { key: string }) => void) {
11941196
onDidChangeCallback = callback
11951197
return { dispose: vi.fn() }
11961198
})
@@ -1220,7 +1222,7 @@ describe("WebAuthService", () => {
12201222

12211223
let onDidChangeCallback: (e: { key: string }) => void
12221224

1223-
mockContext.secrets.onDidChange.mockImplementation((callback: (e: { key: string }) => void) => {
1225+
mockContext.secrets.onDidChange.mockImplementation(function (callback: (e: { key: string }) => void) {
12241226
onDidChangeCallback = callback
12251227
return { dispose: vi.fn() }
12261228
})
@@ -1246,7 +1248,7 @@ describe("WebAuthService", () => {
12461248

12471249
let onDidChangeCallback: (e: { key: string }) => void
12481250

1249-
mockContext.secrets.onDidChange.mockImplementation((callback: (e: { key: string }) => void) => {
1251+
mockContext.secrets.onDidChange.mockImplementation(function (callback: (e: { key: string }) => void) {
12501252
onDidChangeCallback = callback
12511253
return { dispose: vi.fn() }
12521254
})

packages/cloud/src/retry-queue/__tests__/RetryQueue.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,9 @@ describe("RetryQueue", () => {
403403
await retryQueue.enqueue("https://api.example.com/test", { method: "POST" }, "telemetry")
404404

405405
// Mock a slow response
406-
fetchMock.mockImplementation(() => new Promise((resolve) => setTimeout(() => resolve({ ok: true }), 100)))
406+
fetchMock.mockImplementation(function () {
407+
return new Promise((resolve) => setTimeout(() => resolve({ ok: true }), 100))
408+
})
407409

408410
// Start first retryAll (don't await)
409411
const firstCall = retryQueue.retryAll()

src/__tests__/extension.spec.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,17 +158,21 @@ vi.mock("../utils/autoImportSettings", () => ({
158158
}))
159159

160160
vi.mock("../extension/api", () => ({
161-
API: vi.fn().mockImplementation(() => ({})),
161+
API: vi.fn().mockImplementation(function () {
162+
return {}
163+
}),
162164
}))
163165

164166
vi.mock("../activate", () => ({
165167
handleUri: vi.fn(),
166168
registerCommands: vi.fn(),
167169
registerCodeActions: vi.fn(),
168170
registerTerminalActions: vi.fn(),
169-
CodeActionProvider: vi.fn().mockImplementation(() => ({
170-
providedCodeActionKinds: [],
171-
})),
171+
CodeActionProvider: vi.fn().mockImplementation(function () {
172+
return {
173+
providedCodeActionKinds: [],
174+
}
175+
}),
172176
}))
173177

174178
vi.mock("../i18n", () => ({
@@ -192,7 +196,9 @@ vi.mock("../core/webview/ClineProvider", async () => {
192196
}
193197
return {
194198
ClineProvider: Object.assign(
195-
vi.fn().mockImplementation(() => mockInstance),
199+
vi.fn().mockImplementation(function () {
200+
return mockInstance
201+
}),
196202
{
197203
// Static method used by extension.ts
198204
getVisibleInstance: vi.fn().mockReturnValue(mockInstance),
@@ -270,7 +276,7 @@ describe("extension.ts", () => {
270276
const { CloudService } = await import("@roo-code/cloud")
271277
const { ClineProvider } = await import("../core/webview/ClineProvider")
272278

273-
vi.mocked(CloudService.createInstance).mockImplementation(async (_context, _logger, handlers) => {
279+
vi.mocked(CloudService.createInstance).mockImplementation(async function (_context, _logger, handlers) {
274280
if (handlers?.["auth-state-changed"]) {
275281
authStateChangedHandler = handlers["auth-state-changed"]
276282
}

src/__tests__/history-resume-delegation.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ describe("History resume delegation - parent metadata transitions", () => {
457457

458458
const provider = {
459459
contextProxy: { globalStorageUri: { fsPath: "/tmp" } },
460-
getTaskWithId: vi.fn().mockImplementation(async (id: string) => {
460+
getTaskWithId: vi.fn().mockImplementation(async function (id: string) {
461461
if (id === "parent-rpd06") {
462462
return {
463463
historyItem: {
@@ -580,7 +580,7 @@ describe("History resume delegation - parent metadata transitions", () => {
580580

581581
const provider = {
582582
contextProxy: { globalStorageUri: { fsPath: "/tmp" } },
583-
getTaskWithId: vi.fn().mockImplementation(async (id: string) => {
583+
getTaskWithId: vi.fn().mockImplementation(async function (id: string) {
584584
if (id === "parent-rpd02") {
585585
return {
586586
historyItem: {
@@ -651,7 +651,7 @@ describe("History resume delegation - parent metadata transitions", () => {
651651
overwriteApiConversationHistory: vi.fn().mockResolvedValue(undefined),
652652
}
653653

654-
const updateTaskHistory = vi.fn().mockImplementation(async (historyItem: { id?: string }) => {
654+
const updateTaskHistory = vi.fn().mockImplementation(async function (historyItem: { id?: string }) {
655655
if (historyItem.id === "child-rpd04") {
656656
throw new Error("child status persist failed")
657657
}
@@ -660,7 +660,7 @@ describe("History resume delegation - parent metadata transitions", () => {
660660

661661
const provider = {
662662
contextProxy: { globalStorageUri: { fsPath: "/tmp" } },
663-
getTaskWithId: vi.fn().mockImplementation(async (id: string) => {
663+
getTaskWithId: vi.fn().mockImplementation(async function (id: string) {
664664
if (id === "parent-rpd04") {
665665
return {
666666
historyItem: {

src/__tests__/migrateSettings.spec.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ describe("Settings Migration", () => {
6262
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)
6363

6464
// Mock file existence checks - only return true for paths we want to exist
65-
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
65+
vitest.mocked(fileExistsAtPath).mockImplementation(async function (path: string) {
6666
if (path === mockSettingsDir) return true
6767
if (path === legacyClineCustomModesPath) return true
6868
return false // All other paths don't exist, including destination files
@@ -83,7 +83,7 @@ describe("Settings Migration", () => {
8383
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)
8484

8585
// Ensure the other files don't interfere with this test
86-
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
86+
vitest.mocked(fileExistsAtPath).mockImplementation(async function (path: string) {
8787
if (path === mockSettingsDir) return true
8888
if (path === legacyMcpSettingsPath) return true
8989
if (path === legacyClineCustomModesPath) return false // Ensure this file doesn't exist
@@ -106,7 +106,7 @@ describe("Settings Migration", () => {
106106
const mockRename = vitest.mocked(fs.rename).mockResolvedValue(undefined)
107107

108108
// Mock file existence checks - both source and destination exist
109-
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
109+
vitest.mocked(fileExistsAtPath).mockImplementation(async function (path: string) {
110110
if (path === mockSettingsDir) return true
111111
if (path === legacyClineCustomModesPath) return true
112112
if (path === legacyCustomModesJson) return true // Destination already exists
@@ -147,15 +147,15 @@ describe("Settings Migration", () => {
147147
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)
148148

149149
// Mock file read to return JSON content
150-
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
150+
vitest.mocked(fs.readFile).mockImplementation(async function (path: any) {
151151
if (path === legacyCustomModesJson) {
152152
return testJsonContent
153153
}
154154
throw new Error("File not found: " + path)
155155
})
156156

157157
// Isolate this test by making sure only the specific JSON file exists
158-
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
158+
vitest.mocked(fileExistsAtPath).mockImplementation(async function (path: string) {
159159
if (path === mockSettingsDir) return true
160160
if (path === legacyCustomModesJson) return true
161161
if (path === legacyClineCustomModesPath) return false
@@ -185,15 +185,15 @@ describe("Settings Migration", () => {
185185
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)
186186

187187
// Mock file read to return corrupt JSON
188-
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
188+
vitest.mocked(fs.readFile).mockImplementation(async function (path: any) {
189189
if (path === legacyCustomModesJson) {
190190
return "{ invalid json content" // This will cause an error when parsed
191191
}
192192
throw new Error("File not found: " + path)
193193
})
194194

195195
// Isolate this test
196-
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
196+
vitest.mocked(fileExistsAtPath).mockImplementation(async function (path: string) {
197197
if (path === mockSettingsDir) return true
198198
if (path === legacyCustomModesJson) return true
199199
if (path === legacyClineCustomModesPath) return false
@@ -222,15 +222,15 @@ describe("Settings Migration", () => {
222222
const mockUnlink = vitest.mocked(fs.unlink).mockResolvedValue(undefined)
223223

224224
// Mock file read
225-
vitest.mocked(fs.readFile).mockImplementation(async (path: any) => {
225+
vitest.mocked(fs.readFile).mockImplementation(async function (path: any) {
226226
if (path === legacyCustomModesJson) {
227227
return JSON.stringify({ customModes: [] })
228228
}
229229
throw new Error("File not found: " + path)
230230
})
231231

232232
// Mock file existence checks - both source and yaml destination exist
233-
vitest.mocked(fileExistsAtPath).mockImplementation(async (path: string) => {
233+
vitest.mocked(fileExistsAtPath).mockImplementation(async function (path: string) {
234234
if (path === mockSettingsDir) return true
235235
if (path === legacyCustomModesJson) return true
236236
if (path === newCustomModesYaml) return true // YAML already exists

src/__tests__/nested-delegation-resume.spec.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -111,25 +111,26 @@ describe("Nested delegation resume (A → B → C)", () => {
111111
}
112112

113113
const emitSpy = vi.fn()
114-
const removeClineFromStack = vi.fn().mockImplementation(async () => {
114+
const removeClineFromStack = vi.fn().mockImplementation(async function () {
115115
// Simulate closing current child
116116
currentActiveId = undefined
117117
})
118-
const createTaskWithHistoryItem = vi
119-
.fn()
120-
.mockImplementation(async (historyItem: any, opts?: { startTask?: boolean }) => {
121-
// Assert startTask:false to avoid resume asks
122-
expect(opts).toEqual(expect.objectContaining({ startTask: false }))
123-
// Reopen the parent
124-
currentActiveId = historyItem.id
125-
// Return minimal parent instance with resumeAfterDelegation
126-
return {
127-
taskId: historyItem.id,
128-
resumeAfterDelegation: vi.fn().mockResolvedValue(undefined),
129-
overwriteClineMessages: vi.fn().mockResolvedValue(undefined),
130-
overwriteApiConversationHistory: vi.fn().mockResolvedValue(undefined),
131-
}
132-
})
118+
const createTaskWithHistoryItem = vi.fn().mockImplementation(async function (
119+
historyItem: any,
120+
opts?: { startTask?: boolean },
121+
) {
122+
// Assert startTask:false to avoid resume asks
123+
expect(opts).toEqual(expect.objectContaining({ startTask: false }))
124+
// Reopen the parent
125+
currentActiveId = historyItem.id
126+
// Return minimal parent instance with resumeAfterDelegation
127+
return {
128+
taskId: historyItem.id,
129+
resumeAfterDelegation: vi.fn().mockResolvedValue(undefined),
130+
overwriteClineMessages: vi.fn().mockResolvedValue(undefined),
131+
overwriteApiConversationHistory: vi.fn().mockResolvedValue(undefined),
132+
}
133+
})
133134

134135
const getTaskWithId = vi.fn(async (id: string) => {
135136
if (!historyIndex[id]) throw new Error("Task not found")

0 commit comments

Comments
 (0)