Skip to content

Commit

Permalink
Replace test renderer's fake Scheduler implementation with mock build (
Browse files Browse the repository at this point in the history
…facebook#14970)

* Replace test renderer's fake Scheduler implementation with mock build

The test renderer has its own mock implementation of the Scheduler
interface, with the ability to partially render work in tests. Now that
this functionality has been lifted into a proper mock Scheduler build,
we can use that instead.

* Fix Profiler tests in prod
  • Loading branch information
acdlite authored Feb 28, 2019
1 parent 53e787b commit ccb2a8a
Show file tree
Hide file tree
Showing 16 changed files with 598 additions and 761 deletions.
3 changes: 2 additions & 1 deletion packages/jest-react/src/JestReact.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ function captureAssertion(fn) {
}

function assertYieldsWereCleared(root) {
const actualYields = root.unstable_clearYields();
const Scheduler = root._Scheduler;
const actualYields = Scheduler.unstable_clearYields();
invariant(
actualYields.length === 0,
'Log of yielded values is not empty. ' +
Expand Down
73 changes: 13 additions & 60 deletions packages/react-cache/src/__tests__/ReactCache-test.internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,55 +14,15 @@ let createResource;
let React;
let ReactFeatureFlags;
let ReactTestRenderer;
let Scheduler;
let Suspense;
let TextResource;
let textResourceShouldFail;
let flushScheduledWork;
let evictLRU;

describe('ReactCache', () => {
beforeEach(() => {
jest.resetModules();

let currentPriorityLevel = 3;

jest.mock('scheduler', () => {
let callbacks = [];
return {
unstable_scheduleCallback(callback) {
const callbackIndex = callbacks.length;
callbacks.push(callback);
return {callbackIndex};
},
flushScheduledWork() {
while (callbacks.length) {
const callback = callbacks.pop();
callback();
}
},

unstable_ImmediatePriority: 1,
unstable_UserBlockingPriority: 2,
unstable_NormalPriority: 3,
unstable_LowPriority: 4,
unstable_IdlePriority: 5,

unstable_runWithPriority(priorityLevel, fn) {
const prevPriorityLevel = currentPriorityLevel;
currentPriorityLevel = priorityLevel;
try {
return fn();
} finally {
currentPriorityLevel = prevPriorityLevel;
}
},

unstable_getCurrentPriorityLevel() {
return currentPriorityLevel;
},
};
});

ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
Expand All @@ -71,8 +31,7 @@ describe('ReactCache', () => {
ReactCache = require('react-cache');
createResource = ReactCache.unstable_createResource;
ReactTestRenderer = require('react-test-renderer');
flushScheduledWork = require('scheduler').flushScheduledWork;
evictLRU = flushScheduledWork;
Scheduler = require('scheduler');

TextResource = createResource(([text, ms = 0]) => {
let listeners = null;
Expand All @@ -86,16 +45,12 @@ describe('ReactCache', () => {
listeners = [{resolve, reject}];
setTimeout(() => {
if (textResourceShouldFail) {
ReactTestRenderer.unstable_yield(
`Promise rejected [${text}]`,
);
Scheduler.yieldValue(`Promise rejected [${text}]`);
status = 'rejected';
value = new Error('Failed to load: ' + text);
listeners.forEach(listener => listener.reject(value));
} else {
ReactTestRenderer.unstable_yield(
`Promise resolved [${text}]`,
);
Scheduler.yieldValue(`Promise resolved [${text}]`);
status = 'resolved';
value = text;
listeners.forEach(listener => listener.resolve(value));
Expand Down Expand Up @@ -123,21 +78,21 @@ describe('ReactCache', () => {
});

function Text(props) {
ReactTestRenderer.unstable_yield(props.text);
Scheduler.yieldValue(props.text);
return props.text;
}

function AsyncText(props) {
const text = props.text;
try {
TextResource.read([props.text, props.ms]);
ReactTestRenderer.unstable_yield(text);
Scheduler.yieldValue(text);
return text;
} catch (promise) {
if (typeof promise.then === 'function') {
ReactTestRenderer.unstable_yield(`Suspend! [${text}]`);
Scheduler.yieldValue(`Suspend! [${text}]`);
} else {
ReactTestRenderer.unstable_yield(`Error! [${text}]`);
Scheduler.yieldValue(`Error! [${text}]`);
}
throw promise;
}
Expand Down Expand Up @@ -201,7 +156,7 @@ describe('ReactCache', () => {
});

function App() {
ReactTestRenderer.unstable_yield('App');
Scheduler.yieldValue('App');
return BadTextResource.read(['Hi', 100]);
}

Expand Down Expand Up @@ -284,9 +239,7 @@ describe('ReactCache', () => {
expect(root).toMatchRenderedOutput('145');

// We've now rendered values 1, 2, 3, 4, 5, over our limit of 3. The least
// recently used values are 2 and 3. They will be evicted during the
// next sweep.
evictLRU();
// recently used values are 2 and 3. They should have been evicted.

root.update(
<Suspense fallback={<Text text="Loading..." />}>
Expand Down Expand Up @@ -368,13 +321,13 @@ describe('ReactCache', () => {
const text = props.text;
try {
const actualText = BadTextResource.read([props.text, props.ms]);
ReactTestRenderer.unstable_yield(actualText);
Scheduler.yieldValue(actualText);
return actualText;
} catch (promise) {
if (typeof promise.then === 'function') {
ReactTestRenderer.unstable_yield(`Suspend! [${text}]`);
Scheduler.yieldValue(`Suspend! [${text}]`);
} else {
ReactTestRenderer.unstable_yield(`Error! [${text}]`);
Scheduler.yieldValue(`Error! [${text}]`);
}
throw promise;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ describe('ErrorBoundaryReconciliation', () => {
let React;
let ReactFeatureFlags;
let ReactTestRenderer;
let Scheduler;
let span;

beforeEach(() => {
Expand All @@ -14,6 +15,7 @@ describe('ErrorBoundaryReconciliation', () => {
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
ReactTestRenderer = require('react-test-renderer');
React = require('react');
Scheduler = require('scheduler');

DidCatchErrorBoundary = class extends React.Component {
state = {error: null};
Expand Down Expand Up @@ -56,9 +58,7 @@ describe('ErrorBoundaryReconciliation', () => {
</ErrorBoundary>,
{unstable_isConcurrent: isConcurrent},
);
if (isConcurrent) {
renderer.unstable_flushAll();
}
Scheduler.flushAll();
expect(renderer).toMatchRenderedOutput(<span prop="BrokenRender" />);

expect(() => {
Expand All @@ -67,9 +67,7 @@ describe('ErrorBoundaryReconciliation', () => {
<BrokenRender fail={true} />
</ErrorBoundary>,
);
if (isConcurrent) {
renderer.unstable_flushAll();
}
Scheduler.flushAll();
}).toWarnDev(isConcurrent ? ['invalid', 'invalid'] : ['invalid']);
const Fallback = fallbackTagName;
expect(renderer).toMatchRenderedOutput(<Fallback prop="ErrorBoundary" />);
Expand Down
52 changes: 24 additions & 28 deletions packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
let React;
let ReactFeatureFlags;
let ReactTestRenderer;
let Scheduler;
let ReactDOMServer;
let act;

Expand All @@ -28,6 +29,7 @@ describe('ReactHooks', () => {
ReactFeatureFlags.debugRenderPhaseSideEffectsForStrictMode = false;
React = require('react');
ReactTestRenderer = require('react-test-renderer');
Scheduler = require('scheduler');
ReactDOMServer = require('react-dom/server');
act = ReactTestRenderer.act;
});
Expand All @@ -53,7 +55,7 @@ describe('ReactHooks', () => {
const {useState, useLayoutEffect} = React;

function Child({text}) {
ReactTestRenderer.unstable_yield('Child: ' + text);
Scheduler.yieldValue('Child: ' + text);
return text;
}

Expand All @@ -66,9 +68,9 @@ describe('ReactHooks', () => {
setCounter2 = _setCounter2;

const text = `${counter1}, ${counter2}`;
ReactTestRenderer.unstable_yield(`Parent: ${text}`);
Scheduler.yieldValue(`Parent: ${text}`);
useLayoutEffect(() => {
ReactTestRenderer.unstable_yield(`Effect: ${text}`);
Scheduler.yieldValue(`Effect: ${text}`);
});
return <Child text={text} />;
}
Expand Down Expand Up @@ -161,7 +163,7 @@ describe('ReactHooks', () => {
const {useState, memo} = React;

function Child({text}) {
ReactTestRenderer.unstable_yield('Child: ' + text);
Scheduler.yieldValue('Child: ' + text);
return text;
}

Expand All @@ -174,7 +176,7 @@ describe('ReactHooks', () => {
setCounter2 = _setCounter2;

const text = `${counter1}, ${counter2} (${theme})`;
ReactTestRenderer.unstable_yield(`Parent: ${text}`);
Scheduler.yieldValue(`Parent: ${text}`);
return <Child text={text} />;
}

Expand Down Expand Up @@ -243,7 +245,7 @@ describe('ReactHooks', () => {
const [counter, _setCounter] = useState(0);
setCounter = _setCounter;

ReactTestRenderer.unstable_yield(`Count: ${counter}`);
Scheduler.yieldValue(`Count: ${counter}`);
return counter;
}

Expand Down Expand Up @@ -277,7 +279,7 @@ describe('ReactHooks', () => {
const [counter, _dispatch] = useReducer((s, a) => a, 0);
dispatch = _dispatch;

ReactTestRenderer.unstable_yield(`Count: ${counter}`);
Scheduler.yieldValue(`Count: ${counter}`);
return counter;
}

Expand Down Expand Up @@ -311,15 +313,15 @@ describe('ReactHooks', () => {
let setTheme;
function ThemeProvider({children}) {
const [theme, _setTheme] = useState('light');
ReactTestRenderer.unstable_yield('Theme: ' + theme);
Scheduler.yieldValue('Theme: ' + theme);
setTheme = _setTheme;
return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
);
}

function Child({text}) {
ReactTestRenderer.unstable_yield('Child: ' + text);
Scheduler.yieldValue('Child: ' + text);
return text;
}

Expand All @@ -331,9 +333,9 @@ describe('ReactHooks', () => {
const theme = useContext(ThemeContext);

const text = `${counter} (${theme})`;
ReactTestRenderer.unstable_yield(`Parent: ${text}`);
Scheduler.yieldValue(`Parent: ${text}`);
useLayoutEffect(() => {
ReactTestRenderer.unstable_yield(`Effect: ${text}`);
Scheduler.yieldValue(`Effect: ${text}`);
});
return <Child text={text} />;
}
Expand Down Expand Up @@ -392,17 +394,17 @@ describe('ReactHooks', () => {
const {useState, useLayoutEffect} = React;

function Child({text}) {
ReactTestRenderer.unstable_yield('Child: ' + text);
Scheduler.yieldValue('Child: ' + text);
return text;
}

let setCounter;
function Parent() {
const [counter, _setCounter] = useState(0);
setCounter = _setCounter;
ReactTestRenderer.unstable_yield('Parent: ' + counter);
Scheduler.yieldValue('Parent: ' + counter);
useLayoutEffect(() => {
ReactTestRenderer.unstable_yield('Effect: ' + counter);
Scheduler.yieldValue('Effect: ' + counter);
});
return <Child text={counter} />;
}
Expand Down Expand Up @@ -470,15 +472,15 @@ describe('ReactHooks', () => {
const {useState} = React;

function Child({text}) {
ReactTestRenderer.unstable_yield('Child: ' + text);
Scheduler.yieldValue('Child: ' + text);
return text;
}

let setCounter;
function Parent() {
const [counter, _setCounter] = useState(0);
setCounter = _setCounter;
ReactTestRenderer.unstable_yield('Parent: ' + counter);
Scheduler.yieldValue('Parent: ' + counter);
return <Child text={counter} />;
}

Expand All @@ -489,9 +491,7 @@ describe('ReactHooks', () => {

const update = value => {
setCounter(previous => {
ReactTestRenderer.unstable_yield(
`Compute state (${previous} -> ${value})`,
);
Scheduler.yieldValue(`Compute state (${previous} -> ${value})`);
return value;
});
};
Expand Down Expand Up @@ -530,15 +530,15 @@ describe('ReactHooks', () => {
const {useState} = React;

function Child({text}) {
ReactTestRenderer.unstable_yield('Child: ' + text);
Scheduler.yieldValue('Child: ' + text);
return text;
}

let setCounter;
function Parent() {
const [counter, _setCounter] = useState(1);
setCounter = _setCounter;
ReactTestRenderer.unstable_yield('Parent: ' + counter);
Scheduler.yieldValue('Parent: ' + counter);
return <Child text={counter} />;
}

Expand All @@ -550,9 +550,7 @@ describe('ReactHooks', () => {
const update = compute => {
setCounter(previous => {
const value = compute(previous);
ReactTestRenderer.unstable_yield(
`Compute state (${previous} -> ${value})`,
);
Scheduler.yieldValue(`Compute state (${previous} -> ${value})`);
return value;
});
};
Expand Down Expand Up @@ -590,9 +588,7 @@ describe('ReactHooks', () => {
const {useLayoutEffect} = React;
function App(props) {
useLayoutEffect(() => {
ReactTestRenderer.unstable_yield(
'Did commit: ' + props.dependencies.join(', '),
);
Scheduler.yieldValue('Did commit: ' + props.dependencies.join(', '));
}, props.dependencies);
return props.dependencies;
}
Expand All @@ -613,7 +609,7 @@ describe('ReactHooks', () => {
const {useMemo} = React;
function App({text, hasDeps}) {
const resolvedText = useMemo(() => {
ReactTestRenderer.unstable_yield('Compute');
Scheduler.yieldValue('Compute');
return text.toUpperCase();
}, hasDeps ? null : [text]);
return resolvedText;
Expand Down
Loading

0 comments on commit ccb2a8a

Please sign in to comment.