Skip to content

Commit 8b6fc53

Browse files
committed
fix(testing): make vitest 4 constructor mocks type-check cleanly
- logging-session & mcp-oauth mocks: a class passed to mockImplementation has a construct signature that isn't assignable to its (...args) => any parameter, failing tsc. Use named function declarations instead (constructable via Reflect.construct, assignable to mockImplementation, and not rewritten to arrows by biome's useArrowFunction). - database.mock.ts: vitest 4's generic vi.fn typings no longer break the self-referential cycle on the transaction callback's tx param; loosen tx and annotate the callback's return type to resolve the implicit-any errors.
1 parent a6deca8 commit 8b6fc53

3 files changed

Lines changed: 37 additions & 25 deletions

File tree

packages/testing/src/mocks/database.mock.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ const set = vi.fn(() => ({ where }))
155155
const update = vi.fn(() => ({ set }))
156156
const del = vi.fn(() => ({ where }))
157157
const transaction: ReturnType<typeof vi.fn> = vi.fn(
158-
async (cb: (tx: typeof dbChainMock.db) => unknown) => cb(dbChainMock.db)
158+
async (cb: (tx: any) => unknown): Promise<unknown> => cb(dbChainMock.db)
159159
)
160160

161161
export const dbChainMockFns = {

packages/testing/src/mocks/logging-session.mock.ts

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,36 @@ export const loggingSessionMockFns = {
3131
mockMarkAsFailed: vi.fn().mockResolvedValue(undefined),
3232
}
3333

34+
/**
35+
* Builds the object returned by each `new LoggingSession(...)` call. Declared as
36+
* a named function (not an arrow) so it stays constructable under vitest 4's
37+
* `Reflect.construct` path while remaining assignable to `mockImplementation`; a
38+
* returned object overrides the constructed instance.
39+
*/
40+
function buildLoggingSessionInstance() {
41+
return {
42+
start: loggingSessionMockFns.mockStart,
43+
complete: loggingSessionMockFns.mockComplete,
44+
completeWithError: loggingSessionMockFns.mockCompleteWithError,
45+
completeWithCancellation: loggingSessionMockFns.mockCompleteWithCancellation,
46+
completeWithPause: loggingSessionMockFns.mockCompleteWithPause,
47+
safeStart: loggingSessionMockFns.mockSafeStart,
48+
waitForCompletion: loggingSessionMockFns.mockWaitForCompletion,
49+
waitForPostExecution: loggingSessionMockFns.mockWaitForPostExecution,
50+
safeComplete: loggingSessionMockFns.mockSafeComplete,
51+
safeCompleteWithError: loggingSessionMockFns.mockSafeCompleteWithError,
52+
safeCompleteWithCancellation: loggingSessionMockFns.mockSafeCompleteWithCancellation,
53+
safeCompleteWithPause: loggingSessionMockFns.mockSafeCompleteWithPause,
54+
markAsFailed: loggingSessionMockFns.mockMarkAsFailed,
55+
}
56+
}
57+
3458
/**
3559
* Constructor-shaped mock for `LoggingSession`. Each `new LoggingSession(...)`
3660
* call returns an object whose methods point at the shared `vi.fn()` refs in
3761
* `loggingSessionMockFns`.
3862
*/
39-
export const LoggingSessionMock = vi.fn().mockImplementation(
40-
class {
41-
start = loggingSessionMockFns.mockStart
42-
complete = loggingSessionMockFns.mockComplete
43-
completeWithError = loggingSessionMockFns.mockCompleteWithError
44-
completeWithCancellation = loggingSessionMockFns.mockCompleteWithCancellation
45-
completeWithPause = loggingSessionMockFns.mockCompleteWithPause
46-
safeStart = loggingSessionMockFns.mockSafeStart
47-
waitForCompletion = loggingSessionMockFns.mockWaitForCompletion
48-
waitForPostExecution = loggingSessionMockFns.mockWaitForPostExecution
49-
safeComplete = loggingSessionMockFns.mockSafeComplete
50-
safeCompleteWithError = loggingSessionMockFns.mockSafeCompleteWithError
51-
safeCompleteWithCancellation = loggingSessionMockFns.mockSafeCompleteWithCancellation
52-
safeCompleteWithPause = loggingSessionMockFns.mockSafeCompleteWithPause
53-
markAsFailed = loggingSessionMockFns.mockMarkAsFailed
54-
}
55-
)
63+
export const LoggingSessionMock = vi.fn().mockImplementation(buildLoggingSessionInstance)
5664

5765
/**
5866
* Static mock module for `@/lib/logs/execution/logging-session`.

packages/testing/src/mocks/mcp-oauth.mock.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@ export class McpOauthInsecureUrlErrorMock extends Error {
4343
}
4444
}
4545

46+
/**
47+
* Returns the provider config back as the constructed instance, matching the
48+
* original identity passthrough. Declared as a named function (not an arrow) so
49+
* it stays constructable under vitest 4's `Reflect.construct` path while
50+
* remaining assignable to `mockImplementation`.
51+
*/
52+
function buildSimMcpOauthProvider(value: object) {
53+
return value
54+
}
55+
4656
/**
4757
* Static mock module for `@/lib/mcp/oauth`.
4858
*
@@ -70,11 +80,5 @@ export const mcpOauthMock = {
7080
withMcpOauthRefreshLock: mcpOauthMockFns.mockWithMcpOauthRefreshLock,
7181
McpOauthRedirectRequired: McpOauthRedirectRequiredMock,
7282
McpOauthInsecureUrlError: McpOauthInsecureUrlErrorMock,
73-
SimMcpOauthProvider: vi.fn().mockImplementation(
74-
class {
75-
constructor(value: object) {
76-
Object.assign(this, value)
77-
}
78-
}
79-
),
83+
SimMcpOauthProvider: vi.fn().mockImplementation(buildSimMcpOauthProvider),
8084
}

0 commit comments

Comments
 (0)