UNPKG

5.93 kBJavaScriptView Raw
1/**
2 * Copyright 2013-present, Facebook, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
8 *
9 */
10
11'use strict';
12
13var _prodInvariant = require('./reactProdInvariant'),
14 _assign = require('object-assign');
15
16function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
17
18var React = require('react/lib/React');
19var ReactCompositeComponent = require('./ReactCompositeComponent');
20var ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy');
21var ReactReconciler = require('./ReactReconciler');
22var ReactReconcileTransaction = require('./ReactReconcileTransaction');
23var ReactUpdates = require('./ReactUpdates');
24
25var emptyObject = require('fbjs/lib/emptyObject');
26var getNextDebugID = require('react/lib/getNextDebugID');
27var invariant = require('fbjs/lib/invariant');
28
29function injectDefaults() {
30 ReactUpdates.injection.injectReconcileTransaction(ReactReconcileTransaction);
31 ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
32}
33
34var NoopInternalComponent = function () {
35 function NoopInternalComponent(element) {
36 _classCallCheck(this, NoopInternalComponent);
37
38 this._renderedOutput = element;
39 this._currentElement = element;
40
41 if (process.env.NODE_ENV !== 'production') {
42 this._debugID = getNextDebugID();
43 }
44 }
45
46 NoopInternalComponent.prototype.mountComponent = function mountComponent() {};
47
48 NoopInternalComponent.prototype.receiveComponent = function receiveComponent(element) {
49 this._renderedOutput = element;
50 this._currentElement = element;
51 };
52
53 NoopInternalComponent.prototype.unmountComponent = function unmountComponent() {};
54
55 NoopInternalComponent.prototype.getHostNode = function getHostNode() {
56 return undefined;
57 };
58
59 NoopInternalComponent.prototype.getPublicInstance = function getPublicInstance() {
60 return null;
61 };
62
63 return NoopInternalComponent;
64}();
65
66var ShallowComponentWrapper = function (element) {
67 // TODO: Consolidate with instantiateReactComponent
68 if (process.env.NODE_ENV !== 'production') {
69 this._debugID = getNextDebugID();
70 }
71
72 this.construct(element);
73};
74_assign(ShallowComponentWrapper.prototype, ReactCompositeComponent, {
75 _constructComponent: ReactCompositeComponent._constructComponentWithoutOwner,
76 _instantiateReactComponent: function (element) {
77 return new NoopInternalComponent(element);
78 },
79 _replaceNodeWithMarkup: function () {},
80 _renderValidatedComponent: ReactCompositeComponent._renderValidatedComponentWithoutOwnerOrContext
81});
82
83function _batchedRender(renderer, element, context) {
84 var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(true);
85 renderer._render(element, transaction, context);
86 ReactUpdates.ReactReconcileTransaction.release(transaction);
87}
88
89var ReactShallowRenderer = function () {
90 function ReactShallowRenderer() {
91 _classCallCheck(this, ReactShallowRenderer);
92
93 this._instance = null;
94 }
95
96 ReactShallowRenderer.prototype.getMountedInstance = function getMountedInstance() {
97 return this._instance ? this._instance._instance : null;
98 };
99
100 ReactShallowRenderer.prototype.render = function render(element, context) {
101 // Ensure we've done the default injections. This might not be true in the
102 // case of a simple test that only requires React and the TestUtils in
103 // conjunction with an inline-requires transform.
104 injectDefaults();
105
106 !React.isValidElement(element) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Invalid component element.%s', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : _prodInvariant('12', typeof element === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' : '') : void 0;
107 !(typeof element.type !== 'string') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactShallowRenderer render(): Shallow rendering works only with custom components, not primitives (%s). Instead of calling `.render(el)` and inspecting the rendered output, look at `el.props` directly instead.', element.type) : _prodInvariant('13', element.type) : void 0;
108
109 if (!context) {
110 context = emptyObject;
111 }
112 ReactUpdates.batchedUpdates(_batchedRender, this, element, context);
113
114 return this.getRenderOutput();
115 };
116
117 ReactShallowRenderer.prototype.getRenderOutput = function getRenderOutput() {
118 return this._instance && this._instance._renderedComponent && this._instance._renderedComponent._renderedOutput || null;
119 };
120
121 ReactShallowRenderer.prototype.unmount = function unmount() {
122 if (this._instance) {
123 ReactReconciler.unmountComponent(this._instance, false);
124 }
125 };
126
127 ReactShallowRenderer.prototype.unstable_batchedUpdates = function unstable_batchedUpdates(callback, bookkeeping) {
128 // This is used by Enzyme for fake-simulating events in shallow mode.
129 injectDefaults();
130 return ReactUpdates.batchedUpdates(callback, bookkeeping);
131 };
132
133 ReactShallowRenderer.prototype._render = function _render(element, transaction, context) {
134 if (this._instance) {
135 ReactReconciler.receiveComponent(this._instance, element, transaction, context);
136 } else {
137 var instance = new ShallowComponentWrapper(element);
138 ReactReconciler.mountComponent(instance, transaction, null, null, context, 0);
139 this._instance = instance;
140 }
141 };
142
143 return ReactShallowRenderer;
144}();
145
146ReactShallowRenderer.createRenderer = function () {
147 return new ReactShallowRenderer();
148};
149
150module.exports = ReactShallowRenderer;
\No newline at end of file