From ad8f88228c5d644ffd33b5ba7824baa10f588aa6 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 5 Aug 2021 09:38:29 -0400 Subject: [PATCH] Updated scheduling profiler tests (and refactored to use inline snapshots) --- .../__tests__/preprocessData-test.internal.js | 805 +++++++++++------- .../src/import-worker/preprocessData.js | 2 +- .../src/SchedulingProfiler.js | 9 +- .../SchedulingProfiler-test.internal.js | 628 ++++++++------ .../SchedulingProfilerLabels-test.internal.js | 154 ++-- 5 files changed, 988 insertions(+), 610 deletions(-) diff --git a/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js b/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js index f47200c6f0e21..81333c8e5abd0 100644 --- a/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js +++ b/packages/react-devtools-scheduling-profiler/src/import-worker/__tests__/preprocessData-test.internal.js @@ -7,10 +7,13 @@ 'use strict'; +import {getLaneLabels} from 'react-reconciler/src/SchedulingProfiler'; import preprocessData, { + SUPPORTED_PROFILER_VERSION, getLanesFromTransportDecimalBitmask, } from '../preprocessData'; import {REACT_TOTAL_NUM_LANES} from '../../constants'; +import REACT_VERSION from 'shared/ReactVersion'; describe(getLanesFromTransportDecimalBitmask, () => { it('should return array of lane numbers from bitmask string', () => { @@ -109,6 +112,35 @@ describe(preprocessData, () => { }; } + function createProfilerVersionEntry() { + return createUserTimingEntry({ + cat: 'blink.user_timing', + name: '--profiler-version-' + SUPPORTED_PROFILER_VERSION, + }); + } + + function createReactVersionEntry() { + return createUserTimingEntry({ + cat: 'blink.user_timing', + name: '--react-version-' + REACT_VERSION, + }); + } + + function createLaneLabelsEntry() { + return createUserTimingEntry({ + cat: 'blink.user_timing', + name: '--react-lane-labels-' + getLaneLabels().join(','), + }); + } + + function createBoilerplateEntries() { + return [ + createProfilerVersionEntry(), + createReactVersionEntry(), + createLaneLabelsEntry(), + ]; + } + function createUserTimingData(sampleMarks) { const cpuProfilerSample = createUserTimingEntry({ args: {data: {startTime: ++startTime}}, @@ -192,7 +224,6 @@ describe(preprocessData, () => { name: 'Profile', ph: 'P', }); - const randomSample = createUserTimingEntry({ dur: 100, tdur: 200, @@ -202,20 +233,62 @@ describe(preprocessData, () => { args: {}, }); - expect(preprocessData([cpuProfilerSample, randomSample])).toStrictEqual({ - componentMeasures: [], - duration: 0.002, - flamechart: [], - measures: [], - nativeEvents: [], - otherUserTimingMarks: [], - schedulingEvents: [], - startTime: 1, - suspenseEvents: [], - }); + if (gate(flags => flags.enableSchedulingProfiler)) { + const data = preprocessData([ + ...createBoilerplateEntries(), + cpuProfilerSample, + randomSample, + ]); + expect(data).toMatchInlineSnapshot(` + Object { + "componentMeasures": Array [], + "duration": 0.005, + "flamechart": Array [], + "laneToLabelMap": Map { + 0 => "Sync", + 1 => "InputContinuousHydration", + 2 => "InputContinuous", + 3 => "DefaultHydration", + 4 => "Default", + 5 => "TransitionHydration", + 6 => "Transition", + 7 => "Transition", + 8 => "Transition", + 9 => "Transition", + 10 => "Transition", + 11 => "Transition", + 12 => "Transition", + 13 => "Transition", + 14 => "Transition", + 15 => "Transition", + 16 => "Transition", + 17 => "Transition", + 18 => "Transition", + 19 => "Transition", + 20 => "Transition", + 21 => "Transition", + 22 => "Retry", + 23 => "Retry", + 24 => "Retry", + 25 => "Retry", + 26 => "Retry", + 27 => "SelectiveHydration", + 28 => "IdleHydration", + 29 => "Idle", + 30 => "Offscreen", + }, + "measures": Array [], + "nativeEvents": Array [], + "otherUserTimingMarks": Array [], + "reactVersion": "17.0.3", + "schedulingEvents": Array [], + "startTime": 1, + "suspenseEvents": Array [], + } + `); + } }); - // NOTE This test doesn't have to be gated because it has hard-coded profiler samples. it('should process legacy data format (before lane labels were added)', () => { const cpuProfilerSample = createUserTimingEntry({ args: {data: {startTime: ++startTime}}, @@ -225,10 +298,11 @@ describe(preprocessData, () => { ph: 'P', }); - expect( + if (gate(flags => flags.enableSchedulingProfiler)) { // Data below is hard-coded based on an older profile sample. // Should be fine since this is explicitly a legacy-format test. - preprocessData([ + const data = preprocessData([ + ...createBoilerplateEntries(), cpuProfilerSample, createUserTimingEntry({ cat: 'blink.user_timing', @@ -258,140 +332,220 @@ describe(preprocessData, () => { cat: 'blink.user_timing', name: '--commit-stop', }), - ]), - ).toStrictEqual({ - componentMeasures: [], - duration: 0.008, - flamechart: [], - measures: [ - { - batchUID: 0, - depth: 0, - duration: 0.005, - laneLabels: [], - lanes: [9], - timestamp: 0.003, - type: 'render-idle', - }, - { - batchUID: 0, - depth: 0, - duration: 0.001, - laneLabels: [], - lanes: [9], - timestamp: 0.003, - type: 'render', - }, - { - batchUID: 0, - depth: 0, - duration: 0.003, - laneLabels: [], - lanes: [9], - timestamp: 0.005, - type: 'commit', + ]); + expect(data).toMatchInlineSnapshot(` + Object { + "componentMeasures": Array [], + "duration": 0.011, + "flamechart": Array [], + "laneToLabelMap": Map { + 0 => "Sync", + 1 => "InputContinuousHydration", + 2 => "InputContinuous", + 3 => "DefaultHydration", + 4 => "Default", + 5 => "TransitionHydration", + 6 => "Transition", + 7 => "Transition", + 8 => "Transition", + 9 => "Transition", + 10 => "Transition", + 11 => "Transition", + 12 => "Transition", + 13 => "Transition", + 14 => "Transition", + 15 => "Transition", + 16 => "Transition", + 17 => "Transition", + 18 => "Transition", + 19 => "Transition", + 20 => "Transition", + 21 => "Transition", + 22 => "Retry", + 23 => "Retry", + 24 => "Retry", + 25 => "Retry", + 26 => "Retry", + 27 => "SelectiveHydration", + 28 => "IdleHydration", + 29 => "Idle", + 30 => "Offscreen", }, - { - batchUID: 0, - depth: 1, - duration: 0.001, - laneLabels: [], - lanes: [9], - timestamp: 0.006, - type: 'layout-effects', - }, - ], - nativeEvents: [], - otherUserTimingMarks: [], - schedulingEvents: [ - { - laneLabels: [], - lanes: [9], - timestamp: 0.002, - type: 'schedule-render', - warning: null, - }, - ], - startTime: 1, - suspenseEvents: [], - }); + "measures": Array [ + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.004999999999999999, + "lanes": Array [ + 9, + ], + "timestamp": 0.006, + "type": "render-idle", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.001, + "lanes": Array [ + 9, + ], + "timestamp": 0.006, + "type": "render", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.002999999999999999, + "lanes": Array [ + 9, + ], + "timestamp": 0.008, + "type": "commit", + }, + Object { + "batchUID": 0, + "depth": 1, + "duration": 0.0010000000000000009, + "lanes": Array [ + 9, + ], + "timestamp": 0.009, + "type": "layout-effects", + }, + ], + "nativeEvents": Array [], + "otherUserTimingMarks": Array [], + "reactVersion": "17.0.3", + "schedulingEvents": Array [ + Object { + "lanes": Array [ + 9, + ], + "timestamp": 0.005, + "type": "schedule-render", + "warning": null, + }, + ], + "startTime": 1, + "suspenseEvents": Array [], + } + `); + } }); - // @gate enableSchedulingProfiler it('should process a sample legacy render sequence', () => { ReactDOM.render(
, document.createElement('div')); - const reactVersion = require('shared/ReactVersion').default; - - const userTimingData = createUserTimingData(clearedMarks); - expect(preprocessData(userTimingData)).toStrictEqual({ - componentMeasures: [], - duration: 0.011, - flamechart: [], - measures: [ - { - batchUID: 0, - depth: 0, - duration: 0.004999999999999999, - laneLabels: ['Sync'], - lanes: [0], - timestamp: 0.006, - type: 'render-idle', - }, - { - batchUID: 0, - depth: 0, - duration: 0.001, - laneLabels: ['Sync'], - lanes: [0], - timestamp: 0.006, - type: 'render', - }, - { - batchUID: 0, - depth: 0, - duration: 0.002999999999999999, - laneLabels: ['Sync'], - lanes: [0], - timestamp: 0.008, - type: 'commit', - }, - { - batchUID: 0, - depth: 1, - duration: 0.0010000000000000009, - laneLabels: ['Sync'], - lanes: [0], - timestamp: 0.009, - type: 'layout-effects', - }, - ], - nativeEvents: [], - otherUserTimingMarks: [ - { - name: '__v3', - timestamp: 0.003, - }, - { - name: `--react-init-${reactVersion}`, - timestamp: 0.004, + if (gate(flags => flags.enableSchedulingProfiler)) { + const data = preprocessData([ + ...createBoilerplateEntries(), + ...createUserTimingData(clearedMarks), + ]); + expect(data).toMatchInlineSnapshot(` + Object { + "componentMeasures": Array [], + "duration": 0.013, + "flamechart": Array [], + "laneToLabelMap": Map { + 0 => "Sync", + 1 => "InputContinuousHydration", + 2 => "InputContinuous", + 3 => "DefaultHydration", + 4 => "Default", + 5 => "TransitionHydration", + 6 => "Transition", + 7 => "Transition", + 8 => "Transition", + 9 => "Transition", + 10 => "Transition", + 11 => "Transition", + 12 => "Transition", + 13 => "Transition", + 14 => "Transition", + 15 => "Transition", + 16 => "Transition", + 17 => "Transition", + 18 => "Transition", + 19 => "Transition", + 20 => "Transition", + 21 => "Transition", + 22 => "Retry", + 23 => "Retry", + 24 => "Retry", + 25 => "Retry", + 26 => "Retry", + 27 => "SelectiveHydration", + 28 => "IdleHydration", + 29 => "Idle", + 30 => "Offscreen", }, - ], - schedulingEvents: [ - { - laneLabels: ['Sync'], - lanes: [0], - timestamp: 0.005, - type: 'schedule-render', - warning: null, - }, - ], - startTime: 1, - suspenseEvents: [], - }); + "measures": Array [ + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.008, + "lanes": Array [ + 0, + ], + "timestamp": 0.005, + "type": "render-idle", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.001, + "lanes": Array [ + 0, + ], + "timestamp": 0.005, + "type": "render", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.005999999999999999, + "lanes": Array [ + 0, + ], + "timestamp": 0.007, + "type": "commit", + }, + Object { + "batchUID": 0, + "depth": 1, + "duration": 0.0010000000000000009, + "lanes": Array [ + 0, + ], + "timestamp": 0.011, + "type": "layout-effects", + }, + ], + "nativeEvents": Array [], + "otherUserTimingMarks": Array [ + Object { + "name": "__v3", + "timestamp": 0.003, + }, + ], + "reactVersion": "17.0.3", + "schedulingEvents": Array [ + Object { + "lanes": Array [ + 0, + ], + "timestamp": 0.004, + "type": "schedule-render", + "warning": null, + }, + ], + "startTime": 4, + "suspenseEvents": Array [], + } + `); + } }); - // @gate enableSchedulingProfiler it('should process a sample createRoot render sequence', () => { function App() { const [didMount, setDidMount] = React.useState(false); @@ -403,150 +557,199 @@ describe(preprocessData, () => { return true; } - const root = ReactDOM.createRoot(document.createElement('div')); - act(() => root.render()); - - const userTimingData = createUserTimingData(clearedMarks); - expect(preprocessData(userTimingData)).toStrictEqual({ - componentMeasures: [ - { - componentName: 'App', - duration: 0.001, - timestamp: 0.007, - warning: null, - }, - { - componentName: 'App', - duration: 0.0010000000000000009, - timestamp: 0.018, - warning: null, - }, - ], - duration: 0.026, - flamechart: [], - measures: [ - { - batchUID: 0, - depth: 0, - duration: 0.006999999999999999, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.006, - type: 'render-idle', - }, - { - batchUID: 0, - depth: 0, - duration: 0.002999999999999999, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.006, - type: 'render', - }, - { - batchUID: 0, - depth: 0, - duration: 0.002999999999999999, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.01, - type: 'commit', - }, - { - batchUID: 0, - depth: 1, - duration: 0.0010000000000000009, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.011, - type: 'layout-effects', - }, - { - batchUID: 0, - depth: 0, - duration: 0.002, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.014, - type: 'passive-effects', - }, - { - batchUID: 1, - depth: 0, - duration: 0.006999999999999999, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.017, - type: 'render-idle', - }, - { - batchUID: 1, - depth: 0, - duration: 0.002999999999999999, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.017, - type: 'render', - }, - { - batchUID: 1, - depth: 0, - duration: 0.002999999999999999, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.021, - type: 'commit', - }, - { - batchUID: 1, - depth: 1, - duration: 0.0010000000000000009, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.022, - type: 'layout-effects', + if (gate(flags => flags.enableSchedulingProfiler)) { + const root = ReactDOM.createRoot(document.createElement('div')); + act(() => root.render()); + + const data = preprocessData([ + ...createBoilerplateEntries(), + ...createUserTimingData(clearedMarks), + ]); + expect(data).toMatchInlineSnapshot(` + Object { + "componentMeasures": Array [ + Object { + "componentName": "App", + "duration": 0.001, + "timestamp": 0.006, + "warning": null, + }, + Object { + "componentName": "App", + "duration": 0.0010000000000000009, + "timestamp": 0.02, + "warning": null, + }, + ], + "duration": 0.031, + "flamechart": Array [], + "laneToLabelMap": Map { + 0 => "Sync", + 1 => "InputContinuousHydration", + 2 => "InputContinuous", + 3 => "DefaultHydration", + 4 => "Default", + 5 => "TransitionHydration", + 6 => "Transition", + 7 => "Transition", + 8 => "Transition", + 9 => "Transition", + 10 => "Transition", + 11 => "Transition", + 12 => "Transition", + 13 => "Transition", + 14 => "Transition", + 15 => "Transition", + 16 => "Transition", + 17 => "Transition", + 18 => "Transition", + 19 => "Transition", + 20 => "Transition", + 21 => "Transition", + 22 => "Retry", + 23 => "Retry", + 24 => "Retry", + 25 => "Retry", + 26 => "Retry", + 27 => "SelectiveHydration", + 28 => "IdleHydration", + 29 => "Idle", + 30 => "Offscreen", }, - { - batchUID: 1, - depth: 0, - duration: 0.0009999999999999974, - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.025, - type: 'passive-effects', - }, - ], - nativeEvents: [], - otherUserTimingMarks: [ - { - name: '__v3', - timestamp: 0.003, - }, - { - name: '--react-init-17.0.3', - timestamp: 0.004, - }, - ], - schedulingEvents: [ - { - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.005, - type: 'schedule-render', - warning: null, - }, - { - componentName: 'App', - laneLabels: ['Default'], - lanes: [4], - timestamp: 0.015, - type: 'schedule-state-update', - warning: null, - }, - ], - startTime: 1, - suspenseEvents: [], - }); + "measures": Array [ + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.009999999999999998, + "lanes": Array [ + 4, + ], + "timestamp": 0.005, + "type": "render-idle", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.003, + "lanes": Array [ + 4, + ], + "timestamp": 0.005, + "type": "render", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.006, + "lanes": Array [ + 4, + ], + "timestamp": 0.009, + "type": "commit", + }, + Object { + "batchUID": 0, + "depth": 1, + "duration": 0.0010000000000000009, + "lanes": Array [ + 4, + ], + "timestamp": 0.013, + "type": "layout-effects", + }, + Object { + "batchUID": 0, + "depth": 0, + "duration": 0.0019999999999999983, + "lanes": Array [ + 4, + ], + "timestamp": 0.016, + "type": "passive-effects", + }, + Object { + "batchUID": 1, + "depth": 0, + "duration": 0.010000000000000002, + "lanes": Array [ + 4, + ], + "timestamp": 0.019, + "type": "render-idle", + }, + Object { + "batchUID": 1, + "depth": 0, + "duration": 0.002999999999999999, + "lanes": Array [ + 4, + ], + "timestamp": 0.019, + "type": "render", + }, + Object { + "batchUID": 1, + "depth": 0, + "duration": 0.006000000000000002, + "lanes": Array [ + 4, + ], + "timestamp": 0.023, + "type": "commit", + }, + Object { + "batchUID": 1, + "depth": 1, + "duration": 0.0010000000000000009, + "lanes": Array [ + 4, + ], + "timestamp": 0.027, + "type": "layout-effects", + }, + Object { + "batchUID": 1, + "depth": 0, + "duration": 0.0010000000000000009, + "lanes": Array [ + 4, + ], + "timestamp": 0.03, + "type": "passive-effects", + }, + ], + "nativeEvents": Array [], + "otherUserTimingMarks": Array [ + Object { + "name": "__v3", + "timestamp": 0.003, + }, + ], + "reactVersion": "17.0.3", + "schedulingEvents": Array [ + Object { + "lanes": Array [ + 4, + ], + "timestamp": 0.004, + "type": "schedule-render", + "warning": null, + }, + Object { + "componentName": "App", + "lanes": Array [ + 4, + ], + "timestamp": 0.017, + "type": "schedule-state-update", + "warning": null, + }, + ], + "startTime": 4, + "suspenseEvents": Array [], + } + `); + } }); // @gate enableSchedulingProfiler @@ -560,7 +763,7 @@ describe(preprocessData, () => { const invalidUserTimingData = createUserTimingData(invalidMarks); const error = spyOnDevAndProd(console, 'error'); - preprocessData(invalidUserTimingData); + preprocessData([...createBoilerplateEntries(), ...invalidUserTimingData]); expect(error).toHaveBeenCalled(); }); @@ -575,7 +778,7 @@ describe(preprocessData, () => { const invalidUserTimingData = createUserTimingData(invalidMarks); const error = spyOnDevAndProd(console, 'error'); - preprocessData(invalidUserTimingData); + preprocessData([...createBoilerplateEntries(), ...invalidUserTimingData]); expect(error).toHaveBeenCalled(); }); @@ -606,20 +809,26 @@ describe(preprocessData, () => { }), ); - expect(preprocessData(userTimingData).otherUserTimingMarks).toStrictEqual([ - { - name: 'VCWithoutImage: root', - timestamp: 0.003, - }, - { - name: '--a-mark-that-looks-like-one-of-ours', - timestamp: 0.004, - }, - { - name: 'Some other mark', - timestamp: 0.005, - }, + const data = preprocessData([ + ...createBoilerplateEntries(), + ...userTimingData, ]); + expect(data.otherUserTimingMarks).toMatchInlineSnapshot(` + Array [ + Object { + "name": "VCWithoutImage: root", + "timestamp": 0.003, + }, + Object { + "name": "--a-mark-that-looks-like-one-of-ours", + "timestamp": 0.004, + }, + Object { + "name": "Some other mark", + "timestamp": 0.005, + }, + ] + `); }); // TODO: Add test for flamechart parsing diff --git a/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js b/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js index 75f10b4c9570d..60c0c36c11a32 100644 --- a/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js +++ b/packages/react-devtools-scheduling-profiler/src/import-worker/preprocessData.js @@ -47,7 +47,7 @@ type ProcessorState = {| // Increment this number any time a backwards breaking change is made to the profiler metadata. // It should be in sync with the version in react-reconciler/src/SchedulingProfiler -const SUPPORTED_PROFILER_VERSION = 1; +export const SUPPORTED_PROFILER_VERSION = 1; const NATIVE_EVENT_DURATION_THRESHOLD = 20; diff --git a/packages/react-reconciler/src/SchedulingProfiler.js b/packages/react-reconciler/src/SchedulingProfiler.js index 504202b1c9c07..461d30666a555 100644 --- a/packages/react-reconciler/src/SchedulingProfiler.js +++ b/packages/react-reconciler/src/SchedulingProfiler.js @@ -71,9 +71,9 @@ if (enableSchedulingProfiler) { } } -const laneLabels: Array = []; +const laneLabels: Array = []; -function markLaneToLabelMetadata() { +export function getLaneLabels(): Array { if (laneLabels.length === 0) { let lane = 1; for (let index = 0; index < TotalLanes; index++) { @@ -82,6 +82,11 @@ function markLaneToLabelMetadata() { lane *= 2; } } + return laneLabels; +} + +function markLaneToLabelMetadata() { + getLaneLabels(); markAndClear(`--react-lane-labels-${laneLabels.join(',')}`); } diff --git a/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js b/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js index 4b496b732a21d..8680d19b710bf 100644 --- a/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js +++ b/packages/react-reconciler/src/__tests__/SchedulingProfiler-test.internal.js @@ -10,17 +10,6 @@ 'use strict'; -// This test is *.internal so that it can import this shared file. -import ReactVersion from 'shared/ReactVersion'; - -// Hard-coding because importing will not work with bundle tests and to -// avoid leaking exports for lanes that are only imported in this test. -const ReactFiberLane = { - SyncLane: /* */ 0b0000000000000000000000000000001, - DefaultLane: /* */ 0b0000000000000000000000000010000, - TransitionLane1: /* */ 0b0000000000000000000000001000000, -}; - describe('SchedulingProfiler', () => { let React; let ReactTestRenderer; @@ -30,7 +19,6 @@ describe('SchedulingProfiler', () => { let clearedMarks; let featureDetectionMarkName = null; - let formatLanes; let marks; function createUserTimingPolyfill() { @@ -63,16 +51,10 @@ describe('SchedulingProfiler', () => { clearedMarks.splice(0); } - function expectMarksToContain(expectedMarks) { - expect(clearedMarks).toContain(expectedMarks); - } - - function expectMarksToEqual(expectedMarks) { - expect( - clearedMarks[0] === featureDetectionMarkName - ? clearedMarks.slice(1) - : clearedMarks, - ).toEqual(expectedMarks); + function getMarks() { + return clearedMarks[0] === featureDetectionMarkName + ? clearedMarks.slice(1) + : clearedMarks; } beforeEach(() => { @@ -88,9 +70,6 @@ describe('SchedulingProfiler', () => { Scheduler = require('scheduler'); act = require('jest-react').act; - - const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler'); - formatLanes = SchedulingProfiler.formatLanes; }); afterEach(() => { @@ -103,54 +82,62 @@ describe('SchedulingProfiler', () => { // @gate !enableSchedulingProfiler it('should not mark if enableSchedulingProfiler is false', () => { ReactTestRenderer.create(
); - expectMarksToEqual([]); + expect(getMarks()).toEqual([]); }); - // @gate enableSchedulingProfiler - it('should log React version on initialization', () => { - expectMarksToEqual([`--react-init-${ReactVersion}`]); - }); - - // @gate enableSchedulingProfiler it('should mark sync render without suspends or state updates', () => { ReactTestRenderer.create(
); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, - `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--layout-effects-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-1", + "--render-start-1", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-1", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark concurrent render without suspends or state updates', () => { ReactTestRenderer.create(
, {unstable_isConcurrent: true}); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); expect(Scheduler).toFlushUntilNextPaint([]); - expectMarksToEqual([ - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--layout-effects-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark render yields', async () => { function Bar() { Scheduler.unstable_yieldValue('Bar'); @@ -170,30 +157,31 @@ describe('SchedulingProfiler', () => { // Do one step of work. expect(ReactNoop.flushNextYield()).toEqual(['Foo']); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.TransitionLane1)}`, - `--render-start-${formatLanes(ReactFiberLane.TransitionLane1)}`, - '--component-render-start-Foo', - '--component-render-stop', - '--render-yield', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-64", + "--render-start-64", + "--component-render-start-Foo", + "--component-render-stop", + "--render-yield", + ] + `); + } } else { ReactNoop.render(); // Do one step of work. expect(ReactNoop.flushNextYield()).toEqual(['Foo']); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--render-yield', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [] + `); + } } }); - // @gate enableSchedulingProfiler it('should mark sync render with suspense that resolves', async () => { const fakeSuspensePromise = Promise.resolve(true); function Example() { @@ -206,27 +194,38 @@ describe('SchedulingProfiler', () => { , ); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, - `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--suspense-suspend-0-Example-mount-1-Sync', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--layout-effects-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-1", + "--render-start-1", + "--component-render-start-Example", + "--component-render-stop", + "--suspense-suspend-0-Example-mount-1", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-1", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } clearPendingMarks(); await fakeSuspensePromise; - expectMarksToEqual(['--suspense-resolved-0-Example']); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--suspense-resolved-0-Example", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark sync render with suspense that rejects', async () => { const fakeSuspensePromise = Promise.reject(new Error('error')); function Example() { @@ -239,27 +238,38 @@ describe('SchedulingProfiler', () => { , ); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, - `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--suspense-suspend-0-Example-mount-1-Sync', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--layout-effects-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-1", + "--render-start-1", + "--component-render-start-Example", + "--component-render-stop", + "--suspense-suspend-0-Example-mount-1", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-1", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } clearPendingMarks(); await expect(fakeSuspensePromise).rejects.toThrow(); - expectMarksToEqual(['--suspense-rejected-0-Example']); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--suspense-rejected-0-Example", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark concurrent render with suspense that resolves', async () => { const fakeSuspensePromise = Promise.resolve(true); function Example() { @@ -273,34 +283,49 @@ describe('SchedulingProfiler', () => { {unstable_isConcurrent: true}, ); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); expect(Scheduler).toFlushUntilNextPaint([]); - expectMarksToEqual([ - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--suspense-suspend-0-Example-mount-16-Default', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--layout-effects-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--suspense-suspend-0-Example-mount-16", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } clearPendingMarks(); await fakeSuspensePromise; - expectMarksToEqual(['--suspense-resolved-0-Example']); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--suspense-resolved-0-Example", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark concurrent render with suspense that rejects', async () => { const fakeSuspensePromise = Promise.reject(new Error('error')); function Example() { @@ -314,34 +339,49 @@ describe('SchedulingProfiler', () => { {unstable_isConcurrent: true}, ); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); expect(Scheduler).toFlushUntilNextPaint([]); - expectMarksToEqual([ - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--suspense-suspend-0-Example-mount-16-Default', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--layout-effects-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--suspense-suspend-0-Example-mount-16", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } clearPendingMarks(); await expect(fakeSuspensePromise).rejects.toThrow(); - expectMarksToEqual(['--suspense-rejected-0-Example']); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--suspense-rejected-0-Example", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark cascading class component state updates', () => { class Example extends React.Component { state = {didMount: false}; @@ -355,35 +395,47 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); expect(Scheduler).toFlushUntilNextPaint([]); - expectMarksToEqual([ - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`, - '--layout-effects-stop', - `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--commit-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--schedule-state-update-1-Example", + "--layout-effects-stop", + "--render-start-1", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--commit-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark cascading class component force updates', () => { class Example extends React.Component { componentDidMount() { @@ -396,37 +448,47 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); expect(Scheduler).toFlushUntilNextPaint([]); - expectMarksToEqual([ - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--schedule-forced-update-${formatLanes( - ReactFiberLane.SyncLane, - )}-Example`, - '--layout-effects-stop', - `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--commit-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--schedule-forced-update-1-Example", + "--layout-effects-stop", + "--render-start-1", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--commit-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark render phase state updates for class component', () => { class Example extends React.Component { state = {didRender: false}; @@ -440,10 +502,13 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); @@ -451,14 +516,26 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); }).toErrorDev('Cannot update during an existing state transition'); - expectMarksToContain( - `--schedule-state-update-${formatLanes( - ReactFiberLane.DefaultLane, - )}-Example`, - ); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--schedule-state-update-16-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark render phase force updates for class component', () => { class Example extends React.Component { state = {didRender: false}; @@ -472,10 +549,13 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); @@ -483,14 +563,26 @@ describe('SchedulingProfiler', () => { expect(Scheduler).toFlushUntilNextPaint([]); }).toErrorDev('Cannot update during an existing state transition'); - expectMarksToContain( - `--schedule-forced-update-${formatLanes( - ReactFiberLane.DefaultLane, - )}-Example`, - ); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--schedule-forced-update-16-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark cascading layout updates', () => { function Example() { const [didMount, setDidMount] = React.useState(false); @@ -502,37 +594,49 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + ] + `); + } clearPendingMarks(); expect(Scheduler).toFlushUntilNextPaint([]); - expectMarksToEqual([ - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--schedule-state-update-${formatLanes(ReactFiberLane.SyncLane)}-Example`, - '--layout-effects-stop', - `--render-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.SyncLane)}`, - '--commit-stop', - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--schedule-state-update-1-Example", + "--layout-effects-stop", + "--render-start-1", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--commit-stop", + "--commit-stop", + ] + `); + } }); // This test is coupled to lane implementation details, so I'm disabling it in // the new fork until it stabilizes so we don't have to repeatedly update it. - // @gate enableSchedulingProfiler it('should mark cascading passive updates', () => { function Example() { const [didMount, setDidMount] = React.useState(false); @@ -546,32 +650,38 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); }); - expectMarksToEqual([ - `--react-init-${ReactVersion}`, - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--layout-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--layout-effects-stop', - '--commit-stop', - `--passive-effects-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - `--schedule-state-update-${formatLanes( - ReactFiberLane.DefaultLane, - )}-Example`, - '--passive-effects-stop', - `--render-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--component-render-start-Example', - '--component-render-stop', - '--render-stop', - `--commit-start-${formatLanes(ReactFiberLane.DefaultLane)}`, - '--commit-stop', - ]); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + "--passive-effects-start-16", + "--schedule-state-update-16-Example", + "--passive-effects-stop", + "--render-start-16", + "--component-render-start-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('should mark render phase updates', () => { function Example() { const [didRender, setDidRender] = React.useState(false); @@ -585,10 +695,24 @@ describe('SchedulingProfiler', () => { ReactTestRenderer.create(, {unstable_isConcurrent: true}); }); - expectMarksToContain( - `--schedule-state-update-${formatLanes( - ReactFiberLane.DefaultLane, - )}-Example`, - ); + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(getMarks()).toMatchInlineSnapshot(` + Array [ + "--schedule-render-16", + "--render-start-16", + "--component-render-start-Example", + "--schedule-state-update-16-Example", + "--component-render-stop", + "--render-stop", + "--commit-start-16", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-16", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } }); }); diff --git a/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js b/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js index 226607eaed2e2..09fdb95b01e6c 100644 --- a/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js +++ b/packages/react-reconciler/src/__tests__/SchedulingProfilerLabels-test.internal.js @@ -15,12 +15,10 @@ describe('SchedulingProfiler labels', () => { let React; let ReactDOM; - let ReactFiberLane; let act; let clearedMarks; let featureDetectionMarkName = null; - let formatLanes; let marks; function polyfillJSDomUserTiming() { @@ -75,14 +73,6 @@ describe('SchedulingProfiler labels', () => { const TestUtils = require('react-dom/test-utils'); act = TestUtils.act; - - const SchedulingProfiler = require('react-reconciler/src/SchedulingProfiler'); - formatLanes = SchedulingProfiler.formatLanes; - - const ReactFeatureFlags = require('shared/ReactFeatureFlags'); - ReactFiberLane = ReactFeatureFlags.enableNewReconciler - ? require('react-reconciler/src/ReactFiberLane.new') - : require('react-reconciler/src/ReactFiberLane.old'); }); afterEach(() => { @@ -92,29 +82,45 @@ describe('SchedulingProfiler labels', () => { delete global.performance; }); - // @gate enableSchedulingProfiler it('regression test SyncLane', () => { ReactDOM.render(
, document.createElement('div')); - expect(clearedMarks).toContain( - `--schedule-render-${formatLanes(ReactFiberLane.SyncLane)}`, - ); + + if (gate(flags => flags.enableSchedulingProfiler)) { + expect(clearedMarks).toMatchInlineSnapshot(` + Array [ + "__v3", + "--schedule-render-1", + "--render-start-1", + "--render-stop", + "--commit-start-1", + "--react-version-17.0.3", + "--profiler-version-1", + "--react-lane-labels-Sync,InputContinuousHydration,InputContinuous,DefaultHydration,Default,TransitionHydration,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Transition,Retry,Retry,Retry,Retry,Retry,SelectiveHydration,IdleHydration,Idle,Offscreen", + "--layout-effects-start-1", + "--layout-effects-stop", + "--commit-stop", + ] + `); + } }); - // @gate enableSchedulingProfiler it('regression test DefaultLane', () => { - const container = document.createElement('div'); - const root = ReactDOM.createRoot(container); - - act(() => { - root.render(
); - expect(clearedMarks).toContain( - `--schedule-render-${formatLanes(ReactFiberLane.DefaultLane)}`, - ); - }); + if (gate(flags => flags.enableSchedulingProfiler)) { + act(() => { + const container = document.createElement('div'); + const root = ReactDOM.createRoot(container); + + root.render(
); + expect(clearedMarks).toMatchInlineSnapshot(` + Array [ + "__v3", + "--schedule-render-16", + ] + `); + }); + } }); - // @gate enableSchedulingProfiler - // @gate !enableLegacyFBSupport it('regression test InputDiscreteLane', () => { const container = document.createElement('div'); const root = ReactDOM.createRoot(container); @@ -128,24 +134,41 @@ describe('SchedulingProfiler labels', () => { return