Skip to content

Commit 0cf30f7

Browse files
committed
test(web-shell): pin the measure-guard contract against mutations
Harden the budget test per review feedback: drive the counted measures on a non-Components track, assert the timeline is cleared without a name filter and with the performance object as receiver, assert every measure is still forwarded detail-stripped (including the clear- triggering one), and drive a second window to prove the clear is not latched. Each of the five one-line mutants these assertions target was verified to flip the suite red.
1 parent 8c2c638 commit 0cf30f7

1 file changed

Lines changed: 27 additions & 8 deletions

File tree

packages/web-shell/client/index-html.test.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,28 +79,47 @@ describe('React performance measure guard', () => {
7979

8080
it('clears the measure timeline on a budget so entries cannot accumulate', () => {
8181
const measure = vi.fn(() => 'measure');
82-
const clearMeasures = vi.fn();
83-
const performance = installMeasureGuard(measure, clearMeasures);
82+
const clearThis: unknown[] = [];
83+
const clearMeasures = vi.fn(function (this: unknown) {
84+
clearThis.push(this);
85+
});
86+
const fakePerformance = installMeasureGuard(measure, clearMeasures);
8487
const reactOptions = {
8588
start: 1,
8689
end: 2,
87-
detail: { devtools: { track: 'Components ⚛' } },
90+
// A non-Components track: the flood is dominated by lane/scheduler
91+
// tracks, so the budget must count every React devtools measure.
92+
detail: { devtools: { track: 'Blocking' } },
8893
};
8994

9095
for (let i = 0; i < 16384; i += 1) {
91-
performance.measure('React', reactOptions);
96+
fakePerformance.measure('⏱ track', reactOptions);
9297
}
98+
// The timeline is cleared with no name filter (React never names its
99+
// measures) and with the performance object as receiver (a detached
100+
// brand-checked clearMeasures throws Illegal invocation).
93101
expect(clearMeasures).toHaveBeenCalledTimes(1);
102+
expect(clearMeasures).toHaveBeenCalledWith();
103+
expect(clearThis).toEqual([fakePerformance]);
104+
// Every React measure is still forwarded, detail stripped — including
105+
// the one that triggers the clear.
106+
expect(measure).toHaveBeenCalledTimes(16384);
107+
expect(
108+
(measure.mock.calls[16383]?.[1] as PerformanceMeasureOptions).detail,
109+
).toBeNull();
94110

95-
performance.measure('React', reactOptions);
96-
expect(clearMeasures).toHaveBeenCalledTimes(1);
111+
// The clear is not latched: a second full window clears again.
112+
for (let i = 0; i < 16384; i += 1) {
113+
fakePerformance.measure('⏱ track', reactOptions);
114+
}
115+
expect(clearMeasures).toHaveBeenCalledTimes(2);
97116

98117
// Non-React measures do not count toward the budget.
99118
for (let i = 0; i < 16384 - 1; i += 1) {
100-
performance.measure('custom-measure', {
119+
fakePerformance.measure('custom-measure', {
101120
detail: { source: 'web-shell' },
102121
});
103122
}
104-
expect(clearMeasures).toHaveBeenCalledTimes(1);
123+
expect(clearMeasures).toHaveBeenCalledTimes(2);
105124
});
106125
});

0 commit comments

Comments
 (0)