Skip to content

Commit dc7941d

Browse files
rshestfacebook-github-bot
authored andcommitted
Shim implementation for NativePerformance on JS side
Summary: Changelog: [Internal] Implements a shim for the NativePerformance TurboModule, which can be used as a mock to unit test the JS side of WebPerformance functionality (in particular, the higher level API logic of `Performance` and `PerformanceObserver` implementations in JS) without need to have the native NativePerformance implementation available (which would otherwise require running some heavy weight e2e tests). Reviewed By: rubennorte Differential Revision: D43985454 fbshipit-source-id: da10387c1d70cb0300c077972d3925bc2fad4f5e
1 parent 803bb16 commit dc7941d

File tree

2 files changed

+147
-0
lines changed

2 files changed

+147
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
*/
10+
11+
import type {
12+
NativeMemoryInfo,
13+
ReactNativeStartupTiming,
14+
Spec as NativePerformance,
15+
} from '../NativePerformance';
16+
17+
import NativePerformanceObserver from '../NativePerformanceObserver';
18+
import {RawPerformanceEntryTypeValues} from '../RawPerformanceEntry';
19+
20+
const marks: Map<string, number> = new Map();
21+
22+
const NativePerformanceMock: NativePerformance = {
23+
mark: (name: string, startTime: number, duration: number): void => {
24+
NativePerformanceObserver?.logRawEntry({
25+
name,
26+
entryType: RawPerformanceEntryTypeValues.MARK,
27+
startTime,
28+
duration,
29+
});
30+
marks.set(name, startTime);
31+
},
32+
33+
measure: (
34+
name: string,
35+
startTime: number,
36+
endTime: number,
37+
duration?: number,
38+
startMark?: string,
39+
endMark?: string,
40+
): void => {
41+
const start = startMark != null ? marks.get(startMark) ?? 0 : startTime;
42+
const end = endMark != null ? marks.get(endMark) ?? 0 : endTime;
43+
NativePerformanceObserver?.logRawEntry({
44+
name,
45+
entryType: RawPerformanceEntryTypeValues.MEASURE,
46+
startTime: start,
47+
duration: duration ?? (end ? end - start : 0),
48+
});
49+
},
50+
51+
getSimpleMemoryInfo: (): NativeMemoryInfo => {
52+
return {};
53+
},
54+
55+
getReactNativeStartupTiming: (): ReactNativeStartupTiming => {
56+
return {
57+
startTime: 0,
58+
endTime: 0,
59+
executeJavaScriptBundleEntryPointStart: 0,
60+
executeJavaScriptBundleEntryPointEnd: 0,
61+
};
62+
},
63+
};
64+
65+
export default NativePerformanceMock;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @oncall react_native
9+
*/
10+
11+
const NativePerformanceMock = require('../__mocks__/NativePerformance').default;
12+
const PerformanceObserver = require('../PerformanceObserver').default;
13+
14+
describe('NativePerformanceMock', () => {
15+
jest.mock(
16+
'../NativePerformanceObserver',
17+
() => require('../__mocks__/NativePerformanceObserver').default,
18+
);
19+
20+
it('marks get reported', async () => {
21+
let entries = [];
22+
const observer = new PerformanceObserver((list, _observer) => {
23+
entries = [...entries, ...list.getEntries()];
24+
});
25+
26+
observer.observe({type: 'mark'});
27+
28+
NativePerformanceMock.mark('mark1', 0, 10);
29+
NativePerformanceMock.mark('mark2', 5, 10);
30+
NativePerformanceMock.mark('mark3', 10, 20);
31+
32+
await jest.runAllTicks();
33+
expect(entries).toHaveLength(3);
34+
expect(entries.map(e => e.name)).toStrictEqual(['mark1', 'mark2', 'mark3']);
35+
expect(entries.map(e => e.startTime)).toStrictEqual([0, 5, 10]);
36+
});
37+
38+
it('measures get reported', async () => {
39+
let entries = [];
40+
const observer = new PerformanceObserver((list, _observer) => {
41+
entries = [...entries, ...list.getEntries()];
42+
});
43+
44+
observer.observe({entryTypes: ['measure']});
45+
46+
NativePerformanceMock.mark('mark0', 0.0, 1.0);
47+
NativePerformanceMock.mark('mark1', 1.0, 3.0);
48+
NativePerformanceMock.mark('mark2', 2.0, 4.0);
49+
50+
NativePerformanceMock.measure('measure0', 0, 2);
51+
NativePerformanceMock.measure('measure1', 0, 2, 4);
52+
NativePerformanceMock.measure(
53+
'measure2',
54+
0,
55+
0,
56+
undefined,
57+
'mark1',
58+
'mark2',
59+
);
60+
NativePerformanceMock.measure('measure3', 0, 0, 5, 'mark1');
61+
NativePerformanceMock.measure(
62+
'measure4',
63+
1.5,
64+
0,
65+
undefined,
66+
undefined,
67+
'mark2',
68+
);
69+
70+
await jest.runAllTicks();
71+
expect(entries).toHaveLength(5);
72+
expect(entries.map(e => e.name)).toStrictEqual([
73+
'measure0',
74+
'measure1',
75+
'measure2',
76+
'measure3',
77+
'measure4',
78+
]);
79+
expect(entries.map(e => e.startTime)).toStrictEqual([0, 0, 1, 1, 1.5]);
80+
expect(entries.map(e => e.duration)).toStrictEqual([2, 4, 1, 5, 0.5]);
81+
});
82+
});

0 commit comments

Comments
 (0)