'use strict';
if (typeof Blob === 'undefined') {
global.Blob = require('buffer').Blob;
}
if (typeof File === 'undefined' || typeof FormData === 'undefined') {
global.File = require('undici').File;
global.FormData = require('undici').FormData;
}
function normalizeCodeLocInfo(str) {
return (
str &&
str.replace(/^ +(?:at|in) ([\S]+)[^\n]*/gm, function (m, name) {
const dot = name.lastIndexOf('.');
if (dot !== -1) {
name = name.slice(dot + 1);
}
return ' in ' + name + (/\d/.test(m) ? ' (at **)' : '');
})
);
}
let ReactServer;
let ReactNoopFlightServer;
let Scheduler;
let advanceTimersByTime;
let assertLog;
describe('ReactFlight', () => {
beforeEach(() => {
let time = 0;
advanceTimersByTime = timeMS => {
time += timeMS;
jest.advanceTimersByTime(timeMS);
};
const now = jest.fn().mockImplementation(() => {
return time++;
});
Object.defineProperty(performance, 'timeOrigin', {
value: time,
configurable: true,
});
Object.defineProperty(performance, 'now', {
value: now,
configurable: true,
});
jest.resetModules();
jest.mock('react', () => require('react/react.react-server'));
ReactServer = require('react');
ReactNoopFlightServer = require('react-noop-renderer/flight-server');
Scheduler = require('scheduler');
const InternalTestUtils = require('internal-test-utils');
assertLog = InternalTestUtils.assertLog;
});
afterEach(() => {
jest.restoreAllMocks();
});
it('resets the owner stack limit periodically', async () => {
function App({siblingsBeforeStackOne, timeout}) {
const children = [];
for (
let i = 0;
i <
siblingsBeforeStackOne -
1 -
1;
i++
) {
children.push(ReactServer.createElement(Component, {key: i}));
}
children.push(
ReactServer.createElement(OwnerStackOne, {key: 'stackOne'}),
);
children.push(
ReactServer.createElement(OwnerStackDelayed, {
key: 'stackTwo',
timeout,
}),
);
return children;
}
function Component() {
return null;
}
let stackOne;
function OwnerStackOne() {
Scheduler.log('render OwnerStackOne');
stackOne = ReactServer.captureOwnerStack();
}
let stackTwo;
function OwnerStackTwo() {
Scheduler.log('render OwnerStackTwo');
stackTwo = ReactServer.captureOwnerStack();
}
function OwnerStackDelayed({timeout}) {
Scheduler.log('render OwnerStackDelayed');
jest.advanceTimersByTime(timeout);
return ReactServer.createElement(OwnerStackTwo, {});
}
ReactNoopFlightServer.render(
ReactServer.createElement(App, {
key: 'one',
siblingsBeforeStackOne: 500,
timeout: 1000,
}),
);
assertLog([
'render OwnerStackOne',
'render OwnerStackDelayed',
'render OwnerStackTwo',
]);
expect({
pendingTimers: jest.getTimerCount(),
stackOne: normalizeCodeLocInfo(stackOne),
stackTwo: normalizeCodeLocInfo(stackTwo),
}).toEqual({
pendingTimers: 0,
stackOne: '\n in App (at **)',
stackTwo: __VARIANT__
?
'\n in UnknownOwner (at **)' + '\n in UnknownOwner (at **)'
:
'\n in OwnerStackDelayed (at **)' + '\n in App (at **)',
});
advanceTimersByTime(1000);
ReactNoopFlightServer.render(
ReactServer.createElement(App, {
key: 'two',
siblingsBeforeStackOne: 0,
timeout: 0,
}),
);
expect({
pendingTimers: jest.getTimerCount(),
stackOne: normalizeCodeLocInfo(stackOne),
stackTwo: normalizeCodeLocInfo(stackTwo),
}).toEqual({
pendingTimers: 0,
stackOne: '\n in App (at **)',
stackTwo: '\n in OwnerStackDelayed (at **)' + '\n in App (at **)',
});
});
});