diff --git a/.changeset/two-laws-provide.md b/.changeset/two-laws-provide.md new file mode 100644 index 000000000..6ecb3a7e1 --- /dev/null +++ b/.changeset/two-laws-provide.md @@ -0,0 +1,5 @@ +--- +'@emotion/jest': minor +--- + +Fixed an issue with Enzyme snapshots for components using an array as the `css` prop - those should be printed OK now. diff --git a/packages/jest/src/create-serializer.js b/packages/jest/src/create-serializer.js index 2799a8770..3b0275ffa 100644 --- a/packages/jest/src/create-serializer.js +++ b/packages/jest/src/create-serializer.js @@ -89,12 +89,34 @@ function filterEmotionProps(props = {}) { return rest } -function isShallowEnzymeElement(element: any, classNames: string[]) { +function getLabelsFromCss(css) { + const getLabel = style => { + const styleString = style.styles || style + const matches = styleString.match(/.*;label:([^;]+);/) + return matches && matches[1] + } + return (Array.isArray(css) ? css.map(getLabel) : [getLabel(css)]).filter( + Boolean + ) +} + +function isShallowEnzymeElement( + element: any, + keys: string[], + labels: string[] +) { const delimiter = ' ' const childClassNames = flatMap(element.children || [], ({ props = {} }) => (props.className || '').split(delimiter) ).filter(Boolean) - return !hasIntersection(classNames, childClassNames) + return !childClassNames.some(className => { + const [childKey, hash, ...childLabels] = className.split('-') + return ( + keys.includes(childKey) && + childLabels.length && + childLabels.every(childLabel => labels.includes(childLabel)) + ) + }) } const createConvertEmotionElements = (keys: string[], printer: *) => ( @@ -104,13 +126,20 @@ const createConvertEmotionElements = (keys: string[], printer: *) => ( return node } if (isEmotionCssPropEnzymeElement(node)) { - const cssClassNames = (node.props.css.name || '').split(' ') + const labels = getLabelsFromCss(node.props.css) + const cssName = Array.isArray(node.props.css) + ? node.props.css + .map(({ name }) => name) + .filter(Boolean) + .join(' ') + : node.props.css.name + const cssClassNames = (cssName || '').split(' ') const expectedClassNames = flatMap(cssClassNames, cssClassName => keys.map(key => `${key}-${cssClassName}`) ) // if this is a shallow element, we need to manufacture the className // since the underlying component is not rendered. - if (isShallowEnzymeElement(node, expectedClassNames)) { + if (isShallowEnzymeElement(node, keys, labels)) { const className = [node.props.className] .concat(expectedClassNames) .filter(Boolean) @@ -128,7 +157,7 @@ const createConvertEmotionElements = (keys: string[], printer: *) => ( type } } else { - return node.children + return node.children[0] } } if (isEmotionCssPropElementType(node)) { diff --git a/packages/jest/test/__snapshots__/react-enzyme.test.js.snap b/packages/jest/test/__snapshots__/react-enzyme.test.js.snap index 92e069411..b75a3c0c9 100644 --- a/packages/jest/test/__snapshots__/react-enzyme.test.js.snap +++ b/packages/jest/test/__snapshots__/react-enzyme.test.js.snap @@ -114,6 +114,19 @@ exports[`enzyme mount theming 1`] = ` `; +exports[`enzyme mount with array of styles as css prop 1`] = ` +.emotion-0 { + background-color: black; + color: white; +} + +