(refInst = ref)} />,
+ {createNodeMock},
+ );
+ });
+
const root = renderer.getInstance();
expect(root).toEqual(refInst);
});
- it('toTree() renders complicated trees of composites and hosts', () => {
+ it('toTree() renders complicated trees of composites and hosts', async () => {
// SFC returning host. no children props.
const Qoo = () =>
;
@@ -835,7 +996,11 @@ describe('ReactTestRenderer', () => {
}
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
+
const tree = renderer.toTree();
// we test for the presence of instances before nulling them out
@@ -894,30 +1059,45 @@ describe('ReactTestRenderer', () => {
);
});
- it('can update text nodes when rendered as root', () => {
- const renderer = ReactTestRenderer.create(['Hello', 'world']);
+ it('can update text nodes when rendered as root', async () => {
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(['Hello', 'world']);
+ });
expect(renderer.toJSON()).toEqual(['Hello', 'world']);
- renderer.update(42);
+ await act(() => {
+ renderer.update(42);
+ });
expect(renderer.toJSON()).toEqual('42');
- renderer.update([42, 'world']);
+ await act(() => {
+ renderer.update([42, 'world']);
+ });
expect(renderer.toJSON()).toEqual(['42', 'world']);
});
- it('can render and update root fragments', () => {
+ it('can render and update root fragments', async () => {
const Component = props => props.children;
- const renderer = ReactTestRenderer.create([
-
,
- ]);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create([
+
,
+ ]);
+ });
+
expect(renderer.toJSON()).toEqual(['Hi', 'Bye']);
- renderer.update(
);
+ });
expect(renderer.toJSON()).toEqual({
type: 'div',
children: null,
props: {},
});
- renderer.update([
, 'world']);
+ });
expect(renderer.toJSON()).toEqual([
{
type: 'div',
@@ -928,7 +1108,7 @@ describe('ReactTestRenderer', () => {
]);
});
- it('supports context providers and consumers', () => {
+ it('supports context providers and consumers', async () => {
const {Consumer, Provider} = React.createContext('a');
function Child(props) {
@@ -943,7 +1123,10 @@ describe('ReactTestRenderer', () => {
);
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const child = renderer.root.findByType(Child);
expect(child.children).toEqual(['b']);
expect(prettyFormat(renderer.toTree())).toEqual(
@@ -965,7 +1148,7 @@ describe('ReactTestRenderer', () => {
);
});
- it('supports modes', () => {
+ it('supports modes', async () => {
function Child(props) {
return props.value;
}
@@ -978,7 +1161,10 @@ describe('ReactTestRenderer', () => {
);
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const child = renderer.root.findByType(Child);
expect(child.children).toEqual(['a']);
expect(prettyFormat(renderer.toTree())).toEqual(
@@ -1002,7 +1188,7 @@ describe('ReactTestRenderer', () => {
);
});
- it('supports forwardRef', () => {
+ it('supports forwardRef', async () => {
const InnerRefed = React.forwardRef((props, ref) => (
@@ -1020,7 +1206,10 @@ describe('ReactTestRenderer', () => {
}
}
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const tree = renderer.toTree();
cleanNodeOrArray(tree);
@@ -1065,12 +1254,17 @@ describe('ReactTestRenderer', () => {
);
ReactNoop.render(
);
await waitForAll([]);
- ReactTestRenderer.create(
);
+ await act(() => {
+ ReactTestRenderer.create(
);
+ });
});
- it('calling findByType() with an invalid component will fall back to "Unknown" for component name', () => {
+ it('calling findByType() with an invalid component will fall back to "Unknown" for component name', async () => {
const App = () => null;
- const renderer = ReactTestRenderer.create(
);
+ let renderer;
+ await act(() => {
+ renderer = ReactTestRenderer.create(
);
+ });
const NonComponent = {};
expect(() => {
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
index 0118fa53f3ad3..e6ed9fa11c291 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRenderer-test.js
@@ -13,7 +13,7 @@ let ReactDOM;
let React;
let ReactCache;
let ReactTestRenderer;
-let waitForAll;
+let act;
describe('ReactTestRenderer', () => {
beforeEach(() => {
@@ -26,32 +26,28 @@ describe('ReactTestRenderer', () => {
ReactCache = require('react-cache');
ReactTestRenderer = require('react-test-renderer');
const InternalTestUtils = require('internal-test-utils');
- waitForAll = InternalTestUtils.waitForAll;
+ act = InternalTestUtils.act;
});
- it('should warn if used to render a ReactDOM portal', () => {
+ it('should warn if used to render a ReactDOM portal', async () => {
const container = document.createElement('div');
- expect(() => {
- let error;
- try {
+ let error;
+
+ await expect(async () => {
+ await act(() => {
ReactTestRenderer.create(ReactDOM.createPortal('foo', container));
- } catch (e) {
- error = e;
- }
- // After the update throws, a subsequent render is scheduled to
- // unmount the whole tree. This update also causes an error, so React
- // throws an AggregateError.
- const errors = error.errors;
- expect(errors.length).toBe(2);
- expect(errors[0].message.includes('indexOf is not a function')).toBe(
- true,
- );
- expect(errors[1].message.includes('indexOf is not a function')).toBe(
- true,
- );
+ }).catch(e => (error = e));
}).toErrorDev('An invalid container has been provided.', {
withoutStack: true,
});
+
+ // After the update throws, a subsequent render is scheduled to
+ // unmount the whole tree. This update also causes an error, so React
+ // throws an AggregateError.
+ const errors = error.errors;
+ expect(errors.length).toBe(2);
+ expect(errors[0].message.includes('indexOf is not a function')).toBe(true);
+ expect(errors[1].message.includes('indexOf is not a function')).toBe(true);
});
describe('timed out Suspense hidden subtrees should not be observable via toJSON', () => {
@@ -84,16 +80,23 @@ describe('ReactTestRenderer', () => {
);
};
- const root = ReactTestRenderer.create(
);
- PendingResources.initial('initial');
- await waitForAll([]);
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(
);
+ });
+ await act(() => {
+ PendingResources.initial('initial');
+ });
expect(root.toJSON()).toEqual('initial');
- root.update(
);
+ await act(() => {
+ root.update(
);
+ });
expect(root.toJSON()).toEqual('fallback');
- PendingResources.dynamic('dynamic');
- await waitForAll([]);
+ await act(() => {
+ PendingResources.dynamic('dynamic');
+ });
expect(root.toJSON()).toEqual('dynamic');
});
@@ -108,16 +111,23 @@ describe('ReactTestRenderer', () => {
);
};
- const root = ReactTestRenderer.create(
);
- PendingResources.initial('initial');
- await waitForAll([]);
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(
);
+ });
+ await act(() => {
+ PendingResources.initial('initial');
+ });
expect(root.toJSON().children).toEqual(['initial']);
- root.update(
);
+ await act(() => {
+ root.update(
);
+ });
expect(root.toJSON().children).toEqual(['fallback']);
- PendingResources.dynamic('dynamic');
- await waitForAll([]);
+ await act(() => {
+ PendingResources.dynamic('dynamic');
+ });
expect(root.toJSON().children).toEqual(['dynamic']);
});
});
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js
index 2306a895b785c..ef27de6d0fe2f 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererAct-test.js
@@ -16,6 +16,7 @@ describe('ReactTestRenderer.act()', () => {
const InternalTestUtils = require('internal-test-utils');
assertLog = InternalTestUtils.assertLog;
+ global.IS_REACT_ACT_ENVIRONMENT = true;
});
// @gate __DEV__
@@ -91,7 +92,10 @@ describe('ReactTestRenderer.act()', () => {
});
return step;
}
- const root = ReactTestRenderer.create(null);
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(null);
+ });
await act(async () => {
root.update(
);
});
diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js
index d61f0a7c9075a..b4f79d2c55f19 100644
--- a/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js
+++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererTraversal-test.js
@@ -13,6 +13,7 @@
const React = require('react');
let ReactTestRenderer;
let Context;
+let act;
const RCTView = 'RCTView';
const View = props =>
;
@@ -21,6 +22,7 @@ describe('ReactTestRendererTraversal', () => {
beforeEach(() => {
jest.resetModules();
ReactTestRenderer = require('react-test-renderer');
+ act = require('internal-test-utils').act;
Context = React.createContext(null);
});
@@ -68,8 +70,11 @@ describe('ReactTestRendererTraversal', () => {
));
- it('initializes', () => {
- const render = ReactTestRenderer.create(
);
+ it('initializes', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
const hasFooProp = node => node.props.hasOwnProperty('foo');
// assert .props, .type and .parent attributes
@@ -80,8 +85,12 @@ describe('ReactTestRendererTraversal', () => {
expect(foo.children[0].parent).toBe(foo);
});
- it('searches via .find() / .findAll()', () => {
- const render = ReactTestRenderer.create(
);
+ it('searches via .find() / .findAll()', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
+
const hasFooProp = node => node.props.hasOwnProperty('foo');
const hasBarProp = node => node.props.hasOwnProperty('bar');
const hasBazProp = node => node.props.hasOwnProperty('baz');
@@ -135,8 +144,11 @@ describe('ReactTestRendererTraversal', () => {
expect(itself.findAll(hasBazProp)).toHaveLength(2);
});
- it('searches via .findByType() / .findAllByType()', () => {
- const render = ReactTestRenderer.create(
);
+ it('searches via .findByType() / .findAllByType()', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
expect(() => render.root.findByType(ExampleFn)).not.toThrow(); // 1 match
expect(() => render.root.findByType(View)).not.toThrow(); // 1 match
@@ -159,8 +171,11 @@ describe('ReactTestRendererTraversal', () => {
expect(fn[0].findAllByType(View)).toHaveLength(1);
});
- it('searches via .findByProps() / .findAllByProps()', () => {
- const render = ReactTestRenderer.create(
);
+ it('searches via .findByProps() / .findAllByProps()', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
const foo = 'foo';
const bar = 'bar';
const baz = 'baz';
@@ -182,8 +197,11 @@ describe('ReactTestRendererTraversal', () => {
expect(render.root.findAllByProps({qux})).toHaveLength(3);
});
- it('skips special nodes', () => {
- const render = ReactTestRenderer.create(
);
+ it('skips special nodes', async () => {
+ let render;
+ await act(() => {
+ render = ReactTestRenderer.create(
);
+ });
expect(render.root.findAllByType(React.Fragment)).toHaveLength(0);
expect(render.root.findAllByType(Context.Consumer)).toHaveLength(0);
expect(render.root.findAllByType(Context.Provider)).toHaveLength(0);
@@ -200,47 +218,62 @@ describe('ReactTestRendererTraversal', () => {
expect(nestedViews[2].parent).toBe(expectedParent);
});
- it('can have special nodes as roots', () => {
+ it('can have special nodes as roots', async () => {
const FR = React.forwardRef((props, ref) =>
);
- expect(
- ReactTestRenderer.create(
+
+ let render1;
+ await act(() => {
+ render1 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render1.root.findAllByType('div').length).toBe(2);
+
+ let render2;
+ await act(() => {
+ render2 = ReactTestRenderer.create(
<>
>,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render2.root.findAllByType('div').length).toBe(2);
+
+ let render3;
+ await act(() => {
+ render3 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render3.root.findAllByType('div').length).toBe(2);
+
+ let render4;
+ await act(() => {
+ render4 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
- expect(
- ReactTestRenderer.create(
+ );
+ });
+ expect(render4.root.findAllByType('div').length).toBe(2);
+
+ let render5;
+ await act(() => {
+ render5 = ReactTestRenderer.create(
,
- ).root.findAllByType('div').length,
- ).toBe(2);
+ );
+ });
+ expect(render5.root.findAllByType('div').length).toBe(2);
});
});
diff --git a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
index 2f28d2b60d43b..ba29cbbe461f8 100644
--- a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
+++ b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js
@@ -19,6 +19,7 @@ describe('ReactProfiler DevTools integration', () => {
let hook;
let waitForAll;
let waitFor;
+ let act;
beforeEach(() => {
global.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook = {
@@ -39,6 +40,7 @@ describe('ReactProfiler DevTools integration', () => {
const InternalTestUtils = require('internal-test-utils');
waitForAll = InternalTestUtils.waitForAll;
waitFor = InternalTestUtils.waitFor;
+ act = InternalTestUtils.act;
AdvanceTime = class extends React.Component {
static defaultProps = {
@@ -56,7 +58,7 @@ describe('ReactProfiler DevTools integration', () => {
};
});
- it('should auto-Profile all fibers if the DevTools hook is detected', () => {
+ it('should auto-Profile all fibers if the DevTools hook is detected', async () => {
const App = ({multiplier}) => {
Scheduler.unstable_advanceTime(2);
return (
@@ -71,7 +73,12 @@ describe('ReactProfiler DevTools integration', () => {
};
const onRender = jest.fn(() => {});
- const rendered = ReactTestRenderer.create(
);
+ let rendered;
+ await act(() => {
+ rendered = ReactTestRenderer.create(
, {
+ unstable_isConcurrent: true,
+ });
+ });
expect(hook.onCommitFiberRoot).toHaveBeenCalledTimes(1);
@@ -90,7 +97,9 @@ describe('ReactProfiler DevTools integration', () => {
12,
);
- rendered.update(
);
+ await act(() => {
+ rendered.update(
);
+ });
// Measure observable timing using the Profiler component.
// The time spent in App (above the Profiler) won't be included in the durations,
@@ -107,14 +116,18 @@ describe('ReactProfiler DevTools integration', () => {
);
});
- it('should reset the fiber stack correctly after an error when profiling host roots', () => {
+ it('should reset the fiber stack correctly after an error when profiling host roots', async () => {
Scheduler.unstable_advanceTime(20);
- const rendered = ReactTestRenderer.create(
-
,
- );
+ let rendered;
+ await act(() => {
+ rendered = ReactTestRenderer.create(
+
,
+ {unstable_isConcurrent: true},
+ );
+ });
Scheduler.unstable_advanceTime(20);
@@ -122,22 +135,26 @@ describe('ReactProfiler DevTools integration', () => {
throw new Error('Oops!');
}
- expect(() => {
- rendered.update(
-
-
- ,
- );
- }).toThrow('Oops!');
+ await expect(async () => {
+ await act(() => {
+ rendered.update(
+
+
+ ,
+ );
+ });
+ }).rejects.toThrow('Oops!');
Scheduler.unstable_advanceTime(20);
- // But this should render correctly, if the profiler's fiber stack has been reset.
- rendered.update(
-
,
- );
+ await act(() => {
+ // But this should render correctly, if the profiler's fiber stack has been reset.
+ rendered.update(
+
,
+ );
+ });
// Measure unobservable timing required by the DevTools profiler.
// At this point, the base time should include only the most recent (not failed) render.
@@ -154,7 +171,10 @@ describe('ReactProfiler DevTools integration', () => {
return text;
}
- const root = ReactTestRenderer.create(null, {unstable_isConcurrent: true});
+ let root;
+ await act(() => {
+ root = ReactTestRenderer.create(null, {unstable_isConcurrent: true});
+ });
// Commit something
root.update(
);