/** * Vitest compatibility shim for running tests under Deno. * * Redirected from 'vitest' via deno.json import map. * Implements vi.fn() / vi.spyOn() / vi.mocked() using the @std/expect * MockCall interface so that @std/expect matchers (toHaveBeenCalledWith, etc.) work. */ import { beforeAll, beforeEach, afterAll, afterEach, describe, it } from "jsr:@std/testing/bdd"; import { expect } from "jsr:@std/expect"; // @std/expect recognises mock functions via this well-known symbol (@std/expect 1.0.18+) const MOCK_SYMBOL = Symbol.for("@MOCK"); type MockCall = { args: unknown[]; returned?: unknown; thrown?: unknown; timestamp: number; returns: boolean; throws: boolean; }; function createMock(impl?: (...args: unknown[]) => unknown) { let currentImpl = impl; const calls: MockCall[] = []; const mockInfo = { calls }; const mockFn = function (this: unknown, ...args: unknown[]) { const call: MockCall = { args, timestamp: Date.now(), returns: false, throws: false, }; calls.push(call); try { const result = currentImpl ? currentImpl.apply(this, args) : undefined; call.returned = result; call.returns = true; return result; } catch (err) { call.thrown = err; call.throws = true; throw err; } }; // @std/expect mock interface — required for toHaveBeenCalledWith etc. (mockFn as any)[MOCK_SYMBOL] = mockInfo; // vitest-style chainable methods (mockFn as any).mockReturnValue = (val: unknown) => { currentImpl = () => val; return mockFn; }; (mockFn as any).mockResolvedValue = (val: unknown) => { currentImpl = () => Promise.resolve(val); return mockFn; }; (mockFn as any).mockRejectedValue = (val: unknown) => { currentImpl = () => Promise.reject(val); return mockFn; }; (mockFn as any).mockImplementation = (fn: (...args: unknown[]) => unknown) => { currentImpl = fn; return mockFn; }; (mockFn as any).mockReset = () => { calls.length = 0; currentImpl = undefined; return mockFn; }; (mockFn as any).mockClear = () => { calls.length = 0; return mockFn; }; (mockFn as any).mockRestore = () => {}; return mockFn; } export const vi = { fn: (impl?: (...args: unknown[]) => unknown) => createMock(impl), // vi.mocked() is a TypeScript type cast — just return the same value at runtime mocked: (fn: T): T => fn, spyOn: >(obj: T, method: keyof T) => { const original = obj[method]; const mock = createMock(typeof original === "function" ? (original as (...args: unknown[]) => unknown) : undefined); const restore = () => { obj[method] = original; }; (mock as any).mockRestore = restore; obj[method] = mock as unknown as T[keyof T]; return mock; }, }; export { describe, it, it as test, beforeAll, beforeEach, afterAll, afterEach, expect };