@trackunit/react-vite-test-setup 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@trackunit/react-vite-test-setup",
3
+ "description": "Test setup utilities for React applications",
4
+ "version": "0.0.1",
5
+ "repository": "https://github.com/Trackunit/manager",
6
+ "license": "SEE LICENSE IN LICENSE.txt",
7
+ "engines": {
8
+ "node": ">=24.x"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "import": "./index.esm.js",
13
+ "require": "./index.cjs.js",
14
+ "types": "./index.esm.d.ts"
15
+ },
16
+ "./preset": {
17
+ "import": "./preset.esm.js",
18
+ "require": "./preset.cjs.js",
19
+ "types": "./preset.esm.d.ts"
20
+ }
21
+ },
22
+ "dependencies": {
23
+ "@googlemaps/jest-mocks": "2.22.6",
24
+ "@js-temporal/polyfill": "^0.5.1",
25
+ "@react-spring/web": "9.7.5",
26
+ "@testing-library/jest-dom": "^6.9.1",
27
+ "@testing-library/react": "16.2.0",
28
+ "@vis.gl/react-google-maps": "^1.7.1",
29
+ "mapbox-gl": "^3.18.1",
30
+ "vitest-canvas-mock": "^1.1.4",
31
+ "vitest-fail-on-console": "^0.10.1",
32
+ "react-i18next": "^15.5.1",
33
+ "react-virtualized-auto-sizer": "^1.0.20",
34
+ "web-streams-polyfill": "^4.2.0"
35
+ },
36
+ "peerDependencies": {
37
+ "react": "^19.0.0",
38
+ "vitest": "^4.0.0"
39
+ },
40
+ "module": "./index.esm.js",
41
+ "main": "./index.cjs.js",
42
+ "types": "./index.d.ts"
43
+ }
package/preset.cjs.js ADDED
@@ -0,0 +1,101 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var fs = require('node:fs');
6
+ var path = require('node:path');
7
+
8
+ function _interopNamespaceDefault(e) {
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
26
+
27
+ /**
28
+ * Walk up from `process.cwd()` to the first directory containing
29
+ * `nx.json` (the workspace-root marker). Used so the stub-file path
30
+ * the preset returns is correct regardless of whether Vitest was
31
+ * invoked from the workspace root (the standard `nx run <p>:test`
32
+ * path) or from inside a project directory (e.g. `cd libs/foo && vitest`
33
+ * during local debugging). Falls back to `process.cwd()` if the
34
+ * marker is never found.
35
+ */
36
+ const findWorkspaceRoot = () => {
37
+ let dir = process.cwd();
38
+ for (let i = 0; i < 16; i++) {
39
+ if (fs__namespace.existsSync(path.join(dir, "nx.json")))
40
+ return dir;
41
+ const parent = path.dirname(dir);
42
+ if (parent === dir)
43
+ break;
44
+ dir = parent;
45
+ }
46
+ return process.cwd();
47
+ };
48
+ /**
49
+ * Repo-wide stub used to neutralise imports of CSS / SVG-sprite assets
50
+ * during tests. The Jest equivalent (`irisPreset`) used
51
+ * `jest-transform-stub` for the same purpose - this preset wires up
52
+ * `resolve.alias` instead so the same imports return an empty module
53
+ * under Vitest.
54
+ *
55
+ * Mirrors the `moduleNameMapper` keys from `jestPreset.ts`: any change
56
+ * there should be mirrored here.
57
+ */
58
+ const STUB_FILE = path.resolve(findWorkspaceRoot(), "vitest.empty-stub.ts");
59
+ const STUBBED_MODULES = [
60
+ /^@trackunit\/css-core$/,
61
+ /^@trackunit\/ui-icons\/icons-sprite-mini\.svg$/,
62
+ /^@trackunit\/ui-icons\/icons-sprite-outline\.svg$/,
63
+ /^@trackunit\/ui-icons\/icons-sprite-solid\.svg$/,
64
+ /^@trackunit\/ui-icons\/icons-sprite-micro\.svg$/,
65
+ ];
66
+ /**
67
+ * Vitest preset for Trackunit applications.
68
+ *
69
+ * Provides the cross-cutting bits that all per-project vitest configs need:
70
+ *
71
+ * - `resolve.alias` stubs for the design-system asset modules that have no
72
+ * JS implementation at runtime (CSS files / SVG sprite manifests).
73
+ * - `test.env.TZ = "UTC"` so date/time arithmetic is deterministic on every
74
+ * machine, mirroring what `vitest.preset.js` did via
75
+ * `process.env.TZ = "UTC"` at the top of the file. The same line is also
76
+ * set inside `setupTimeAndLanguage.ts` for redundancy in libs that import
77
+ * that helper directly without going through this preset.
78
+ *
79
+ * Per-project configs should `mergeConfig(vitestPreset, defineConfig({...}))`
80
+ * to layer their own `test.name`, `setupFiles`, `cacheDir`, etc. on top.
81
+ *
82
+ * Other Vitest-only concerns from `vitest.preset.js` are handled differently:
83
+ * - `transformIgnorePatterns` is unnecessary - Vite transforms ESM
84
+ * packages by default; if a CJS package needs forcing, add
85
+ * `server.deps.inline` in the per-project config.
86
+ * - `resolver: @nx/jest/plugins/resolver` is replaced by the
87
+ * `nxViteTsPaths()` plugin in each per-project config.
88
+ */
89
+ const vitestPreset = {
90
+ resolve: {
91
+ alias: STUBBED_MODULES.map(find => ({ find, replacement: STUB_FILE })),
92
+ },
93
+ test: {
94
+ env: {
95
+ TZ: "UTC",
96
+ },
97
+ },
98
+ };
99
+
100
+ exports.default = vitestPreset;
101
+ exports.vitestPreset = vitestPreset;
package/preset.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./src/preset";
2
+ export { default } from "./src/preset";
package/preset.esm.js ADDED
@@ -0,0 +1,77 @@
1
+ import * as fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ /**
5
+ * Walk up from `process.cwd()` to the first directory containing
6
+ * `nx.json` (the workspace-root marker). Used so the stub-file path
7
+ * the preset returns is correct regardless of whether Vitest was
8
+ * invoked from the workspace root (the standard `nx run <p>:test`
9
+ * path) or from inside a project directory (e.g. `cd libs/foo && vitest`
10
+ * during local debugging). Falls back to `process.cwd()` if the
11
+ * marker is never found.
12
+ */
13
+ const findWorkspaceRoot = () => {
14
+ let dir = process.cwd();
15
+ for (let i = 0; i < 16; i++) {
16
+ if (fs.existsSync(path.join(dir, "nx.json")))
17
+ return dir;
18
+ const parent = path.dirname(dir);
19
+ if (parent === dir)
20
+ break;
21
+ dir = parent;
22
+ }
23
+ return process.cwd();
24
+ };
25
+ /**
26
+ * Repo-wide stub used to neutralise imports of CSS / SVG-sprite assets
27
+ * during tests. The Jest equivalent (`irisPreset`) used
28
+ * `jest-transform-stub` for the same purpose - this preset wires up
29
+ * `resolve.alias` instead so the same imports return an empty module
30
+ * under Vitest.
31
+ *
32
+ * Mirrors the `moduleNameMapper` keys from `jestPreset.ts`: any change
33
+ * there should be mirrored here.
34
+ */
35
+ const STUB_FILE = path.resolve(findWorkspaceRoot(), "vitest.empty-stub.ts");
36
+ const STUBBED_MODULES = [
37
+ /^@trackunit\/css-core$/,
38
+ /^@trackunit\/ui-icons\/icons-sprite-mini\.svg$/,
39
+ /^@trackunit\/ui-icons\/icons-sprite-outline\.svg$/,
40
+ /^@trackunit\/ui-icons\/icons-sprite-solid\.svg$/,
41
+ /^@trackunit\/ui-icons\/icons-sprite-micro\.svg$/,
42
+ ];
43
+ /**
44
+ * Vitest preset for Trackunit applications.
45
+ *
46
+ * Provides the cross-cutting bits that all per-project vitest configs need:
47
+ *
48
+ * - `resolve.alias` stubs for the design-system asset modules that have no
49
+ * JS implementation at runtime (CSS files / SVG sprite manifests).
50
+ * - `test.env.TZ = "UTC"` so date/time arithmetic is deterministic on every
51
+ * machine, mirroring what `vitest.preset.js` did via
52
+ * `process.env.TZ = "UTC"` at the top of the file. The same line is also
53
+ * set inside `setupTimeAndLanguage.ts` for redundancy in libs that import
54
+ * that helper directly without going through this preset.
55
+ *
56
+ * Per-project configs should `mergeConfig(vitestPreset, defineConfig({...}))`
57
+ * to layer their own `test.name`, `setupFiles`, `cacheDir`, etc. on top.
58
+ *
59
+ * Other Vitest-only concerns from `vitest.preset.js` are handled differently:
60
+ * - `transformIgnorePatterns` is unnecessary - Vite transforms ESM
61
+ * packages by default; if a CJS package needs forcing, add
62
+ * `server.deps.inline` in the per-project config.
63
+ * - `resolver: @nx/jest/plugins/resolver` is replaced by the
64
+ * `nxViteTsPaths()` plugin in each per-project config.
65
+ */
66
+ const vitestPreset = {
67
+ resolve: {
68
+ alias: STUBBED_MODULES.map(find => ({ find, replacement: STUB_FILE })),
69
+ },
70
+ test: {
71
+ env: {
72
+ TZ: "UTC",
73
+ },
74
+ },
75
+ };
76
+
77
+ export { vitestPreset as default, vitestPreset };
package/src/index.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export * from "./setupAllMocks";
2
+ export * from "./setupBasicMocks";
3
+ export * from "./setupCanvasMock";
4
+ export * from "./setupDefaultMocks";
5
+ export * from "./setupFailOnConsole";
6
+ export * from "./setupGoogleMaps";
7
+ export * from "./setupHelmetMock";
8
+ export * from "./setupIntersectionObserver";
9
+ export * from "./setupMapbox";
10
+ export * from "./setupMatchMediaMock";
11
+ export * from "./setupReactTestingLibrary";
12
+ export * from "./setupReactVirtualizedAutoSizer";
13
+ export * from "./setupResizeObserver";
14
+ export * from "./setupTanstackReactRouter";
15
+ export * from "./setupTanstackReactVirtualize";
16
+ export * from "./setupTimeAndLanguage";
17
+ export * from "./setupTranslations";
18
+ export * from "./setupWebStreams";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Minimal shape of the `mergeConfig`-friendly object we return.
3
+ *
4
+ * We intentionally don't pull in `UserConfig` from `vitest/config` or
5
+ * `vite` here: vitest 4 renames its re-export to `ViteUserConfig` and
6
+ * the `react-vite-test-setup` package doesn't list `vite` as a direct
7
+ * dependency, so threading the type through would force a real dep
8
+ * (and a corresponding `dependency-owner.json` entry) for nothing -
9
+ * `mergeConfig` accepts any object-shaped config at runtime.
10
+ */
11
+ type VitestPresetShape = {
12
+ readonly resolve: {
13
+ readonly alias: ReadonlyArray<{
14
+ readonly find: RegExp;
15
+ readonly replacement: string;
16
+ }>;
17
+ };
18
+ readonly test: {
19
+ readonly env: {
20
+ readonly TZ: string;
21
+ };
22
+ };
23
+ };
24
+ /**
25
+ * Vitest preset for Trackunit applications.
26
+ *
27
+ * Provides the cross-cutting bits that all per-project vitest configs need:
28
+ *
29
+ * - `resolve.alias` stubs for the design-system asset modules that have no
30
+ * JS implementation at runtime (CSS files / SVG sprite manifests).
31
+ * - `test.env.TZ = "UTC"` so date/time arithmetic is deterministic on every
32
+ * machine, mirroring what `vitest.preset.js` did via
33
+ * `process.env.TZ = "UTC"` at the top of the file. The same line is also
34
+ * set inside `setupTimeAndLanguage.ts` for redundancy in libs that import
35
+ * that helper directly without going through this preset.
36
+ *
37
+ * Per-project configs should `mergeConfig(vitestPreset, defineConfig({...}))`
38
+ * to layer their own `test.name`, `setupFiles`, `cacheDir`, etc. on top.
39
+ *
40
+ * Other Vitest-only concerns from `vitest.preset.js` are handled differently:
41
+ * - `transformIgnorePatterns` is unnecessary - Vite transforms ESM
42
+ * packages by default; if a CJS package needs forcing, add
43
+ * `server.deps.inline` in the per-project config.
44
+ * - `resolver: @nx/jest/plugins/resolver` is replaced by the
45
+ * `nxViteTsPaths()` plugin in each per-project config.
46
+ */
47
+ export declare const vitestPreset: VitestPresetShape;
48
+ export {};
@@ -0,0 +1,3 @@
1
+ import { vitestPreset } from "./preset/vitestPreset";
2
+ export { vitestPreset };
3
+ export default vitestPreset;
@@ -0,0 +1,39 @@
1
+ import { setupFailOnConsole } from "./setupFailOnConsole";
2
+ export interface SetupAllMocksOptions {
3
+ failOnConsoleOptions?: Parameters<typeof setupFailOnConsole>[0];
4
+ }
5
+ /**
6
+ * Sets up all available testing mocks in a single function call.
7
+ *
8
+ * This convenience function sets up all the test mocks provided by the library:
9
+ * - Canvas API mocks
10
+ * - Console error reporting to fail tests (includes automatic CSS parser error suppression)
11
+ * - Google Maps API and components mocks
12
+ * - Mapbox GL JS mocks
13
+ * - React Helmet mocks
14
+ * - IntersectionObserver mocks
15
+ * - MatchMedia API mocks
16
+ * - React Testing Library and Okta authentication mocks
17
+ * - React Virtualized AutoSizer mocks
18
+ * - ResizeObserver mocks
19
+ * - Tanstack React Virtual mocks
20
+ * - Time and language related mocks (timezone, timers, etc.)
21
+ * - Translation mocks (i18n)
22
+ * - Web Streams API mocks
23
+ *
24
+ * Using this function is equivalent to calling each setup function individually.
25
+ *
26
+ * @param options Configuration options for individual mocks
27
+ * @param options.failOnConsoleOptions Options for setupFailOnConsole
28
+ * @example
29
+ * // In your jest setup file
30
+ * import { setupAllMocks } from '@trackunit/react-vite-test-setup';
31
+ *
32
+ * setupAllMocks();
33
+ *
34
+ * // Or with options for specific mocks:
35
+ * setupAllMocks({
36
+ * failOnConsoleOptions: { shouldFailOnWarn: true }
37
+ * });
38
+ */
39
+ export declare const setupAllMocks: (options?: SetupAllMocksOptions) => void;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Sets up essential testing mocks that don't have external library dependencies.
3
+ *
4
+ * This convenience function configures a minimal set of test mocks that are broadly
5
+ * applicable for most React testing scenarios without requiring specific external
6
+ * libraries. It includes:
7
+ *
8
+ * - Canvas API mocks
9
+ * - Console error reporting to fail tests
10
+ * - IntersectionObserver mocks
11
+ * - MatchMedia API mocks
12
+ * - ResizeObserver mocks
13
+ * - Timer mocks (setTimeout, setInterval)
14
+ * - Web Streams API mocks
15
+ *
16
+ * This is perfect for projects that want essential testing mocks without bringing
17
+ * in dependencies for libraries they don't use like Google Maps, React Virtual, etc.
18
+ *
19
+ * @param options Configuration options for individual mocks
20
+ * @param options.failOnConsoleOptions Options for setupFailOnConsole
21
+ * @example
22
+ * // In your jest setup file
23
+ * import { setupBasicMocks } from '@trackunit/react-vite-test-setup';
24
+ *
25
+ * setupBasicMocks();
26
+ *
27
+ * // Or with options for specific mocks:
28
+ * setupBasicMocks({
29
+ * failOnConsoleOptions: { shouldFailOnWarn: true }
30
+ * });
31
+ */
32
+ import { SetupAllMocksOptions } from "./setupAllMocks";
33
+ /**
34
+ * Options for configuring the setupBasicMocks function.
35
+ * Currently shares the same options structure as SetupAllMocksOptions.
36
+ */
37
+ export type SetupBasicMocksOptions = SetupAllMocksOptions;
38
+ /**
39
+ * Sets up essential testing mocks with no external library dependencies.
40
+ *
41
+ * @param options Configuration options for the mocks
42
+ */
43
+ export declare const setupBasicMocks: (options?: SetupBasicMocksOptions) => void;
@@ -0,0 +1,19 @@
1
+ import "vitest-canvas-mock";
2
+ /**
3
+ * Sets up a mock implementation for HTML Canvas API in testing environments.
4
+ *
5
+ * This function uses vitest-canvas-mock to provide a mock implementation of the
6
+ * HTML Canvas API, allowing tests to run without requiring a real DOM canvas.
7
+ * Useful for testing components that use canvas rendering.
8
+ *
9
+ * Importing vitest-canvas-mock at module load time has the side effect of
10
+ * patching HTMLCanvasElement.prototype.getContext globally; calling this
11
+ * function is a no-op kept for API compatibility with the previous Jest
12
+ * setup.
13
+ *
14
+ * @example
15
+ * import { setupCanvasMock } from '@trackunit/react-vite-test-setup';
16
+ *
17
+ * setupCanvasMock();
18
+ */
19
+ export declare const setupCanvasMock: () => void;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Sets up default testing mocks that cover most common React testing needs.
3
+ *
4
+ * This convenience function provides a balanced set of mocks that cover most React
5
+ * application testing needs. It includes all the basic mocks plus essential React
6
+ * testing utilities. Specifically, it includes:
7
+ *
8
+ * From setupBasicMocks:
9
+ * - Canvas API mocks
10
+ * - Console error reporting to fail tests
11
+ * - IntersectionObserver mocks
12
+ * - MatchMedia API mocks
13
+ * - ResizeObserver mocks
14
+ * - Timer mocks (setTimeout, setInterval)
15
+ * - Web Streams API mocks
16
+ *
17
+ * Plus these additional mocks:
18
+ * - React Testing Library and Okta authentication mocks
19
+ * - Translation mocks (i18n)
20
+ *
21
+ * This is ideal for most React applications that use i18n translations and need
22
+ * standard testing environment setup, without requiring specialized mocks for things
23
+ * like Google Maps or virtualized lists.
24
+ *
25
+ * @param options Configuration options for individual mocks
26
+ * @param options.failOnConsoleOptions Options for setupFailOnConsole
27
+ * @example
28
+ * // In your jest setup file
29
+ * import { setupDefaultMocks } from '@trackunit/react-vite-test-setup';
30
+ *
31
+ * setupDefaultMocks();
32
+ *
33
+ * // Or with options for specific mocks:
34
+ * setupDefaultMocks({
35
+ * failOnConsoleOptions: { shouldFailOnWarn: true }
36
+ * });
37
+ */
38
+ import { SetupBasicMocksOptions } from "./setupBasicMocks";
39
+ /**
40
+ * Options for configuring the setupDefaultMocks function.
41
+ * Currently shares the same options structure as SetupBasicMocksOptions.
42
+ */
43
+ export type SetupDefaultMocksOptions = SetupBasicMocksOptions;
44
+ /**
45
+ * Sets up default testing mocks covering most common React testing scenarios.
46
+ *
47
+ * @param options Configuration options for the mocks
48
+ */
49
+ export declare const setupDefaultMocks: (options?: SetupDefaultMocksOptions) => void;
@@ -0,0 +1,19 @@
1
+ import failOnConsole from "vitest-fail-on-console";
2
+ type VitestFailOnConsoleOptions = NonNullable<Parameters<typeof failOnConsole>[0]>;
3
+ /**
4
+ * This will make your tests fail if they log to console.error during the tests.
5
+ * See more details here: https://www.npmjs.com/package/vitest-fail-on-console
6
+ *
7
+ * This setup also automatically suppresses jsdom CSS parsing errors for modern CSS features
8
+ * that jsdom doesn't support (@container queries and :has() selector). Other CSS parsing
9
+ * errors will still cause tests to fail.
10
+ *
11
+ * If your tests logs to console.error on purpose, you should spy on the console like so:
12
+ * ```
13
+ * vi.spyOn(console, 'error').mockImplementation()
14
+ * // Do your logic ...
15
+ * expect(console.error).toHaveBeenCalledWith('your error message')
16
+ * ```
17
+ */
18
+ export declare const setupFailOnConsole: (overrides?: VitestFailOnConsoleOptions) => void;
19
+ export {};
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Sets up mocks for Google Maps API and @vis.gl/react-google-maps components
3
+ * in testing environments.
4
+ *
5
+ * Replaces the `@vis.gl/react-google-maps` hooks/components (`APIProvider`,
6
+ * `useMap`, `Map`, `Marker`, `AdvancedMarker`, `InfoWindow`,
7
+ * `useApiIsLoaded`, `useApiLoadingStatus`) with deterministic fakes and
8
+ * registers a `beforeEach` hook that re-populates `global.window.google.maps`
9
+ * with mocked `Geocoder` / `geometry` / `AutocompleteService` implementations
10
+ * via `@googlemaps/jest-mocks`.
11
+ *
12
+ * Opt-in: the mock is registered via `vi.doMock` so it is
13
+ * NOT hoisted and only takes effect once `setupGoogleMaps()` is called from
14
+ * a test setup file. Tests that need the real `@vis.gl/react-google-maps`
15
+ * (or their own mock) are unaffected unless they explicitly call this.
16
+ *
17
+ * The factory body uses `require()` rather than `import` for
18
+ * `@vis.gl/react-google-maps` and `@googlemaps/jest-mocks` so neither
19
+ * package is evaluated until the factory actually runs (the latter still
20
+ * uses Jest globals internally, so a static import would crash any
21
+ * consumer that doesn't actually use the Google Maps mock).
22
+ *
23
+ * @example
24
+ * import { setupGoogleMaps } from '@trackunit/react-vite-test-setup';
25
+ * setupGoogleMaps();
26
+ */
27
+ export declare const setupGoogleMaps: () => void;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Replaces `react-helmet-async`'s `Helmet` and `HelmetProvider` with no-op
3
+ * components so head-mutating components rendered under test do not touch
4
+ * the jsdom document.
5
+ *
6
+ * Opt-in: the mock is registered via `vi.doMock` so it is
7
+ * NOT hoisted and only takes effect once `setupHelmetMock()` is called from
8
+ * a test setup file. Tests that need the real `react-helmet-async` (or
9
+ * their own mock) are unaffected unless they explicitly call this.
10
+ *
11
+ * See more details here: https://www.npmjs.com/package/react-helmet-async
12
+ *
13
+ * @example
14
+ * import { setupHelmetMock } from '@trackunit/react-vite-test-setup';
15
+ * setupHelmetMock();
16
+ */
17
+ export declare const setupHelmetMock: () => void;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Mocks the IntersectionObserver API for testing environments.
3
+ *
4
+ * This function adds a mock implementation of the IntersectionObserver API to the global window object.
5
+ * The mock implementation provides all the necessary methods (observe, unobserve, disconnect, takeRecords)
6
+ * but with empty implementations, allowing tests of components that use IntersectionObserver to run
7
+ * without errors in Jest's JSDOM environment.
8
+ *
9
+ * Useful for testing components that rely on:
10
+ * - Lazy loading
11
+ * - Infinite scrolling
12
+ * - Visibility-based rendering
13
+ * - Any other intersection-based functionality
14
+ *
15
+ * @example
16
+ * // In your jest setup file
17
+ * import { setupIntersectionObserver } from '@trackunit/react-vite-test-setup';
18
+ *
19
+ * setupIntersectionObserver();
20
+ */
21
+ export declare const setupIntersectionObserver: () => typeof MockIntersectionObserver;
22
+ declare class MockIntersectionObserver {
23
+ readonly root: Element | null;
24
+ readonly rootMargin: string;
25
+ readonly scrollMargin: string;
26
+ readonly thresholds: ReadonlyArray<number>;
27
+ constructor();
28
+ disconnect(): void;
29
+ observe(): void;
30
+ takeRecords(): Array<IntersectionObserverEntry>;
31
+ unobserve(): void;
32
+ }
33
+ export {};
@@ -0,0 +1,120 @@
1
+ import type { LngLat, LngLatBounds, LngLatLike, MapMouseEvent } from "mapbox-gl";
2
+ import { type Mock } from "vitest";
3
+ /**
4
+ * Type for event handlers stored in our mock map's listener registry.
5
+ * Using a generic to avoid `as` assertions when retrieving handlers.
6
+ */
7
+ type MapEventHandler<TEvent = unknown> = (event: TEvent) => void;
8
+ /**
9
+ * Shape of the mock map returned by createMockMapboxMap.
10
+ * Extends the necessary parts of mapboxgl.Map for adapter testing.
11
+ */
12
+ type MockMapboxMap = {
13
+ on: Mock<(event: string, handler: MapEventHandler) => MockMapboxMap>;
14
+ once: Mock<(event: string, handler: MapEventHandler) => MockMapboxMap>;
15
+ off: Mock<(event: string, handler: MapEventHandler) => MockMapboxMap>;
16
+ remove: Mock<() => void>;
17
+ getCenter: Mock<() => LngLat>;
18
+ getZoom: Mock<() => number>;
19
+ getBounds: Mock<() => LngLatBounds>;
20
+ setCenter: Mock<(center: LngLatLike) => MockMapboxMap>;
21
+ setZoom: Mock<(zoom: number) => MockMapboxMap>;
22
+ panTo: Mock<(lngLat: LngLatLike) => MockMapboxMap>;
23
+ panBy: Mock<(offset: [number, number]) => MockMapboxMap>;
24
+ fitBounds: Mock<(bounds: LngLatBounds, options: unknown) => MockMapboxMap>;
25
+ setStyle: Mock<(style: string) => MockMapboxMap>;
26
+ isStyleLoaded: Mock<() => boolean>;
27
+ isMoving: Mock<() => boolean>;
28
+ addSource: Mock;
29
+ removeSource: Mock;
30
+ getSource: Mock;
31
+ addLayer: Mock;
32
+ removeLayer: Mock;
33
+ getLayer: Mock;
34
+ setPaintProperty: Mock;
35
+ hasImage: Mock<() => boolean>;
36
+ addImage: Mock;
37
+ getCanvas: Mock;
38
+ getCanvasContainer: Mock;
39
+ };
40
+ /**
41
+ * Return type of createMockMapboxMap - provides both the mock map
42
+ * and a triggerEvent helper for simulating Mapbox events in tests.
43
+ */
44
+ type MockMapboxMapResult = {
45
+ /**
46
+ * The mock map instance. Cast to mapboxgl.Map when passing to adapter.connect().
47
+ * We return MockMapboxMap to preserve access to jest mock methods in tests.
48
+ */
49
+ readonly map: MockMapboxMap;
50
+ /**
51
+ * Triggers an event on the mock map, calling all registered handlers.
52
+ * Handles both regular (on) and one-time (once) listeners.
53
+ */
54
+ readonly triggerEvent: <TEvent = unknown>(eventName: string, event?: TEvent) => void;
55
+ };
56
+ /**
57
+ * Creates a mock Mapbox map instance for unit testing adapter instances directly.
58
+ *
59
+ * Use this when you need fine-grained control over mock behavior, such as:
60
+ * - Testing adapter instance methods (connect, setCenter, etc.)
61
+ * - Simulating map events (idle, click, movestart)
62
+ * - Verifying method calls on the map
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * import { createMockMapboxMap } from "@trackunit/react-vite-test-setup";
67
+ *
68
+ * it("should connect to map", () => {
69
+ * const { map, triggerEvent } = createMockMapboxMap();
70
+ * const adapter = new MapboxAdapterInstance(config);
71
+ *
72
+ * adapter.connect(map as unknown as mapboxgl.Map);
73
+ * triggerEvent("idle");
74
+ *
75
+ * expect(adapter.getState().isReady).toBe(true);
76
+ * });
77
+ * ```
78
+ */
79
+ export declare const createMockMapboxMap: () => MockMapboxMapResult;
80
+ /**
81
+ * Mock click event matching Mapbox GL's MapMouseEvent shape.
82
+ * Use with triggerEvent("click", createMockClickEvent(...))
83
+ *
84
+ * Note: The `point` property is intentionally omitted because:
85
+ * 1. It requires the full Point class from @mapbox/point-geometry with 30+ methods
86
+ * 2. No tests currently use the point property
87
+ * 3. Since this returns Partial<MapMouseEvent>, point is optional
88
+ */
89
+ export declare const createMockClickEvent: (lng: number, lat: number) => Partial<MapMouseEvent>;
90
+ /**
91
+ * Sets up mocks for Mapbox GL JS in testing environments.
92
+ *
93
+ * Replaces `mapbox-gl`'s `Map` and `Marker` constructors with deterministic
94
+ * fakes (the `Map` mock auto-fires the `load` event so renderer tests don't
95
+ * have to wait for it) and registers a `beforeEach` hook that clears mock
96
+ * call records between tests.
97
+ *
98
+ * Opt-in: the mock is registered via `vi.doMock` so it is
99
+ * NOT hoisted and only takes effect once `setupMapbox()` is called from a
100
+ * test setup file. Tests that need the real `mapbox-gl` (or their own mock)
101
+ * are unaffected unless they explicitly call this.
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * // In your test file
106
+ * import { setupMapbox } from "@trackunit/react-vite-test-setup";
107
+ *
108
+ * setupMapbox();
109
+ *
110
+ * describe("MapboxRenderer", () => {
111
+ * it("renders map when loaded", async () => {
112
+ * // The mock will auto-fire "load" event
113
+ * render(<MapboxRenderer adapterInstance={instance} />);
114
+ * await waitFor(() => expect(screen.getByRole("application")).toBeInTheDocument());
115
+ * });
116
+ * });
117
+ * ```
118
+ */
119
+ export declare const setupMapbox: () => void;
120
+ export {};