@samitouri / QOS-React-2 / commits / f9c0a45441

Convert the rest of react-dom and react-test-renderer to Named Exports (#18145)

Nothing interesting here except that ReactShallowRenderer currently exports a class with a static method instead of an object. I think the public API is probably just meant to be createRenderer but currently the whole class is exposed. So this means that we have to keep it as default export. We could potentially also expose a named export for createRenderer but that's going to cause compatibility issues. So I'm just going to make that export default. Unfortunately Rollup and Babel (which powers Jest) disagree on how to import this. So to make it work I had to move the jest tests to imports. This doesn't work with module resetting. Some tests weren't doing that anyway and the rest is just testing ReactShallowRenderer so meh.

Sebastian Markbåge committed Feb 26, 2020 at 18:04 UTC f9c0a454415172433b8b94eec94fc36b2461065c
22 files changed +412 -471
packages/react-dom/server.browser.js
+7 -7
@@ -7,10 +7,10 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactDOMServer = require('./src/server/ReactDOMServerBrowser');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest
16 -module.exports = ReactDOMServer.default || ReactDOMServer;
10 +export {
11 + renderToString,
12 + renderToStaticMarkup,
13 + renderToNodeStream,
14 + renderToStaticNodeStream,
15 + version,
16 +} from './src/server/ReactDOMServerBrowser';
packages/react-dom/server.js
+1 -3
@@ -7,6 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -module.exports = require('./server.node');
10 +export * from './server.node';
packages/react-dom/server.node.js
+8 -7
@@ -7,10 +7,11 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactDOMServer = require('./src/server/ReactDOMServerNode');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest
16 -module.exports = ReactDOMServer.default || ReactDOMServer;
10 +// For some reason Flow doesn't like export * in this file. I don't know why.
11 +export {
12 + renderToString,
13 + renderToStaticMarkup,
14 + renderToNodeStream,
15 + renderToStaticNodeStream,
16 + version,
17 +} from './src/server/ReactDOMServerNode';
packages/react-dom/src/__tests__/ReactTestUtils-test.js
+6 -14
@@ -9,11 +9,11 @@
9
10 'use strict';
11
12 -let createRenderer;
13 -let React;
14 -let ReactDOM;
15 -let ReactDOMServer;
16 -let ReactTestUtils;
12 +import ReactShallowRenderer from 'react-test-renderer/shallow';
13 +import * as React from 'react';
14 +import * as ReactDOM from 'react-dom';
15 +import * as ReactDOMServer from 'react-dom/server';
16 +import * as ReactTestUtils from 'react-dom/test-utils';
17
18 function getTestDocument(markup) {
19 const doc = document.implementation.createHTMLDocument('');
@@ -27,14 +27,6 @@ function getTestDocument(markup) {
27 }
28
29 describe('ReactTestUtils', () => {
30 - beforeEach(() => {
31 - createRenderer = require('react-test-renderer/shallow').createRenderer;
32 - React = require('react');
33 - ReactDOM = require('react-dom');
34 - ReactDOMServer = require('react-dom/server');
35 - ReactTestUtils = require('react-dom/test-utils');
36 - });
37 -
30 it('Simulate should have locally attached media events', () => {
31 expect(Object.keys(ReactTestUtils.Simulate).sort()).toMatchSnapshot();
32 });
@@ -403,7 +395,7 @@ describe('ReactTestUtils', () => {
395 }
396
397 const handler = jest.fn().mockName('spy');
406 - const shallowRenderer = createRenderer();
398 + const shallowRenderer = ReactShallowRenderer.createRenderer();
399 const result = shallowRenderer.render(
400 <SomeComponent handleClick={handler} />,
401 );
packages/react-dom/src/server/ReactDOMFizzServerBrowser.js
+1 -3
@@ -29,6 +29,4 @@ function renderToReadableStream(children: ReactNodeList): ReadableStream {
29 });
30 }
31
32 -export default {
33 - renderToReadableStream,
34 -};
32 +export {renderToReadableStream};
packages/react-dom/src/server/ReactDOMFizzServerNode.js
+1 -3
@@ -25,6 +25,4 @@ function pipeToNodeWritable(
25 startWork(request);
26 }
27
28 -export default {
29 - pipeToNodeWritable,
30 -};
28 +export {pipeToNodeWritable};
packages/react-dom/src/server/ReactDOMServerBrowser.js
+2 -3
@@ -26,11 +26,10 @@ function renderToStaticNodeStream() {
26 );
27 }
28
29 -// Note: when changing this, also consider https://github.com/facebook/react/issues/11526
30 -export default {
29 +export {
30 renderToString,
31 renderToStaticMarkup,
32 renderToNodeStream,
33 renderToStaticNodeStream,
35 - version: ReactVersion,
34 + ReactVersion as version,
35 };
packages/react-dom/src/server/ReactDOMServerNode.js
+2 -3
@@ -13,11 +13,10 @@ import {
13 renderToStaticNodeStream,
14 } from './ReactDOMNodeStreamRenderer';
15
16 -// Note: when changing this, also consider https://github.com/facebook/react/issues/11526
17 -export default {
16 +export {
17 renderToString,
18 renderToStaticMarkup,
19 renderToNodeStream,
20 renderToStaticNodeStream,
22 - version: ReactVersion,
21 + ReactVersion as version,
22 };
packages/react-dom/src/test-utils/ReactTestUtils.js
+236 -231
@@ -159,243 +159,233 @@ function validateClassInstance(inst, methodName) {
159 * utilities will suffice for testing purposes.
160 * @lends ReactTestUtils
161 */
162 -const ReactTestUtils = {
163 - renderIntoDocument: function(element) {
164 - const div = document.createElement('div');
165 - // None of our tests actually require attaching the container to the
166 - // DOM, and doing so creates a mess that we rely on test isolation to
167 - // clean up, so we're going to stop honoring the name of this method
168 - // (and probably rename it eventually) if no problems arise.
169 - // document.documentElement.appendChild(div);
170 - return ReactDOM.render(element, div);
171 - },
172 -
173 - isElement: function(element) {
174 - return React.isValidElement(element);
175 - },
176 -
177 - isElementOfType: function(inst, convenienceConstructor) {
178 - return React.isValidElement(inst) && inst.type === convenienceConstructor;
179 - },
180 -
181 - isDOMComponent: function(inst) {
182 - return !!(inst && inst.nodeType === ELEMENT_NODE && inst.tagName);
183 - },
184 -
185 - isDOMComponentElement: function(inst) {
186 - return !!(inst && React.isValidElement(inst) && !!inst.tagName);
187 - },
188 -
189 - isCompositeComponent: function(inst) {
190 - if (ReactTestUtils.isDOMComponent(inst)) {
191 - // Accessing inst.setState warns; just return false as that'll be what
192 - // this returns when we have DOM nodes as refs directly
193 - return false;
194 - }
195 - return (
196 - inst != null &&
197 - typeof inst.render === 'function' &&
198 - typeof inst.setState === 'function'
199 - );
200 - },
162 +function renderIntoDocument(element) {
163 + const div = document.createElement('div');
164 + // None of our tests actually require attaching the container to the
165 + // DOM, and doing so creates a mess that we rely on test isolation to
166 + // clean up, so we're going to stop honoring the name of this method
167 + // (and probably rename it eventually) if no problems arise.
168 + // document.documentElement.appendChild(div);
169 + return ReactDOM.render(element, div);
170 +}
171
202 - isCompositeComponentWithType: function(inst, type) {
203 - if (!ReactTestUtils.isCompositeComponent(inst)) {
204 - return false;
205 - }
206 - const internalInstance = getInstance(inst);
207 - const constructor = internalInstance.type;
208 - return constructor === type;
209 - },
210 -
211 - findAllInRenderedTree: function(inst, test) {
212 - validateClassInstance(inst, 'findAllInRenderedTree');
213 - if (!inst) {
214 - return [];
215 - }
216 - const internalInstance = getInstance(inst);
217 - return findAllInRenderedFiberTreeInternal(internalInstance, test);
218 - },
172 +function isElement(element) {
173 + return React.isValidElement(element);
174 +}
175
220 - /**
221 - * Finds all instance of components in the rendered tree that are DOM
222 - * components with the class name matching `className`.
223 - * @return {array} an array of all the matches.
224 - */
225 - scryRenderedDOMComponentsWithClass: function(root, classNames) {
226 - validateClassInstance(root, 'scryRenderedDOMComponentsWithClass');
227 - return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
228 - if (ReactTestUtils.isDOMComponent(inst)) {
229 - let className = inst.className;
230 - if (typeof className !== 'string') {
231 - // SVG, probably.
232 - className = inst.getAttribute('class') || '';
233 - }
234 - const classList = className.split(/\s+/);
235 -
236 - if (!Array.isArray(classNames)) {
237 - invariant(
238 - classNames !== undefined,
239 - 'TestUtils.scryRenderedDOMComponentsWithClass expects a ' +
240 - 'className as a second argument.',
241 - );
242 - classNames = classNames.split(/\s+/);
243 - }
244 - return classNames.every(function(name) {
245 - return classList.indexOf(name) !== -1;
246 - });
247 - }
248 - return false;
249 - });
250 - },
176 +function isElementOfType(inst, convenienceConstructor) {
177 + return React.isValidElement(inst) && inst.type === convenienceConstructor;
178 +}
179
252 - /**
253 - * Like scryRenderedDOMComponentsWithClass but expects there to be one result,
254 - * and returns that one result, or throws exception if there is any other
255 - * number of matches besides one.
256 - * @return {!ReactDOMComponent} The one match.
257 - */
258 - findRenderedDOMComponentWithClass: function(root, className) {
259 - validateClassInstance(root, 'findRenderedDOMComponentWithClass');
260 - const all = ReactTestUtils.scryRenderedDOMComponentsWithClass(
261 - root,
262 - className,
263 - );
264 - if (all.length !== 1) {
265 - throw new Error(
266 - 'Did not find exactly one match (found: ' +
267 - all.length +
268 - ') ' +
269 - 'for class:' +
270 - className,
271 - );
272 - }
273 - return all[0];
274 - },
180 +function isDOMComponent(inst) {
181 + return !!(inst && inst.nodeType === ELEMENT_NODE && inst.tagName);
182 +}
183
276 - /**
277 - * Finds all instance of components in the rendered tree that are DOM
278 - * components with the tag name matching `tagName`.
279 - * @return {array} an array of all the matches.
280 - */
281 - scryRenderedDOMComponentsWithTag: function(root, tagName) {
282 - validateClassInstance(root, 'scryRenderedDOMComponentsWithTag');
283 - return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
284 - return (
285 - ReactTestUtils.isDOMComponent(inst) &&
286 - inst.tagName.toUpperCase() === tagName.toUpperCase()
287 - );
288 - });
289 - },
184 +function isDOMComponentElement(inst) {
185 + return !!(inst && React.isValidElement(inst) && !!inst.tagName);
186 +}
187
291 - /**
292 - * Like scryRenderedDOMComponentsWithTag but expects there to be one result,
293 - * and returns that one result, or throws exception if there is any other
294 - * number of matches besides one.
295 - * @return {!ReactDOMComponent} The one match.
296 - */
297 - findRenderedDOMComponentWithTag: function(root, tagName) {
298 - validateClassInstance(root, 'findRenderedDOMComponentWithTag');
299 - const all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName);
300 - if (all.length !== 1) {
301 - throw new Error(
302 - 'Did not find exactly one match (found: ' +
303 - all.length +
304 - ') ' +
305 - 'for tag:' +
306 - tagName,
307 - );
308 - }
309 - return all[0];
310 - },
188 +function isCompositeComponent(inst) {
189 + if (isDOMComponent(inst)) {
190 + // Accessing inst.setState warns; just return false as that'll be what
191 + // this returns when we have DOM nodes as refs directly
192 + return false;
193 + }
194 + return (
195 + inst != null &&
196 + typeof inst.render === 'function' &&
197 + typeof inst.setState === 'function'
198 + );
199 +}
200
312 - /**
313 - * Finds all instances of components with type equal to `componentType`.
314 - * @return {array} an array of all the matches.
315 - */
316 - scryRenderedComponentsWithType: function(root, componentType) {
317 - validateClassInstance(root, 'scryRenderedComponentsWithType');
318 - return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
319 - return ReactTestUtils.isCompositeComponentWithType(inst, componentType);
320 - });
321 - },
201 +function isCompositeComponentWithType(inst, type) {
202 + if (!isCompositeComponent(inst)) {
203 + return false;
204 + }
205 + const internalInstance = getInstance(inst);
206 + const constructor = internalInstance.type;
207 + return constructor === type;
208 +}
209
323 - /**
324 - * Same as `scryRenderedComponentsWithType` but expects there to be one result
325 - * and returns that one result, or throws exception if there is any other
326 - * number of matches besides one.
327 - * @return {!ReactComponent} The one match.
328 - */
329 - findRenderedComponentWithType: function(root, componentType) {
330 - validateClassInstance(root, 'findRenderedComponentWithType');
331 - const all = ReactTestUtils.scryRenderedComponentsWithType(
332 - root,
333 - componentType,
334 - );
335 - if (all.length !== 1) {
336 - throw new Error(
337 - 'Did not find exactly one match (found: ' +
338 - all.length +
339 - ') ' +
340 - 'for componentType:' +
341 - componentType,
342 - );
343 - }
344 - return all[0];
345 - },
210 +function findAllInRenderedTree(inst, test) {
211 + validateClassInstance(inst, 'findAllInRenderedTree');
212 + if (!inst) {
213 + return [];
214 + }
215 + const internalInstance = getInstance(inst);
216 + return findAllInRenderedFiberTreeInternal(internalInstance, test);
217 +}
218
347 - /**
348 - * Pass a mocked component module to this method to augment it with
349 - * useful methods that allow it to be used as a dummy React component.
350 - * Instead of rendering as usual, the component will become a simple
351 - * <div> containing any provided children.
352 - *
353 - * @param {object} module the mock function object exported from a
354 - * module that defines the component to be mocked
355 - * @param {?string} mockTagName optional dummy root tag name to return
356 - * from render method (overrides
357 - * module.mockTagName if provided)
358 - * @return {object} the ReactTestUtils object (for chaining)
359 - */
360 - mockComponent: function(module, mockTagName) {
361 - if (__DEV__) {
362 - if (!hasWarnedAboutDeprecatedMockComponent) {
363 - hasWarnedAboutDeprecatedMockComponent = true;
364 - console.warn(
365 - 'ReactTestUtils.mockComponent() is deprecated. ' +
366 - 'Use shallow rendering or jest.mock() instead.\n\n' +
367 - 'See https://fb.me/test-utils-mock-component for more information.',
219 +/**
220 + * Finds all instance of components in the rendered tree that are DOM
221 + * components with the class name matching `className`.
222 + * @return {array} an array of all the matches.
223 + */
224 +function scryRenderedDOMComponentsWithClass(root, classNames) {
225 + validateClassInstance(root, 'scryRenderedDOMComponentsWithClass');
226 + return findAllInRenderedTree(root, function(inst) {
227 + if (isDOMComponent(inst)) {
228 + let className = inst.className;
229 + if (typeof className !== 'string') {
230 + // SVG, probably.
231 + className = inst.getAttribute('class') || '';
232 + }
233 + const classList = className.split(/\s+/);
234 +
235 + if (!Array.isArray(classNames)) {
236 + invariant(
237 + classNames !== undefined,
238 + 'TestUtils.scryRenderedDOMComponentsWithClass expects a ' +
239 + 'className as a second argument.',
240 );
241 + classNames = classNames.split(/\s+/);
242 }
243 + return classNames.every(function(name) {
244 + return classList.indexOf(name) !== -1;
245 + });
246 }
247 + return false;
248 + });
249 +}
250
372 - mockTagName = mockTagName || module.mockTagName || 'div';
251 +/**
252 + * Like scryRenderedDOMComponentsWithClass but expects there to be one result,
253 + * and returns that one result, or throws exception if there is any other
254 + * number of matches besides one.
255 + * @return {!ReactDOMComponent} The one match.
256 + */
257 +function findRenderedDOMComponentWithClass(root, className) {
258 + validateClassInstance(root, 'findRenderedDOMComponentWithClass');
259 + const all = scryRenderedDOMComponentsWithClass(root, className);
260 + if (all.length !== 1) {
261 + throw new Error(
262 + 'Did not find exactly one match (found: ' +
263 + all.length +
264 + ') ' +
265 + 'for class:' +
266 + className,
267 + );
268 + }
269 + return all[0];
270 +}
271
374 - module.prototype.render.mockImplementation(function() {
375 - return React.createElement(mockTagName, null, this.props.children);
376 - });
272 +/**
273 + * Finds all instance of components in the rendered tree that are DOM
274 + * components with the tag name matching `tagName`.
275 + * @return {array} an array of all the matches.
276 + */
277 +function scryRenderedDOMComponentsWithTag(root, tagName) {
278 + validateClassInstance(root, 'scryRenderedDOMComponentsWithTag');
279 + return findAllInRenderedTree(root, function(inst) {
280 + return (
281 + isDOMComponent(inst) &&
282 + inst.tagName.toUpperCase() === tagName.toUpperCase()
283 + );
284 + });
285 +}
286
378 - return this;
379 - },
287 +/**
288 + * Like scryRenderedDOMComponentsWithTag but expects there to be one result,
289 + * and returns that one result, or throws exception if there is any other
290 + * number of matches besides one.
291 + * @return {!ReactDOMComponent} The one match.
292 + */
293 +function findRenderedDOMComponentWithTag(root, tagName) {
294 + validateClassInstance(root, 'findRenderedDOMComponentWithTag');
295 + const all = scryRenderedDOMComponentsWithTag(root, tagName);
296 + if (all.length !== 1) {
297 + throw new Error(
298 + 'Did not find exactly one match (found: ' +
299 + all.length +
300 + ') ' +
301 + 'for tag:' +
302 + tagName,
303 + );
304 + }
305 + return all[0];
306 +}
307
381 - nativeTouchData: function(x, y) {
382 - return {
383 - touches: [{pageX: x, pageY: y}],
384 - };
385 - },
308 +/**
309 + * Finds all instances of components with type equal to `componentType`.
310 + * @return {array} an array of all the matches.
311 + */
312 +function scryRenderedComponentsWithType(root, componentType) {
313 + validateClassInstance(root, 'scryRenderedComponentsWithType');
314 + return findAllInRenderedTree(root, function(inst) {
315 + return isCompositeComponentWithType(inst, componentType);
316 + });
317 +}
318
387 - Simulate: null,
388 - SimulateNative: {},
319 +/**
320 + * Same as `scryRenderedComponentsWithType` but expects there to be one result
321 + * and returns that one result, or throws exception if there is any other
322 + * number of matches besides one.
323 + * @return {!ReactComponent} The one match.
324 + */
325 +function findRenderedComponentWithType(root, componentType) {
326 + validateClassInstance(root, 'findRenderedComponentWithType');
327 + const all = scryRenderedComponentsWithType(root, componentType);
328 + if (all.length !== 1) {
329 + throw new Error(
330 + 'Did not find exactly one match (found: ' +
331 + all.length +
332 + ') ' +
333 + 'for componentType:' +
334 + componentType,
335 + );
336 + }
337 + return all[0];
338 +}
339
390 - act,
391 -};
340 +/**
341 + * Pass a mocked component module to this method to augment it with
342 + * useful methods that allow it to be used as a dummy React component.
343 + * Instead of rendering as usual, the component will become a simple
344 + * <div> containing any provided children.
345 + *
346 + * @param {object} module the mock function object exported from a
347 + * module that defines the component to be mocked
348 + * @param {?string} mockTagName optional dummy root tag name to return
349 + * from render method (overrides
350 + * module.mockTagName if provided)
351 + * @return {object} the ReactTestUtils object (for chaining)
352 + */
353 +function mockComponent(module, mockTagName) {
354 + if (__DEV__) {
355 + if (!hasWarnedAboutDeprecatedMockComponent) {
356 + hasWarnedAboutDeprecatedMockComponent = true;
357 + console.warn(
358 + 'ReactTestUtils.mockComponent() is deprecated. ' +
359 + 'Use shallow rendering or jest.mock() instead.\n\n' +
360 + 'See https://fb.me/test-utils-mock-component for more information.',
361 + );
362 + }
363 + }
364 +
365 + mockTagName = mockTagName || module.mockTagName || 'div';
366 +
367 + module.prototype.render.mockImplementation(function() {
368 + return React.createElement(mockTagName, null, this.props.children);
369 + });
370 +
371 + return this;
372 +}
373 +
374 +function nativeTouchData(x, y) {
375 + return {
376 + touches: [{pageX: x, pageY: y}],
377 + };
378 +}
379 +
380 +const Simulate = {};
381 +const SimulateNative = {};
382
383 /**
384 * Exports:
385 *
396 - * - `ReactTestUtils.Simulate.click(Element)`
397 - * - `ReactTestUtils.Simulate.mouseMove(Element)`
398 - * - `ReactTestUtils.Simulate.change(Element)`
386 + * - `Simulate.click(Element)`
387 + * - `Simulate.mouseMove(Element)`
388 + * - `Simulate.change(Element)`
389 * - ... (All keys from event plugin `eventTypes` objects)
390 */
391 function makeSimulator(eventType) {
@@ -407,7 +397,7 @@ function makeSimulator(eventType) {
397 'Note that TestUtils.Simulate will not work if you are using shallow rendering.',
398 );
399 invariant(
410 - !ReactTestUtils.isCompositeComponent(domNode),
400 + !isCompositeComponent(domNode),
401 'TestUtils.Simulate expected a DOM node as the first argument but received ' +
402 'a component instance. Pass the DOM node you wish to simulate the event on instead.',
403 );
@@ -450,15 +440,13 @@ function makeSimulator(eventType) {
440 }
441
442 function buildSimulators() {
453 - ReactTestUtils.Simulate = {};
454 -
443 let eventType;
444 for (eventType in eventNameDispatchConfigs) {
445 /**
446 * @param {!Element|ReactDOMComponent} domComponentOrNode
447 * @param {?object} eventData Fake event data to use in SyntheticEvent.
448 */
461 - ReactTestUtils.Simulate[eventType] = makeSimulator(eventType);
449 + Simulate[eventType] = makeSimulator(eventType);
450 }
451 }
452
@@ -467,16 +455,16 @@ buildSimulators();
455 /**
456 * Exports:
457 *
470 - * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)`
471 - * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)`
472 - * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)`
473 - * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)`
458 + * - `SimulateNative.click(Element/ReactDOMComponent)`
459 + * - `SimulateNative.mouseMove(Element/ReactDOMComponent)`
460 + * - `SimulateNative.mouseIn/ReactDOMComponent)`
461 + * - `SimulateNative.mouseOut(Element/ReactDOMComponent)`
462 * - ... (All keys from `BrowserEventConstants.topLevelTypes`)
463 *
464 * Note: Top level event types are a subset of the entire set of handler types
465 * (which include a broader set of "synthetic" events). For example, onDragDone
466 * is a synthetic event. Except when testing an event plugin or React's event
479 - * handling code specifically, you probably want to use ReactTestUtils.Simulate
467 + * handling code specifically, you probably want to use Simulate
468 * to dispatch synthetic events.
469 */
470
@@ -484,7 +472,7 @@ function makeNativeSimulator(eventType, topLevelType) {
472 return function(domComponentOrNode, nativeEventData) {
473 const fakeNativeEvent = new Event(eventType);
474 Object.assign(fakeNativeEvent, nativeEventData);
487 - if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {
475 + if (isDOMComponent(domComponentOrNode)) {
476 simulateNativeEventOnDOMComponent(
477 topLevelType,
478 domComponentOrNode,
@@ -576,10 +564,27 @@ function makeNativeSimulator(eventType, topLevelType) {
564 * @param {!Element|ReactDOMComponent} domComponentOrNode
565 * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent.
566 */
579 - ReactTestUtils.SimulateNative[eventType] = makeNativeSimulator(
580 - eventType,
581 - topLevelType,
582 - );
567 + SimulateNative[eventType] = makeNativeSimulator(eventType, topLevelType);
568 });
569
585 -export default ReactTestUtils;
570 +export {
571 + renderIntoDocument,
572 + isElement,
573 + isElementOfType,
574 + isDOMComponent,
575 + isDOMComponentElement,
576 + isCompositeComponent,
577 + isCompositeComponentWithType,
578 + findAllInRenderedTree,
579 + scryRenderedDOMComponentsWithClass,
580 + findRenderedDOMComponentWithClass,
581 + scryRenderedDOMComponentsWithTag,
582 + findRenderedDOMComponentWithTag,
583 + scryRenderedComponentsWithType,
584 + findRenderedComponentWithType,
585 + mockComponent,
586 + nativeTouchData,
587 + Simulate,
588 + SimulateNative,
589 + act,
590 +};
packages/react-dom/test-utils.js
+1 -7
@@ -7,10 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactTestUtils = require('./src/test-utils/ReactTestUtils');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest.
16 -module.exports = ReactTestUtils.default || ReactTestUtils;
10 +export * from './src/test-utils/ReactTestUtils';
packages/react-dom/unstable-fizz.browser.js
+1 -7
@@ -7,10 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactDOMFizzServerBrowser = require('./src/server/ReactDOMFizzServerBrowser');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest
16 -module.exports = ReactDOMFizzServerBrowser.default || ReactDOMFizzServerBrowser;
10 +export * from './src/server/ReactDOMFizzServerBrowser';
packages/react-dom/unstable-fizz.js
+1 -3
@@ -7,6 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -module.exports = require('./unstable-fizz.node');
10 +export * from './unstable-fizz.node';
packages/react-dom/unstable-fizz.node.js
+1 -7
@@ -7,10 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactDOMFizzServerNode = require('./src/server/ReactDOMFizzServerNode');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest
16 -module.exports = ReactDOMFizzServerNode.default || ReactDOMFizzServerNode;
10 +export * from './src/server/ReactDOMFizzServerNode';
packages/react-dom/unstable-native-dependencies.js
+1 -3
@@ -7,6 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -module.exports = require('./src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies');
10 +export * from './src/unstable-native-dependencies/ReactDOMUnstableNativeDependencies';
packages/react-server/src/ReactDOMServerFormatConfig.js
+2 -2
@@ -9,7 +9,7 @@
9
10 import {convertStringToBuffer} from 'react-server/src/ReactServerHostConfig';
11
12 -import ReactDOMServer from 'react-dom/server';
12 +import {renderToStaticMarkup} from 'react-dom/server';
13
14 export function formatChunkAsString(type: string, props: Object): string {
15 let str = '<' + type + '>';
@@ -31,5 +31,5 @@ export function renderHostChildrenToString(
31 // so we can't actually reference the renderer here. Instead, we
32 // should replace this method with a reference to Fizz which
33 // then uses this file to implement the server renderer.
34 - return ReactDOMServer.renderToStaticMarkup(children);
34 + return renderToStaticMarkup(children);
35 }
packages/react-test-renderer/index.js
+1 -7
@@ -7,10 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactTestRenderer = require('./src/ReactTestRenderer');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest.
16 -module.exports = ReactTestRenderer.default || ReactTestRenderer;
10 +export * from './src/ReactTestRenderer';
packages/react-test-renderer/shallow.js
+1 -7
@@ -7,10 +7,4 @@
7 * @flow
8 */
9
10 -'use strict';
11 -
12 -const ReactShallowRenderer = require('./src/ReactShallowRenderer');
13 -
14 -// TODO: decide on the top-level export form.
15 -// This is hacky but makes it work with both Rollup and Jest.
16 -module.exports = ReactShallowRenderer.default || ReactShallowRenderer;
10 +export {default} from './src/ReactShallowRenderer';
packages/react-test-renderer/src/ReactShallowRenderer.js
+4
@@ -856,4 +856,8 @@ function getMaskedContext(contextTypes, unmaskedContext) {
856 return context;
857 }
858
859 +// This should probably be a default export and a named export.
860 +// However, this not how any of other APIs are designed so doesn't line up
861 +// with our build configs and makes it hard to properly support ES modules
862 +// and CommonJS.
863 export default ReactShallowRenderer;
packages/react-test-renderer/src/ReactTestRenderer.js
+121 -124
@@ -433,138 +433,129 @@ function propsMatch(props: Object, filter: Object): boolean {
433 return true;
434 }
435
436 -const ReactTestRendererFiber = {
437 - _Scheduler: Scheduler,
438 -
439 - create(element: React$Element<any>, options: TestRendererOptions) {
440 - let createNodeMock = defaultTestOptions.createNodeMock;
441 - let isConcurrent = false;
442 - if (typeof options === 'object' && options !== null) {
443 - if (typeof options.createNodeMock === 'function') {
444 - createNodeMock = options.createNodeMock;
436 +function create(element: React$Element<any>, options: TestRendererOptions) {
437 + let createNodeMock = defaultTestOptions.createNodeMock;
438 + let isConcurrent = false;
439 + if (typeof options === 'object' && options !== null) {
440 + if (typeof options.createNodeMock === 'function') {
441 + createNodeMock = options.createNodeMock;
442 + }
443 + if (options.unstable_isConcurrent === true) {
444 + isConcurrent = true;
445 + }
446 + }
447 + let container = {
448 + children: [],
449 + createNodeMock,
450 + tag: 'CONTAINER',
451 + };
452 + let root: FiberRoot | null = createContainer(
453 + container,
454 + isConcurrent ? ConcurrentRoot : LegacyRoot,
455 + false,
456 + null,
457 + );
458 + invariant(root != null, 'something went wrong');
459 + updateContainer(element, root, null, null);
460 +
461 + const entry = {
462 + _Scheduler: Scheduler,
463 +
464 + root: undefined, // makes flow happy
465 + // we define a 'getter' for 'root' below using 'Object.defineProperty'
466 + toJSON(): Array<ReactTestRendererNode> | ReactTestRendererNode | null {
467 + if (root == null || root.current == null || container == null) {
468 + return null;
469 }
446 - if (options.unstable_isConcurrent === true) {
447 - isConcurrent = true;
470 + if (container.children.length === 0) {
471 + return null;
472 }
449 - }
450 - let container = {
451 - children: [],
452 - createNodeMock,
453 - tag: 'CONTAINER',
454 - };
455 - let root: FiberRoot | null = createContainer(
456 - container,
457 - isConcurrent ? ConcurrentRoot : LegacyRoot,
458 - false,
459 - null,
460 - );
461 - invariant(root != null, 'something went wrong');
462 - updateContainer(element, root, null, null);
463 -
464 - const entry = {
465 - _Scheduler: Scheduler,
466 -
467 - root: undefined, // makes flow happy
468 - // we define a 'getter' for 'root' below using 'Object.defineProperty'
469 - toJSON(): Array<ReactTestRendererNode> | ReactTestRendererNode | null {
470 - if (root == null || root.current == null || container == null) {
471 - return null;
472 - }
473 - if (container.children.length === 0) {
474 - return null;
475 - }
476 - if (container.children.length === 1) {
477 - return toJSON(container.children[0]);
478 - }
479 - if (
480 - container.children.length === 2 &&
481 - container.children[0].isHidden === true &&
482 - container.children[1].isHidden === false
483 - ) {
484 - // Omit timed out children from output entirely, including the fact that we
485 - // temporarily wrap fallback and timed out children in an array.
486 - return toJSON(container.children[1]);
487 - }
488 - let renderedChildren = null;
489 - if (container.children && container.children.length) {
490 - for (let i = 0; i < container.children.length; i++) {
491 - const renderedChild = toJSON(container.children[i]);
492 - if (renderedChild !== null) {
493 - if (renderedChildren === null) {
494 - renderedChildren = [renderedChild];
495 - } else {
496 - renderedChildren.push(renderedChild);
497 - }
473 + if (container.children.length === 1) {
474 + return toJSON(container.children[0]);
475 + }
476 + if (
477 + container.children.length === 2 &&
478 + container.children[0].isHidden === true &&
479 + container.children[1].isHidden === false
480 + ) {
481 + // Omit timed out children from output entirely, including the fact that we
482 + // temporarily wrap fallback and timed out children in an array.
483 + return toJSON(container.children[1]);
484 + }
485 + let renderedChildren = null;
486 + if (container.children && container.children.length) {
487 + for (let i = 0; i < container.children.length; i++) {
488 + const renderedChild = toJSON(container.children[i]);
489 + if (renderedChild !== null) {
490 + if (renderedChildren === null) {
491 + renderedChildren = [renderedChild];
492 + } else {
493 + renderedChildren.push(renderedChild);
494 }
495 }
496 }
501 - return renderedChildren;
502 - },
503 - toTree() {
504 - if (root == null || root.current == null) {
505 - return null;
506 - }
507 - return toTree(root.current);
508 - },
509 - update(newElement: React$Element<any>) {
510 - if (root == null || root.current == null) {
511 - return;
512 - }
513 - updateContainer(newElement, root, null, null);
514 - },
515 - unmount() {
516 - if (root == null || root.current == null) {
517 - return;
497 + }
498 + return renderedChildren;
499 + },
500 + toTree() {
501 + if (root == null || root.current == null) {
502 + return null;
503 + }
504 + return toTree(root.current);
505 + },
506 + update(newElement: React$Element<any>) {
507 + if (root == null || root.current == null) {
508 + return;
509 + }
510 + updateContainer(newElement, root, null, null);
511 + },
512 + unmount() {
513 + if (root == null || root.current == null) {
514 + return;
515 + }
516 + updateContainer(null, root, null, null);
517 + container = null;
518 + root = null;
519 + },
520 + getInstance() {
521 + if (root == null || root.current == null) {
522 + return null;
523 + }
524 + return getPublicRootInstance(root);
525 + },
526 +
527 + unstable_flushSync<T>(fn: () => T): T {
528 + return flushSync(fn);
529 + },
530 + };
531 +
532 + Object.defineProperty(
533 + entry,
534 + 'root',
535 + ({
536 + configurable: true,
537 + enumerable: true,
538 + get: function() {
539 + if (root === null) {
540 + throw new Error("Can't access .root on unmounted test renderer");
541 }
519 - updateContainer(null, root, null, null);
520 - container = null;
521 - root = null;
522 - },
523 - getInstance() {
524 - if (root == null || root.current == null) {
525 - return null;
542 + const children = getChildren(root.current);
543 + if (children.length === 0) {
544 + throw new Error("Can't access .root on unmounted test renderer");
545 + } else if (children.length === 1) {
546 + // Normally, we skip the root and just give you the child.
547 + return children[0];
548 + } else {
549 + // However, we give you the root if there's more than one root child.
550 + // We could make this the behavior for all cases but it would be a breaking change.
551 + return wrapFiber(root.current);
552 }
527 - return getPublicRootInstance(root);
528 - },
529 -
530 - unstable_flushSync<T>(fn: () => T): T {
531 - return flushSync(fn);
553 },
533 - };
534 -
535 - Object.defineProperty(
536 - entry,
537 - 'root',
538 - ({
539 - configurable: true,
540 - enumerable: true,
541 - get: function() {
542 - if (root === null) {
543 - throw new Error("Can't access .root on unmounted test renderer");
544 - }
545 - const children = getChildren(root.current);
546 - if (children.length === 0) {
547 - throw new Error("Can't access .root on unmounted test renderer");
548 - } else if (children.length === 1) {
549 - // Normally, we skip the root and just give you the child.
550 - return children[0];
551 - } else {
552 - // However, we give you the root if there's more than one root child.
553 - // We could make this the behavior for all cases but it would be a breaking change.
554 - return wrapFiber(root.current);
555 - }
556 - },
557 - }: Object),
558 - );
559 -
560 - return entry;
561 - },
554 + }: Object),
555 + );
556
563 - /* eslint-disable-next-line camelcase */
564 - unstable_batchedUpdates: batchedUpdates,
565 -
566 - act,
567 -};
557 + return entry;
558 +}
559
560 const fiberToWrapper = new WeakMap();
561 function wrapFiber(fiber: Fiber): ReactTestInstance {
@@ -589,4 +580,10 @@ injectIntoDevTools({
580 rendererPackageName: 'react-test-renderer',
581 });
582
592 -export default ReactTestRendererFiber;
583 +export {
584 + Scheduler as _Scheduler,
585 + create,
586 + /* eslint-disable-next-line camelcase */
587 + batchedUpdates as unstable_batchedUpdates,
588 + act,
589 +};
packages/react-test-renderer/src/__tests__/ReactShallowRenderer-test.js
+5 -11
@@ -10,19 +10,13 @@
10
11 'use strict';
12
13 -let createRenderer;
14 -let PropTypes;
15 -let React;
13 +import * as PropTypes from 'prop-types';
14 +import * as React from 'react';
15 +import ReactShallowRenderer from 'react-test-renderer/shallow';
16
17 -describe('ReactShallowRenderer', () => {
18 - beforeEach(() => {
19 - jest.resetModules();
20 -
21 - createRenderer = require('react-test-renderer/shallow').createRenderer;
22 - PropTypes = require('prop-types');
23 - React = require('react');
24 - });
17 +const createRenderer = ReactShallowRenderer.createRenderer;
18
19 +describe('ReactShallowRenderer', () => {
20 it('should call all of the legacy lifecycle hooks', () => {
21 const logs = [];
22 const logger = message => () => logs.push(message) || true;
packages/react-test-renderer/src/__tests__/ReactShallowRendererHooks-test.js
+4 -8
@@ -10,16 +10,12 @@
10
11 'use strict';
12
13 -let createRenderer;
14 -let React;
13 +import * as React from 'react';
14 +import ReactShallowRenderer from 'react-test-renderer/shallow';
15
16 -describe('ReactShallowRenderer with hooks', () => {
17 - beforeEach(() => {
18 - jest.resetModules();
19 - createRenderer = require('react-test-renderer/shallow').createRenderer;
20 - React = require('react');
21 - });
16 +const createRenderer = ReactShallowRenderer.createRenderer;
17
18 +describe('ReactShallowRenderer with hooks', () => {
19 it('should work with useState', () => {
20 function SomeComponent({defaultName}) {
21 const [name] = React.useState(defaultName);
packages/react-test-renderer/src/__tests__/ReactShallowRendererMemo-test.js
+5 -11
@@ -10,19 +10,13 @@
10
11 'use strict';
12
13 -let createRenderer;
14 -let PropTypes;
15 -let React;
13 +import * as PropTypes from 'prop-types';
14 +import * as React from 'react';
15 +import ReactShallowRenderer from 'react-test-renderer/shallow';
16
17 -describe('ReactShallowRendererMemo', () => {
18 - beforeEach(() => {
19 - jest.resetModules();
20 -
21 - createRenderer = require('react-test-renderer/shallow').createRenderer;
22 - PropTypes = require('prop-types');
23 - React = require('react');
24 - });
17 +const createRenderer = ReactShallowRenderer.createRenderer;
18
19 +describe('ReactShallowRendererMemo', () => {
20 it('should call all of the legacy lifecycle hooks', () => {
21 const logs = [];
22 const logger = message => () => logs.push(message) || true;