Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace test renderer's fake Scheduler implementation with mock build #14970

Merged
merged 2 commits into from
Feb 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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