Fix instrumentation in shallow rendering (#6867)

Previously, this threw:

```
 FAIL  src/test/__tests__/ReactTestUtils-test.js (7.291s)
● ReactTestUtils › it can fail context when shallowly rendering
  - TypeError: Cannot read property '_source' of null
        at describeID (src/renderers/shared/devtools/ReactComponentTreeDevtool.js:70:46)
        at Object.ReactComponentTreeDevtool.getStackAddendumByID (src/renderers/shared/devtools/ReactComponentTreeDevtool.js:203:15)
        at checkReactTypeSpec (src/isomorphic/classic/types/checkReactTypeSpec.js:76:58)
        at ReactCompositeComponentMixin._checkContextTypes (src/renderers/shared/stack/reconciler/ReactCompositeComponent.js:668:5)
        at ReactCompositeComponentMixin._processContext (src/renderers/shared/stack/reconciler/ReactCompositeComponent.js:607:14)
        at ReactCompositeComponentMixin.mountComponent (src/renderers/shared/stack/reconciler/ReactCompositeComponent.js:191:30)
        at ReactShallowRenderer._render (src/test/ReactTestUtils.js:483:14)
        at _batchedRender (src/test/ReactTestUtils.js:460:12)
        at ReactDefaultBatchingStrategyTransaction.Mixin.perform (src/shared/utils/Transaction.js:140:20)
        at Object.ReactDefaultBatchingStrategy.batchedUpdates (src/renderers/shared/stack/reconciler/ReactDefaultBatchingStrategy.js:65:19)
        at Object.batchedUpdates (src/renderers/shared/stack/reconciler/ReactUpdates.js:112:20)
        at ReactShallowRenderer.render (src/test/ReactTestUtils.js:453:16)
        at Spec.eval (src/test/__tests__/ReactTestUtils-test.js:289:34)
        at jasmine.Block.execute (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:1067:17)
        at jasmine.Queue.next_ (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2100:31)
        at jasmine.Queue.start (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2053:8)
        at Spec.jasmine.Spec.execute (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2380:14)
        at jasmine.Queue.next_ (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2100:31)
        at onComplete (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2096:18)
        at Spec.jasmine.Spec.finish (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2354:5)
        at eval [as onComplete] (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2381:10)
        at jasmine.Queue.next_ (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2110:14)
        at eval (node_modules/jest-jasmine1/vendor/jasmine-1.3.0.js:2090:18)
        at Timeout.e [as _onTimeout] (node_modules/jsdom/lib/jsdom/browser/Window.js:440:19)
        at tryOnTimeout (timers.js:224:11)
        at Timer.listOnTimeout (timers.js:198:5)
```
This commit is contained in:
Ben Alpert
2016-05-25 09:46:50 -07:00
parent 8d7161e004
commit 510155e027
2 changed files with 37 additions and 3 deletions
+14 -3
View File
@@ -23,6 +23,8 @@ var ReactElement = require('ReactElement');
var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
var ReactCompositeComponent = require('ReactCompositeComponent');
var ReactInstanceMap = require('ReactInstanceMap');
var ReactInstrumentation = require('ReactInstrumentation');
var ReactReconciler = require('ReactReconciler');
var ReactUpdates = require('ReactUpdates');
var SyntheticEvent = require('SyntheticEvent');
@@ -407,7 +409,11 @@ NoopInternalComponent.prototype = {
};
var ShallowComponentWrapper = function(element) {
// TODO: Consolidate with instantiateReactComponent
this._debugID = nextDebugID++;
var displayName = element.type.displayName || element.type.name || 'Unknown';
ReactInstrumentation.debugTool.onSetDisplayName(this._debugID, displayName);
this.construct(element);
};
Object.assign(
@@ -471,16 +477,21 @@ ReactShallowRenderer.prototype.getRenderOutput = function() {
ReactShallowRenderer.prototype.unmount = function() {
if (this._instance) {
this._instance.unmountComponent(false);
ReactReconciler.unmountComponent(this._instance, false);
}
};
ReactShallowRenderer.prototype._render = function(element, transaction, context) {
if (this._instance) {
this._instance.receiveComponent(element, transaction, context);
ReactReconciler.receiveComponent(
this._instance,
element,
transaction,
context
);
} else {
var instance = new ShallowComponentWrapper(element);
instance.mountComponent(transaction, null, null, context);
ReactReconciler.mountComponent(instance, transaction, null, null, context);
this._instance = instance;
}
};
+23
View File
@@ -275,6 +275,29 @@ describe('ReactTestUtils', function() {
expect(result).toEqual(<div>foo</div>);
});
it('can fail context when shallowly rendering', function() {
spyOn(console, 'error');
var SimpleComponent = React.createClass({
contextTypes: {
name: React.PropTypes.string.isRequired,
},
render: function() {
return <div>{this.context.name}</div>;
},
});
var shallowRenderer = ReactTestUtils.createRenderer();
shallowRenderer.render(<SimpleComponent />);
expect(console.error.argsForCall.length).toBe(1);
expect(
console.error.argsForCall[0][0].replace(/\(at .+?:\d+\)/g, '(at **)')
).toBe(
'Warning: Failed context type: Required context `name` was not ' +
'specified in `SimpleComponent`.\n' +
' in SimpleComponent (at **)'
);
});
it('can scryRenderedDOMComponentsWithClass with TextComponent', function() {
var Wrapper = React.createClass({
render: function() {