import { transform as transformCode } from '../../test-utils'; describe('css prop object literal', () => { const transform = (code: string) => transformCode(code, { pretty: false }); it('should inline the variable when it is a constant in string css', () => { const actual = transform(` import '@compiled/react'; const bg = 'blue'; let cl = 'red'; cl = 'red';
hello world
`); expect(actual).toInclude('{background-color:blue'); expect(actual).toInclude('{color:var(--_bo0rwa)'); expect(actual).toInclude('text-decoration-line:none'); expect(actual).toInclude('style={{"--_bo0rwa":ix(cl)}}'); }); it('should inline constant variable', () => { const actual = transform(` import '@compiled/react'; const fontSize = 20;
hello world
`); expect(actual).toInclude('{font-size:20px}'); }); it('should inline constant object property value', () => { const actual = transform(` import '@compiled/react'; const colors = { error: 'red' };
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should inline nested constant object property value', () => { const actual = transform(` import '@compiled/react'; const theme = { colors: { light: { primary: '#fff', } } };
hello world
`); expect(actual).toInclude('{color:#fff}'); }); it('should persist suffix of dynamic property value from objects into inline styles', () => { const actual = transform(` import '@compiled/react'; let heading = { depth: 20 }; heading = {};
hello world
`); expect(actual).toInclude('{margin-left:var(--_5un9uz)}'); expect(actual).toInclude('{color:red}'); expect(actual).toInclude('style={{"--_5un9uz":ix(heading.depth,"rem")}}'); }); it('should persist prefix of dynamic property value into inline styles', () => { const actual = transform(` import '@compiled/react'; let fontSize = 20; fontSize = 20;
hello world
`); expect(actual).toInclude('{font-size:calc(100% - var(--_1j2e0s2))}'); expect(actual).toInclude('{color:red}'); expect(actual).toInclude('style={{"--_1j2e0s2":ix(fontSize,"px")}}'); }); it('should move prefix of grouped interpolation into inline styles', () => { const actual = transform(` import '@compiled/react'; let heading = header || { depth: 20 };
hello world
`); expect(actual).toInclude('{margin-left:calc(100% - var(--_5un9uz))}'); expect(actual).toInclude('style={{"--_5un9uz":ix(heading.depth,"rem")}}'); }); it('should move multiple groups of interpolations into inline styles', () => { // See: https://codesandbox.io/s/dank-star-443ps?file=/src/index.js const actual = transform(` import '@compiled/react'; const N30 = 'gray';
hello world
`); expect(actual).toInclude( 'background-image:linear-gradient(45deg,gray 25%,transparent 25%),linear-gradient(-45deg,gray 25%,transparent 25%),linear-gradient(45deg,transparent 75%,gray 75%),linear-gradient(-45deg,transparent 75%,gray 75%)' ); }); it('should move multiple groups of interpolations into inline styles with css variable for dynamic value', () => { // See: https://codesandbox.io/s/dank-star-443ps?file=/src/index.js const actual = transform(` import '@compiled/react'; let N30 = 'gray'; N30 = 'gray';
hello world
`); expect(actual).toInclude('style={{"--_1vrvste":ix(N30)}}'); expect(actual).toInclude( 'background-image:linear-gradient(45deg,var(--_1vrvste) 25%,transparent 25%),linear-gradient(-45deg,var(--_1vrvste) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--_1vrvste) 75%),linear-gradient(-45deg,transparent 75%,var(--_1vrvste) 75%)' ); }); it('should transform object with simple values', () => { const actual = transform(` import '@compiled/react';
hello world
`); expect(actual).toInclude('{line-height:20}'); expect(actual).toInclude('{color:blue}'); }); it('should inline constant', () => { const actual = transform(` import '@compiled/react'; const fontSize = 12;
hello world
`); expect(actual).toInclude('{font-size:12px}'); }); it('should transform object with nested object into a selector', () => { const actual = transform(` import '@compiled/react';
hello world
`); expect(actual).toInclude(':hover{color:blue}'); }); it('should transform object that has a variable reference', () => { const actual = transform(` import '@compiled/react'; let blue = 'blue'; blue = 'blue';
hello world
`); expect(actual).toInclude('{color:var(--_13q2bts)}'); expect(actual).toInclude('style={{"--_13q2bts":ix(blue)}}'); }); it('should transform object that has a destructured variable reference', () => { const actual = transform(` import '@compiled/react'; import { useState } from 'react'; const [color, setColor] = useState('blue');
hello world
`); expect(actual).toInclude('style={{"--_1ylxx6h":ix(color)}}'); expect(actual).toInclude('{color:var(--_1ylxx6h)}'); }); it('should transform object spread from variable', () => { const actual = transform(` import '@compiled/react'; const mixin = { color: 'red' };
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should transform object with string variable', () => { const actual = transform(` import '@compiled/react'; const text = 'red';
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should transform object with string variable using shorthand notation', () => { const actual = transform(` import '@compiled/react'; const color = 'red';
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should transform object with obj variable', () => { const actual = transform(` import '@compiled/react'; const mixin = { color: 'red' };
Hello, world!
`); expect(actual).toInclude('{display:flex}'); expect(actual).toInclude('{font-size:50px}'); expect(actual).toInclude('{color:blue}'); expect(actual).toInclude(':hover{color:red}'); }); it('should transform object with no argument arrow function variable', () => { const actual = transform(` import '@compiled/react'; const mixin = () => ({ color: 'red' });
hello world
`); expect(actual).toInclude(`{color:red}`); }); it('should transform object with argument arrow function variable', () => { const actual = transform(` import '@compiled/react'; const color1 = 'black'; const mixin = ({ color1, color2: c }, color3, radius) => ({ color: color1, backgroundColor: c, borderColor: color3 , borderRadius: radius, }); const color = { red: 'red' }; const greenColor = 'green'; const Component = (props) => { const color2 = 'black'; return
}; `); expect(actual).toIncludeMultiple([ '{color:red}', '{background-color:blue}', '{border-color:green}', '{border-radius:10px}', ]); }); it('should transform object with unresolved argument arrow function variable', () => { const actual = transform(` import '@compiled/react'; const radius = 10; const mixin = (color1, radius, size, weight) => ({ color: color1, borderRadius: radius, fontSize: size, fontWeight: weight }); const Component = (props) =>
`); expect(actual).toIncludeMultiple([ '{color:var(--_zo7lop)}', '"--_zo7lop":ix(props.color1)', '{border-radius:10px}', '{font-weight:var(--_u6vle4)}', '"--_u6vle4":ix()', '{font-size:var(--_kre2x8)}', '"--_kre2x8":ix()', ]); }); it('should transform object with argument arrow function variable inside member expression', () => { const actual = transform(` import '@compiled/react'; const mixin = { value: (color1, r, color2) => ({ color: color1, borderRadius: r, borderColor: color2, }) } const radius = 10; const Component = (props) =>
`); expect(actual).toIncludeMultiple([ '"--_zo7lop":ix(props.color1)', '{border-radius:10px}', '{border-color:red}', ]); }); it('should transform template literal value', () => { const actual = transform(` import '@compiled/react';
hello world
`); expect(actual).toInclude(`{color:blue}`); }); it('should transform object spread with no argument arrow function variable', () => { const actual = transform(` import '@compiled/react'; const mixin = () => ({ color: 'red' });
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should transform inline template literal with suffix', () => { const actual = transform(` import '@compiled/react'; const gridSize = 4; const Div = () => (
); `); expect(actual).toInclude('{padding-left:4px}'); expect(actual).toInclude('{padding-right:4px}'); expect(actual).toInclude('{padding-top:0}'); expect(actual).toInclude('{padding-bottom:0}'); expect(actual).toInclude('{color:red}'); }); it('should transform object spread with no argument function variable', () => { const actual = transform(` import '@compiled/react'; function mixin() { return { color: 'red' }; }
hello world
`); expect(actual).toInclude(`{color:red}`); }); it('should transform object with no argument arrow function', () => { const actual = transform(` import '@compiled/react'; const mixin = () => ({ color: 'red' });
hello world
`); expect(actual).toInclude(`{color:blue}`); expect(actual).toInclude(':hover{color:red}'); }); it('should transform object with no argument functions', () => { const actual = transform(` import '@compiled/react'; const bgColor = 'blue'; const fontStyling = { style: 'italic', family: 'sans-serif', }; const mixin1 = () => ({ color: 'red', backgroundColor: bgColor }); const mixin2 = function() { return { fontStyle: fontStyling.style } }; function mixin3() { return { fontFamily: fontStyling.family } };
hello world
`); expect(actual).toInclude(`{color:blue}`); expect(actual).toInclude(`{font-style:italic}`); expect(actual).toInclude(`{font-family:sans-serif}`); expect(actual).toInclude(':hover{color:red}'); expect(actual).toInclude(':hover{background-color:blue}'); }); it('should transform object with no argument function properties belonging to a variable', () => { const actual = transform(` import '@compiled/react'; const bgColor = 'blue'; const fontSize = 12; const fontStyling = { weight: 500, }; const sizes = { mixin1: () => \`1px solid \${bgColor}\`, mixin2: () => ({ fontSize }), mixin3: function() {return {fontWeight: fontStyling.weight};} };
hello world
`); expect(actual).toInclude(`{color:blue}`); expect(actual).toInclude(`{border:1px solid blue}`); expect(actual).toInclude(`{font-size:12px}`); expect(actual).toInclude(`font-weight:500}`); }); it('should extract mixin from identifier', () => { const actual = transform(` import '@compiled/react'; const base = { color: 'red' };
hello world
`); expect(actual).toInclude(`{color:red}`); }); it('should extract collocated mixin from member expression', () => { const actual = transform(` import '@compiled/react'; const styles = { default: { color: 'black' }, success: { color: 'green' }, fail: { color: 'red' } };
hello world
`); expect(actual).toInclude(`{color:green}`); }); it('should extract collocated mixin from deeply nested member expression', () => { const actual = transform(` import '@compiled/react'; const styles = { list: { item: { layout: { display: 'flex' } } } };
hello world
`); expect(actual).toInclude(`{display:flex}`); }); it('should transform identifier referencing an template literal', () => { const actual = transform(` import '@compiled/react'; const base = \` color: red; \`;
hello world
`); expect(actual).toInclude(`{color:red}`); }); it('should transform object with no argument function variable', () => { const actual = transform(` import '@compiled/react'; function mixin() { return { color: 'red' }; }
hello world
`); expect(actual).toInclude(`{color:blue}`); expect(actual).toInclude(':hover{color:red}'); }); it('should transform object spread with no argument function variable', () => { const actual = transform(` import '@compiled/react'; function mixin() { return { color: 'red' }; }
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should parse an inline string interpolation delimited by spaces', () => { const actual = transform(` import '@compiled/react'; const gridSize = () => 8; const HORIZONTAL_SPACING = \`\${gridSize() / 2}px\`;
hello world
`); expect(actual).toInclude('{padding:0 var(--_1xlms2h)}'); }); it('should parse an inline string interpolation delimited by multiple spaces', () => { const actual = transform(` import '@compiled/react'; const gridSize = () => 8; const HORIZONTAL_SPACING = \`\${gridSize() / 2}px\`;
hello world
`); expect(actual).toInclude('{padding:0 var(--_1xlms2h) 0 0}'); }); it('should parse an inline string interpolation delimited by multiple spaces and suffix', () => { const actual = transform(` import '@compiled/react'; const gridSize = () => 8; const HORIZONTAL_SPACING = gridSize();
hello world
`); expect(actual).toInclude('{padding-top:0}'); expect(actual).toInclude('{padding-right:8px}'); expect(actual).toInclude('{padding-bottom:0}'); expect(actual).toInclude('{padding-left:0}'); expect(actual).toInclude('{color:red}'); }); it('should parse an inline string interpolation delimited by multiple spaces and multiple suffix', () => { const actual = transform(` import '@compiled/react'; const gridSize = () => 8; const HORIZONTAL_SPACING = gridSize();
hello world
`); expect(actual).toInclude('{padding-top:8px}'); expect(actual).toInclude('{padding-right:8px}'); expect(actual).toInclude('{padding-bottom:8px}'); expect(actual).toInclude('{padding-left:8px}'); expect(actual).toInclude('{color:red}'); }); it('should do nothing when content already has single quotes', () => { const actual = transform(` import '@compiled/react'; const yeah = true;
hello world
`); expect(actual).toInclude(`{content:'hello'}`); }); it('should do nothing when content already has double quotes', () => { const actual = transform(` import '@compiled/react'; const yeah = true;
hello world
`); expect(actual).toInclude(`{content:\\\"hello\\\"}`); }); it('should add quotations to static content if missing', () => { const actual = transform(` import '@compiled/react'; const yeah = true;
hello world
`); expect(actual).toInclude(`{content:\\\"hello\\\"}`); }); it('should transform function returning an object', () => { const actual = transform(` import '@compiled/react'; const color = 'red'; const mixin = () => ({ color });
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should transform member expression referencing a function which returns an object', () => { const actual = transform(` import '@compiled/react'; const color = 'red'; const mixin = () => ({ color }); const colors = mixin();
hello world
`); expect(actual).toInclude('{color:red}'); }); it('should transform the CSS call expression', () => { const actual = transform(` import { css } from '@compiled/react'; const taggedObjectLiteralCss = css({ color: 'purple', });
hello world
`); expect(actual).toInclude('{color:purple}'); }); it('should transform the CSS call expression and traverse referenced variables', () => { const actual = transform(` import { css } from '@compiled/react'; const backgroundColor = 'green'; const taggedObjectLiteralCss = css({ color: 'purple', backgroundColor, });
hello world
`); expect(actual).toIncludeMultiple(['{color:purple}', '{background-color:green}']); }); it('should transform the CSS call expression from member expression', () => { const actual = transform(` import { css } from '@compiled/react'; const styles = { layout: { grid: { item: css({ display: 'grid' }) } } }; const gridItem = styles.layout.grid.item;
hello world
`); expect(actual).toInclude('{display:grid}'); }); it('should correctly expand shorthand property with ternary expression', () => { const actual = transform(` import { css } from '@compiled/react'; const morePadding = true;
Hello world
`); expect(actual).toMatchInlineSnapshot(` "import*as React from'react';import{ax,ix,CC,CS}from"@compiled/react/runtime";const _4="._19bv1ylp{padding-left:40px}";const _3="._n3td1ul9{padding-bottom:30px}";const _2="._u5f3gktf{padding-right:20px}";const _="._ca0q19bv{padding-top:10px}";const morePadding=true; {[_,_2,_3,_4]} {
Hello world
}
;" `); }); });