Skip to content

Commit

Permalink
Implement optional mockConfig and getMockRef
Browse files Browse the repository at this point in the history
  • Loading branch information
Brandon Dail authored and Brandon Dail committed Sep 2, 2016
1 parent 4c365ea commit d7bd655
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
27 changes: 21 additions & 6 deletions src/renderers/testing/ReactTestMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var getHostComponentFromComposite = require('getHostComponentFromComposite');
var instantiateReactComponent = require('instantiateReactComponent');
var invariant = require('invariant');

type TestRendererMockConfig = {
getMockRef: (element: ReactElement) => Object,
};

/**
* Temporary (?) hack so that we can store all top-level pending updates on
* composites instead of having to worry about different types of components
Expand All @@ -45,7 +49,9 @@ TopLevelWrapper.isReactTopLevelWrapper = true;
*/
function mountComponentIntoNode(
componentInstance,
transaction) {
transaction,
mockConfig,
) {
var image = ReactReconciler.mountComponent(
componentInstance,
transaction,
Expand All @@ -54,6 +60,9 @@ function mountComponentIntoNode(
emptyObject
);
componentInstance._renderedComponent._topLevelWrapper = componentInstance;
if (mockConfig) {
componentInstance._renderedComponent._mockConfig = mockConfig;
}
return image;
}

Expand All @@ -65,13 +74,16 @@ function mountComponentIntoNode(
* @param {number} containerTag container element to mount into.
*/
function batchedMountComponentIntoNode(
componentInstance) {
componentInstance,
mockConfig,
) {
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
var image = transaction.perform(
mountComponentIntoNode,
null,
componentInstance,
transaction
transaction,
mockConfig,
);
ReactUpdates.ReactReconcileTransaction.release(transaction);
return image;
Expand Down Expand Up @@ -135,22 +147,25 @@ ReactTestInstance.prototype.toJSON = function() {
var ReactTestMount = {

render: function(
nextElement: ReactElement<any>
nextElement: ReactElement<any>,
mockConfig: TestRendererMockConfig,
): ReactTestInstance {
var nextWrappedElement = React.createElement(
TopLevelWrapper,
{ child: nextElement }
{ child: nextElement },
);

var instance = instantiateReactComponent(nextWrappedElement, false);

// The initial render is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidMount, will be batched
// according to the current batching strategy.
//

ReactUpdates.batchedUpdates(
batchedMountComponentIntoNode,
instance
instance,
mockConfig,
);
return new ReactTestInstance(instance);
},
Expand Down
13 changes: 9 additions & 4 deletions src/renderers/testing/ReactTestRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ var ReactTestComponent = function(element) {
this._currentElement = element;
this._renderedChildren = null;
this._topLevelWrapper = null;
this._mockConfig = null;
};
ReactTestComponent.prototype.mountComponent = function(
transaction,
Expand All @@ -62,9 +63,13 @@ ReactTestComponent.prototype.receiveComponent = function(
};
ReactTestComponent.prototype.getHostNode = function() {};
ReactTestComponent.prototype.getPublicInstance = function() {
// I can't say this makes a ton of sense but it seems better than throwing.
// Maybe we'll revise later if someone has a good use case.
return null;
if (this._mockConfig) {
var { getMockRef } = this._mockConfig;
if (getMockRef) {
return getMockRef(this._currentElement);
}
}
return {};
};
ReactTestComponent.prototype.unmountComponent = function() {};
ReactTestComponent.prototype.toJSON = function() {
Expand Down Expand Up @@ -134,9 +139,9 @@ ReactComponentEnvironment.injection.injectEnvironment({
replaceNodeWithMarkup: function() {},
});


var ReactTestRenderer = {
create: ReactTestMount.render,

/* eslint-disable camelcase */
unstable_batchedUpdates: ReactUpdates.batchedUpdates,
/* eslint-enable camelcase */
Expand Down
19 changes: 18 additions & 1 deletion src/renderers/testing/__tests__/ReactTestRenderer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,24 @@ describe('ReactTestRenderer', function() {
it('gives a ref to native components', function() {
var log = [];
ReactTestRenderer.create(<div ref={(r) => log.push(r)} />);
expect(log).toEqual([null]);
expect(log).toEqual([{}]);
});

it('allows an optional getMockRef function', function() {
var mockDOMInstance = { focus: () => {} };
var log = [];
ReactTestRenderer.create(
<div ref={(r) => log.push(r)} />,
{
getMockRef: instance => {
return mockDOMInstance;
},
}
);
ReactTestRenderer.create(
<div ref={(r) => log.push(r)} />,
);
expect(log).toEqual([mockDOMInstance, {}]);
});

it('supports error boundaries', function() {
Expand Down

0 comments on commit d7bd655

Please sign in to comment.