@multiplatform.one/test-utils 7.49.1 → 7.49.2
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 +6 -1
- package/src/frames.ts +85 -0
- package/src/setup.ts +8 -9
- package/types/frames.d.ts +19 -0
- package/types/frames.d.ts.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/test-utils",
|
|
3
|
-
"version": "7.49.
|
|
3
|
+
"version": "7.49.2",
|
|
4
4
|
"description": "Shared testing utilities for multiplatform.one packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multiplatform.one",
|
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
"import": "./src/setup.ts",
|
|
44
44
|
"require": "./src/setup.ts"
|
|
45
45
|
},
|
|
46
|
+
"./frames": {
|
|
47
|
+
"types": "./types/frames.d.ts",
|
|
48
|
+
"import": "./src/frames.ts",
|
|
49
|
+
"require": "./src/frames.ts"
|
|
50
|
+
},
|
|
46
51
|
"./mocks": {
|
|
47
52
|
"types": "./types/mocks.d.ts",
|
|
48
53
|
"import": "./src/mocks.ts",
|
package/src/frames.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animation frames that die with the spec file that requested them (FZ-7904).
|
|
3
|
+
*
|
|
4
|
+
* A frame is one zero-delay timer, resolved at call time so fake timers still
|
|
5
|
+
* drive it. A bare Node timer belongs to Node, not to the test window, so the
|
|
6
|
+
* window's close() in vitest's teardown never stops it: a frame still pending
|
|
7
|
+
* when the file ends fires after teardown deleted the requestAnimationFrame
|
|
8
|
+
* global, and vitest fails the whole run on that one unhandled error. These
|
|
9
|
+
* frames stay tracked. close() cancels every pending frame and refuses new
|
|
10
|
+
* ones, which is what a browser does with the frames of a document it unloads.
|
|
11
|
+
*/
|
|
12
|
+
import { vi } from "vitest";
|
|
13
|
+
|
|
14
|
+
export interface AnimationFrames {
|
|
15
|
+
request: (callback: FrameRequestCallback) => number;
|
|
16
|
+
cancel: (handle: number) => void;
|
|
17
|
+
close: () => void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createAnimationFrames(): AnimationFrames {
|
|
21
|
+
const pending = new Map<number, ReturnType<typeof setTimeout>>();
|
|
22
|
+
let last = 0;
|
|
23
|
+
let closed = false;
|
|
24
|
+
return {
|
|
25
|
+
request(callback) {
|
|
26
|
+
last += 1;
|
|
27
|
+
const handle = last;
|
|
28
|
+
if (closed) return handle;
|
|
29
|
+
pending.set(
|
|
30
|
+
handle,
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
if (pending.delete(handle)) callback(performance.now());
|
|
33
|
+
}, 0),
|
|
34
|
+
);
|
|
35
|
+
return handle;
|
|
36
|
+
},
|
|
37
|
+
cancel(handle) {
|
|
38
|
+
clearTimeout(pending.get(handle));
|
|
39
|
+
pending.delete(handle);
|
|
40
|
+
},
|
|
41
|
+
close() {
|
|
42
|
+
closed = true;
|
|
43
|
+
for (const timer of pending.values()) clearTimeout(timer);
|
|
44
|
+
pending.clear();
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface HeldAnimationFrames {
|
|
50
|
+
/** Frames requested and neither run nor cancelled. */
|
|
51
|
+
readonly pending: number;
|
|
52
|
+
/** Run the frames pending right now; frames they request wait for the next call. */
|
|
53
|
+
flush: () => void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Replace requestAnimationFrame with frames that only run on `flush()`, so a
|
|
58
|
+
* spec can see which frames a component leaves behind. Undone by
|
|
59
|
+
* `vi.unstubAllGlobals()`.
|
|
60
|
+
*/
|
|
61
|
+
export function holdAnimationFrames(): HeldAnimationFrames {
|
|
62
|
+
const pending = new Map<number, FrameRequestCallback>();
|
|
63
|
+
let last = 0;
|
|
64
|
+
vi.stubGlobal("requestAnimationFrame", (callback: FrameRequestCallback) => {
|
|
65
|
+
last += 1;
|
|
66
|
+
pending.set(last, callback);
|
|
67
|
+
return last;
|
|
68
|
+
});
|
|
69
|
+
vi.stubGlobal("cancelAnimationFrame", (handle: number) => {
|
|
70
|
+
pending.delete(handle);
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
get pending() {
|
|
74
|
+
return pending.size;
|
|
75
|
+
},
|
|
76
|
+
flush() {
|
|
77
|
+
for (const handle of [...pending.keys()]) {
|
|
78
|
+
const callback = pending.get(handle);
|
|
79
|
+
if (!callback) continue;
|
|
80
|
+
pending.delete(handle);
|
|
81
|
+
callback(performance.now());
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
package/src/setup.ts
CHANGED
|
@@ -217,7 +217,8 @@ import "matchmedia-polyfill";
|
|
|
217
217
|
import { config } from "@tamagui/config";
|
|
218
218
|
import { cleanup } from "@testing-library/react";
|
|
219
219
|
import { createTamagui } from "tamagui";
|
|
220
|
-
import { afterEach, beforeEach, vi } from "vitest";
|
|
220
|
+
import { afterAll, afterEach, beforeEach, vi } from "vitest";
|
|
221
|
+
import { createAnimationFrames } from "./frames";
|
|
221
222
|
|
|
222
223
|
// Patch @floating-ui/react to handle missing forEach in test environment
|
|
223
224
|
try {
|
|
@@ -306,14 +307,12 @@ window.matchMedia =
|
|
|
306
307
|
removeListener: () => {},
|
|
307
308
|
}));
|
|
308
309
|
|
|
309
|
-
//
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
clearTimeout(id);
|
|
316
|
-
};
|
|
310
|
+
// Tracked frames (FZ-7904). This afterAll is registered first, so it runs
|
|
311
|
+
// last in the file: after every unmount, before vitest tears the window down.
|
|
312
|
+
const animationFrames = createAnimationFrames();
|
|
313
|
+
global.requestAnimationFrame = animationFrames.request;
|
|
314
|
+
global.cancelAnimationFrame = animationFrames.cancel;
|
|
315
|
+
afterAll(animationFrames.close);
|
|
317
316
|
|
|
318
317
|
// ResizeObserver mock
|
|
319
318
|
class MockResizeObserver {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface AnimationFrames {
|
|
2
|
+
request: (callback: FrameRequestCallback) => number;
|
|
3
|
+
cancel: (handle: number) => void;
|
|
4
|
+
close: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createAnimationFrames(): AnimationFrames;
|
|
7
|
+
export interface HeldAnimationFrames {
|
|
8
|
+
/** Frames requested and neither run nor cancelled. */
|
|
9
|
+
readonly pending: number;
|
|
10
|
+
/** Run the frames pending right now; frames they request wait for the next call. */
|
|
11
|
+
flush: () => void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Replace requestAnimationFrame with frames that only run on `flush()`, so a
|
|
15
|
+
* spec can see which frames a component leaves behind. Undone by
|
|
16
|
+
* `vi.unstubAllGlobals()`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function holdAnimationFrames(): HeldAnimationFrames;
|
|
19
|
+
//# sourceMappingURL=frames.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../src/frames.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,MAAM,CAAC;IACpD,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,qBAAqB,IAAI,eAAe,CA2BvD;AAED,MAAM,WAAW,mBAAmB;IAClC,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,mBAAmB,CAwBzD"}
|