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; +} + +
+ Test content +
+`; + exports[`enzyme mount with prop containing css element 1`] = ` .emotion-0 { background-color: blue; @@ -251,17 +264,34 @@ exports[`enzyme mount with styles on top level 1`] = ` background-color: red; } -Array [ - +
-
- Hello -
- , -] + Hello +
+
+`; + +exports[`enzyme parent and child using css property 1`] = ` +.emotion-0 { + background-color: black; +} + +.emotion-1 { + color: white; +} + +
+ Test content +
+
`; exports[`enzyme shallow basic 1`] = ` @@ -343,6 +373,19 @@ exports[`enzyme shallow theming 1`] = `
`; +exports[`enzyme shallow with array of styles as css prop 1`] = ` +.emotion-0 { + background-color: black; + color: white; +} + +
+ Test content +
+`; + exports[`enzyme shallow with prop containing css element 1`] = ` .emotion-0 { background-color: blue; diff --git a/packages/jest/test/react-enzyme.test.js b/packages/jest/test/react-enzyme.test.js index 2b2528948..71bf84492 100644 --- a/packages/jest/test/react-enzyme.test.js +++ b/packages/jest/test/react-enzyme.test.js @@ -3,7 +3,7 @@ import 'test-utils/enzyme-env' import jestInCase from 'jest-in-case' import * as enzyme from 'enzyme' -import { jsx, ThemeProvider } from '@emotion/react' +import { css, jsx, ThemeProvider } from '@emotion/react' import styled from '@emotion/styled' import React from 'react' import toJson from 'enzyme-to-json' @@ -143,6 +143,19 @@ const cases = { ) } }, + 'with array of styles as css prop': { + render() { + const style1 = css` + background-color: black; + ` + + const style2 = css` + color: white; + ` + + return
Test content
+ } + }, theming: { render() { const Button = styled.button` @@ -191,6 +204,25 @@ describe('enzyme', () => { cases ) + test('parent and child using css property', () => { + const parentStyle = css` + background-color: black; + ` + + const childStyle = css` + color: white; + ` + + const wrapper = enzyme.mount( +
+ Test content +
+
+ ) + + expect(wrapper).toMatchSnapshot() + }) + test('with prop containing css element in fragment', () => { const FragmentComponent = () => (