Skip to content
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

Support ForwardRef type of work in TestRenderer #12392

Merged
merged 5 commits into from
Mar 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/react-is/src/ReactIs.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function typeOf(object: any) {
case REACT_STRICT_MODE_TYPE:
return type;
default:
const $$typeofType = type.$$typeof;
const $$typeofType = type && type.$$typeof;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's possible to have a null React element type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not in practice but the ShallowRenderer tests do <NullIdentifer> which was how i was hitting this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see. 👍


switch ($$typeofType) {
case REACT_CONTEXT_TYPE:
Expand Down
17 changes: 4 additions & 13 deletions packages/react-test-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
"description": "React package for snapshot testing.",
"main": "index.js",
"repository": "facebook/react",
"keywords": [
"react",
"react-native",
"react-testing"
],
"keywords": ["react", "react-native", "react-testing"],
"license": "MIT",
"bugs": {
"url": "https://github.com/facebook/react/issues"
Expand All @@ -17,16 +13,11 @@
"dependencies": {
"fbjs": "^0.8.16",
"object-assign": "^4.1.1",
"prop-types": "^15.6.0"
"prop-types": "^15.6.0",
"react-is": "^16.3.0-alpha.2"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this require updates to our release/build script to keep these deps in sync? Needs follow up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i don't know, I was conflating workspaces and lerna, the latter of which handles the updates

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These versions are bumped by our release script manually. It's fine. I'll add it to my list of follow up things.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed via 610df95

},
"peerDependencies": {
"react": "^16.0.0 || 16.3.0-alpha.2"
},
"files": [
"LICENSE",
"README.md",
"index.js",
"shallow.js",
"cjs/"
]
"files": ["LICENSE", "README.md", "index.js", "shallow.js", "cjs/"]
}
7 changes: 5 additions & 2 deletions packages/react-test-renderer/src/ReactShallowRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import React from 'react';
import {isForwardRef} from 'react-is';
import {warnAboutDeprecatedLifecycles} from 'shared/ReactFeatureFlags';
import describeComponentFrame from 'shared/describeComponentFrame';
import getComponentName from 'shared/getComponentName';
Expand Down Expand Up @@ -77,7 +78,7 @@ class ReactShallowRenderer {
element.type,
);
invariant(
typeof element.type === 'function',
isForwardRef(element) || typeof element.type === 'function',
'ReactShallowRenderer render(): Shallow rendering works only with custom ' +
'components, but the provided element type was `%s`.',
Array.isArray(element.type)
Expand All @@ -96,7 +97,9 @@ class ReactShallowRenderer {
if (this._instance) {
this._updateClassComponent(element, this._context);
} else {
if (shouldConstruct(element.type)) {
if (isForwardRef(element)) {
this._rendered = element.type.render(element.props, element.ref);
} else if (shouldConstruct(element.type)) {
this._instance = new element.type(
element.props,
this._context,
Expand Down
3 changes: 3 additions & 0 deletions packages/react-test-renderer/src/ReactTestRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ContextConsumer,
ContextProvider,
Mode,
ForwardRef,
} from 'shared/ReactTypeOfWork';
import invariant from 'fbjs/lib/invariant';

Expand Down Expand Up @@ -372,6 +373,7 @@ function toTree(node: ?Fiber) {
case ContextProvider:
case ContextConsumer:
case Mode:
case ForwardRef:
return childrenToTree(node.child);
default:
invariant(
Expand Down Expand Up @@ -472,6 +474,7 @@ class ReactTestInstance {
case ContextProvider:
case ContextConsumer:
case Mode:
case ForwardRef:
descend = true;
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,28 @@ describe('ReactShallowRenderer', () => {
]);
});

it('should handle ForwardRef', () => {
const testRef = React.createRef();
const SomeComponent = React.forwardRef((props, ref) => {
expect(ref).toEqual(testRef);
return (
<div>
<span className="child1" />
<span className="child2" />
</div>
);
});

const shallowRenderer = createRenderer();
const result = shallowRenderer.render(<SomeComponent ref={testRef} />);

expect(result.type).toBe('div');
expect(result.props.children).toEqual([
<span className="child1" />,
<span className="child2" />,
]);
});

it('should enable shouldComponentUpdate to prevent a re-render', () => {
let renderCounter = 0;
class SimpleComponent extends React.Component {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ describe('ReactTestRenderer', () => {
log.push('Angry render');
throw new Error('Please, do not render me.');
}

componentDidMount() {
log.push('Angry componentDidMount');
}
Expand Down Expand Up @@ -957,4 +958,46 @@ describe('ReactTestRenderer', () => {
}),
);
});

it('supports forwardRef', () => {
const InnerRefed = React.forwardRef((props, ref) => (
<div>
<span ref={ref} />
</div>
));

class App extends React.Component {
render() {
return <InnerRefed ref={r => (this.ref = r)} />;
}
}

const renderer = ReactTestRenderer.create(<App />);
const tree = renderer.toTree();
cleanNodeOrArray(tree);

expect(prettyFormat(tree)).toEqual(
prettyFormat({
instance: null,
nodeType: 'component',
props: {},
rendered: {
instance: null,
nodeType: 'host',
props: {},
rendered: [
{
instance: null,
nodeType: 'host',
props: {},
rendered: [],
type: 'span',
},
],
type: 'div',
},
type: App,
}),
);
});
});
10 changes: 10 additions & 0 deletions scripts/release/build-commands/update-package-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ const update = async ({cwd, dry, packages, version}) => {
if (prerelease) {
json.peerDependencies.react += ` || ${version}`;
}

// Update inter-package dependencies as well.
// e.g. react-test-renderer depends on react-is
if (json.dependencies) {
Object.keys(json.dependencies).forEach(dependency => {
if (packages.indexOf(dependency) >= 0) {
json.dependencies[dependency] = `^${version}`;
}
});
}
}

await writeJson(path, json, {spaces: 2});
Expand Down