-
Notifications
You must be signed in to change notification settings - Fork 47k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement createNodeMock for ReactTestRenderer #7649
Changes from 1 commit
d7bd655
f24dbcd
cf63a1b
86f13a1
5c73a3d
4b1f273
ff6171d
b27a7f8
839e353
1145e6c
c33d571
3e5ca78
4f18142
780b641
eb6b129
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -45,7 +49,9 @@ TopLevelWrapper.isReactTopLevelWrapper = true; | |
*/ | ||
function mountComponentIntoNode( | ||
componentInstance, | ||
transaction) { | ||
transaction, | ||
mockConfig, | ||
) { | ||
var image = ReactReconciler.mountComponent( | ||
componentInstance, | ||
transaction, | ||
|
@@ -54,6 +60,9 @@ function mountComponentIntoNode( | |
emptyObject | ||
); | ||
componentInstance._renderedComponent._topLevelWrapper = componentInstance; | ||
if (mockConfig) { | ||
componentInstance._renderedComponent._mockConfig = mockConfig; | ||
} | ||
return image; | ||
} | ||
|
||
|
@@ -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; | ||
|
@@ -135,22 +147,25 @@ ReactTestInstance.prototype.toJSON = function() { | |
var ReactTestMount = { | ||
|
||
render: function( | ||
nextElement: ReactElement<any> | ||
nextElement: ReactElement<any>, | ||
mockConfig: TestRendererMockConfig, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably |
||
): ReactTestInstance { | ||
var nextWrappedElement = React.createElement( | ||
TopLevelWrapper, | ||
{ child: nextElement } | ||
{ child: nextElement }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: no need for extra spacing. |
||
); | ||
|
||
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. | ||
// | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: extra line |
||
|
||
ReactUpdates.batchedUpdates( | ||
batchedMountComponentIntoNode, | ||
instance | ||
instance, | ||
mockConfig, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we pass default here instead, as this is the first place where it appears? |
||
); | ||
return new ReactTestInstance(instance); | ||
}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we make a default There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we have a default There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, default impl is what I meant. |
||
} | ||
} | ||
return {}; | ||
}; | ||
ReactTestComponent.prototype.unmountComponent = function() {}; | ||
ReactTestComponent.prototype.toJSON = function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here |
||
|
@@ -134,9 +139,9 @@ ReactComponentEnvironment.injection.injectEnvironment({ | |
replaceNodeWithMarkup: function() {}, | ||
}); | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let’s remove this newline |
||
var ReactTestRenderer = { | ||
create: ReactTestMount.render, | ||
|
||
/* eslint-disable camelcase */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And keep this one, so the diff is smaller. In general better not to formatting changes to code you didn’t directly touch unless it’s horribly formatted |
||
unstable_batchedUpdates: ReactUpdates.batchedUpdates, | ||
/* eslint-enable camelcase */ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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([{}]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per @spicyj, let’s keep |
||
}); | ||
|
||
it('allows an optional getMockRef function', function() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let’s also test that we receive the correct element. |
||
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() { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how this would be typed, is there a better way to type an object that looks like a DOM node?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me.