/** * Vitest 测试环境设置 * 提供全局 mock 和测试工具 */ import { config } from '@vue/test-utils' import { vi } from 'vitest' // Mock requestIdleCallback (Safari < 15 不支持) if (typeof globalThis.requestIdleCallback === 'undefined') { globalThis.requestIdleCallback = ((callback: IdleRequestCallback) => { return window.setTimeout(() => callback({ didTimeout: false, timeRemaining: () => 50 }), 1) }) as unknown as typeof requestIdleCallback } if (typeof globalThis.cancelIdleCallback === 'undefined') { globalThis.cancelIdleCallback = ((id: number) => { window.clearTimeout(id) }) as unknown as typeof cancelIdleCallback } // Mock IntersectionObserver class MockIntersectionObserver { observe = vi.fn() disconnect = vi.fn() unobserve = vi.fn() } globalThis.IntersectionObserver = MockIntersectionObserver as unknown as typeof IntersectionObserver // Mock ResizeObserver class MockResizeObserver { observe = vi.fn() disconnect = vi.fn() unobserve = vi.fn() } globalThis.ResizeObserver = MockResizeObserver as unknown as typeof ResizeObserver // Mock matchMedia (jsdom doesn't implement it). // Default matches=true so desktop viewport queries pass and components that // only lazy-load on mobile render content immediately in tests. if (typeof window !== 'undefined' && !window.matchMedia) { window.matchMedia = (query: string): MediaQueryList => ({ matches: true, media: query, onchange: null, addListener: vi.fn(), removeListener: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn() }) as MediaQueryList } // Vue Test Utils 全局配置 config.global.stubs = { // 可以在这里添加全局 stub } // 设置全局测试超时 vi.setConfig({ testTimeout: 10000 })