diff --git a/packages/react-noop-renderer/src/ReactNoop.js b/packages/react-noop-renderer/src/ReactNoop.js
index d25e2dcac73..f7f750cd306 100644
--- a/packages/react-noop-renderer/src/ReactNoop.js
+++ b/packages/react-noop-renderer/src/ReactNoop.js
@@ -20,7 +20,9 @@ import createReactNoop from './createReactNoop';
export const {
_Scheduler,
getChildren,
+ dangerouslyGetChildren,
getPendingChildren,
+ dangerouslyGetPendingChildren,
getOrCreateRootContainer,
createRoot,
createLegacyRoot,
diff --git a/packages/react-noop-renderer/src/ReactNoopPersistent.js b/packages/react-noop-renderer/src/ReactNoopPersistent.js
index 1a94a5a179c..c4bce280f21 100644
--- a/packages/react-noop-renderer/src/ReactNoopPersistent.js
+++ b/packages/react-noop-renderer/src/ReactNoopPersistent.js
@@ -20,7 +20,9 @@ import createReactNoop from './createReactNoop';
export const {
_Scheduler,
getChildren,
+ dangerouslyGetChildren,
getPendingChildren,
+ dangerouslyGetPendingChildren,
getOrCreateRootContainer,
createRoot,
createLegacyRoot,
diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js
index 68d415a12aa..c8ce26b4f6d 100644
--- a/packages/react-noop-renderer/src/createReactNoop.js
+++ b/packages/react-noop-renderer/src/createReactNoop.js
@@ -789,11 +789,35 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
_Scheduler: Scheduler,
getChildren(rootID: string = DEFAULT_ROOT_ID) {
+ throw new Error(
+ 'No longer supported due to bad performance when used with `expect()`. ' +
+ 'Use `ReactNoop.getChildrenAsJSX()` instead or, if you really need to, `dangerouslyGetChildren` after you carefully considered the warning in its JSDOC.',
+ );
+ },
+
+ getPendingChildren(rootID: string = DEFAULT_ROOT_ID) {
+ throw new Error(
+ 'No longer supported due to bad performance when used with `expect()`. ' +
+ 'Use `ReactNoop.getPendingChildrenAsJSX()` instead or, if you really need to, `dangerouslyGetPendingChildren` after you carefully considered the warning in its JSDOC.',
+ );
+ },
+
+ /**
+ * Prefer using `getChildrenAsJSX`.
+ * Using the returned children in `.toEqual` has very poor performance on mismatch due to deep equality checking of fiber structures.
+ * Make sure you deeply remove enumerable properties before passing it to `.toEqual`, or, better, use `getChildrenAsJSX` or `toMatchRenderedOutput`.
+ */
+ dangerouslyGetChildren(rootID: string = DEFAULT_ROOT_ID) {
const container = rootContainers.get(rootID);
return getChildren(container);
},
- getPendingChildren(rootID: string = DEFAULT_ROOT_ID) {
+ /**
+ * Prefer using `getPendingChildrenAsJSX`.
+ * Using the returned children in `.toEqual` has very poor performance on mismatch due to deep equality checking of fiber structures.
+ * Make sure you deeply remove enumerable properties before passing it to `.toEqual`, or, better, use `getChildrenAsJSX` or `toMatchRenderedOutput`.
+ */
+ dangerouslyGetPendingChildren(rootID: string = DEFAULT_ROOT_ID) {
const container = rootContainers.get(rootID);
return getPendingChildren(container);
},
diff --git a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
index 72ca257fefa..7b96efc2b9f 100644
--- a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js
@@ -105,10 +105,6 @@ describe('ReactExpiration', () => {
}
}
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
function flushNextRenderIfExpired() {
// This will start rendering the next level of work. If the work hasn't
// expired yet, React will exit without doing anything. If it has expired,
@@ -127,21 +123,21 @@ describe('ReactExpiration', () => {
ReactNoop.render();
}
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Nothing has expired yet because time hasn't advanced.
flushNextRenderIfExpired();
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance time a bit, but not enough to expire the low pri update.
ReactNoop.expire(4500);
flushNextRenderIfExpired();
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance by another second. Now the update should expire and flush.
ReactNoop.expire(500);
flushNextRenderIfExpired();
- expect(ReactNoop.getChildren()).toEqual([span('done')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('two updates of like priority in the same event always flush within the same batch', () => {
@@ -181,20 +177,20 @@ describe('ReactExpiration', () => {
// Don't advance time by enough to expire the first update.
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Schedule another update.
ReactNoop.render();
// Both updates are batched
expect(Scheduler).toFlushAndYield(['B [render]', 'B [commit]']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Now do the same thing again, except this time don't flush any work in
// between the two updates.
ReactNoop.render();
Scheduler.unstable_advanceTime(2000);
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Schedule another update.
ReactNoop.render();
// The updates should flush in the same batch, since as far as the scheduler
@@ -242,20 +238,20 @@ describe('ReactExpiration', () => {
// Don't advance time by enough to expire the first update.
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Schedule another update.
ReactNoop.render();
// Both updates are batched
expect(Scheduler).toFlushAndYield(['B [render]', 'B [commit]']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Now do the same thing again, except this time don't flush any work in
// between the two updates.
ReactNoop.render();
Scheduler.unstable_advanceTime(2000);
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Perform some synchronous work. The scheduler must assume we're inside
// the same event.
diff --git a/packages/react-reconciler/src/__tests__/ReactFragment-test.js b/packages/react-reconciler/src/__tests__/ReactFragment-test.js
index 423cee2ed38..f56602881df 100644
--- a/packages/react-reconciler/src/__tests__/ReactFragment-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactFragment-test.js
@@ -22,21 +22,6 @@ describe('ReactFragment', () => {
Scheduler = require('scheduler');
});
- function div(...children) {
- children = children.map(c =>
- typeof c === 'string' ? {text: c, hidden: false} : c,
- );
- return {type: 'div', children, prop: undefined, hidden: false};
- }
-
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
- function text(t) {
- return {text: t, hidden: false};
- }
-
it('should render a single child via noop renderer', () => {
const element = (
<>
@@ -47,7 +32,7 @@ describe('ReactFragment', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span()]);
+ expect(ReactNoop).toMatchRenderedOutput(foo);
});
it('should render zero children via noop renderer', () => {
@@ -56,7 +41,7 @@ describe('ReactFragment', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('should render multiple children via noop renderer', () => {
@@ -69,7 +54,11 @@ describe('ReactFragment', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('hello '), span()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+ hello world
+ >,
+ );
});
it('should render an iterable via noop renderer', () => {
@@ -80,7 +69,12 @@ describe('ReactFragment', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span(), span()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+ hi
+ bye
+ >,
+ );
});
it('should preserve state of children with 1 level nesting', function () {
@@ -114,13 +108,18 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div(), div()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
Hello
+ World
+ >,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state between top-level fragments', function () {
@@ -155,13 +154,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state of children nested at same level', function () {
@@ -205,13 +204,18 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div(), div()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+ Hello
+ >,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state in non-top-level fragment nesting', function () {
@@ -248,13 +252,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state of children if nested 2 levels without siblings', function () {
@@ -289,13 +293,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state of children if nested 2 levels with siblings', function () {
@@ -331,13 +335,18 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div(), div()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+ Hello
+
+ >,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state between array nested in fragment and fragment', function () {
@@ -370,13 +379,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state between top level fragment and array', function () {
@@ -409,13 +418,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state between array nested in fragment and double nested fragment', function () {
@@ -450,13 +459,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state between array nested in fragment and double nested array', function () {
@@ -487,13 +496,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state between double nested fragment and double nested array', function () {
@@ -528,13 +537,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state of children when the keys are different', function () {
@@ -570,13 +579,18 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div(), span()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+ Hello
+ World
+ >,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state between unkeyed and keyed fragment', function () {
@@ -611,13 +625,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state with reordering in multiple levels', function () {
@@ -664,13 +678,29 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([div(span(), div(div()), span())]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('should not preserve state when switching to a keyed fragment to an array', function () {
@@ -713,13 +743,23 @@ describe('ReactFragment', () => {
);
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div(div(), span())]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('should not preserve state when switching a nested unkeyed fragment to a passthrough component', function () {
@@ -762,13 +802,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state when switching a nested keyed fragment to a passthrough component', function () {
@@ -811,13 +851,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should not preserve state when switching a nested keyed array to a passthrough component', function () {
@@ -856,13 +896,13 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual([]);
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
});
it('should preserve state when it does not change positions', function () {
@@ -904,13 +944,23 @@ describe('ReactFragment', () => {
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([span(), div()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+ Hello
+ >,
+ );
ReactNoop.render();
// The key warning gets deduped because it's in the same component.
expect(Scheduler).toFlushWithoutYielding();
expect(ops).toEqual(['Update Stateful', 'Update Stateful']);
- expect(ReactNoop.getChildren()).toEqual([span(), div()]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+ Hello
+ >,
+ );
});
});
diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
index 417077c8179..2455f51965c 100644
--- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js
@@ -113,10 +113,6 @@ describe('ReactHooksWithNoopRenderer', () => {
};
});
- function span(prop) {
- return {type: 'span', hidden: false, children: [], prop};
- }
-
function Text(props) {
Scheduler.unstable_yieldValue(props.text);
return ;
@@ -167,7 +163,7 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Schedule some updates
act(() => {
@@ -183,7 +179,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Partially flush without committing
expect(Scheduler).toFlushAndYieldThrough(['Count: 11']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Interrupt with a high priority update
ReactNoop.flushSync(() => {
@@ -193,7 +189,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// Resume rendering
expect(Scheduler).toFlushAndYield(['Total: 11']);
- expect(ReactNoop.getChildren()).toEqual([span('Total: 11')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -289,15 +285,15 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => counter.current.updateCount(1));
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => counter.current.updateCount(count => count + 10));
expect(Scheduler).toHaveYielded(['Count: 11']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('lazy state initializer', () => {
@@ -313,11 +309,11 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['getInitialState', 'Count: 42']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 42')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => counter.current.updateCount(7));
expect(Scheduler).toHaveYielded(['Count: 7']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 7')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('multiple states', () => {
@@ -331,7 +327,7 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => counter.current.updateCount(7));
expect(Scheduler).toHaveYielded(['Count: 7']);
@@ -349,19 +345,19 @@ describe('ReactHooksWithNoopRenderer', () => {
}
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
const firstUpdater = updater;
act(() => firstUpdater(1));
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
const secondUpdater = updater;
act(() => firstUpdater(count => count + 10));
expect(Scheduler).toHaveYielded(['Count: 11']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(firstUpdater).toBe(secondUpdater);
});
@@ -392,15 +388,15 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render();
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => _updateCount(1));
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -421,27 +417,39 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Scrolling down: false']);
- expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Scrolling down: true']);
- expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Scrolling down: true']);
- expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Scrolling down: true']);
- expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: true')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Scrolling down: false']);
- expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Scrolling down: false']);
- expect(ReactNoop.getChildren()).toEqual([span('Scrolling down: false')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('warns about render phase update on a different component', async () => {
@@ -517,7 +525,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Render: 3',
3,
]);
- expect(ReactNoop.getChildren()).toEqual([span(3)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('updates multiple times within same render function', () => {
@@ -542,7 +550,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Render: 12',
12,
]);
- expect(ReactNoop.getChildren()).toEqual([span(12)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('throws after too many iterations', () => {
@@ -580,7 +588,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Render: 3',
3,
]);
- expect(ReactNoop.getChildren()).toEqual([span(3)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('uses reducer passed at time of render, not time of dispatch', () => {
@@ -632,7 +640,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Render: 21',
21,
]);
- expect(ReactNoop.getChildren()).toEqual([span(21)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Test that it works on update, too. This time the log is a bit different
// because we started with reducerB instead of reducerA.
@@ -648,7 +656,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Render: 22',
22,
]);
- expect(ReactNoop.getChildren()).toEqual([span(22)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('discards render phase updates if something suspends', async () => {
@@ -873,11 +881,11 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => counter.current.dispatch(INCREMENT));
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => {
counter.current.dispatch(DECREMENT);
counter.current.dispatch(DECREMENT);
@@ -885,7 +893,7 @@ describe('ReactHooksWithNoopRenderer', () => {
});
expect(Scheduler).toHaveYielded(['Count: -2']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: -2')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('lazy init', () => {
@@ -915,11 +923,11 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Init', 'Count: 10']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 10')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => counter.current.dispatch(INCREMENT));
expect(Scheduler).toHaveYielded(['Count: 11']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 11')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => {
counter.current.dispatch(DECREMENT);
@@ -928,7 +936,7 @@ describe('ReactHooksWithNoopRenderer', () => {
});
expect(Scheduler).toHaveYielded(['Count: 8']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 8')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Regression test for https://github.com/facebook/react/issues/14360
@@ -950,7 +958,7 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.batchedUpdates(() => {
counter.current.dispatch(INCREMENT);
@@ -963,12 +971,12 @@ describe('ReactHooksWithNoopRenderer', () => {
});
if (gate(flags => flags.enableUnifiedSyncLane)) {
expect(Scheduler).toHaveYielded(['Count: 4']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 4')]);
+ expect(ReactNoop).toMatchRenderedOutput();
} else {
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(Scheduler).toFlushAndYield(['Count: 4']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 4')]);
+ expect(ReactNoop).toMatchRenderedOutput();
}
});
});
@@ -986,7 +994,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Effects are deferred until after the commit
expect(Scheduler).toFlushAndYield(['Passive effect [0]']);
});
@@ -996,7 +1004,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Effects are deferred until after the commit
expect(Scheduler).toFlushAndYield(['Passive effect [1]']);
});
@@ -1023,15 +1031,17 @@ describe('ReactHooksWithNoopRenderer', () => {
'Passive',
'Layout effect',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Layout'),
- span('Passive'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Destroying the first child shouldn't prevent the passive effect from
// being executed
ReactNoop.render([passive]);
expect(Scheduler).toFlushAndYield(['Passive effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Passive')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// exiting act calls flushPassiveEffects(), but there are none left to flush.
expect(Scheduler).toHaveYielded([]);
@@ -1069,10 +1079,12 @@ describe('ReactHooksWithNoopRenderer', () => {
]);
});
- expect(ReactNoop.getChildren()).toEqual([
- span('Passive'),
- span('Layout'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
it('flushes passive effects even if siblings schedule a new root', () => {
@@ -1099,10 +1111,12 @@ describe('ReactHooksWithNoopRenderer', () => {
'Passive effect',
'New Root',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Passive'),
- span('Layout'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
});
@@ -1111,11 +1125,11 @@ describe('ReactHooksWithNoopRenderer', () => {
"new ones, if they haven't already fired",
() => {
function getCommittedText() {
- const children = ReactNoop.getChildren();
+ const children = ReactNoop.getChildrenAsJSX();
if (children === null) {
return null;
}
- return children[0].prop;
+ return children.props.prop;
}
function Counter(props) {
@@ -1131,7 +1145,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough([0, 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Before the effects have a chance to flush, schedule another update
ReactNoop.render(, () =>
Scheduler.unstable_yieldValue('Sync effect'),
@@ -1142,7 +1156,7 @@ describe('ReactHooksWithNoopRenderer', () => {
1,
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span(1)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded([
@@ -1622,7 +1636,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Count: (empty)',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushPassiveEffects();
expect(Scheduler).toHaveYielded(['Schedule update [0]']);
expect(Scheduler).toFlushAndYield(['Count: 0']);
@@ -1633,7 +1647,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushPassiveEffects();
expect(Scheduler).toHaveYielded(['Schedule update [1]']);
expect(Scheduler).toFlushAndYield(['Count: 1']);
@@ -1657,7 +1671,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Count: (empty)',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Rendering again should flush the previous commit's effects
if (gate(flags => flags.enableSyncDefaultUpdates)) {
@@ -1678,7 +1692,7 @@ describe('ReactHooksWithNoopRenderer', () => {
]);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(Scheduler).toFlushAndYieldThrough([
'Count: 0',
'Sync effect',
@@ -1686,16 +1700,18 @@ describe('ReactHooksWithNoopRenderer', () => {
'Count: 1',
]);
} else {
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
expect(Scheduler).toFlushAndYieldThrough(['Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushPassiveEffects();
expect(Scheduler).toHaveYielded(['Schedule update [1]']);
expect(Scheduler).toFlushAndYield(['Count: 1']);
}
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -1715,7 +1731,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// A flush sync doesn't cause the passive effects to fire.
// So we haven't added the other update yet.
act(() => {
@@ -1737,7 +1753,7 @@ describe('ReactHooksWithNoopRenderer', () => {
]);
}
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it(
@@ -1765,14 +1781,16 @@ describe('ReactHooksWithNoopRenderer', () => {
// Even in legacy mode, effects are deferred until after paint
expect(Scheduler).toHaveYielded(['Count: (empty)']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
// effects get forced on exiting act()
// There were multiple updates, but there should only be a
// single render
expect(Scheduler).toHaveYielded(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
},
);
@@ -1784,10 +1802,11 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.flushSync(() => {
updateCount(props.count);
});
+ expect(Scheduler).toHaveYielded([`Schedule update [${props.count}]`]);
// This shouldn't flush synchronously.
- expect(ReactNoop.getChildren()).not.toEqual([
- span('Count: ' + props.count),
- ]);
+ expect(ReactNoop).not.toMatchRenderedOutput(
+ ,
+ );
}, [props.count]);
return ;
}
@@ -1800,10 +1819,13 @@ describe('ReactHooksWithNoopRenderer', () => {
'Count: (empty)',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: (empty)')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
}).toErrorDev('flushSync was called from inside a lifecycle method');
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(Scheduler).toHaveYielded([`Count: 0`]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('unmounts previous effect', () => {
@@ -1821,7 +1843,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did create [0]']);
@@ -1831,7 +1853,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did destroy [0]', 'Did create [1]']);
@@ -1852,14 +1874,14 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did create [0]']);
ReactNoop.render(null);
expect(Scheduler).toFlushAndYield(['Did destroy [0]']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('unmounts on deletion after skipped effect', () => {
@@ -1877,7 +1899,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did create [0]']);
@@ -1887,14 +1909,14 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded([]);
ReactNoop.render(null);
expect(Scheduler).toFlushAndYield(['Did destroy [0]']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('always fires effects if no dependencies are provided', () => {
@@ -1913,7 +1935,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did create']);
@@ -1923,14 +1945,14 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did destroy', 'Did create']);
ReactNoop.render(null);
expect(Scheduler).toFlushAndYield(['Did destroy']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('skips effect if inputs have not changed', () => {
@@ -1952,7 +1974,7 @@ describe('ReactHooksWithNoopRenderer', () => {
});
expect(Scheduler).toHaveYielded(['Did create [Count: 0]']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => {
ReactNoop.render(, () =>
@@ -1960,7 +1982,7 @@ describe('ReactHooksWithNoopRenderer', () => {
);
// Count changed
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded([
@@ -1977,7 +1999,7 @@ describe('ReactHooksWithNoopRenderer', () => {
});
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => {
ReactNoop.render(, () =>
@@ -1985,7 +2007,7 @@ describe('ReactHooksWithNoopRenderer', () => {
);
// Label changed
expect(Scheduler).toFlushAndYieldThrough(['Total: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Total: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded([
@@ -2009,7 +2031,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did commit 1 [0]', 'Did commit 2 [0]']);
@@ -2019,7 +2041,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Did commit 1 [1]', 'Did commit 2 [1]']);
});
@@ -2045,7 +2067,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
@@ -2055,7 +2077,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
expect(Scheduler).toHaveYielded([
'Unmount A [0]',
@@ -2084,7 +2106,12 @@ describe('ReactHooksWithNoopRenderer', () => {
() => Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['A 0', 'B 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('A 0'), span('B 0')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
@@ -2098,7 +2125,12 @@ describe('ReactHooksWithNoopRenderer', () => {
() => Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['A 1', 'B 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('A 1'), span('B 1')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
expect(Scheduler).toHaveYielded([
'Unmount A [0]',
@@ -2116,7 +2148,12 @@ describe('ReactHooksWithNoopRenderer', () => {
() => Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['B 2', 'C 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('B 2'), span('C 0')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
expect(Scheduler).toHaveYielded([
'Unmount A [1]',
@@ -2150,7 +2187,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
});
@@ -2161,7 +2198,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// never mounted.
'Unmount A [0]',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('handles errors in create on update', () => {
@@ -2189,7 +2226,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushPassiveEffects();
expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
});
@@ -2200,7 +2237,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
expect(Scheduler).toHaveYielded([
'Unmount A [0]',
@@ -2208,7 +2245,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Mount A [1]',
'Oops!',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
expect(Scheduler).toHaveYielded([
// Clean up effect A runs passively on unmount.
@@ -2242,7 +2279,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 0', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushPassiveEffects();
expect(Scheduler).toHaveYielded(['Mount A [0]', 'Mount B [0]']);
});
@@ -2253,7 +2290,7 @@ describe('ReactHooksWithNoopRenderer', () => {
Scheduler.unstable_yieldValue('Sync effect'),
);
expect(Scheduler).toFlushAndYieldThrough(['Count: 1', 'Sync effect']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(() => ReactNoop.flushPassiveEffects()).toThrow('Oops');
// This branch enables a feature flag that flushes all passive destroys in a
@@ -2272,7 +2309,7 @@ describe('ReactHooksWithNoopRenderer', () => {
// The remaining destroy functions are run later on unmount, since they're passive.
// In this case, one of them throws again (because of how the test is written).
expect(Scheduler).toHaveYielded(['Oops!', 'Unmount B [1]']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('works with memo', () => {
@@ -2293,7 +2330,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Mount: 0',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render(, () =>
Scheduler.unstable_yieldValue('Sync effect'),
@@ -2304,11 +2341,11 @@ describe('ReactHooksWithNoopRenderer', () => {
'Mount: 1',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render(null);
expect(Scheduler).toFlushAndYieldThrough(['Unmount: 1']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
describe('errors thrown in passive destroy function within unmounted trees', () => {
@@ -2473,9 +2510,9 @@ describe('ReactHooksWithNoopRenderer', () => {
'ErrorBoundary componentDidCatch',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('ErrorBoundary fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
// @gate skipUnmountedBoundaries
@@ -2511,7 +2548,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'BrokenUseEffectCleanup useEffect destroy',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
});
@@ -3191,12 +3228,12 @@ describe('ReactHooksWithNoopRenderer', () => {
it('fires layout effects after the host has been mutated', () => {
function getCommittedText() {
const yields = Scheduler.unstable_clearYields();
- const children = ReactNoop.getChildren();
+ const children = ReactNoop.getChildrenAsJSX();
Scheduler.unstable_yieldValue(yields);
if (children === null) {
return null;
}
- return children[0].prop;
+ return children.props.prop;
}
function Counter(props) {
@@ -3214,7 +3251,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Current: 0',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render(, () =>
Scheduler.unstable_yieldValue('Sync effect'),
@@ -3224,7 +3261,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'Current: 1',
'Sync effect',
]);
- expect(ReactNoop.getChildren()).toEqual([span(1)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('force flushes passive effects before firing new layout effects', () => {
@@ -3341,10 +3378,12 @@ describe('ReactHooksWithNoopRenderer', () => {
'InnerBoundary render success',
'BrokenLayoutEffectDestroy render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('sibling'),
- span('broken'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
ReactNoop.render(
@@ -3361,7 +3400,7 @@ describe('ReactHooksWithNoopRenderer', () => {
'OuterBoundary render error',
'Component render OuterFallback',
]);
- expect(ReactNoop.getChildren()).toEqual([span('OuterFallback')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('assumes layout effect destroy function is either a function or undefined', () => {
@@ -3441,10 +3480,12 @@ describe('ReactHooksWithNoopRenderer', () => {
const button = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Increment', 'Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 0'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -3452,10 +3493,12 @@ describe('ReactHooksWithNoopRenderer', () => {
// 'Increment',
'Count: 1',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 1'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Increase the increment amount
ReactNoop.render();
@@ -3464,18 +3507,22 @@ describe('ReactHooksWithNoopRenderer', () => {
'Increment',
'Count: 1',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 1'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Callback should have updated
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Count: 11']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 11'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
});
@@ -3492,19 +3539,19 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(["Capitalize 'hello'", 'HELLO']);
- expect(ReactNoop.getChildren()).toEqual([span('HELLO')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render();
expect(Scheduler).toFlushAndYield(["Capitalize 'hi'", 'HI']);
- expect(ReactNoop.getChildren()).toEqual([span('HI')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['HI']);
- expect(ReactNoop.getChildren()).toEqual([span('HI')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render();
expect(Scheduler).toFlushAndYield(["Capitalize 'goodbye'", 'GOODBYE']);
- expect(ReactNoop.getChildren()).toEqual([span('GOODBYE')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('always re-computes if no inputs are provided', () => {
@@ -3583,14 +3630,14 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(counter.current.count).toBe(0);
act(() => {
counter.current.dispatch(INCREMENT);
});
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Intentionally not updated because of [] deps:
expect(counter.current.count).toBe(0);
});
@@ -3613,14 +3660,14 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(counter.current.count).toBe(0);
act(() => {
counter.current.dispatch(INCREMENT);
});
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(counter.current.count).toBe(1);
});
@@ -3649,7 +3696,7 @@ describe('ReactHooksWithNoopRenderer', () => {
const counter = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(counter.current.count).toBe(0);
expect(totalRefUpdates).toBe(1);
@@ -3657,14 +3704,14 @@ describe('ReactHooksWithNoopRenderer', () => {
counter.current.dispatch(INCREMENT);
});
expect(Scheduler).toHaveYielded(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(counter.current.count).toBe(1);
expect(totalRefUpdates).toBe(2);
// Update that doesn't change the ref dependencies
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(counter.current.count).toBe(1);
expect(totalRefUpdates).toBe(2); // Should not increase since last time
});
@@ -3694,9 +3741,9 @@ describe('ReactHooksWithNoopRenderer', () => {
}
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Before... Pending: false']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Before... Pending: false'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
await act(async () => {
transition();
@@ -3706,27 +3753,27 @@ describe('ReactHooksWithNoopRenderer', () => {
'Suspend! [After... Pending: false]',
'Loading... Pending: false',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Before... Pending: true'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
Scheduler.unstable_advanceTime(500);
await advanceTimers(500);
// Even after a long amount of time, we still don't show a placeholder.
Scheduler.unstable_advanceTime(100000);
await advanceTimers(100000);
- expect(ReactNoop.getChildren()).toEqual([
- span('Before... Pending: true'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
await resolveText('After... Pending: false');
expect(Scheduler).toHaveYielded([
'Promise resolved [After... Pending: false]',
]);
expect(Scheduler).toFlushAndYield(['After... Pending: false']);
- expect(ReactNoop.getChildren()).toEqual([
- span('After... Pending: false'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
});
});
@@ -3759,12 +3806,22 @@ describe('ReactHooksWithNoopRenderer', () => {
});
expect(Scheduler).toHaveYielded(['A', 'Suspend! [A]', 'Loading']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('Loading')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
await resolveText('A');
expect(Scheduler).toHaveYielded(['Promise resolved [A]']);
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
await act(async () => {
_setText('B');
@@ -3776,7 +3833,12 @@ describe('ReactHooksWithNoopRenderer', () => {
'Loading',
]);
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span('B'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
await act(async () => {
@@ -3784,19 +3846,34 @@ describe('ReactHooksWithNoopRenderer', () => {
await advanceTimers(250);
});
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([span('B'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Even after a long amount of time, we don't show a fallback
Scheduler.unstable_advanceTime(100000);
await advanceTimers(100000);
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span('B'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
await act(async () => {
await resolveText('B');
});
expect(Scheduler).toHaveYielded(['Promise resolved [B]', 'B', 'B']);
- expect(ReactNoop.getChildren()).toEqual([span('B'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
});
@@ -3824,9 +3901,9 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['A: 0, B: 0, C: [not loaded]']);
- expect(ReactNoop.getChildren()).toEqual([
- span('A: 0, B: 0, C: [not loaded]'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
act(() => {
updateA(2);
@@ -3834,9 +3911,9 @@ describe('ReactHooksWithNoopRenderer', () => {
});
expect(Scheduler).toHaveYielded(['A: 2, B: 3, C: [not loaded]']);
- expect(ReactNoop.getChildren()).toEqual([
- span('A: 2, B: 3, C: [not loaded]'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(() => {
@@ -3856,11 +3933,11 @@ describe('ReactHooksWithNoopRenderer', () => {
]);
// Uncomment if/when we support this again
- // expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 0')]);
+ // expect(ReactNoop).toMatchRenderedOutput(]);
// updateC(4);
// expect(Scheduler).toFlushAndYield(['A: 2, B: 3, C: 4']);
- // expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]);
+ // expect(ReactNoop).toMatchRenderedOutput(]);
});
it('unmount state', () => {
@@ -3888,14 +3965,14 @@ describe('ReactHooksWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['A: 0, B: 0, C: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('A: 0, B: 0, C: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
act(() => {
updateA(2);
updateB(3);
updateC(4);
});
expect(Scheduler).toHaveYielded(['A: 2, B: 3, C: 4']);
- expect(ReactNoop.getChildren()).toEqual([span('A: 2, B: 3, C: 4')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.render();
expect(Scheduler).toFlushAndThrow(
'Rendered fewer hooks than expected. This may be caused by an ' +
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
index 80f1779e119..37869121ba1 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js
@@ -29,15 +29,6 @@ describe('ReactIncrementalErrorHandling', () => {
act = require('jest-react').act;
});
- function div(...children) {
- children = children.map(c => (typeof c === 'string' ? {text: c} : c));
- return {type: 'div', children, prop: undefined, hidden: false};
- }
-
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
function normalizeCodeLocInfo(str) {
return (
str &&
@@ -149,7 +140,7 @@ describe('ReactIncrementalErrorHandling', () => {
// Since the error was thrown during an async render, React won't commit
// the result yet.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Instead, it will try rendering one more time, synchronously, in case that
// happens to fix the error.
@@ -169,7 +160,9 @@ describe('ReactIncrementalErrorHandling', () => {
'ErrorMessage',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('recovers from errors asynchronously (legacy, no getDerivedStateFromError)', () => {
@@ -267,7 +260,9 @@ describe('ReactIncrementalErrorHandling', () => {
'ErrorBoundary (catch)',
'ErrorMessage',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it("retries at a lower priority if there's additional pending work", async () => {
@@ -307,7 +302,9 @@ describe('ReactIncrementalErrorHandling', () => {
'commit',
'commit',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Everything is fine.')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
// @gate www
@@ -424,7 +421,7 @@ describe('ReactIncrementalErrorHandling', () => {
'Sibling',
'commit',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('retries one more time if an error occurs during a render that expires midway through the tree', async () => {
@@ -484,7 +481,7 @@ describe('ReactIncrementalErrorHandling', () => {
'C',
'D',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('calls componentDidCatch multiple times for multiple errors', () => {
@@ -531,7 +528,9 @@ describe('ReactIncrementalErrorHandling', () => {
'componentDidCatch: Error 2',
'componentDidCatch: Error 3',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Number of errors: 3')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('catches render error in a boundary during full deferred mounting', () => {
@@ -560,7 +559,9 @@ describe('ReactIncrementalErrorHandling', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('catches render error in a boundary during partial deferred mounting', () => {
@@ -604,7 +605,7 @@ describe('ReactIncrementalErrorHandling', () => {
}
expect(Scheduler).toFlushAndYieldThrough(['ErrorBoundary render success']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
expect(Scheduler).toFlushAndYield([
'BrokenRender',
@@ -616,7 +617,9 @@ describe('ReactIncrementalErrorHandling', () => {
'ErrorBoundary componentDidCatch',
'ErrorBoundary render error',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('catches render error in a boundary during synchronous mounting', () => {
@@ -663,7 +666,9 @@ describe('ReactIncrementalErrorHandling', () => {
'ErrorBoundary componentDidCatch',
'ErrorBoundary render error',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('catches render error in a boundary during batched mounting', () => {
@@ -711,7 +716,9 @@ describe('ReactIncrementalErrorHandling', () => {
'ErrorBoundary componentDidCatch',
'ErrorBoundary render error',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello.')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('propagates an error from a noop error boundary during full deferred mounting', () => {
@@ -750,7 +757,7 @@ describe('ReactIncrementalErrorHandling', () => {
'RethrowErrorBoundary componentDidCatch',
]);
}).toThrow('Hello');
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop.getChildrenAsJSX()).toEqual(null);
});
it('propagates an error from a noop error boundary during partial deferred mounting', () => {
@@ -801,7 +808,7 @@ describe('ReactIncrementalErrorHandling', () => {
// Errored again on retry. Now handle it.
'RethrowErrorBoundary componentDidCatch',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('propagates an error from a noop error boundary during synchronous mounting', () => {
@@ -841,7 +848,7 @@ describe('ReactIncrementalErrorHandling', () => {
// Errored again on retry. Now handle it.
'RethrowErrorBoundary componentDidCatch',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('propagates an error from a noop error boundary during batched mounting', () => {
@@ -884,7 +891,7 @@ describe('ReactIncrementalErrorHandling', () => {
// Errored again on retry. Now handle it.
'RethrowErrorBoundary componentDidCatch',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('applies batched updates regardless despite errors in scheduling', () => {
@@ -897,7 +904,7 @@ describe('ReactIncrementalErrorHandling', () => {
});
}).toThrow('Hello');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('a:3')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('applies nested batched updates despite errors in scheduling', () => {
@@ -914,7 +921,7 @@ describe('ReactIncrementalErrorHandling', () => {
});
}).toThrow('Hello');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('a:5')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// TODO: Is this a breaking change?
@@ -930,7 +937,7 @@ describe('ReactIncrementalErrorHandling', () => {
});
}).toThrow('Hello');
Scheduler.unstable_flushAll();
- expect(ReactNoop.getChildren()).toEqual([span('a:3')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('can schedule updates after uncaught error in render on mount', () => {
@@ -1127,11 +1134,11 @@ describe('ReactIncrementalErrorHandling', () => {
);
ReactNoop.renderToRootWithID(, 'b');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual([
- span('Caught an error: Hello.'),
- ]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual(
+ ,
+ );
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('b')).toEqual([span('b:1')]);
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual();
});
it('continues work on other roots despite uncaught errors', () => {
@@ -1143,7 +1150,7 @@ describe('ReactIncrementalErrorHandling', () => {
expect(() => {
expect(Scheduler).toFlushWithoutYielding();
}).toThrow('a');
- expect(ReactNoop.getChildren('a')).toEqual([]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual(null);
ReactNoop.renderToRootWithID(, 'a');
ReactNoop.renderToRootWithID(, 'b');
@@ -1152,16 +1159,16 @@ describe('ReactIncrementalErrorHandling', () => {
}).toThrow('a');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual([]);
- expect(ReactNoop.getChildren('b')).toEqual([span('b:2')]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual();
ReactNoop.renderToRootWithID(, 'a');
ReactNoop.renderToRootWithID(, 'b');
expect(() => {
expect(Scheduler).toFlushWithoutYielding();
}).toThrow('b');
- expect(ReactNoop.getChildren('a')).toEqual([span('a:3')]);
- expect(ReactNoop.getChildren('b')).toEqual([]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual(null);
ReactNoop.renderToRootWithID(, 'a');
ReactNoop.renderToRootWithID(, 'b');
@@ -1170,9 +1177,9 @@ describe('ReactIncrementalErrorHandling', () => {
expect(Scheduler).toFlushWithoutYielding();
}).toThrow('b');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual([span('a:4')]);
- expect(ReactNoop.getChildren('b')).toEqual([]);
- expect(ReactNoop.getChildren('c')).toEqual([span('c:4')]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('c')).toEqual();
ReactNoop.renderToRootWithID(, 'a');
ReactNoop.renderToRootWithID(, 'b');
@@ -1183,11 +1190,11 @@ describe('ReactIncrementalErrorHandling', () => {
expect(Scheduler).toFlushWithoutYielding();
}).toThrow('e');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual([span('a:5')]);
- expect(ReactNoop.getChildren('b')).toEqual([span('b:5')]);
- expect(ReactNoop.getChildren('c')).toEqual([span('c:5')]);
- expect(ReactNoop.getChildren('d')).toEqual([span('d:5')]);
- expect(ReactNoop.getChildren('e')).toEqual([]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('c')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('d')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('e')).toEqual(null);
ReactNoop.renderToRootWithID(, 'a');
ReactNoop.renderToRootWithID(, 'b');
@@ -1207,12 +1214,12 @@ describe('ReactIncrementalErrorHandling', () => {
}).toThrow('e');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual([]);
- expect(ReactNoop.getChildren('b')).toEqual([span('b:6')]);
- expect(ReactNoop.getChildren('c')).toEqual([]);
- expect(ReactNoop.getChildren('d')).toEqual([span('d:6')]);
- expect(ReactNoop.getChildren('e')).toEqual([]);
- expect(ReactNoop.getChildren('f')).toEqual([span('f:6')]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('c')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('d')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('e')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('f')).toEqual();
ReactNoop.unmountRootWithID('a');
ReactNoop.unmountRootWithID('b');
@@ -1221,12 +1228,12 @@ describe('ReactIncrementalErrorHandling', () => {
ReactNoop.unmountRootWithID('e');
ReactNoop.unmountRootWithID('f');
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual(null);
- expect(ReactNoop.getChildren('b')).toEqual(null);
- expect(ReactNoop.getChildren('c')).toEqual(null);
- expect(ReactNoop.getChildren('d')).toEqual(null);
- expect(ReactNoop.getChildren('e')).toEqual(null);
- expect(ReactNoop.getChildren('f')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('c')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('d')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('e')).toEqual(null);
+ expect(ReactNoop.getChildrenAsJSX('f')).toEqual(null);
});
it('unwinds the context stack correctly on error', () => {
@@ -1284,7 +1291,7 @@ describe('ReactIncrementalErrorHandling', () => {
expect(Scheduler).toFlushWithoutYielding();
// If the context stack does not unwind, span will get 'abcde'
- expect(ReactNoop.getChildren()).toEqual([span('a')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('catches reconciler errors in a boundary during mounting', () => {
@@ -1315,17 +1322,19 @@ describe('ReactIncrementalErrorHandling', () => {
// React retries once on error
'Warning: React.createElement: type is invalid -- expected a string',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span(
- 'Element type is invalid: expected a string (for built-in components) or ' +
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('catches reconciler errors in a boundary during update', () => {
@@ -1364,17 +1373,19 @@ describe('ReactIncrementalErrorHandling', () => {
// React retries once on error
'Warning: React.createElement: type is invalid -- expected a string',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span(
- 'Element type is invalid: expected a string (for built-in components) or ' +
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('recovers from uncaught reconciler errors', () => {
@@ -1394,7 +1405,7 @@ describe('ReactIncrementalErrorHandling', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('hi')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('unmounts components with uncaught errors', () => {
@@ -1447,7 +1458,7 @@ describe('ReactIncrementalErrorHandling', () => {
'Parent componentWillUnmount [!]',
'BrokenRenderAndUnmount componentWillUnmount',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
expect(() => {
ReactNoop.flushSync();
@@ -1478,7 +1489,11 @@ describe('ReactIncrementalErrorHandling', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['barRef attach']);
- expect(ReactNoop.getChildren()).toEqual([div(span('Bar'))]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+
,
+ );
// Unmount
ReactNoop.render();
@@ -1489,7 +1504,7 @@ describe('ReactIncrementalErrorHandling', () => {
'Bar unmount',
]);
// Because there was an error, entire tree should unmount
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
it('handles error thrown by host config while working on failed root', () => {
@@ -1562,7 +1577,9 @@ describe('ReactIncrementalErrorHandling', () => {
'componentDidCatch',
'ErrorBoundary (catch)',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
if (__DEV__) {
expect(console.error).toHaveBeenCalledTimes(1);
@@ -1635,7 +1652,9 @@ describe('ReactIncrementalErrorHandling', () => {
'ErrorBoundary (catch)',
'ErrorMessage',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('calls the correct lifecycles on the error boundary after catching an error (mixed)', () => {
@@ -1676,7 +1695,9 @@ describe('ReactIncrementalErrorHandling', () => {
'render error message',
'did update',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: oops!')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('provides component stack to the error boundary with componentDidCatch', () => {
@@ -1710,13 +1731,15 @@ describe('ReactIncrementalErrorHandling', () => {
,
);
expect(Scheduler).toFlushAndYield(['render error message']);
- expect(ReactNoop.getChildren()).toEqual([
- span(
- 'Caught an error:\n' +
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('does not provide component stack to the error boundary with getDerivedStateFromError', () => {
@@ -1744,7 +1767,9 @@ describe('ReactIncrementalErrorHandling', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Caught an error: Hello')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('provides component stack even if overriding prepareStackTrace', () => {
@@ -1794,13 +1819,15 @@ describe('ReactIncrementalErrorHandling', () => {
expect(Scheduler).toFlushAndYield(['render error message']);
Error.prepareStackTrace = undefined;
- expect(ReactNoop.getChildren()).toEqual([
- span(
- 'Caught an error:\n' +
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
if (!ReactFeatureFlags.disableModulePatternComponents) {
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js
index 247ef5f4068..3cc006dad1c 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js
@@ -25,13 +25,9 @@ describe('ReactIncrementalScheduling', () => {
act = require('jest-react').act;
});
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
it('schedules and flushes deferred work', () => {
ReactNoop.render();
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
expect(Scheduler).toFlushWithoutYielding();
expect(ReactNoop).toMatchRenderedOutput();
@@ -44,9 +40,9 @@ describe('ReactIncrementalScheduling', () => {
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren('a')).toEqual([span('a:1')]);
- expect(ReactNoop.getChildren('b')).toEqual([span('b:1')]);
- expect(ReactNoop.getChildren('c')).toEqual([span('c:1')]);
+ expect(ReactNoop.getChildrenAsJSX('a')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('b')).toEqual();
+ expect(ReactNoop.getChildrenAsJSX('c')).toEqual();
});
it('schedules top-level updates in order of priority', () => {
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js
index bb5f2e59700..3e4cd2e4f55 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js
@@ -23,21 +23,6 @@ describe('ReactIncrementalSideEffects', () => {
Scheduler = require('scheduler');
});
- function div(...children) {
- children = children.map(c =>
- typeof c === 'string' ? {text: c, hidden: false} : c,
- );
- return {type: 'div', children, prop: undefined, hidden: false};
- }
-
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
- function text(t) {
- return {text: t, hidden: false};
- }
-
// Note: This is based on a similar component we use in www. We can delete
// once the extra div wrapper is no longer necessary.
function LegacyHiddenDiv({children, mode}) {
@@ -67,11 +52,20 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span())]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+ Hello
+
,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span(), span())]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+ World
+ World
+
,
+ );
});
it('can update child nodes of a fragment', function () {
@@ -95,19 +89,34 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span(), span('test'))]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+ Hello
+
+
,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- div(span(), span(), div(), span('test')),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- div(span(), div(), span(), span('test')),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('can update child nodes rendering into text nodes', function () {
@@ -128,11 +137,11 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div('Hello')]);
+ expect(ReactNoop).toMatchRenderedOutput(Hello
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div('World', 'World', '!')]);
+ expect(ReactNoop).toMatchRenderedOutput(WorldWorld!
);
});
it('can deletes children either components, host or text', function () {
@@ -152,13 +161,17 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- div(div(), span('Hello'), 'World'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div()]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('can delete a child that changes type - implicit keys', function () {
@@ -194,23 +207,33 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span('Class'), 'Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ Trail
+
,
+ );
expect(unmounted).toBe(false);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span('Function'), 'Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ Trail
+
,
+ );
expect(unmounted).toBe(true);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div('Text', 'Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(TextTrail
);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div('Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(Trail
);
});
it('can delete a child that changes type - explicit keys', function () {
@@ -244,19 +267,29 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span('Class'), 'Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ Trail
+
,
+ );
expect(unmounted).toBe(false);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div(span('Function'), 'Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ Trail
+
,
+ );
expect(unmounted).toBe(true);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div('Trail')]);
+ expect(ReactNoop).toMatchRenderedOutput(Trail
);
});
it('can delete a child when it unmounts inside a portal', () => {
@@ -280,12 +313,14 @@ describe('ReactIncrementalSideEffects', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div()]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([
- div(),
- span('Hello'),
- text('World'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput();
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(
+ <>
+
+
+ World
+ >,
+ );
ReactNoop.render(
@@ -293,8 +328,8 @@ describe('ReactIncrementalSideEffects', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div()]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput();
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(null);
ReactNoop.render(
@@ -302,36 +337,40 @@ describe('ReactIncrementalSideEffects', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div()]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([
- div(),
- span('Hello'),
- text('World'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput();
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(
+ <>
+
+
+ World
+ >,
+ );
ReactNoop.render(null);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(null);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(null);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([
- div(),
- span('Hello'),
- text('World'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(
+ <>
+
+
+ World
+ >,
+ );
ReactNoop.render(null);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(null);
});
it('can delete a child when it unmounts with a portal', () => {
@@ -355,31 +394,35 @@ describe('ReactIncrementalSideEffects', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([div()]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([
- div(),
- span('Hello'),
- text('World'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput();
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(
+ <>
+
+
+ World
+ >,
+ );
ReactNoop.render(null);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(null);
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([
- div(),
- span('Hello'),
- text('World'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(
+ <>
+
+
+ World
+ >,
+ );
ReactNoop.render(null);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
- expect(ReactNoop.getChildren('portalContainer')).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
+ expect(ReactNoop.getChildrenAsJSX('portalContainer')).toEqual(null);
});
it('does not update child nodes if a flush is aborted', () => {
@@ -403,9 +446,15 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo', 'Bar', 'Bar', 'Bar']);
- expect(ReactNoop.getChildren()).toEqual([
- div(div(span('Hello'), span('Hello')), span('Yo')),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.startTransition(() => {
@@ -417,9 +466,15 @@ describe('ReactIncrementalSideEffects', () => {
// Flush some of the work without committing
expect(Scheduler).toFlushAndYieldThrough(['Foo', 'Bar']);
- expect(ReactNoop.getChildren()).toEqual([
- div(div(span('Hello'), span('Hello')), span('Yo')),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
// @gate www
@@ -729,55 +784,61 @@ describe('ReactIncrementalSideEffects', () => {
}
ReactNoop.render();
ReactNoop.flushDeferredPri(40 + 25);
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(0),
- div(/*the spans are down-prioritized and not rendered yet*/),
- ),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
ReactNoop.render();
ReactNoop.flushDeferredPri(35 + 25);
- expect(ReactNoop.getChildren()).toEqual([
- div(span(1), div(/*still not rendered yet*/)),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+
{/*still not rendered yet*/}
+
,
+ );
ReactNoop.flushDeferredPri(30 + 25);
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(1),
- div(
- // Now we had enough time to finish the spans.
- span(0),
- span(1),
- ),
- ),
- ]);
- const innerSpanA = ReactNoop.getChildren()[0].children[1].children[1];
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+
+ {/* Now we had enough time to finish the spans. */}
+
+
+
+ ,
+
,
+ );
+ const innerSpanA =
+ ReactNoop.dangerouslyGetChildren()[0].children[1].children[1];
ReactNoop.render();
ReactNoop.flushDeferredPri(30 + 25);
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(2),
- div(
- // Still same old numbers.
- span(0),
- span(1),
- ),
- ),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+
+ {/* Still same old numbers. */}
+
+
+
+
,
+ );
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(3),
- div(
- // New numbers.
- span(1),
- span(2),
- ),
- ),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+
+ {/* New numbers. */}
+
+
+
+
,
+ );
- const innerSpanB = ReactNoop.getChildren()[0].children[1].children[1];
+ const innerSpanB =
+ ReactNoop.dangerouslyGetChildren()[0].children[1].children[1];
// This should have been an update to an existing instance, not recreation.
// We verify that by ensuring that the child instance was the same as
// before.
@@ -823,39 +884,44 @@ describe('ReactIncrementalSideEffects', () => {
}
ReactNoop.render();
ReactNoop.flushDeferredPri(65 + 5);
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(0),
- div(/*the spans are down-prioritized and not rendered yet*/),
- ),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ {/*the spans are down-prioritized and not rendered yet*/}
+
+
,
+ );
expect(ops).toEqual(['Foo', 'Baz', 'Bar']);
ops = [];
ReactNoop.render();
ReactNoop.flushDeferredPri(70);
- expect(ReactNoop.getChildren()).toEqual([
- div(span(1), div(/*still not rendered yet*/)),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ {/*still not rendered yet*/}
+
+
,
+ );
expect(ops).toEqual(['Foo']);
ops = [];
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(1),
- div(
- // Now we had enough time to finish the spans.
- span(0),
- span(0),
- span(0),
- span(0),
- span(0),
- span(0),
- ),
- ),
+ expect(ReactNoop).toMatchRenderedOutput([
+
+
,
+
+ {/* Now we had enough time to finish the spans. */}
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+
+
,
]);
expect(ops).toEqual(['Bar', 'Baz', 'Bar', 'Bar', 'Baz', 'Bar', 'Bar']);
@@ -865,20 +931,20 @@ describe('ReactIncrementalSideEffects', () => {
// way through.
ReactNoop.render();
ReactNoop.flushDeferredPri(95);
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(2),
- div(
- // Still same old numbers.
- span(0),
- span(0),
- span(0),
- span(0),
- span(0),
- span(0),
- ),
- ),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
,
+
+ {/* Still same old numbers. */}
+
+
+
+
+
+
+
+
,
+ );
// We let it finish half way through. That means we'll have one fully
// completed Baz, one half-way completed Baz and one fully incomplete Baz.
@@ -889,20 +955,20 @@ describe('ReactIncrementalSideEffects', () => {
// way through.
ReactNoop.render();
ReactNoop.flushDeferredPri(50);
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(3),
- div(
- // Old numbers.
- span(0),
- span(0),
- span(0),
- span(0),
- span(0),
- span(0),
- ),
- ),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+
+ {/* Old numbers. */}
+
+
+
+
+
+
+
+
,
+ );
expect(ops).toEqual(['Foo']);
ops = [];
@@ -910,19 +976,19 @@ describe('ReactIncrementalSideEffects', () => {
// We should now be able to reuse some of the work we've already done
// and replay those side-effects.
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- div(
- span(3),
- div(
- // New numbers.
- span(1),
- span(1),
- span(1),
- span(1),
- span(1),
- span(1),
- ),
- ),
+ expect(ReactNoop).toMatchRenderedOutput([
+
+
,
+
+ {/* New numbers. */}
+
+
+
+
+
+
+
+
,
]);
expect(ops).toEqual(['Bar', 'Baz', 'Bar', 'Bar']);
@@ -1039,10 +1105,10 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('foo')]);
+ expect(ReactNoop).toMatchRenderedOutput();
let called = false;
instance.setState({text: 'bar'}, () => {
- expect(ReactNoop.getChildren()).toEqual([span('bar')]);
+ expect(ReactNoop).toMatchRenderedOutput();
called = true;
});
expect(Scheduler).toFlushWithoutYielding();
@@ -1067,7 +1133,7 @@ describe('ReactIncrementalSideEffects', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('foo')]);
+ expect(ReactNoop).toMatchRenderedOutput();
let called = false;
instance.setState({}, () => {
called = true;
@@ -1253,7 +1319,7 @@ describe('ReactIncrementalSideEffects', () => {
expect(ops).toEqual([
classInstance,
// no call for function components
- div(),
+ {type: 'div', children: [], prop: undefined, hidden: false},
]);
ops = [];
@@ -1267,7 +1333,7 @@ describe('ReactIncrementalSideEffects', () => {
null,
// reattach as a separate phase
classInstance,
- div(),
+ {type: 'div', children: [], prop: undefined, hidden: false},
]);
ops = [];
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalTriangle-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalTriangle-test.js
index effeea5ff5e..07bf3af6e12 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalTriangle-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalTriangle-test.js
@@ -316,7 +316,8 @@ describe('ReactIncrementalTriangle', () => {
reset();
function assertConsistentTree(activeTriangleIndices = new Set(), counter) {
- const children = ReactNoop.getChildren(rootID);
+ const childrenJSX = ReactNoop.getPendingChildrenAsJSX(rootID);
+ const children = childrenJSX === null ? [] : childrenJSX.props.children;
if (children.length !== TOTAL_CHILDREN) {
throw new Error('Wrong number of children.');
@@ -327,7 +328,7 @@ describe('ReactIncrementalTriangle', () => {
for (let i = 0; i < children.length; i++) {
const child = children[i];
- const output = JSON.parse(child.prop);
+ const output = JSON.parse(child.props.prop);
const prop = output.prop;
const isActive = output.isActive;
const counterContext = output.counterContext;
diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
index f5f480ecca9..02c849f6ed5 100644
--- a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js
@@ -28,10 +28,6 @@ describe('ReactIncrementalUpdates', () => {
require('react-reconciler/constants').ContinuousEventPriority;
});
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
function flushNextRenderIfExpired() {
// This will start rendering the next level of work. If the work hasn't
// expired yet, React will exit without doing anything. If it has expired,
@@ -174,7 +170,7 @@ describe('ReactIncrementalUpdates', () => {
// Begin the updates but don't flush them yet
expect(Scheduler).toFlushAndYieldThrough(['a', 'b', 'c']);
- expect(ReactNoop.getChildren()).toEqual([span('')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Schedule some more updates at different priorities
instance.setState(createUpdate('d'));
@@ -193,11 +189,11 @@ describe('ReactIncrementalUpdates', () => {
)
) {
expect(Scheduler).toHaveYielded(['d', 'e', 'f']);
- expect(ReactNoop.getChildren()).toEqual([span('def')]);
+ expect(ReactNoop).toMatchRenderedOutput();
} else {
// Update d was dropped and replaced by e.
expect(Scheduler).toHaveYielded(['e', 'f']);
- expect(ReactNoop.getChildren()).toEqual([span('ef')]);
+ expect(ReactNoop).toMatchRenderedOutput();
}
// Now flush the remaining work. Even though e and f were already processed,
@@ -235,7 +231,7 @@ describe('ReactIncrementalUpdates', () => {
'g',
]);
}
- expect(ReactNoop.getChildren()).toEqual([span('abcdefg')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('can abort an update, schedule a replaceState, and resume', () => {
@@ -279,7 +275,7 @@ describe('ReactIncrementalUpdates', () => {
// Begin the updates but don't flush them yet
expect(Scheduler).toFlushAndYieldThrough(['a', 'b', 'c']);
- expect(ReactNoop.getChildren()).toEqual([span('')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Schedule some more updates at different priorities
instance.setState(createUpdate('d'));
@@ -305,7 +301,7 @@ describe('ReactIncrementalUpdates', () => {
// Update d was dropped and replaced by e.
expect(Scheduler).toHaveYielded(['e', 'f']);
}
- expect(ReactNoop.getChildren()).toEqual([span('f')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Now flush the remaining work. Even though e and f were already processed,
// they should be processed again, to ensure that the terminal state
@@ -342,7 +338,7 @@ describe('ReactIncrementalUpdates', () => {
'g',
]);
}
- expect(ReactNoop.getChildren()).toEqual([span('fg')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('passes accumulation of previous updates to replaceState updater function', () => {
@@ -537,7 +533,7 @@ describe('ReactIncrementalUpdates', () => {
ReactNoop.flushSync(() => {
ReactNoop.render();
});
- expect(ReactNoop.getChildren()).toEqual([span('derived state')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushSync(() => {
// Triggers getDerivedStateFromProps again
@@ -546,12 +542,12 @@ describe('ReactIncrementalUpdates', () => {
// led to this bug. Removing it causes it to "accidentally" work.
foo.setState({value: 'update state'}, function noop() {});
});
- expect(ReactNoop.getChildren()).toEqual([span('derived state')]);
+ expect(ReactNoop).toMatchRenderedOutput();
ReactNoop.flushSync(() => {
bar.setState({});
});
- expect(ReactNoop.getChildren()).toEqual([span('derived state')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('regression: does not expire soon due to layout effects in the last batch', () => {
diff --git a/packages/react-reconciler/src/__tests__/ReactMemo-test.js b/packages/react-reconciler/src/__tests__/ReactMemo-test.js
index bd26d03f058..1ca0cf2e99d 100644
--- a/packages/react-reconciler/src/__tests__/ReactMemo-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactMemo-test.js
@@ -31,10 +31,6 @@ describe('memo', () => {
({Suspense} = React);
});
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
function Text(props) {
Scheduler.unstable_yieldValue(props.text);
return ;
@@ -112,7 +108,7 @@ describe('memo', () => {
expect(Scheduler).toFlushAndYield(['Loading...']);
await Promise.resolve();
expect(Scheduler).toFlushAndYield([0]);
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should bail out because props have not changed
ReactNoop.render(
@@ -121,7 +117,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should update because count prop changed
ReactNoop.render(
@@ -130,7 +126,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield([1]);
- expect(ReactNoop.getChildren()).toEqual([span(1)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it("does not bail out if there's a context change", async () => {
@@ -167,17 +163,17 @@ describe('memo', () => {
expect(Scheduler).toFlushAndYield(['Loading...']);
await Promise.resolve();
expect(Scheduler).toFlushAndYield(['Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should bail out because props have not changed
ReactNoop.render();
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should update because there was a context change
parent.current.setState({count: 1});
expect(Scheduler).toFlushAndYield(['Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Count: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('consistent behavior for reusing props object across different function component types', async () => {
@@ -352,7 +348,7 @@ describe('memo', () => {
expect(Scheduler).toFlushAndYield(['Loading...']);
await Promise.resolve();
expect(Scheduler).toFlushAndYield([0]);
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should bail out because props have not changed
ReactNoop.render(
@@ -361,7 +357,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield(['Old count: 0, New count: 0']);
- expect(ReactNoop.getChildren()).toEqual([span(0)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should update because count prop changed
ReactNoop.render(
@@ -370,7 +366,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield(['Old count: 0, New count: 1', 1]);
- expect(ReactNoop.getChildren()).toEqual([span(1)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('supports non-pure class components', async () => {
@@ -390,7 +386,7 @@ describe('memo', () => {
expect(Scheduler).toFlushAndYield(['Loading...']);
await Promise.resolve();
expect(Scheduler).toFlushAndYield(['0!']);
- expect(ReactNoop.getChildren()).toEqual([span('0!')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should bail out because props have not changed
ReactNoop.render(
@@ -399,7 +395,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span('0!')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should update because count prop changed
ReactNoop.render(
@@ -408,7 +404,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield(['1!']);
- expect(ReactNoop.getChildren()).toEqual([span('1!')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('supports defaultProps defined on the memo() return value', async () => {
@@ -447,7 +443,7 @@ describe('memo', () => {
}).toErrorDev([
'Counter: Support for defaultProps will be removed from memo components in a future major release. Use JavaScript default parameters instead.',
]);
- expect(ReactNoop.getChildren()).toEqual([span(15)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should bail out because props have not changed
ReactNoop.render(
@@ -456,7 +452,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([span(15)]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Should update because count prop changed
ReactNoop.render(
@@ -465,7 +461,7 @@ describe('memo', () => {
,
);
expect(Scheduler).toFlushAndYield([20]);
- expect(ReactNoop.getChildren()).toEqual([span(20)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('warns if the first argument is undefined', () => {
diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js
index bc776874517..25da1d13a6b 100644
--- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js
@@ -128,12 +128,12 @@ describe('ReactNewContext', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Result: 2')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Result: 3')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('propagates through shouldComponentUpdate false', () => {
@@ -193,7 +193,7 @@ describe('ReactNewContext', () => {
'Consumer',
'Consumer render prop',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Result: 2')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
ReactNoop.render();
@@ -202,7 +202,7 @@ describe('ReactNewContext', () => {
'Provider',
'Consumer render prop',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Result: 3')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('consumers bail out if context value is the same', () => {
@@ -262,7 +262,7 @@ describe('ReactNewContext', () => {
'Consumer',
'Consumer render prop',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Result: 2')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update with the same context value
ReactNoop.render();
@@ -271,7 +271,7 @@ describe('ReactNewContext', () => {
'Provider',
// Don't call render prop again
]);
- expect(ReactNoop.getChildren()).toEqual([span('Result: 2')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('nested providers', () => {
@@ -322,12 +322,12 @@ describe('ReactNewContext', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Result: 8')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Result: 12')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('should provide the correct (default) values to consumers outside of a provider', () => {
@@ -417,26 +417,32 @@ describe('ReactNewContext', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- span('Result: 4'),
- span('Result: 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- span('Result: 6'),
- span('Result: 3'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Another update
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
- span('Result: 8'),
- span('Result: 4'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
it('compares context values with Object.is semantics', () => {
@@ -496,7 +502,7 @@ describe('ReactNewContext', () => {
'Consumer',
'Consumer render prop',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Result: NaN')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
ReactNoop.render();
@@ -506,7 +512,7 @@ describe('ReactNewContext', () => {
// Consumer should not re-render again
// 'Consumer render prop',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Result: NaN')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('context unwinds when interrupted', () => {
@@ -555,10 +561,10 @@ describe('ReactNewContext', () => {
ReactNoop.render();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([
+ expect(ReactNoop).toMatchRenderedOutput(
// The second provider should use the default value.
- span('Result: Does not unwind'),
- ]);
+ ,
+ );
});
it("does not re-render if there's an update in a child", () => {
@@ -594,11 +600,15 @@ describe('ReactNewContext', () => {
// Initial mount
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Consumer render prop', 'Child']);
- expect(ReactNoop.getChildren()).toEqual([span('Context: 1, Step: 0')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
child.setState({step: 1});
expect(Scheduler).toFlushAndYield(['Child']);
- expect(ReactNoop.getChildren()).toEqual([span('Context: 1, Step: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
it('consumer bails out if value is unchanged and something above bailed out', () => {
@@ -654,17 +664,32 @@ describe('ReactNewContext', () => {
'ChildWithCachedRenderCallback',
'Consumer',
]);
- expect(ReactNoop.getChildren()).toEqual([span(1), span(1)]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update (bailout)
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['App']);
- expect(ReactNoop.getChildren()).toEqual([span(1), span(1)]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update (no bailout)
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['App', 'Consumer', 'Consumer']);
- expect(ReactNoop.getChildren()).toEqual([span(2), span(2)]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate www
@@ -788,26 +813,32 @@ describe('ReactNewContext', () => {
let inst;
ReactNoop.render( (inst = ref)} />);
expect(Scheduler).toFlushAndYield(['App']);
- expect(ReactNoop.getChildren()).toEqual([
- span('static 1'),
- span('static 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update the first time
inst.setState({step: 1});
expect(Scheduler).toFlushAndYield(['App', 'Consumer']);
- expect(ReactNoop.getChildren()).toEqual([
- span('static 1'),
- span('static 2'),
- span(1),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Update the second time
inst.setState({step: 2});
expect(Scheduler).toFlushAndYield(['App', 'Consumer']);
- expect(ReactNoop.getChildren()).toEqual([
- span('static 1'),
- span('static 2'),
- span(2),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
});
});
}
@@ -936,7 +967,7 @@ describe('ReactNewContext', () => {
// Initial mount
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['App', 'Child']);
- expect(ReactNoop.getChildren()).toEqual([span('Child')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
ReactNoop.render();
@@ -944,7 +975,7 @@ describe('ReactNewContext', () => {
'App',
// Child does not re-render
]);
- expect(ReactNoop.getChildren()).toEqual([span('Child')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('provider does not bail out if legacy context changed above', () => {
@@ -995,22 +1026,22 @@ describe('ReactNewContext', () => {
,
);
expect(Scheduler).toFlushAndYield(['LegacyProvider', 'App', 'Child']);
- expect(ReactNoop.getChildren()).toEqual([span('Child')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update App with same value (should bail out)
appRef.current.setState({value: 1});
expect(Scheduler).toFlushAndYield(['App']);
- expect(ReactNoop.getChildren()).toEqual([span('Child')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update LegacyProvider (should not bail out)
legacyProviderRef.current.setState({value: 1});
expect(Scheduler).toFlushAndYield(['LegacyProvider', 'App', 'Child']);
- expect(ReactNoop.getChildren()).toEqual([span('Child')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update App with same value (should bail out)
appRef.current.setState({value: 1});
expect(Scheduler).toFlushAndYield(['App']);
- expect(ReactNoop.getChildren()).toEqual([span('Child')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -1066,17 +1097,17 @@ describe('ReactNewContext', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo: 1, Bar: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Foo: 1, Bar: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update foo
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo: 2, Bar: 1']);
- expect(ReactNoop.getChildren()).toEqual([span('Foo: 2, Bar: 1')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update bar
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo: 2, Bar: 2']);
- expect(ReactNoop.getChildren()).toEqual([span('Foo: 2, Bar: 2')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Context consumer bails out on propagating "deep" updates when `value` hasn't changed.
@@ -1112,12 +1143,12 @@ describe('ReactNewContext', () => {
let inst;
ReactNoop.render( (inst = ref)} />);
expect(Scheduler).toFlushAndYield(['App', 'App#renderConsumer']);
- expect(ReactNoop.getChildren()).toEqual([span('hello')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
inst.setState({text: 'goodbye'});
expect(Scheduler).toFlushAndYield(['App', 'App#renderConsumer']);
- expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -1186,33 +1217,33 @@ describe('ReactNewContext', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo: 1, Bar: 1', 'Baz: 1']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Foo: 1, Bar: 1'),
- span('Baz: 1'),
+ expect(ReactNoop).toMatchRenderedOutput([
+ ,
+ ,
]);
// Update only foo
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo: 2, Bar: 1']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Foo: 2, Bar: 1'),
- span('Baz: 1'),
+ expect(ReactNoop).toMatchRenderedOutput([
+ ,
+ ,
]);
// Update only bar
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo: 2, Bar: 2']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Foo: 2, Bar: 2'),
- span('Baz: 1'),
+ expect(ReactNoop).toMatchRenderedOutput([
+ ,
+ ,
]);
// Update only baz
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Baz: 2']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Foo: 2, Bar: 2'),
- span('Baz: 2'),
+ expect(ReactNoop).toMatchRenderedOutput([
+ ,
+ ,
]);
});
@@ -1255,12 +1286,12 @@ describe('ReactNewContext', () => {
let inst;
ReactNoop.render( (inst = ref)} />);
expect(Scheduler).toFlushAndYield(['App', 'App#renderConsumer']);
- expect(ReactNoop.getChildren()).toEqual([span('hello')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
inst.setState({text: 'goodbye'});
expect(Scheduler).toFlushAndYield(['App', 'App#renderConsumer']);
- expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
it('warns when reading context inside render phase class setState updater', () => {
@@ -1366,12 +1397,12 @@ describe('ReactNewContext', () => {
let inst;
ReactNoop.render( (inst = ref)} />);
expect(Scheduler).toFlushAndYield(['App', 'App#renderConsumer']);
- expect(ReactNoop.getChildren()).toEqual([span('hello')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Update
inst.setState({text: 'goodbye'});
expect(Scheduler).toFlushAndYield(['App', 'App#renderConsumer']);
- expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -1393,7 +1424,7 @@ describe('ReactNewContext', () => {
,
);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span(10)]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
describe('fuzz test', () => {
@@ -1518,9 +1549,10 @@ describe('ReactNewContext', () => {
);
function assertConsistentTree(expectedValues = {}) {
- const children = ReactNoop.getChildren();
+ const jsx = ReactNoop.getChildrenAsJSX();
+ const children = jsx === null ? [] : jsx.props.children;
children.forEach(child => {
- const text = child.prop;
+ const text = child.props.prop;
const key = text[0];
const value = parseInt(text[2], 10);
const expectedValue = expectedValues[key];
diff --git a/packages/react-reconciler/src/__tests__/ReactNoopRendererAct-test.js b/packages/react-reconciler/src/__tests__/ReactNoopRendererAct-test.js
index bf660226fd2..b6f20c509cb 100644
--- a/packages/react-reconciler/src/__tests__/ReactNoopRendererAct-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactNoopRendererAct-test.js
@@ -58,6 +58,6 @@ describe('internal act()', () => {
});
expect(Scheduler).toHaveYielded(['stage 1', 'stage 2']);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([{text: '1', hidden: false}]);
+ expect(ReactNoop).toMatchRenderedOutput('1');
});
});
diff --git a/packages/react-reconciler/src/__tests__/ReactPersistent-test.js b/packages/react-reconciler/src/__tests__/ReactPersistent-test.js
index e8306f852db..f53f45e30d6 100644
--- a/packages/react-reconciler/src/__tests__/ReactPersistent-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactPersistent-test.js
@@ -49,8 +49,12 @@ describe('ReactPersistent', () => {
return {type: 'span', children: [], prop, hidden: false};
}
- function getChildren() {
- return ReactNoopPersistent.getChildren();
+ // For persistent renderers we have to mix deep equality and reference equality checks
+ // for which we need the actual children.
+ // None of the tests are gated and the underlying implementation is rarely touch
+ // so it's unlikely we deal with failing `toEqual` checks which cause bad performance.
+ function dangerouslyGetChildren() {
+ return ReactNoopPersistent.dangerouslyGetChildren();
}
it('can update child nodes of a host instance', () => {
@@ -69,12 +73,12 @@ describe('ReactPersistent', () => {
render();
expect(Scheduler).toFlushWithoutYielding();
- const originalChildren = getChildren();
+ const originalChildren = dangerouslyGetChildren();
expect(originalChildren).toEqual([div(span())]);
render();
expect(Scheduler).toFlushWithoutYielding();
- const newChildren = getChildren();
+ const newChildren = dangerouslyGetChildren();
expect(newChildren).toEqual([div(span(), span())]);
expect(originalChildren).toEqual([div(span())]);
@@ -103,12 +107,12 @@ describe('ReactPersistent', () => {
render();
expect(Scheduler).toFlushWithoutYielding();
- const originalChildren = getChildren();
+ const originalChildren = dangerouslyGetChildren();
expect(originalChildren).toEqual([div(span('Hello'))]);
render();
expect(Scheduler).toFlushWithoutYielding();
- const newChildren = getChildren();
+ const newChildren = dangerouslyGetChildren();
expect(newChildren).toEqual([div(span('Hello'), span('World'))]);
expect(originalChildren).toEqual([div(span('Hello'))]);
@@ -129,12 +133,12 @@ describe('ReactPersistent', () => {
render();
expect(Scheduler).toFlushWithoutYielding();
- const originalChildren = getChildren();
+ const originalChildren = dangerouslyGetChildren();
expect(originalChildren).toEqual([div('Hello', span())]);
render();
expect(Scheduler).toFlushWithoutYielding();
- const newChildren = getChildren();
+ const newChildren = dangerouslyGetChildren();
expect(newChildren).toEqual([div('World', span())]);
expect(originalChildren).toEqual([div('Hello', span())]);
@@ -173,7 +177,7 @@ describe('ReactPersistent', () => {
expect(emptyPortalChildSet).toEqual([]);
- const originalChildren = getChildren();
+ const originalChildren = dangerouslyGetChildren();
expect(originalChildren).toEqual([div()]);
const originalPortalChildren = portalContainer.children;
expect(originalPortalChildren).toEqual([div(span())]);
@@ -185,7 +189,7 @@ describe('ReactPersistent', () => {
);
expect(Scheduler).toFlushWithoutYielding();
- const newChildren = getChildren();
+ const newChildren = dangerouslyGetChildren();
expect(newChildren).toEqual([div()]);
const newPortalChildren = portalContainer.children;
expect(newPortalChildren).toEqual([div(span(), 'Hello ', 'World')]);
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.js
index afa9ab499dc..b14f7494a57 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseCallback-test.js
@@ -22,10 +22,6 @@ describe('ReactSuspense', () => {
Scheduler = require('scheduler');
});
- function text(t) {
- return {text: t, hidden: false};
- }
-
function createThenable() {
let completed = false;
let resolve;
@@ -88,13 +84,13 @@ describe('ReactSuspense', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Waiting')]);
+ expect(ReactNoop).toMatchRenderedOutput('Waiting');
expect(ops).toEqual([new Set([promise])]);
ops = [];
await resolve();
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Done')]);
+ expect(ReactNoop).toMatchRenderedOutput('Done');
expect(ops).toEqual([]);
});
@@ -127,21 +123,21 @@ describe('ReactSuspense', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Waiting Tier 1')]);
+ expect(ReactNoop).toMatchRenderedOutput('Waiting Tier 1');
expect(ops).toEqual([new Set([promise1, promise2])]);
ops = [];
await resolve1();
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Waiting Tier 1')]);
+ expect(ReactNoop).toMatchRenderedOutput('Waiting Tier 1');
expect(ops).toEqual([new Set([promise2])]);
ops = [];
await resolve2();
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Done'), text('Done')]);
+ expect(ReactNoop).toMatchRenderedOutput('DoneDone');
expect(ops).toEqual([]);
});
@@ -172,7 +168,7 @@ describe('ReactSuspense', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Waiting Tier 2')]);
+ expect(ReactNoop).toMatchRenderedOutput('Waiting Tier 2');
expect(ops1).toEqual([]);
expect(ops2).toEqual([new Set([promise])]);
});
@@ -214,7 +210,7 @@ describe('ReactSuspense', () => {
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Waiting Tier 1')]);
+ expect(ReactNoop).toMatchRenderedOutput('Waiting Tier 1');
expect(ops1).toEqual([new Set([promise1])]);
expect(ops2).toEqual([]);
ops1 = [];
@@ -228,10 +224,7 @@ describe('ReactSuspense', () => {
// TODO: Should be able to use `act` here.
jest.runAllTimers();
- expect(ReactNoop.getChildren()).toEqual([
- text('Waiting Tier 2'),
- text('Done'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput('Waiting Tier 2Done');
expect(ops1).toEqual([]);
expect(ops2).toEqual([new Set([promise2])]);
ops1 = [];
@@ -240,7 +233,7 @@ describe('ReactSuspense', () => {
await resolve2();
ReactNoop.render(element);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([text('Done'), text('Done')]);
+ expect(ReactNoop).toMatchRenderedOutput('DoneDone');
expect(ops1).toEqual([]);
expect(ops2).toEqual([]);
});
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js
index 863c9e878a2..76a6b7794be 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseEffectsSemantics-test.js
@@ -185,14 +185,6 @@ describe('ReactSuspenseEffectsSemantics', () => {
const resolveText = resolveMostRecentTextCache;
- function span(prop, children = []) {
- return {type: 'span', children, prop, hidden: false};
- }
-
- function spanHidden(prop, children = []) {
- return {type: 'span', children, prop, hidden: true};
- }
-
function advanceTimers(ms) {
// Note: This advances Jest's virtual time but not React's. Use
// ReactNoop.expire for that.
@@ -278,10 +270,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outside create passive',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Resolving the suspended resource should
await act(async () => {
@@ -299,12 +293,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside:Before create passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Async'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -320,7 +316,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'AsyncText:Async destroy passive',
'Text:Outside destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -398,12 +394,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outside create passive',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside:Before'),
- spanHidden('Inside:After'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should
await act(async () => {
@@ -416,12 +414,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Async'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.renderLegacySyncRoot(null);
@@ -437,7 +437,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'AsyncText:Async destroy passive',
'Text:Outside destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
});
@@ -488,11 +488,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outside create passive',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
act(() => {
@@ -512,23 +514,27 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
'Text:Fallback create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside:Before'),
- spanHidden('Inside:After'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await advanceTimers(1000);
// Noop since sync root has already committed
expect(Scheduler).toHaveYielded([]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside:Before'),
- spanHidden('Inside:After'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -541,12 +547,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Async'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.renderLegacySyncRoot(null);
@@ -610,11 +618,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outside create passive',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
act(() => {
@@ -632,11 +642,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback render',
'Text:Outside render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
await advanceTimers(1000);
@@ -647,12 +659,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:Fallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside:Before'),
- spanHidden('Inside:After'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -669,12 +683,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Async'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -758,11 +774,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'App create layout',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
act(() => {
@@ -780,11 +798,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Fallback render',
'ClassText:Outside render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Inside:After'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
await advanceTimers(1000);
@@ -795,12 +815,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Fallback componentDidMount',
'ClassText:Outside componentDidUpdate',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside:Before'),
- spanHidden('Inside:After'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -816,13 +838,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Inside:After componentDidMount',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside:Before'),
- span('Async'),
- span('Inside:After'),
- span('Outside'),
- ]);
-
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
});
@@ -878,7 +901,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outer create passive',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Outer', [span('Inner')])]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ ,
+ );
// Schedule an update that causes React to suspend.
act(() => {
@@ -895,7 +922,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inner render',
'Text:Fallback render',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Outer', [span('Inner')])]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ ,
+ );
await advanceTimers(1000);
@@ -906,10 +937,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:Fallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer', [span('Inner')]),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -926,10 +961,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Async'),
- span('Outer', [span('Inner')]),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -989,9 +1028,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outer create passive',
'App create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer', [span('MemoizedInner')]),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ ,
+ );
// Schedule an update that causes React to suspend.
act(() => {
@@ -1008,9 +1049,11 @@ describe('ReactSuspenseEffectsSemantics', () => {
// Text:MemoizedInner is memoized
'Text:Fallback render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer', [span('MemoizedInner')]),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+
+
+ ,
+ );
await advanceTimers(1000);
@@ -1022,10 +1065,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:Fallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer', [span('MemoizedInner')]),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -1041,10 +1088,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Async'),
- span('Outer', [span('MemoizedInner')]),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -1088,7 +1139,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outer create passive',
'Text:Inner create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Outer'), span('Inner')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -1106,11 +1162,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:InnerFallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:InnerFallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer'),
- spanHidden('Inner'),
- span('InnerFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Suspend the outer Suspense subtree (outer effects and inner fallback effects should be destroyed)
// (This check also ensures we don't destroy effects for mounted inner fallback.)
@@ -1135,12 +1193,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:OuterFallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:OuterFallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer'),
- spanHidden('Inner'),
- spanHidden('InnerFallback'),
- span('OuterFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Show the inner Suspense subtree (no effects should be recreated)
await act(async () => {
@@ -1152,12 +1212,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inner render',
'AsyncText:InnerAsync_1 render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer'),
- spanHidden('Inner'),
- spanHidden('InnerFallback'),
- span('OuterFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Suspend the inner Suspense subtree (no effects should be destroyed)
act(() => {
@@ -1177,12 +1239,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:InnerFallback render',
'Text:OuterFallback render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer'),
- spanHidden('Inner'),
- spanHidden('InnerFallback'),
- span('OuterFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Show the outer Suspense subtree (only outer effects should be recreated)
await act(async () => {
@@ -1201,12 +1265,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:OuterFallback destroy passive',
'AsyncText:OuterAsync_1 create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer'),
- span('OuterAsync_1'),
- spanHidden('Inner'),
- span('InnerFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Show the inner Suspense subtree (only inner effects should be recreated)
await act(async () => {
@@ -1221,12 +1287,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:InnerFallback destroy passive',
'AsyncText:InnerAsync_2 create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer'),
- span('OuterAsync_1'),
- span('Inner'),
- span('InnerAsync_2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Suspend the outer Suspense subtree (all effects should be destroyed)
act(() => {
@@ -1250,13 +1318,15 @@ describe('ReactSuspenseEffectsSemantics', () => {
'AsyncText:InnerAsync_2 destroy layout',
'Text:OuterFallback create layout',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer'),
- spanHidden('OuterAsync_1'),
- spanHidden('Inner'),
- spanHidden('InnerAsync_2'),
- span('OuterFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+
+ >,
+ );
// Show the outer Suspense subtree (all effects should be recreated)
await act(async () => {
@@ -1275,12 +1345,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'AsyncText:InnerAsync_2 create layout',
'Text:OuterFallback destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer'),
- span('OuterAsync_2'),
- span('Inner'),
- span('InnerAsync_2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -1310,7 +1382,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Outer create passive',
'Text:Inner create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Outer'), span('Inner')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -1328,11 +1405,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:InnerFallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:InnerFallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer'),
- spanHidden('Inner'),
- span('InnerFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Suspend the outer Suspense subtree (outer effects and inner fallback effects should be destroyed)
// (This check also ensures we don't destroy effects for mounted inner fallback.)
@@ -1357,12 +1436,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:OuterFallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:OuterFallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Outer'),
- spanHidden('Inner'),
- spanHidden('InnerFallback'),
- span('OuterFallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolve both suspended trees.
await act(async () => {
@@ -1384,12 +1465,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'AsyncText:OuterAsync_1 create passive',
'AsyncText:InnerAsync_1 create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Outer'),
- span('OuterAsync_1'),
- span('Inner'),
- span('InnerAsync_1'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -1427,10 +1510,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Suspend the outer shell
act(() => {
@@ -1445,10 +1530,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Outside render',
'Text:Outside render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Timing out should commit the fallback and destroy inner layout effects.
await advanceTimers(1000);
@@ -1461,12 +1548,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Inside create passive',
'Text:Fallback:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside'),
- span('Fallback:Inside'),
- span('Fallback:Outside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Suspend the fallback and verify that it's effects get cleaned up as well
act(() => {
@@ -1486,12 +1575,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Outside render',
'Text:Outside render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside'),
- span('Fallback:Inside'),
- span('Fallback:Outside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Timing out should commit the inner fallback and destroy outer fallback layout effects.
await advanceTimers(1000);
@@ -1502,13 +1593,15 @@ describe('ReactSuspenseEffectsSemantics', () => {
expect(Scheduler).toFlushAndYield([
'Text:Fallback:Fallback create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside'),
- spanHidden('Fallback:Inside'),
- span('Fallback:Fallback'),
- span('Fallback:Outside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+
+ >,
+ );
// Resolving both resources should cleanup fallback effects and recreate main effects
await act(async () => {
@@ -1527,11 +1620,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Outside destroy passive',
'AsyncText:OutsideAsync create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('OutsideAsync'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -1569,10 +1664,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Suspend both the outer boundary and the fallback
act(() => {
@@ -1600,12 +1697,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Fallback create passive',
'Text:Fallback:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside'),
- span('Fallback:Fallback'),
- span('Fallback:Outside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the inside fallback
await act(async () => {
@@ -1621,13 +1720,15 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Inside create passive',
'AsyncText:FallbackAsync create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside'),
- span('Fallback:Inside'),
- span('FallbackAsync'),
- span('Fallback:Outside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+
+ >,
+ );
// Resolving the outer fallback only
await act(async () => {
@@ -1646,11 +1747,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback:Outside destroy passive',
'AsyncText:OutsideAsync create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('OutsideAsync'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -1685,10 +1788,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Suspending a component in the middle of the tree
// should still properly cleanup effects deeper in the tree
@@ -1700,10 +1805,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback render',
'Text:Outside render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Timing out should commit the inner fallback and destroy outer fallback layout effects.
await advanceTimers(1000);
@@ -1712,11 +1819,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
]);
expect(Scheduler).toFlushAndYield(['Text:Fallback create passive']);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Inside'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Resolving should cleanup.
await act(async () => {
@@ -1728,10 +1837,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create layout',
'Text:Fallback destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
describe('that throw errors', () => {
@@ -1797,11 +1908,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('ThrowsInDidMount'),
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
await act(async () => {
@@ -1826,12 +1939,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
'Text:Fallback create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('ThrowsInDidMount'),
- spanHidden('Inside'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolve the pending suspense and throw
componentDidMountShouldThrow = true;
@@ -1870,7 +1985,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Error create layout',
'Text:Error create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Error')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -1933,11 +2048,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('ThrowsInWillUnmount'),
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that suspends and triggers our error code.
await act(async () => {
@@ -1981,7 +2098,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Error create layout',
'Text:Error create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Error')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -2047,11 +2164,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('ThrowsInLayoutEffect'),
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
await act(async () => {
@@ -2076,12 +2195,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
'Text:Fallback create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('ThrowsInLayoutEffect'),
- spanHidden('Inside'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolve the pending suspense and throw
useLayoutEffectShouldThrow = true;
@@ -2120,7 +2241,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Error create layout',
'Text:Error create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Error')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -2182,11 +2303,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('ThrowsInLayoutEffectDestroy'),
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that suspends and triggers our error code.
await act(async () => {
@@ -2230,7 +2353,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Error create layout',
'Text:Error create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Error')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -2278,10 +2401,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Class componentDidMount',
'Text:Function create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Function'),
- span('Class'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
act(() => {
@@ -2299,10 +2424,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Class render',
'ClassText:Fallback render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Function'),
- span('Class'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
await advanceTimers(1000);
@@ -2312,11 +2439,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Class componentWillUnmount',
'ClassText:Fallback componentDidMount',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Function'),
- spanHidden('Class'),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2328,11 +2457,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Suspend:Async_2',
'ClassText:Class render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Function'),
- spanHidden('Class'),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2351,12 +2482,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'AsyncText:Async_1 create passive',
'AsyncText:Async_2 create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Function'),
- span('Async_1'),
- span('Async_2'),
- span('Class'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -2427,11 +2560,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Class componentDidMount',
'Text:Function create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Function'),
- span('Suspender'),
- span('Class'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
textToRead = 'A';
@@ -2445,11 +2580,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Class render',
'ClassText:Fallback render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Function'),
- span('Suspender'),
- span('Class'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
await advanceTimers(1000);
@@ -2459,12 +2596,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'ClassText:Class componentWillUnmount',
'ClassText:Fallback componentDidMount',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Function'),
- spanHidden('Suspender'),
- spanHidden('Class'),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
textToRead = 'B';
@@ -2477,12 +2616,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Suspend:B',
'ClassText:Class render',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('Function'),
- spanHidden('Suspender'),
- spanHidden('Class'),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2496,11 +2637,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Function create layout',
'ClassText:Class componentDidMount',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Function'),
- span('Suspender'),
- span('Class'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -2609,7 +2752,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerOuter refCallback value? true',
'RefCheckerOuter create layout refObject? true refCallback? true',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -2630,7 +2773,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
'Text:Fallback create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2643,7 +2786,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Async')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
ReactNoop.renderLegacySyncRoot(null);
@@ -2656,7 +2799,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'AsyncText:Async destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -2685,10 +2828,12 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerOuter refCallback value? true',
'RefCheckerOuter create layout refObject? true refCallback? true',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('refObject'),
- span('refCallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -2710,11 +2855,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'Text:Fallback create layout',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('refObject'),
- spanHidden('refCallback'),
- span('Fallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2735,11 +2882,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Async'),
- span('refObject'),
- span('refCallback'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
await act(async () => {
ReactNoop.render(null);
@@ -2752,7 +2901,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'AsyncText:Async destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -2792,7 +2941,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerOuter refCallback value? true',
'RefCheckerOuter create layout refObject? true refCallback? true',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -2816,7 +2965,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'Text:Fallback create layout',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2839,7 +2988,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Async')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
ReactNoop.render(null);
@@ -2852,7 +3001,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'AsyncText:Async destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -2896,7 +3045,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerOuter refCallback value? true',
'RefCheckerOuter create layout refObject? true refCallback? true',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -2920,7 +3069,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'Text:Fallback create layout',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -2943,7 +3092,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Async')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
ReactNoop.render(null);
@@ -2956,7 +3105,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefCheckerInner:refCallback destroy layout ref? false',
'AsyncText:Async destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -3009,7 +3158,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefChecker create layout ref? true',
'App create layout ref? true',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Suspend the inner Suspense subtree (only inner effects should be destroyed)
act(() => {
@@ -3026,7 +3175,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefChecker destroy layout ref? true',
'Text:Fallback create layout',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Fallback')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Resolving the suspended resource should re-create inner layout effects.
await act(async () => {
@@ -3042,7 +3191,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback destroy passive',
'AsyncText:Async create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Async')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
ReactNoop.render(null);
@@ -3053,7 +3202,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'RefChecker destroy layout ref? true',
'AsyncText:Async destroy passive',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
describe('that throw errors', () => {
@@ -3115,11 +3264,13 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Inside create passive',
'Text:Outside create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('ThrowsInRefCallback'),
- span('Inside'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Schedule an update that causes React to suspend.
await act(async () => {
@@ -3144,12 +3295,14 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Fallback create layout',
'Text:Fallback create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([
- spanHidden('ThrowsInRefCallback'),
- spanHidden('Inside'),
- span('Fallback'),
- span('Outside'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
// Resolve the pending suspense and throw
useRefCallbackShouldThrow = true;
@@ -3188,7 +3341,7 @@ describe('ReactSuspenseEffectsSemantics', () => {
'Text:Error create layout',
'Text:Error create passive',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Error')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
});
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseFallback-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseFallback-test.js
index 8284383c5f6..41c27c4c922 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseFallback-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseFallback-test.js
@@ -127,10 +127,6 @@ describe('ReactSuspenseFallback', () => {
return ;
}
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
// @gate enableLegacyCache
it('suspends and shows fallback', () => {
ReactNoop.render(
@@ -140,7 +136,7 @@ describe('ReactSuspenseFallback', () => {
);
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -155,7 +151,7 @@ describe('ReactSuspenseFallback', () => {
'Suspend! [A]',
// null
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -170,7 +166,7 @@ describe('ReactSuspenseFallback', () => {
'Suspend! [A]',
// null
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -184,7 +180,7 @@ describe('ReactSuspenseFallback', () => {
);
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -201,7 +197,7 @@ describe('ReactSuspenseFallback', () => {
'Suspend! [A]',
// null
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
// @gate enableLegacyCache
@@ -218,6 +214,6 @@ describe('ReactSuspenseFallback', () => {
'Suspend! [A]',
// null
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
});
});
diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
index 9d95a57572f..aad8729adde 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js
@@ -157,14 +157,6 @@ describe('ReactSuspenseWithNoopRenderer', () => {
const rejectText = rejectMostRecentTextCache;
- function span(prop) {
- return {type: 'span', children: [], prop, hidden: false};
- }
-
- function hiddenSpan(prop) {
- return {type: 'span', children: [], prop, hidden: true};
- }
-
function advanceTimers(ms) {
// Note: This advances Jest's virtual time but not React's. Use
// ReactNoop.expire for that.
@@ -231,7 +223,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'C',
// We leave D incomplete.
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Flush the promise completely
await resolveText('A');
@@ -239,11 +231,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Even though the promise has resolved, we should now flush
// and commit the in progress render instead of restarting.
expect(Scheduler).toFlushAndYield(['D']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Loading...'),
- span('C'),
- span('D'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Await one micro task to attach the retry listeners.
await null;
@@ -251,12 +245,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Next, we'll flush the complete content.
expect(Scheduler).toFlushAndYield(['Bar', 'A', 'B']);
- expect(ReactNoop.getChildren()).toEqual([
- span('A'),
- span('B'),
- span('C'),
- span('D'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -301,13 +297,18 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'B',
'Loading...',
]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Resolve the data
await resolveText('A');
// Renders successfully
expect(Scheduler).toFlushAndYield(['Foo', 'Bar', 'A', 'B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -329,24 +330,36 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Suspend! [B]',
'Loading B...',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Loading A...'),
- span('Loading B...'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Resolve first Suspense's promise so that it switches switches back to the
// normal view. The second Suspense should still show the placeholder.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('Loading B...')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Resolve the second Suspense's promise so that it switches back to the
// normal view.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -385,18 +398,20 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading...',
]);
// Did not commit yet.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Wait for data to resolve
await resolveText('B');
// Renders successfully
expect(Scheduler).toFlushAndYield(['A', 'B', 'C', 'D']);
- expect(ReactNoop.getChildren()).toEqual([
- span('A'),
- span('B'),
- span('C'),
- span('D'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+
+ >,
+ );
});
// Second condition is redundant but guarantees that the test runs in prod.
@@ -435,7 +450,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.startTransition(() => {
@@ -445,7 +460,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
}
expect(Scheduler).toFlushAndYield(['Suspend! [Result]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
await rejectText('Result', new Error('Failed to load: Result'));
@@ -458,9 +473,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Errored again on retry. Now handle it.
'Caught error: Failed to load: Result',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Caught error: Failed to load: Result'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
// Second condition is redundant but guarantees that the test runs in prod.
@@ -497,7 +512,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Suspend! [Result]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await rejectText('Result', new Error('Failed to load: Result'));
@@ -510,9 +525,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Errored again on retry. Now handle it.
'Caught error: Failed to load: Result',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Caught error: Failed to load: Result'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
});
// @gate enableLegacyCache
@@ -531,7 +546,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['A', 'Suspend! [1]', 'Loading...']);
await resolveText('1');
expect(Scheduler).toFlushAndYield(['A', '1']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('1')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update the low-pri text
ReactNoop.render();
@@ -548,11 +568,21 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
});
expect(Scheduler).toHaveYielded(['B', '1']);
- expect(ReactNoop.getChildren()).toEqual([span('B'), span('1')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Unblock the low-pri text and finish
await resolveText('2');
- expect(ReactNoop.getChildren()).toEqual([span('B'), span('1')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -571,7 +601,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield([]);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.startTransition(() => {
@@ -581,7 +611,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
}
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance React's virtual time by enough to fall into a new async bucket,
// but not enough to expire the suspense timeout.
@@ -594,11 +624,16 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
}
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'B', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A', 'B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -628,7 +663,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// but we have another pending update that we can work on
'(empty)',
]);
- expect(ReactNoop.getChildren()).toEqual([span('(empty)')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Note: This test was written to test a heuristic used in the expiration
@@ -735,7 +770,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Sync',
]);
// The update hasn't expired yet, so we commit nothing.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance both React's virtual time and Jest's timers by enough to expire
// the update.
@@ -745,12 +780,22 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// the placeholder.
expect(Scheduler).toHaveYielded([]);
// Should have committed the placeholder.
- expect(ReactNoop.getChildren()).toEqual([span('Loading...'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Once the promise resolves, we render the suspended view
await resolveText('Async');
expect(Scheduler).toFlushAndYield(['Async']);
- expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -779,10 +824,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading outer...',
]);
// The outer loading state finishes immediately.
- expect(ReactNoop.getChildren()).toEqual([
- span('Sync'),
- span('Loading outer...'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Resolve the outer promise.
await resolveText('Outer content');
@@ -792,30 +839,36 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading inner...',
]);
// Don't commit the inner placeholder yet.
- expect(ReactNoop.getChildren()).toEqual([
- span('Sync'),
- span('Loading outer...'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Expire the inner timeout.
ReactNoop.expire(500);
await advanceTimers(500);
// Now that 750ms have elapsed since the outer placeholder timed out,
// we can timeout the inner placeholder.
- expect(ReactNoop.getChildren()).toEqual([
- span('Sync'),
- span('Outer content'),
- span('Loading inner...'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Finally, flush the inner promise. We should see the complete screen.
await resolveText('Inner content');
expect(Scheduler).toFlushAndYield(['Inner content']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Sync'),
- span('Outer content'),
- span('Inner content'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -841,12 +894,22 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Sync',
]);
// The tree commits synchronously
- expect(ReactNoop.getChildren()).toEqual([span('Loading...'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Once the promise resolves, we render the suspended view
await resolveText('Async');
expect(Scheduler).toFlushAndYield(['Async']);
- expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -870,7 +933,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading (outer)...',
]);
// The tree commits synchronously
- expect(ReactNoop.getChildren()).toEqual([span('Loading (outer)...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -899,7 +962,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Sync',
]);
// The update hasn't expired yet, so we commit nothing.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance both React's virtual time and Jest's timers by enough to trigger
// the timeout, but not by enough to flush the promise or reach the true
@@ -907,12 +970,22 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.expire(2000);
await advanceTimers(2000);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('Loading...'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Once the promise resolves, we render the suspended view
await resolveText('Async');
expect(Scheduler).toFlushAndYield(['Async']);
- expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -943,22 +1016,27 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Sync',
]);
// The update hasn't expired yet, so we commit nothing.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance both React's virtual time and Jest's timers,
// but not by enough to flush the promise or reach the true expiration time.
ReactNoop.expire(2000);
await advanceTimers(2000);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Even flushing won't yield a fallback in a transition.
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Once the promise resolves, we render the suspended view
await resolveText('Async');
expect(Scheduler).toFlushAndYield(['Async', 'Sync']);
- expect(ReactNoop.getChildren()).toEqual([span('Async'), span('Sync')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -1038,13 +1116,18 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Suspend! [B]',
'Loading...',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await resolveText('A');
await resolveText('B');
expect(Scheduler).toFlushAndYield(['A', 'B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -1068,13 +1151,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
);
}
expect(Scheduler).toFlushAndYield(['Suspend! [Async]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Resolve the promise
await resolveText('Async');
// We can now resume rendering
expect(Scheduler).toFlushAndYield(['Async']);
- expect(ReactNoop.getChildren()).toEqual([span('Async')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -1100,32 +1183,32 @@ describe('ReactSuspenseWithNoopRenderer', () => {
React.startTransition(() => ReactNoop.render());
// The update should suspend.
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([span('S')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Advance time until right before it expires.
await advanceTimers(4999);
ReactNoop.expire(4999);
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('S')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Schedule another low priority update.
React.startTransition(() => ReactNoop.render());
// This update should also suspend.
expect(Scheduler).toFlushAndYield(['Suspend! [B]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([span('S')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Schedule a regular update. Its expiration time will fall between
// the expiration times of the previous two updates.
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['C']);
- expect(ReactNoop.getChildren()).toEqual([span('C')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Flush the remaining work.
await resolveText('A');
await resolveText('B');
// Nothing else to render.
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([span('C')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// TODO: This test was written against the old Expiration Times
@@ -1166,13 +1249,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading...',
'Commit: goodbye',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await resolveText('goodbye');
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
expect(Scheduler).toFlushAndYield(['goodbye']);
- expect(ReactNoop.getChildren()).toEqual([span('goodbye')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -1231,14 +1314,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Times out immediately, ignoring the specified threshold.
ReactNoop.renderLegacySyncRoot();
expect(Scheduler).toHaveYielded(['Suspend! [Result]', 'Loading...']);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
resolveText('Result');
});
expect(Scheduler).toHaveYielded(['Result']);
- expect(ReactNoop.getChildren()).toEqual([span('Result')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -1420,7 +1503,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Suspend! [Hi]',
'Loading...',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
resolveText('Hi');
@@ -1431,7 +1514,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Hi',
'componentDidMount',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Hi')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -1468,12 +1551,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Re-render due to lifecycle update
'Loading...',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await act(async () => {
resolveText('Hi');
});
expect(Scheduler).toHaveYielded(['Hi']);
- expect(ReactNoop.getChildren()).toEqual([span('Hi')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
if (global.__PERSISTENT__) {
@@ -1891,7 +1974,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading...',
]);
// We're now suspended and we haven't shown anything yet.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Flush some of the time
Scheduler.unstable_advanceTime(450);
@@ -1899,7 +1982,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Because we've already been waiting for so long we can
// wait a bit longer. Still nothing...
expect(Scheduler).toFlushWithoutYielding();
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Eventually we'll show the fallback.
Scheduler.unstable_advanceTime(500);
@@ -1908,9 +1991,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushWithoutYielding();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
// Since this is a transition, we never fallback.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
} else {
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
}
// Flush the promise completely
@@ -1922,7 +2005,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
} else {
expect(Scheduler).toFlushAndYield(['A']);
}
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -1950,7 +2033,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading more...',
'Loading...',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await resolveText('A');
// Wait a long time.
@@ -1967,16 +2050,23 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Because we've already been waiting for so long we've exceeded
// our threshold and we show the next level immediately.
- expect(ReactNoop.getChildren()).toEqual([
- span('A'),
- span('Loading more...'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Flush the last promise completely
await resolveText('B');
// Renders successfully
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -2004,7 +2094,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading more...',
'Loading...',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await resolveText('A');
@@ -2017,16 +2107,21 @@ describe('ReactSuspenseWithNoopRenderer', () => {
]);
// Because we've already been waiting for so long we can
// wait a bit longer. Still nothing...
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
await resolveText('B');
// Before we commit another Promise resolves.
// We're still showing the first loading state.
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Restart and render the complete content.
expect(Scheduler).toFlushAndYield(['A', 'B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -2063,7 +2158,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
]);
// We're now suspended and we haven't shown anything yet.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Flush some of the time
Scheduler.unstable_advanceTime(500);
@@ -2076,9 +2171,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushWithoutYielding();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
// Transitions never fallback.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
} else {
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
}
});
@@ -2273,12 +2368,17 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'B',
'Initial load...',
]);
- expect(ReactNoop.getChildren()).toEqual([span('Initial load...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Eventually we resolve and show the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A', 'B']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update to show C
ReactNoop.render();
@@ -2294,16 +2394,24 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(600);
// Since the optional suspense boundary is already showing its content,
// we have to use the inner fallback instead.
- expect(ReactNoop.getChildren()).toEqual([
- hiddenSpan('A'),
- span('Updating...'),
- span('B'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
// Later we load the data.
await resolveText('C');
expect(Scheduler).toFlushAndYield(['A', 'C']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('C'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -2328,12 +2436,17 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'B',
// null
]);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Eventually we resolve and show the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Update to show C
ReactNoop.render();
@@ -2347,12 +2460,23 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Flush to skip suspended time.
Scheduler.unstable_advanceTime(600);
await advanceTimers(600);
- expect(ReactNoop.getChildren()).toEqual([hiddenSpan('A'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Later we load the data.
await resolveText('C');
expect(Scheduler).toFlushAndYield(['A', 'C']);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('C'), span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+
+ >,
+ );
});
// @gate enableLegacyCache
@@ -2384,7 +2508,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
Scheduler.unstable_advanceTime(600);
await advanceTimers(600);
- expect(ReactNoop.getChildren()).toEqual([span('A'), span('Loading B...')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableLegacyCache && enableSuspenseAvoidThisFallback
@@ -2411,7 +2540,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo', 'A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.startTransition(() => {
@@ -2428,7 +2557,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
'Loading B...',
]);
// Still suspended.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Flush to skip suspended time.
Scheduler.unstable_advanceTime(600);
@@ -2436,12 +2565,14 @@ describe('ReactSuspenseWithNoopRenderer', () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
// Transitions never fall back.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
} else {
- expect(ReactNoop.getChildren()).toEqual([
- span('A'),
- span('Loading B...'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
}
});
@@ -2465,7 +2596,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Foo', 'A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
if (gate(flags => flags.enableSyncDefaultUpdates)) {
React.startTransition(() => {
@@ -2482,7 +2613,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Null
]);
// Still suspended.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Flush to skip suspended time.
Scheduler.unstable_advanceTime(600);
@@ -2490,9 +2621,9 @@ describe('ReactSuspenseWithNoopRenderer', () => {
if (gate(flags => flags.enableSyncDefaultUpdates)) {
// Transitions never fall back.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
} else {
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
}
});
@@ -2520,7 +2651,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading A...']);
// We're still suspended.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Schedule an update at idle pri.
ReactNoop.idleUpdates(() => ReactNoop.render());
@@ -2528,20 +2659,20 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield([]);
// We're still suspended.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Advance time a little bit.
Scheduler.unstable_advanceTime(150);
await advanceTimers(150);
// We should not have committed yet because we had a long suspense time.
- expect(ReactNoop.getChildren()).toEqual([]);
+ expect(ReactNoop).toMatchRenderedOutput(null);
// Flush to skip suspended time.
Scheduler.unstable_advanceTime(600);
await advanceTimers(600);
- expect(ReactNoop.getChildren()).toEqual([span('Loading A...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
describe('startTransition', () => {
@@ -2562,12 +2693,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Only a short time is needed to unsuspend the initial loading state.
Scheduler.unstable_advanceTime(400);
await advanceTimers(400);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Later we load the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start transition.
React.startTransition(() => ReactNoop.render());
@@ -2577,11 +2708,11 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(100000);
// Even after lots of time has passed, we have still not yet flushed the
// loading state.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Later we load the data.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -2611,13 +2742,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Only a short time is needed to unsuspend the initial loading state.
Scheduler.unstable_advanceTime(400);
await advanceTimers(400);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start transition.
await act(async () => {
@@ -2628,12 +2759,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(100000);
// Even after lots of time has passed, we have still not yet flushed the
// loading state.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -2666,13 +2797,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Only a short time is needed to unsuspend the initial loading state.
Scheduler.unstable_advanceTime(400);
await advanceTimers(400);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start transition.
await act(async () => {
@@ -2683,12 +2814,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(100000);
// Even after lots of time has passed, we have still not yet flushed the
// loading state.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -2710,12 +2841,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Only a short time is needed to unsuspend the initial loading state.
Scheduler.unstable_advanceTime(400);
await advanceTimers(400);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Later we load the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start transition.
React.startTransition(() => ReactNoop.render());
@@ -2725,12 +2856,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(2999);
// Since the timeout is infinite (or effectively infinite),
// we have still not yet flushed the loading state.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Later we load the data.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start a long (infinite) transition.
React.startTransition(() => ReactNoop.render());
@@ -2740,7 +2871,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// loading state.
Scheduler.unstable_advanceTime(100000);
await advanceTimers(100000);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// @gate enableLegacyCache
@@ -2770,13 +2901,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Only a short time is needed to unsuspend the initial loading state.
Scheduler.unstable_advanceTime(400);
await advanceTimers(400);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start transition.
await act(async () => {
@@ -2788,13 +2919,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(2999);
// Since the timeout is infinite (or effectively infinite),
// we have still not yet flushed the loading state.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start a long (infinite) transition.
await act(async () => {
@@ -2806,7 +2937,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// loading state.
Scheduler.unstable_advanceTime(100000);
await advanceTimers(100000);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
@@ -2840,13 +2971,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Only a short time is needed to unsuspend the initial loading state.
Scheduler.unstable_advanceTime(400);
await advanceTimers(400);
- expect(ReactNoop.getChildren()).toEqual([span('Loading...')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('A');
expect(Scheduler).toFlushAndYield(['A']);
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start transition.
await act(async () => {
@@ -2857,13 +2988,13 @@ describe('ReactSuspenseWithNoopRenderer', () => {
await advanceTimers(2999);
// Since the timeout is infinite (or effectively infinite),
// we have still not yet flushed the loading state.
- expect(ReactNoop.getChildren()).toEqual([span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
// Later we load the data.
await resolveText('B');
expect(Scheduler).toFlushAndYield(['B']);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
// Start a long (infinite) transition.
await act(async () => {
@@ -2875,7 +3006,7 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// loading state.
Scheduler.unstable_advanceTime(100000);
await advanceTimers(100000);
- expect(ReactNoop.getChildren()).toEqual([span('B')]);
+ expect(ReactNoop).toMatchRenderedOutput();
});
});
});
@@ -2900,7 +3031,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [A]', 'Loading...']);
await resolveText('A');
expect(Scheduler).toFlushAndYield(['Hi!', 'A']);
- expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Start transition.
React.startTransition(() => ReactNoop.render());
@@ -2908,12 +3044,22 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [B]', 'Loading B...']);
// Suspended
- expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
Scheduler.unstable_advanceTime(1800);
await advanceTimers(1800);
expect(Scheduler).toFlushAndYield([]);
// We should still be suspended here because this loading state should be avoided.
- expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
await resolveText('B');
expect(Scheduler).toFlushAndYield(['Hi!', 'B']);
expect(ReactNoop).toMatchRenderedOutput(
@@ -2946,7 +3092,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
// Initial render.
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Hi!', 'A']);
- expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Start transition.
React.startTransition(() => ReactNoop.render());
@@ -2954,7 +3105,12 @@ describe('ReactSuspenseWithNoopRenderer', () => {
expect(Scheduler).toFlushAndYield(['Hi!', 'Suspend! [B]', 'Loading B...']);
// Suspended
- expect(ReactNoop.getChildren()).toEqual([span('Hi!'), span('A')]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
Scheduler.unstable_advanceTime(1800);
await advanceTimers(1800);
expect(Scheduler).toFlushAndYield([]);
diff --git a/packages/react-reconciler/src/__tests__/useEffectEvent-test.js b/packages/react-reconciler/src/__tests__/useEffectEvent-test.js
index 5ebfcf56268..c2f58292deb 100644
--- a/packages/react-reconciler/src/__tests__/useEffectEvent-test.js
+++ b/packages/react-reconciler/src/__tests__/useEffectEvent-test.js
@@ -42,10 +42,6 @@ describe('useEffectEvent', () => {
useMemo = React.useMemo;
});
- function span(prop) {
- return {type: 'span', hidden: false, children: [], prop};
- }
-
function Text(props) {
Scheduler.unstable_yieldValue(props.text);
return ;
@@ -77,17 +73,21 @@ describe('useEffectEvent', () => {
const button = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Increment', 'Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 0'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 1']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 1'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -95,26 +95,32 @@ describe('useEffectEvent', () => {
// Event should use the updated callback function closed over the new value.
'Count: 2',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Increase the increment prop amount
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Increment', 'Count: 2']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Event uses the new prop
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 12']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 12'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableUseEffectEventHook
@@ -153,24 +159,30 @@ describe('useEffectEvent', () => {
const button = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Increment', 'Count: 0']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 0'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 5']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 5'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.multiply);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 25']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 25'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableUseEffectEventHook
@@ -206,20 +218,24 @@ describe('useEffectEvent', () => {
const button = React.createRef(null);
ReactNoop.render();
expect(Scheduler).toFlushAndYield(['Say hej', 'Greeting: Seb says hej']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Say hej'),
- span('Greeting: Seb says hej'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.greet);
expect(Scheduler).toHaveYielded([
'Say hej',
'Greeting: undefined says hej',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Say hej'),
- span('Greeting: undefined says hej'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableUseEffectEventHook
@@ -299,10 +315,12 @@ describe('useEffectEvent', () => {
'Increment',
'Count: 2',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -310,10 +328,12 @@ describe('useEffectEvent', () => {
// Effect should not re-run because the dependency hasn't changed.
'Count: 3',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 3'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -321,10 +341,12 @@ describe('useEffectEvent', () => {
// Event should use the updated callback function closed over the new value.
'Count: 4',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 4'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Increase the increment prop amount
ReactNoop.render();
@@ -335,18 +357,22 @@ describe('useEffectEvent', () => {
'Increment',
'Count: 24',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 24'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Event uses the new prop
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 34']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 34'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableUseEffectEventHook
@@ -388,10 +414,12 @@ describe('useEffectEvent', () => {
'Increment',
'Count: 2',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -399,10 +427,12 @@ describe('useEffectEvent', () => {
// Effect should not re-run because the dependency hasn't changed.
'Count: 3',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 3'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -410,10 +440,12 @@ describe('useEffectEvent', () => {
// Event should use the updated callback function closed over the new value.
'Count: 4',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 4'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Increase the increment prop amount
ReactNoop.render();
@@ -424,18 +456,22 @@ describe('useEffectEvent', () => {
'Increment',
'Count: 24',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 24'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Event uses the new prop
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 34']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 34'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableUseEffectEventHook
@@ -483,10 +519,12 @@ describe('useEffectEvent', () => {
'Increment',
'Count: 2',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 2'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -494,10 +532,12 @@ describe('useEffectEvent', () => {
// Effect should not re-run because the dependency hasn't changed.
'Count: 3',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 3'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
act(button.current.increment);
expect(Scheduler).toHaveYielded([
@@ -505,10 +545,12 @@ describe('useEffectEvent', () => {
// Event should use the updated callback function closed over the new value.
'Count: 4',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 4'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Increase the increment prop amount
ReactNoop.render();
@@ -519,18 +561,22 @@ describe('useEffectEvent', () => {
'Increment',
'Count: 24',
]);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 24'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
// Event uses the new prop
act(button.current.increment);
expect(Scheduler).toHaveYielded(['Increment', 'Count: 34']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Increment'),
- span('Count: 34'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ <>
+
+
+ >,
+ );
});
// @gate enableUseEffectEventHook
@@ -693,9 +739,9 @@ describe('useEffectEvent', () => {
act(() => ReactNoop.render());
expect(Scheduler).toHaveYielded(['Welcome to the general room!']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Welcome to the general room!'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
jest.advanceTimersByTime(100);
Scheduler.unstable_advanceTime(100);
@@ -704,9 +750,9 @@ describe('useEffectEvent', () => {
// change roomId only
act(() => ReactNoop.render());
expect(Scheduler).toHaveYielded(['Welcome to the music room!']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Welcome to the music room!'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
jest.advanceTimersByTime(100);
Scheduler.unstable_advanceTime(100);
// should trigger a reconnect
@@ -715,9 +761,9 @@ describe('useEffectEvent', () => {
// change theme only
act(() => ReactNoop.render());
expect(Scheduler).toHaveYielded(['Welcome to the music room!']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Welcome to the music room!'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
jest.advanceTimersByTime(100);
Scheduler.unstable_advanceTime(100);
// should not trigger a reconnect
@@ -726,9 +772,9 @@ describe('useEffectEvent', () => {
// change roomId only
act(() => ReactNoop.render());
expect(Scheduler).toHaveYielded(['Welcome to the travel room!']);
- expect(ReactNoop.getChildren()).toEqual([
- span('Welcome to the travel room!'),
- ]);
+ expect(ReactNoop).toMatchRenderedOutput(
+ ,
+ );
jest.advanceTimersByTime(100);
Scheduler.unstable_advanceTime(100);
// should trigger a reconnect