Skip to content

Commit

Permalink
Support forwardRef and Context in pretty-format (#6093)
Browse files Browse the repository at this point in the history
  • Loading branch information
jkimbo authored and mjesun committed May 2, 2018
1 parent a9e4172 commit cf2b9e8
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@
([#5720](https://github.com/facebook/jest/pull/5720))
* `[pretty-format]` Handle React fragments better
([#5816](https://github.com/facebook/jest/pull/5816))
* `[pretty-format]` Handle formatting of `React.forwardRef` and `Context`
components ([#6093](https://github.com/facebook/jest/pull/6093))
* `[jest-cli]` Switch collectCoverageFrom back to a string
([#5914](https://github.com/facebook/jest/pull/5914))
* `[jest-regex-util]` Fix handling regex symbols in tests path on Windows
Expand Down
35 changes: 35 additions & 0 deletions packages/pretty-format/src/__tests__/react.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -717,3 +717,38 @@ test('ReactTestComponent plugin highlights syntax with color from theme option',
}),
).toMatchSnapshot();
});

test('supports forwardRef with a child', () => {
function Cat(props) {
return React.createElement('div', props, props.children);
}

expect(
// $FlowFixMe - https://github.com/facebook/flow/issues/6103
formatElement(React.createElement(React.forwardRef(Cat), null, 'mouse')),
).toEqual('<ForwardRef(Cat)>\n mouse\n</ForwardRef(Cat)>');
});

test('supports context Provider with a child', () => {
const {Provider} = React.createContext('test');

expect(
formatElement(
React.createElement(Provider, {value: 'test-value'}, 'child'),
),
).toEqual(
'<Context.Provider\n value="test-value"\n>\n child\n</Context.Provider>',
);
});

test('supports context Consumer with a child', () => {
const {Consumer} = React.createContext('test');

expect(
formatElement(
React.createElement(Consumer, null, () =>
React.createElement('div', null, 'child'),
),
),
).toEqual('<Context.Consumer>\n [Function anonymous]\n</Context.Consumer>');
});
34 changes: 23 additions & 11 deletions packages/pretty-format/src/plugins/react_element.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
const elementSymbol = Symbol.for('react.element');
const fragmentSymbol = Symbol.for('react.fragment');
const forwardRefSymbol = Symbol.for('react.forward_ref');
const providerSymbol = Symbol.for('react.provider');
const contextSymbol = Symbol.for('react.context');

// Given element.props.children, or subtree during recursive traversal,
// return flattened array of children.
Expand All @@ -34,22 +36,32 @@ const getChildren = (arg, children = []) => {
};

const getType = element => {
if (typeof element.type === 'string') {
return element.type;
const type = element.type;
if (typeof type === 'string') {
return type;
}
if (typeof element.type === 'function') {
return element.type.displayName || element.type.name || 'Unknown';
if (typeof type === 'function') {
return type.displayName || type.name || 'Unknown';
}
if (element.type === fragmentSymbol) {
if (type === fragmentSymbol) {
return 'React.Fragment';
}
if (element.type === forwardRefSymbol) {
const functionName =
element.type.render.displayName || element.type.render.name || '';
if (typeof type === 'object' && type !== null) {
if (type.$$typeof === providerSymbol) {
return 'Context.Provider';
}

return functionName !== ''
? 'ForwardRef(' + functionName + ')'
: 'ForwardRef';
if (type.$$typeof === contextSymbol) {
return 'Context.Consumer';
}

if (type.$$typeof === forwardRefSymbol) {
const functionName = type.render.displayName || type.render.name || '';

return functionName !== ''
? 'ForwardRef(' + functionName + ')'
: 'ForwardRef';
}
}
return 'UNDEFINED';
};
Expand Down

0 comments on commit cf2b9e8

Please sign in to comment.