import { compileStyle, parse } from '../src' import { assertCode, compileSFCScript, mockId } from './utils' describe('CSS vars injection', () => { test('generating correct code for nested paths', () => { const { content } = compileSFCScript( `\n` + ``, ) expect(content).toMatch(`_useCssVars(_ctx => ({ "${mockId}-color": (_ctx.color), "${mockId}-font\\.size": (_ctx.font.size) })`) assertCode(content) }) test('w/ normal \n` + ``, ) expect(content).toMatch(`_useCssVars(_ctx => ({ "${mockId}-size": (_ctx.size) })`) expect(content).toMatch(`import { useCssVars as _useCssVars } from 'vue'`) assertCode(content) }) test('w/ \n` + ``, ) // should handle: // 1. local const bindings // 2. local potential ref bindings // 3. props bindings (analyzed) expect(content).toMatch(`_useCssVars(_ctx => ({ "${mockId}-color": (color), "${mockId}-size": (size.value), "${mockId}-foo": (__props.foo) })`) expect(content).toMatch( `import { useCssVars as _useCssVars, unref as _unref } from 'vue'`, ) assertCode(content) }) test('should rewrite CSS vars in compileStyle', () => { const { code } = compileStyle({ source: `.foo { color: v-bind(color); font-size: v-bind('font.size'); font-weight: v-bind(_φ); font-size: v-bind(1-字号); font-family: v-bind(フォント); }`, filename: 'test.css', id: 'data-v-test', }) expect(code).toMatchInlineSnapshot(` ".foo { color: var(--test-color); font-size: var(--test-font\\.size); font-weight: var(--test-_φ); font-size: var(--test-1-字号); font-family: var(--test-フォント); }" `) }) test('prod mode', () => { const { content } = compileSFCScript( `\n` + ``, { isProd: true }, ) expect(content).toMatch(`_useCssVars(_ctx => ({ "4003f1a6": (_ctx.color), "41b6490a": (_ctx.font.size) }))}`) const { code } = compileStyle({ source: `.foo { color: v-bind(color); font-size: v-bind('font.size'); }`, filename: 'test.css', id: mockId, isProd: true, }) expect(code).toMatchInlineSnapshot(` ".foo { color: var(--4003f1a6); font-size: var(--41b6490a); }" `) }) describe('codegen', () => { test('\n` + ``, ).content, ) }) test('\n` + ``, ).content, ) }) test('\n` + ``, ).content, ) }) test('w/ \n` + ``, ).content, ) }) //#4185 test('should ignore comments', () => { const { content } = compileSFCScript( `\n` + ``, ) expect(content).not.toMatch(`"${mockId}-color": (color)`) expect(content).toMatch(`"${mockId}-width": (width)`) assertCode(content) }) test('w/ \n` + ``, ) // color should only be injected once, even if it is twice in style expect(content).toMatch(`_useCssVars(_ctx => ({ "${mockId}-color": (color) })`) assertCode(content) }) test('should work with w/ complex expression', () => { const { content } = compileSFCScript( `\n` + ``, ) expect(content).toMatch(`_useCssVars(_ctx => ({ "${mockId}-foo": (_unref(foo)), "${mockId}-foo\\ \\+\\ \\'px\\'": (_unref(foo) + 'px'), "${mockId}-\\(a\\ \\+\\ b\\)\\ \\/\\ 2\\ \\+\\ \\'px\\'": ((_unref(a) + _unref(b)) / 2 + 'px'), "${mockId}-\\(\\(a\\ \\+\\ b\\)\\)\\ \\/\\ \\(2\\ \\*\\ a\\)": (((_unref(a) + _unref(b))) / (2 * _unref(a))) }))`) assertCode(content) }) // #6022 test('should be able to parse incomplete expressions', () => { const { descriptor: { cssVars }, } = parse( ` `, ) expect(cssVars).toMatchObject([`count.toString(`, `xxx`]) }) // #7759 test('It should correctly parse the case where there is no space after the script tag', () => { const { content } = compileSFCScript( ` `, ) expect(content).toMatch( `export default {\n setup(__props, { expose: __expose }) {\n __expose();\n\n_useCssVars(_ctx => ({\n "xxxxxxxx-background": (_unref(background))\n}))`, ) }) describe('skip codegen in SSR', () => { test('script setup, inline', () => { const { content } = compileSFCScript( `\n` + ``, { inlineTemplate: true, templateOptions: { ssr: true, }, }, ) expect(content).not.toMatch(`_useCssVars`) }) // #6926 test('script, non-inline', () => { const { content } = compileSFCScript( `\n` + ``, { inlineTemplate: false, templateOptions: { ssr: true, }, }, ) expect(content).not.toMatch(`_useCssVars`) }) test('normal script', () => { const { content } = compileSFCScript( `\n` + ``, { templateOptions: { ssr: true, }, }, ) expect(content).not.toMatch(`_useCssVars`) }) }) }) })