mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Add additional scheduling tests
Tests whether certain types of work can be performed after the deadline has expired.
This commit is contained in:
committed by
Andrew Clark
parent
3a7844cabb
commit
f56eb89389
@@ -1150,6 +1150,8 @@ src/renderers/shared/fiber/__tests__/ReactIncrementalScheduling-test.js
|
||||
* handles interleaved deferred and animation work
|
||||
* schedules sync updates when inside componentDidMount/Update
|
||||
* can opt-in to deferred/animation scheduling inside componentDidMount/Update
|
||||
* performs Task work even after time runs out
|
||||
* does not perform animation work after time runs out
|
||||
|
||||
src/renderers/shared/fiber/__tests__/ReactIncrementalSideEffects-test.js
|
||||
* can update child nodes of a host instance
|
||||
|
||||
@@ -548,7 +548,9 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
|
||||
nextUnitOfWork = findNextUnitOfWork();
|
||||
}
|
||||
|
||||
if (deadline) {
|
||||
// If there's a deadline, and we're not performing Task work, perform work
|
||||
// using this loop that checks the deadline on every iteration.
|
||||
if (deadline && priorityLevel > TaskPriority) {
|
||||
// The deferred work loop will run until there's no time left in
|
||||
// the current frame.
|
||||
while (nextUnitOfWork && !deadlineHasExpired) {
|
||||
@@ -575,13 +577,9 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// The non-deferred work loop will run until there's no more work
|
||||
// at the given priority level
|
||||
if (priorityLevel >= HighPriority) {
|
||||
throw new Error(
|
||||
'Deferred work should only be performed using deferredWorkLoop'
|
||||
);
|
||||
}
|
||||
// If there's no deadline, or if we're performing Task work, use this loop
|
||||
// that doesn't check how much time is remaining. It will keep running
|
||||
// until we run out of work at this priority level.
|
||||
while (nextUnitOfWork &&
|
||||
nextPriorityLevel !== NoWork &&
|
||||
nextPriorityLevel <= priorityLevel) {
|
||||
@@ -610,6 +608,12 @@ module.exports = function<T, P, I, TI, C>(config : HostConfig<T, P, I, TI, C>) {
|
||||
// catching an error. It also lets us flush Task work at the end of a
|
||||
// deferred batch.
|
||||
while (priorityLevel !== NoWork) {
|
||||
if (priorityLevel >= HighPriority && !deadline) {
|
||||
throw new Error(
|
||||
'Cannot perform deferred work without a deadline.'
|
||||
);
|
||||
}
|
||||
|
||||
// Before starting any work, check to see if there are any pending
|
||||
// commits from the previous frame. An exception is if we're flushing
|
||||
// Task work in a deferred batch and the pending commit does not
|
||||
|
||||
@@ -410,7 +410,7 @@ describe('ReactIncremental', () => {
|
||||
// Make a quick update which will create a low pri tree on top of the
|
||||
// already low pri tree.
|
||||
ReactNoop.render(<Foo text="bar" />);
|
||||
ReactNoop.flushDeferredPri(15 + 5);
|
||||
ReactNoop.flushDeferredPri(15);
|
||||
|
||||
expect(ops).toEqual(['Foo']);
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ describe('ReactIncrementalErrorHandling', () => {
|
||||
expect(ReactNoop.getChildren()).toEqual([]);
|
||||
|
||||
ops.length = 0;
|
||||
ReactNoop.flushDeferredPri(25 + 10);
|
||||
ReactNoop.flushDeferredPri(30);
|
||||
expect(ops).toEqual([
|
||||
'BrokenRender',
|
||||
'ErrorBoundary unstable_handleError',
|
||||
|
||||
@@ -341,7 +341,7 @@ describe('ReactIncrementalScheduling', () => {
|
||||
expect(ReactNoop.getChildren('b')).toEqual([]);
|
||||
expect(ReactNoop.getChildren('c')).toEqual(null);
|
||||
// Then the second one gets processed
|
||||
ReactNoop.flushDeferredPri(15 + 5 + 5);
|
||||
ReactNoop.flushDeferredPri(15 + 5);
|
||||
expect(ReactNoop.getChildren('a')).toEqual([span('a:2')]);
|
||||
expect(ReactNoop.getChildren('b')).toEqual([span('b:2')]);
|
||||
expect(ReactNoop.getChildren('c')).toEqual(null);
|
||||
@@ -483,7 +483,7 @@ describe('ReactIncrementalScheduling', () => {
|
||||
|
||||
ReactNoop.render(<Foo />);
|
||||
|
||||
ReactNoop.flushDeferredPri(5 + 20 + 20);
|
||||
ReactNoop.flushDeferredPri(20 + 5);
|
||||
expect(ops).toEqual([
|
||||
'render: 0',
|
||||
'componentDidMount (before setState): 0',
|
||||
@@ -496,7 +496,7 @@ describe('ReactIncrementalScheduling', () => {
|
||||
|
||||
ops = [];
|
||||
instance.setState({ tick: 2 });
|
||||
ReactNoop.flushDeferredPri(5 + 20 + 20);
|
||||
ReactNoop.flushDeferredPri(20 + 5);
|
||||
|
||||
expect(ops).toEqual([
|
||||
'render: 2',
|
||||
@@ -587,4 +587,63 @@ describe('ReactIncrementalScheduling', () => {
|
||||
'componentDidUpdate: 3',
|
||||
]);
|
||||
});
|
||||
|
||||
it('performs Task work even after time runs out', () => {
|
||||
class Foo extends React.Component {
|
||||
state = { step: 1 };
|
||||
componentDidMount() {
|
||||
this.setState({ step: 2 }, () => {
|
||||
this.setState({ step: 3 }, () => {
|
||||
this.setState({ step: 4 }, () => {
|
||||
this.setState({ step: 5 });
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return <span prop={this.state.step} />;
|
||||
}
|
||||
}
|
||||
ReactNoop.render(<Foo />);
|
||||
// This should be just enough to complete all the work, but not enough to
|
||||
// commit it.
|
||||
ReactNoop.flushDeferredPri(20);
|
||||
expect(ReactNoop.getChildren()).toEqual([]);
|
||||
|
||||
// Do one more unit of work.
|
||||
ReactNoop.flushDeferredPri(10);
|
||||
// The updates should all be flushed with Task priority
|
||||
expect(ReactNoop.getChildren()).toEqual([span(5)]);
|
||||
});
|
||||
|
||||
it('does not perform animation work after time runs out', () => {
|
||||
class Foo extends React.Component {
|
||||
state = { step: 1 };
|
||||
componentDidMount() {
|
||||
ReactNoop.performAnimationWork(() => {
|
||||
this.setState({ step: 2 }, () => {
|
||||
this.setState({ step: 3 }, () => {
|
||||
this.setState({ step: 4 }, () => {
|
||||
this.setState({ step: 5 });
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
render() {
|
||||
return <span prop={this.state.step} />;
|
||||
}
|
||||
}
|
||||
ReactNoop.render(<Foo />);
|
||||
// This should be just enough to complete all the work, but not enough to
|
||||
// commit it.
|
||||
ReactNoop.flushDeferredPri(20);
|
||||
expect(ReactNoop.getChildren()).toEqual([]);
|
||||
|
||||
// Do one more unit of work.
|
||||
ReactNoop.flushDeferredPri(10);
|
||||
// None of the updates should be flushed because they only have
|
||||
// animation priority.
|
||||
expect(ReactNoop.getChildren()).toEqual([span(1)]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user