import type { TransformOptions } from '../../test-utils'; import { transform as transformCode } from '../../test-utils'; describe('class names behaviour', () => { beforeAll(() => { process.env.AUTOPREFIXER = 'off'; }); afterAll(() => { delete process.env.AUTOPREFIXRER; }); const transform = (code: string, opts: TransformOptions = {}) => transformCode(code, { snippet: true, ...opts }); it('should transform class names single usage', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {({ css }) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._1wybgktf{font-size:20px}"; const ListItem = () => ( {[_]} {
hello, world!
}
); " `); }); it('should transform children as function with body', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {({ css }) => { return
hello, world!
; }}
); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._1wybgktf{font-size:20px}"; const ListItem = () => ( {[_]} {(() => { return
hello, world!
; })()}
); " `); }); it('should transform style property access', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {(props) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const ListItem = () => ( {[]} {
hello, world!
}
); " `); }); it('should transform css property access', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {(props) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._1wybgktf{font-size:20px}"; const ListItem = () => ( {[_]} {
hello, world!
}
); " `); }); it('should transform keyframes', () => { const actual = transform(` import { ClassNames, keyframes } from '@compiled/react'; const fadeOut = keyframes({ from: { opacity: 1, }, to: { opacity: 0, }, }); const Component = () => ( {({ css }) => ( <>
longhand object call expression
shorthand object call expression
longhand tagged template expression
shorthand tagged template expression
)}
); `); expect(actual).toMatchInlineSnapshot(` "const _5 = "._y44vonb9{animation:k1m8j3od 2s ease-in-out}"; const _4 = "._1pgl1ytf{animation-timing-function:ease-in-out}"; const _3 = "._j7hq1sbx{animation-name:k1m8j3od}"; const _2 = "._5sagymdr{animation-duration:2s}"; const _ = "@keyframes k1m8j3od{0%{opacity:1}to{opacity:0}}"; const fadeOut = null; const Component = () => ( {[_, _2, _3, _4, _5]} { <>
longhand object call expression
shorthand object call expression
longhand tagged template expression
shorthand tagged template expression
}
); " `); }); it('should not transform object property access from invalid style prop', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {(props) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const ListItem = () => ( {[]} {
hello, world!
}
); " `); }); it('should transform style renamed prop usage', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {({ style: styl }) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const ListItem = () => ( {[]} {
hello, world!
}
); " `); }); it('should transform class names renamed prop single usage', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {({ css: c }) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._1wybgktf{font-size:20px}"; const ListItem = () => ( {[_]} {
hello, world!
}
); " `); }); it('should transform class names multiple usage', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {({ css }) => (
hello, world!
)}
); `); expect(actual).toMatchInlineSnapshot(` "const _3 = "._syaz13q2{color:blue}"; const _2 = "._1wybgktf{font-size:20px}"; const _ = "._syaz5scu{color:red}"; const ListItem = () => ( {[_, _2, _3]} {
hello, world!
}
); " `); }); it('should transform class names renamed usage', () => { const actual = transform(` import { ClassNames as CN } from '@compiled/react'; const ListItem = () => ( {({ css }) =>
hello, world!
}
); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._1wybgktf{font-size:20px}"; const ListItem = () => ( {[_]} {
hello, world!
}
); " `); }); it('should add an identifier nonce to the style element', () => { const code = ` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {({ css }) => (
hello, world!
)}
); `; const actual = transform(code, { nonce: '__webpack_nonce__' }); expect(actual).toInclude(''); }); it('should transform children as function return', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = ({ children }) => ( {({ css }) => children(css({ fontSize: '20px' }))} ); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._1wybgktf{font-size:20px}"; const ListItem = ({ children }) => ( {[_]} {children(ax(["_1wybgktf"]))} ); " `); }); it('should place self closing jsx element as a child', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ZoomOnHover = ({ children }) => ( {({ css }) =>
} ); `); expect(actual).toInclude(`
{ const actual = transform(` import { ClassNames } from '@compiled/react'; const Component = ({ children }) => ( {({ css, style }) =>
} ); `); expect(actual).toInclude(`style={undefined}`); }); it('should replace style identifier with css variable object', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const Component = ({ children, color }) => ( {({ css, style }) =>
} ); `); expect(actual).toMatchInlineSnapshot(` "const _ = "._syaz1aj3{color:var(--_1ylxx6h)}"; const Component = ({ children, color }) => ( {[_]} {
} ); " `); }); it('should not transform style identifier when its coming from outer scope', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const EmphasisText = ({ className, children, style }) => ( {({ css }) => ( {children} )} ); `); expect(actual).toInclude(`style={style}`); }); it('should transform style and css renamed prop coming from local variable', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = () => ( {(arg) => { const { css: c, style: styl } = arg; return (
hello world
); }}
); `); expect(actual).toMatchInlineSnapshot(` "const _2 = "._syaz5scu{color:red}"; const _ = "._1wyb19bv{font-size:10px}"; const ListItem = () => ( {[_, _2]} {(() => { const { css: c, style: styl } = arg; return (
hello world
); })()}
); " `); }); it('should apply conditional logical expression object spread styles', () => { const actual = transform(` import { ClassNames } from '@compiled/react'; const ListItem = (props) => ( {({ css }) => (
hello, world!
)}
); `); expect(actual).toInclude('className={ax([props.isPrimary && "_syaz13q2 _1wybgktf"])}'); }); it('should apply array logical-based conditional css', () => { const actual = transform( ` import { ClassNames } from '@compiled/react'; const ListItem = (props) => ( {({ css }) => (
hello, world!
)}
); `, { pretty: false } ); expect(actual).toInclude( 'className={ax(["_1wyb1ylp",(props.isPrimary||props.isMaybe)&&"_syaz13q2 _1wybgktf"])}' ); }); it('should apply array prop ternary-based inline conditional css', () => { const actual = transform( ` import { ClassNames } from '@compiled/react'; const ListItem = (props) => ( {({ css }) => (
hello, world!
)}
); `, { pretty: false } ); expect(actual).toInclude( 'className={ax([props.isPrimary?"_bfhk1x77 _syaz11x8":"_bfhkbf54 _syaz5scu","_1wyb1fwx"])}' ); }); });