import type { LngLat, LngLatBounds, LngLatLike, MapMouseEvent } from "mapbox-gl"; import { type Mock } from "vitest"; /** * Type for event handlers stored in our mock map's listener registry. * Using a generic to avoid `as` assertions when retrieving handlers. */ type MapEventHandler = (event: TEvent) => void; /** * Shape of the mock map returned by createMockMapboxMap. * Extends the necessary parts of mapboxgl.Map for adapter testing. */ type MockMapboxMap = { on: Mock<(event: string, handler: MapEventHandler) => MockMapboxMap>; once: Mock<(event: string, handler: MapEventHandler) => MockMapboxMap>; off: Mock<(event: string, handler: MapEventHandler) => MockMapboxMap>; remove: Mock<() => void>; getCenter: Mock<() => LngLat>; getZoom: Mock<() => number>; getBounds: Mock<() => LngLatBounds>; setCenter: Mock<(center: LngLatLike) => MockMapboxMap>; setZoom: Mock<(zoom: number) => MockMapboxMap>; panTo: Mock<(lngLat: LngLatLike) => MockMapboxMap>; panBy: Mock<(offset: [number, number]) => MockMapboxMap>; fitBounds: Mock<(bounds: LngLatBounds, options: unknown) => MockMapboxMap>; setStyle: Mock<(style: string) => MockMapboxMap>; isStyleLoaded: Mock<() => boolean>; isMoving: Mock<() => boolean>; addSource: Mock; removeSource: Mock; getSource: Mock; addLayer: Mock; removeLayer: Mock; getLayer: Mock; setPaintProperty: Mock; hasImage: Mock<() => boolean>; addImage: Mock; getCanvas: Mock; getCanvasContainer: Mock; }; /** * Return type of createMockMapboxMap - provides both the mock map * and a triggerEvent helper for simulating Mapbox events in tests. */ type MockMapboxMapResult = { /** * The mock map instance. Cast to mapboxgl.Map when passing to adapter.connect(). * We return MockMapboxMap to preserve access to jest mock methods in tests. */ readonly map: MockMapboxMap; /** * Triggers an event on the mock map, calling all registered handlers. * Handles both regular (on) and one-time (once) listeners. */ readonly triggerEvent: (eventName: string, event?: TEvent) => void; }; /** * Creates a mock Mapbox map instance for unit testing adapter instances directly. * * Use this when you need fine-grained control over mock behavior, such as: * - Testing adapter instance methods (connect, setCenter, etc.) * - Simulating map events (idle, click, movestart) * - Verifying method calls on the map * * @example * ```typescript * import { createMockMapboxMap } from "@trackunit/react-vite-test-setup"; * * it("should connect to map", () => { * const { map, triggerEvent } = createMockMapboxMap(); * const adapter = new MapboxAdapterInstance(config); * * adapter.connect(map as unknown as mapboxgl.Map); * triggerEvent("idle"); * * expect(adapter.getState().isReady).toBe(true); * }); * ``` */ export declare const createMockMapboxMap: () => MockMapboxMapResult; /** * Mock click event matching Mapbox GL's MapMouseEvent shape. * Use with triggerEvent("click", createMockClickEvent(...)) * * Note: The `point` property is intentionally omitted because: * 1. It requires the full Point class from @mapbox/point-geometry with 30+ methods * 2. No tests currently use the point property * 3. Since this returns Partial, point is optional */ export declare const createMockClickEvent: (lng: number, lat: number) => Partial; /** * Sets up mocks for Mapbox GL JS in testing environments. * * Replaces `mapbox-gl`'s `Map` and `Marker` constructors with deterministic * fakes (the `Map` mock auto-fires the `load` event so renderer tests don't * have to wait for it) and registers a `beforeEach` hook that clears mock * call records between tests. * * Opt-in: the mock is registered via `vi.doMock` so it is * NOT hoisted and only takes effect once `setupMapbox()` is called from a * test setup file. Tests that need the real `mapbox-gl` (or their own mock) * are unaffected unless they explicitly call this. * * @example * ```typescript * // In your test file * import { setupMapbox } from "@trackunit/react-vite-test-setup"; * * setupMapbox(); * * describe("MapboxRenderer", () => { * it("renders map when loaded", async () => { * // The mock will auto-fire "load" event * render(); * await waitFor(() => expect(screen.getByRole("application")).toBeInTheDocument()); * }); * }); * ``` */ export declare const setupMapbox: () => void; export {};