UNPKG

32.9 kBJavaScriptView Raw
1/** @license React v16.13.1
2 * react-test-renderer-shallow.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var _assign = require('object-assign');
19var React = require('react');
20var reactIs = require('react-is');
21var checkPropTypes = require('prop-types/checkPropTypes');
22
23// Do not require this module directly! Use normal `invariant` calls with
24// template literal strings. The messages will be replaced with error codes
25// during build.
26function formatProdErrorMessage(code) {
27 var url = 'https://reactjs.org/docs/error-decoder.html?invariant=' + code;
28
29 for (var i = 1; i < arguments.length; i++) {
30 url += '&args[]=' + encodeURIComponent(arguments[i]);
31 }
32
33 return "Minified React error #" + code + "; visit " + url + " for the full message or " + 'use the non-minified dev environment for full errors and additional ' + 'helpful warnings.';
34}
35
36var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
37// Current owner and dispatcher used to share the same ref,
38// but PR #14548 split them out to better support the react-debug-tools package.
39
40if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
41 ReactSharedInternals.ReactCurrentDispatcher = {
42 current: null
43 };
44}
45
46if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
47 ReactSharedInternals.ReactCurrentBatchConfig = {
48 suspense: null
49 };
50}
51
52function error(format) {
53 {
54 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
55 args[_key2 - 1] = arguments[_key2];
56 }
57
58 printWarning('error', format, args);
59 }
60}
61
62function printWarning(level, format, args) {
63 // When changing this logic, you might want to also
64 // update consoleWithStackDev.www.js as well.
65 {
66 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
67
68 if (!hasExistingStack) {
69 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
70 var stack = ReactDebugCurrentFrame.getStackAddendum();
71
72 if (stack !== '') {
73 format += '%s';
74 args = args.concat([stack]);
75 }
76 }
77
78 var argsWithFormat = args.map(function (item) {
79 return '' + item;
80 }); // Careful: RN currently depends on this prefix
81
82 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
83 // breaks IE9: https://github.com/facebook/react/issues/13610
84 // eslint-disable-next-line react-internal/no-production-logging
85
86 Function.prototype.apply.call(console[level], console, argsWithFormat);
87
88 try {
89 // --- Welcome to debugging React ---
90 // This error was thrown as a convenience so that you can use this stack
91 // to find the callsite that caused this warning to fire.
92 var argIndex = 0;
93 var message = 'Warning: ' + format.replace(/%s/g, function () {
94 return args[argIndex++];
95 });
96 throw new Error(message);
97 } catch (x) {}
98 }
99}
100
101var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
102function describeComponentFrame (name, source, ownerName) {
103 var sourceInfo = '';
104
105 if (source) {
106 var path = source.fileName;
107 var fileName = path.replace(BEFORE_SLASH_RE, '');
108
109 {
110 // In DEV, include code for a common special case:
111 // prefer "folder/index.js" instead of just "index.js".
112 if (/^index\./.test(fileName)) {
113 var match = path.match(BEFORE_SLASH_RE);
114
115 if (match) {
116 var pathBeforeSlash = match[1];
117
118 if (pathBeforeSlash) {
119 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
120 fileName = folderName + '/' + fileName;
121 }
122 }
123 }
124 }
125
126 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
127 } else if (ownerName) {
128 sourceInfo = ' (created by ' + ownerName + ')';
129 }
130
131 return '\n in ' + (name || 'Unknown') + sourceInfo;
132}
133
134// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
135// nor polyfill, then a plain number is used for performance.
136var hasSymbol = typeof Symbol === 'function' && Symbol.for;
137var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
138var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
139var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
140var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
141var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
142var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
143var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
144var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
145var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
146var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
147var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
148var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
149
150var Resolved = 1;
151function refineResolvedLazyComponent(lazyComponent) {
152 return lazyComponent._status === Resolved ? lazyComponent._result : null;
153}
154
155function getWrappedName(outerType, innerType, wrapperName) {
156 var functionName = innerType.displayName || innerType.name || '';
157 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
158}
159
160function getComponentName(type) {
161 if (type == null) {
162 // Host root, text node or just invalid type.
163 return null;
164 }
165
166 {
167 if (typeof type.tag === 'number') {
168 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
169 }
170 }
171
172 if (typeof type === 'function') {
173 return type.displayName || type.name || null;
174 }
175
176 if (typeof type === 'string') {
177 return type;
178 }
179
180 switch (type) {
181 case REACT_FRAGMENT_TYPE:
182 return 'Fragment';
183
184 case REACT_PORTAL_TYPE:
185 return 'Portal';
186
187 case REACT_PROFILER_TYPE:
188 return "Profiler";
189
190 case REACT_STRICT_MODE_TYPE:
191 return 'StrictMode';
192
193 case REACT_SUSPENSE_TYPE:
194 return 'Suspense';
195
196 case REACT_SUSPENSE_LIST_TYPE:
197 return 'SuspenseList';
198 }
199
200 if (typeof type === 'object') {
201 switch (type.$$typeof) {
202 case REACT_CONTEXT_TYPE:
203 return 'Context.Consumer';
204
205 case REACT_PROVIDER_TYPE:
206 return 'Context.Provider';
207
208 case REACT_FORWARD_REF_TYPE:
209 return getWrappedName(type, type.render, 'ForwardRef');
210
211 case REACT_MEMO_TYPE:
212 return getComponentName(type.type);
213
214 case REACT_BLOCK_TYPE:
215 return getComponentName(type.render);
216
217 case REACT_LAZY_TYPE:
218 {
219 var thenable = type;
220 var resolvedThenable = refineResolvedLazyComponent(thenable);
221
222 if (resolvedThenable) {
223 return getComponentName(resolvedThenable);
224 }
225
226 break;
227 }
228 }
229 }
230
231 return null;
232}
233
234/**
235 * inlined Object.is polyfill to avoid requiring consumers ship their own
236 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
237 */
238function is(x, y) {
239 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
240 ;
241}
242
243var objectIs = typeof Object.is === 'function' ? Object.is : is;
244
245var hasOwnProperty = Object.prototype.hasOwnProperty;
246/**
247 * Performs equality by iterating through keys on an object and returning false
248 * when any key has values which are not strictly equal between the arguments.
249 * Returns true when the values of all keys are strictly equal.
250 */
251
252function shallowEqual(objA, objB) {
253 if (objectIs(objA, objB)) {
254 return true;
255 }
256
257 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
258 return false;
259 }
260
261 var keysA = Object.keys(objA);
262 var keysB = Object.keys(objB);
263
264 if (keysA.length !== keysB.length) {
265 return false;
266 } // Test for A's keys different from B.
267
268
269 for (var i = 0; i < keysA.length; i++) {
270 if (!hasOwnProperty.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
271 return false;
272 }
273 }
274
275 return true;
276}
277
278var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
279var RE_RENDER_LIMIT = 25;
280var emptyObject = {};
281
282{
283 Object.freeze(emptyObject);
284} // In DEV, this is the name of the currently executing primitive hook
285
286
287var currentHookNameInDev;
288
289function areHookInputsEqual(nextDeps, prevDeps) {
290 if (prevDeps === null) {
291 {
292 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
293 }
294
295 return false;
296 }
297
298 {
299 // Don't bother comparing lengths in prod because these arrays should be
300 // passed inline.
301 if (nextDeps.length !== prevDeps.length) {
302 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + nextDeps.join(', ') + "]", "[" + prevDeps.join(', ') + "]");
303 }
304 }
305
306 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
307 if (objectIs(nextDeps[i], prevDeps[i])) {
308 continue;
309 }
310
311 return false;
312 }
313
314 return true;
315}
316
317var Updater =
318/*#__PURE__*/
319function () {
320 function Updater(renderer) {
321 this._renderer = renderer;
322 this._callbacks = [];
323 }
324
325 var _proto = Updater.prototype;
326
327 _proto._enqueueCallback = function _enqueueCallback(callback, publicInstance) {
328 if (typeof callback === 'function' && publicInstance) {
329 this._callbacks.push({
330 callback: callback,
331 publicInstance: publicInstance
332 });
333 }
334 };
335
336 _proto._invokeCallbacks = function _invokeCallbacks() {
337 var callbacks = this._callbacks;
338 this._callbacks = [];
339 callbacks.forEach(function (_ref) {
340 var callback = _ref.callback,
341 publicInstance = _ref.publicInstance;
342 callback.call(publicInstance);
343 });
344 };
345
346 _proto.isMounted = function isMounted(publicInstance) {
347 return !!this._renderer._element;
348 };
349
350 _proto.enqueueForceUpdate = function enqueueForceUpdate(publicInstance, callback, callerName) {
351 this._enqueueCallback(callback, publicInstance);
352
353 this._renderer._forcedUpdate = true;
354
355 this._renderer.render(this._renderer._element, this._renderer._context);
356 };
357
358 _proto.enqueueReplaceState = function enqueueReplaceState(publicInstance, completeState, callback, callerName) {
359 this._enqueueCallback(callback, publicInstance);
360
361 this._renderer._newState = completeState;
362
363 this._renderer.render(this._renderer._element, this._renderer._context);
364 };
365
366 _proto.enqueueSetState = function enqueueSetState(publicInstance, partialState, callback, callerName) {
367 this._enqueueCallback(callback, publicInstance);
368
369 var currentState = this._renderer._newState || publicInstance.state;
370
371 if (typeof partialState === 'function') {
372 partialState = partialState.call(publicInstance, currentState, publicInstance.props);
373 } // Null and undefined are treated as no-ops.
374
375
376 if (partialState === null || partialState === undefined) {
377 return;
378 }
379
380 this._renderer._newState = _assign({}, currentState, {}, partialState);
381
382 this._renderer.render(this._renderer._element, this._renderer._context);
383 };
384
385 return Updater;
386}();
387
388function createHook() {
389 return {
390 memoizedState: null,
391 queue: null,
392 next: null
393 };
394}
395
396function basicStateReducer(state, action) {
397 // $FlowFixMe: Flow doesn't like mixed types
398 return typeof action === 'function' ? action(state) : action;
399}
400
401var ReactShallowRenderer =
402/*#__PURE__*/
403function () {
404 function ReactShallowRenderer() {
405 this._reset();
406 }
407
408 var _proto2 = ReactShallowRenderer.prototype;
409
410 _proto2._reset = function _reset() {
411 this._context = null;
412 this._element = null;
413 this._instance = null;
414 this._newState = null;
415 this._rendered = null;
416 this._rendering = false;
417 this._forcedUpdate = false;
418 this._updater = new Updater(this);
419 this._dispatcher = this._createDispatcher();
420 this._workInProgressHook = null;
421 this._firstWorkInProgressHook = null;
422 this._isReRender = false;
423 this._didScheduleRenderPhaseUpdate = false;
424 this._renderPhaseUpdates = null;
425 this._numberOfReRenders = 0;
426 };
427
428 _proto2._validateCurrentlyRenderingComponent = function _validateCurrentlyRenderingComponent() {
429 if (!(this._rendering && !this._instance)) {
430 {
431 throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." );
432 }
433 }
434 };
435
436 _proto2._createDispatcher = function _createDispatcher() {
437 var _this = this;
438
439 var useReducer = function (reducer, initialArg, init) {
440 _this._validateCurrentlyRenderingComponent();
441
442 _this._createWorkInProgressHook();
443
444 var workInProgressHook = _this._workInProgressHook;
445
446 if (_this._isReRender) {
447 // This is a re-render.
448 var queue = workInProgressHook.queue;
449 var dispatch = queue.dispatch;
450
451 if (_this._numberOfReRenders > 0) {
452 // Apply the new render phase updates to the previous current hook.
453 if (_this._renderPhaseUpdates !== null) {
454 // Render phase updates are stored in a map of queue -> linked list
455 var firstRenderPhaseUpdate = _this._renderPhaseUpdates.get(queue);
456
457 if (firstRenderPhaseUpdate !== undefined) {
458 _this._renderPhaseUpdates.delete(queue);
459
460 var _newState = workInProgressHook.memoizedState;
461 var _update = firstRenderPhaseUpdate;
462
463 do {
464 var action = _update.action;
465 _newState = reducer(_newState, action);
466 _update = _update.next;
467 } while (_update !== null);
468
469 workInProgressHook.memoizedState = _newState;
470 return [_newState, dispatch];
471 }
472 }
473
474 return [workInProgressHook.memoizedState, dispatch];
475 } // Process updates outside of render
476
477
478 var newState = workInProgressHook.memoizedState;
479 var update = queue.first;
480
481 if (update !== null) {
482 do {
483 var _action = update.action;
484 newState = reducer(newState, _action);
485 update = update.next;
486 } while (update !== null);
487
488 queue.first = null;
489 workInProgressHook.memoizedState = newState;
490 }
491
492 return [newState, dispatch];
493 } else {
494 var initialState;
495
496 if (reducer === basicStateReducer) {
497 // Special case for `useState`.
498 initialState = typeof initialArg === 'function' ? initialArg() : initialArg;
499 } else {
500 initialState = init !== undefined ? init(initialArg) : initialArg;
501 }
502
503 workInProgressHook.memoizedState = initialState;
504
505 var _queue = workInProgressHook.queue = {
506 first: null,
507 dispatch: null
508 };
509
510 var _dispatch = _queue.dispatch = _this._dispatchAction.bind(_this, _queue);
511
512 return [workInProgressHook.memoizedState, _dispatch];
513 }
514 };
515
516 var useState = function (initialState) {
517 return useReducer(basicStateReducer, // useReducer has a special case to support lazy useState initializers
518 initialState);
519 };
520
521 var useMemo = function (nextCreate, deps) {
522 _this._validateCurrentlyRenderingComponent();
523
524 _this._createWorkInProgressHook();
525
526 var nextDeps = deps !== undefined ? deps : null;
527
528 if (_this._workInProgressHook !== null && _this._workInProgressHook.memoizedState !== null) {
529 var prevState = _this._workInProgressHook.memoizedState;
530 var prevDeps = prevState[1];
531
532 if (nextDeps !== null) {
533 if (areHookInputsEqual(nextDeps, prevDeps)) {
534 return prevState[0];
535 }
536 }
537 }
538
539 var nextValue = nextCreate();
540 _this._workInProgressHook.memoizedState = [nextValue, nextDeps];
541 return nextValue;
542 };
543
544 var useRef = function (initialValue) {
545 _this._validateCurrentlyRenderingComponent();
546
547 _this._createWorkInProgressHook();
548
549 var previousRef = _this._workInProgressHook.memoizedState;
550
551 if (previousRef === null) {
552 var ref = {
553 current: initialValue
554 };
555
556 {
557 Object.seal(ref);
558 }
559
560 _this._workInProgressHook.memoizedState = ref;
561 return ref;
562 } else {
563 return previousRef;
564 }
565 };
566
567 var readContext = function (context, observedBits) {
568 return context._currentValue;
569 };
570
571 var noOp = function () {
572 _this._validateCurrentlyRenderingComponent();
573 };
574
575 var identity = function (fn) {
576 return fn;
577 };
578
579 var useResponder = function (responder, props) {
580 return {
581 props: props,
582 responder: responder
583 };
584 }; // TODO: implement if we decide to keep the shallow renderer
585
586
587 var useTransition = function (config) {
588 _this._validateCurrentlyRenderingComponent();
589
590 var startTransition = function (callback) {
591 callback();
592 };
593
594 return [startTransition, false];
595 }; // TODO: implement if we decide to keep the shallow renderer
596
597
598 var useDeferredValue = function (value, config) {
599 _this._validateCurrentlyRenderingComponent();
600
601 return value;
602 };
603
604 return {
605 readContext: readContext,
606 useCallback: identity,
607 useContext: function (context) {
608 _this._validateCurrentlyRenderingComponent();
609
610 return readContext(context);
611 },
612 useDebugValue: noOp,
613 useEffect: noOp,
614 useImperativeHandle: noOp,
615 useLayoutEffect: noOp,
616 useMemo: useMemo,
617 useReducer: useReducer,
618 useRef: useRef,
619 useState: useState,
620 useResponder: useResponder,
621 useTransition: useTransition,
622 useDeferredValue: useDeferredValue
623 };
624 };
625
626 _proto2._dispatchAction = function _dispatchAction(queue, action) {
627 if (!(this._numberOfReRenders < RE_RENDER_LIMIT)) {
628 {
629 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
630 }
631 }
632
633 if (this._rendering) {
634 // This is a render phase update. Stash it in a lazily-created map of
635 // queue -> linked list of updates. After this render pass, we'll restart
636 // and apply the stashed updates on top of the work-in-progress hook.
637 this._didScheduleRenderPhaseUpdate = true;
638 var update = {
639 action: action,
640 next: null
641 };
642 var renderPhaseUpdates = this._renderPhaseUpdates;
643
644 if (renderPhaseUpdates === null) {
645 this._renderPhaseUpdates = renderPhaseUpdates = new Map();
646 }
647
648 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
649
650 if (firstRenderPhaseUpdate === undefined) {
651 renderPhaseUpdates.set(queue, update);
652 } else {
653 // Append the update to the end of the list.
654 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
655
656 while (lastRenderPhaseUpdate.next !== null) {
657 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
658 }
659
660 lastRenderPhaseUpdate.next = update;
661 }
662 } else {
663 var _update2 = {
664 action: action,
665 next: null
666 }; // Append the update to the end of the list.
667
668 var last = queue.first;
669
670 if (last === null) {
671 queue.first = _update2;
672 } else {
673 while (last.next !== null) {
674 last = last.next;
675 }
676
677 last.next = _update2;
678 } // Re-render now.
679
680
681 this.render(this._element, this._context);
682 }
683 };
684
685 _proto2._createWorkInProgressHook = function _createWorkInProgressHook() {
686 if (this._workInProgressHook === null) {
687 // This is the first hook in the list
688 if (this._firstWorkInProgressHook === null) {
689 this._isReRender = false;
690 this._firstWorkInProgressHook = this._workInProgressHook = createHook();
691 } else {
692 // There's already a work-in-progress. Reuse it.
693 this._isReRender = true;
694 this._workInProgressHook = this._firstWorkInProgressHook;
695 }
696 } else {
697 if (this._workInProgressHook.next === null) {
698 this._isReRender = false; // Append to the end of the list
699
700 this._workInProgressHook = this._workInProgressHook.next = createHook();
701 } else {
702 // There's already a work-in-progress. Reuse it.
703 this._isReRender = true;
704 this._workInProgressHook = this._workInProgressHook.next;
705 }
706 }
707
708 return this._workInProgressHook;
709 };
710
711 _proto2._finishHooks = function _finishHooks(element, context) {
712 if (this._didScheduleRenderPhaseUpdate) {
713 // Updates were scheduled during the render phase. They are stored in
714 // the `renderPhaseUpdates` map. Call the component again, reusing the
715 // work-in-progress hooks and applying the additional updates on top. Keep
716 // restarting until no more updates are scheduled.
717 this._didScheduleRenderPhaseUpdate = false;
718 this._numberOfReRenders += 1; // Start over from the beginning of the list
719
720 this._workInProgressHook = null;
721 this._rendering = false;
722 this.render(element, context);
723 } else {
724 this._workInProgressHook = null;
725 this._renderPhaseUpdates = null;
726 this._numberOfReRenders = 0;
727 }
728 };
729
730 _proto2.getMountedInstance = function getMountedInstance() {
731 return this._instance;
732 };
733
734 _proto2.getRenderOutput = function getRenderOutput() {
735 return this._rendered;
736 };
737
738 _proto2.render = function render(element) {
739 var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : emptyObject;
740
741 if (!React.isValidElement(element)) {
742 {
743 throw Error( "ReactShallowRenderer render(): Invalid component element." + (typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') );
744 }
745 }
746
747 element = element; // Show a special message for host elements since it's a common case.
748
749 if (!(typeof element.type !== 'string')) {
750 {
751 throw Error( "ReactShallowRenderer render(): Shallow rendering works only with custom components, not primitives (" + element.type + "). Instead of calling `.render(el)` and inspecting the rendered output, look at `el.props` directly instead." );
752 }
753 }
754
755 if (!(reactIs.isForwardRef(element) || typeof element.type === 'function' || reactIs.isMemo(element))) {
756 {
757 throw Error( "ReactShallowRenderer render(): Shallow rendering works only with custom components, but the provided element type was `" + (Array.isArray(element.type) ? 'array' : element.type === null ? 'null' : typeof element.type) + "`." );
758 }
759 }
760
761 if (this._rendering) {
762 return;
763 }
764
765 if (this._element != null && this._element.type !== element.type) {
766 this._reset();
767 }
768
769 var elementType = reactIs.isMemo(element) ? element.type.type : element.type;
770 var previousElement = this._element;
771 this._rendering = true;
772 this._element = element;
773 this._context = getMaskedContext(elementType.contextTypes, context); // Inner memo component props aren't currently validated in createElement.
774
775 if (reactIs.isMemo(element) && elementType.propTypes) {
776 currentlyValidatingElement = element;
777 checkPropTypes(elementType.propTypes, element.props, 'prop', getComponentName(elementType), getStackAddendum);
778 }
779
780 if (this._instance) {
781 this._updateClassComponent(elementType, element, this._context);
782 } else {
783 if (shouldConstruct(elementType)) {
784 this._instance = new elementType(element.props, this._context, this._updater);
785
786 if (typeof elementType.getDerivedStateFromProps === 'function') {
787 var partialState = elementType.getDerivedStateFromProps.call(null, element.props, this._instance.state);
788
789 if (partialState != null) {
790 this._instance.state = _assign({}, this._instance.state, partialState);
791 }
792 }
793
794 if (elementType.contextTypes) {
795 currentlyValidatingElement = element;
796 checkPropTypes(elementType.contextTypes, this._context, 'context', getName(elementType, this._instance), getStackAddendum);
797 currentlyValidatingElement = null;
798 }
799
800 this._mountClassComponent(elementType, element, this._context);
801 } else {
802 var shouldRender = true;
803
804 if (reactIs.isMemo(element) && previousElement !== null) {
805 // This is a Memo component that is being re-rendered.
806 var compare = element.type.compare || shallowEqual;
807
808 if (compare(previousElement.props, element.props)) {
809 shouldRender = false;
810 }
811 }
812
813 if (shouldRender) {
814 var prevDispatcher = ReactCurrentDispatcher.current;
815 ReactCurrentDispatcher.current = this._dispatcher;
816
817 try {
818 // elementType could still be a ForwardRef if it was
819 // nested inside Memo.
820 if (elementType.$$typeof === reactIs.ForwardRef) {
821 if (!(typeof elementType.render === 'function')) {
822 {
823 throw Error(true ? "forwardRef requires a render function but was given " + typeof elementType.render + "." : formatProdErrorMessage(322, typeof elementType.render));
824 }
825 }
826
827 this._rendered = elementType.render.call(undefined, element.props, element.ref);
828 } else {
829 this._rendered = elementType(element.props, this._context);
830 }
831 } finally {
832 ReactCurrentDispatcher.current = prevDispatcher;
833 }
834
835 this._finishHooks(element, context);
836 }
837 }
838 }
839
840 this._rendering = false;
841
842 this._updater._invokeCallbacks();
843
844 return this.getRenderOutput();
845 };
846
847 _proto2.unmount = function unmount() {
848 if (this._instance) {
849 if (typeof this._instance.componentWillUnmount === 'function') {
850 this._instance.componentWillUnmount();
851 }
852 }
853
854 this._reset();
855 };
856
857 _proto2._mountClassComponent = function _mountClassComponent(elementType, element, context) {
858 this._instance.context = context;
859 this._instance.props = element.props;
860 this._instance.state = this._instance.state || null;
861 this._instance.updater = this._updater;
862
863 if (typeof this._instance.UNSAFE_componentWillMount === 'function' || typeof this._instance.componentWillMount === 'function') {
864 var beforeState = this._newState; // In order to support react-lifecycles-compat polyfilled components,
865 // Unsafe lifecycles should not be invoked for components using the new APIs.
866
867 if (typeof elementType.getDerivedStateFromProps !== 'function' && typeof this._instance.getSnapshotBeforeUpdate !== 'function') {
868 if (typeof this._instance.componentWillMount === 'function') {
869 this._instance.componentWillMount();
870 }
871
872 if (typeof this._instance.UNSAFE_componentWillMount === 'function') {
873 this._instance.UNSAFE_componentWillMount();
874 }
875 } // setState may have been called during cWM
876
877
878 if (beforeState !== this._newState) {
879 this._instance.state = this._newState || emptyObject;
880 }
881 }
882
883 this._rendered = this._instance.render(); // Intentionally do not call componentDidMount()
884 // because DOM refs are not available.
885 };
886
887 _proto2._updateClassComponent = function _updateClassComponent(elementType, element, context) {
888 var props = element.props;
889 var oldState = this._instance.state || emptyObject;
890 var oldProps = this._instance.props;
891
892 if (oldProps !== props) {
893 // In order to support react-lifecycles-compat polyfilled components,
894 // Unsafe lifecycles should not be invoked for components using the new APIs.
895 if (typeof elementType.getDerivedStateFromProps !== 'function' && typeof this._instance.getSnapshotBeforeUpdate !== 'function') {
896 if (typeof this._instance.componentWillReceiveProps === 'function') {
897 this._instance.componentWillReceiveProps(props, context);
898 }
899
900 if (typeof this._instance.UNSAFE_componentWillReceiveProps === 'function') {
901 this._instance.UNSAFE_componentWillReceiveProps(props, context);
902 }
903 }
904 } // Read state after cWRP in case it calls setState
905
906
907 var state = this._newState || oldState;
908
909 if (typeof elementType.getDerivedStateFromProps === 'function') {
910 var partialState = elementType.getDerivedStateFromProps.call(null, props, state);
911
912 if (partialState != null) {
913 state = _assign({}, state, partialState);
914 }
915 }
916
917 var shouldUpdate = true;
918
919 if (this._forcedUpdate) {
920 shouldUpdate = true;
921 this._forcedUpdate = false;
922 } else if (typeof this._instance.shouldComponentUpdate === 'function') {
923 shouldUpdate = !!this._instance.shouldComponentUpdate(props, state, context);
924 } else if (elementType.prototype && elementType.prototype.isPureReactComponent) {
925 shouldUpdate = !shallowEqual(oldProps, props) || !shallowEqual(oldState, state);
926 }
927
928 if (shouldUpdate) {
929 // In order to support react-lifecycles-compat polyfilled components,
930 // Unsafe lifecycles should not be invoked for components using the new APIs.
931 if (typeof elementType.getDerivedStateFromProps !== 'function' && typeof this._instance.getSnapshotBeforeUpdate !== 'function') {
932 if (typeof this._instance.componentWillUpdate === 'function') {
933 this._instance.componentWillUpdate(props, state, context);
934 }
935
936 if (typeof this._instance.UNSAFE_componentWillUpdate === 'function') {
937 this._instance.UNSAFE_componentWillUpdate(props, state, context);
938 }
939 }
940 }
941
942 this._instance.context = context;
943 this._instance.props = props;
944 this._instance.state = state;
945 this._newState = null;
946
947 if (shouldUpdate) {
948 this._rendered = this._instance.render();
949 } // Intentionally do not call componentDidUpdate()
950 // because DOM refs are not available.
951
952 };
953
954 return ReactShallowRenderer;
955}();
956
957ReactShallowRenderer.createRenderer = function () {
958 return new ReactShallowRenderer();
959};
960
961var currentlyValidatingElement = null;
962
963function getDisplayName(element) {
964 if (element == null) {
965 return '#empty';
966 } else if (typeof element === 'string' || typeof element === 'number') {
967 return '#text';
968 } else if (typeof element.type === 'string') {
969 return element.type;
970 } else {
971 var elementType = reactIs.isMemo(element) ? element.type.type : element.type;
972 return elementType.displayName || elementType.name || 'Unknown';
973 }
974}
975
976function getStackAddendum() {
977 var stack = '';
978
979 if (currentlyValidatingElement) {
980 var name = getDisplayName(currentlyValidatingElement);
981 var owner = currentlyValidatingElement._owner;
982 stack += describeComponentFrame(name, currentlyValidatingElement._source, owner && getComponentName(owner.type));
983 }
984
985 return stack;
986}
987
988function getName(type, instance) {
989 var constructor = instance && instance.constructor;
990 return type.displayName || constructor && constructor.displayName || type.name || constructor && constructor.name || null;
991}
992
993function shouldConstruct(Component) {
994 return !!(Component.prototype && Component.prototype.isReactComponent);
995}
996
997function getMaskedContext(contextTypes, unmaskedContext) {
998 if (!contextTypes || !unmaskedContext) {
999 return emptyObject;
1000 }
1001
1002 var context = {};
1003
1004 for (var key in contextTypes) {
1005 context[key] = unmaskedContext[key];
1006 }
1007
1008 return context;
1009}
1010
1011// TODO: decide on the top-level export form.
1012// This is hacky but makes it work with both Rollup and Jest.
1013
1014
1015var shallow = ReactShallowRenderer.default || ReactShallowRenderer;
1016
1017module.exports = shallow;
1018 })();
1019}