| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | import { compileStyle, parse } from '../src'import { mockId, compile, assertCode } from './util'describe('CSS vars injection', () => {  test('generating correct code for nested paths', () => {    const { content } = compile(      `<script>const a = 1</script>\n` +        `<style>div{          color: v-bind(color);          font-size: v-bind('font.size');        }</style>`    )    expect(content).toMatch(`_useCssVars((_vm, _setup) => ({  "${mockId}-color": (_vm.color),  "${mockId}-font_size": (_vm.font.size)})`)    assertCode(content)  })  test('w/ normal <script> binding analysis', () => {    const { content } = compile(      `<script>      export default {        setup() {          return {            size: ref('100px')          }        }      }      </script>\n` +        `<style>          div {            font-size: v-bind(size);          }        </style>`    )    expect(content).toMatch(`_useCssVars((_vm, _setup) => ({  "${mockId}-size": (_vm.size)})`)    expect(content).toMatch(`import { useCssVars as _useCssVars } from 'vue'`)    assertCode(content)  })  test('w/ <script setup> binding analysis', () => {    const { content } = compile(      `<script setup>        import { defineProps, ref } from 'vue'        const color = 'red'        const size = ref('10px')        defineProps({          foo: String        })        </script>\n` +        `<style>          div {            color: v-bind(color);            font-size: v-bind(size);            border: v-bind(foo);          }        </style>`    )    // should handle:    // 1. local const bindings    // 2. local potential ref bindings    // 3. props bindings (analyzed)    expect(content).toMatch(`_useCssVars((_vm, _setup) => ({  "${mockId}-color": (_setup.color),  "${mockId}-size": (_setup.size),  "${mockId}-foo": (_vm.foo)})`)    expect(content).toMatch(`import { useCssVars as _useCssVars } 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');      }`,      filename: 'test.css',      id: 'data-v-test'    })    expect(code).toMatchInlineSnapshot(`      ".foo[data-v-test] {              color: var(--test-color);              font-size: var(--test-font_size);      }"    `)  })  test('prod mode', () => {    const { content } = compile(      `<script>const a = 1</script>\n` +        `<style>div{          color: v-bind(color);          font-size: v-bind('font.size');        }</style>`,      { isProd: true }    )    expect(content).toMatch(`_useCssVars((_vm, _setup) => ({  "4003f1a6": (_vm.color),  "41b6490a": (_vm.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[xxxxxxxx] {              color: var(--4003f1a6);              font-size: var(--41b6490a);      }"    `)  })  describe('codegen', () => {    test('<script> w/ no default export', () => {      assertCode(        compile(          `<script>const a = 1</script>\n` +            `<style>div{ color: v-bind(color); }</style>`        ).content      )    })    test('<script> w/ default export', () => {      assertCode(        compile(          `<script>export default { setup() {} }</script>\n` +            `<style>div{ color: v-bind(color); }</style>`        ).content      )    })    test('<script> w/ default export in strings/comments', () => {      assertCode(        compile(          `<script>          // export default {}          export default {}        </script>\n` + `<style>div{ color: v-bind(color); }</style>`        ).content      )    })    test('w/ <script setup>', () => {      assertCode(        compile(          `<script setup>const color = 'red'</script>\n` +            `<style>div{ color: v-bind(color); }</style>`        ).content      )    })    //#4185    test('should ignore comments', () => {      const { content } = compile(        `<script setup>const color = 'red';const width = 100</script>\n` +          `<style>            /* comment **/            div{ /* color: v-bind(color); */ width:20; }            div{ width: v-bind(width); }            /* comment */          </style>`      )      expect(content).not.toMatch(`"${mockId}-color": (_setup.color)`)      expect(content).toMatch(`"${mockId}-width": (_setup.width)`)      assertCode(content)    })    test('w/ <script setup> using the same var multiple times', () => {      const { content } = compile(        `<script setup>        const color = 'red'        </script>\n` +          `<style>          div {            color: v-bind(color);          }          p {            color: v-bind(color);          }        </style>`      )      // color should only be injected once, even if it is twice in style      expect(content).toMatch(`_useCssVars((_vm, _setup) => ({  "${mockId}-color": (_setup.color)})`)      assertCode(content)    })    test('should work with w/ complex expression', () => {      const { content } = compile(        `<script setup>        let a = 100        let b = 200        let foo = 300        </script>\n` +          `<style>          p{            width: calc(v-bind(foo) - 3px);            height: calc(v-bind('foo') - 3px);            top: calc(v-bind(foo + 'px') - 3px);          }          div {            color: v-bind((a + b) / 2 + 'px' );          }          div {            color: v-bind    ((a + b) / 2 + 'px' );          }          p {            color: v-bind(((a + b)) / (2 * a));          }        </style>`      )      expect(content).toMatch(`_useCssVars((_vm, _setup) => ({  "${mockId}-foo": (_setup.foo),  "${mockId}-foo____px_": (_setup.foo + 'px'),  "${mockId}-_a___b____2____px_": ((_setup.a + _setup.b) / 2 + 'px'),  "${mockId}-__a___b______2___a_": (((_setup.a + _setup.b)) / (2 * _setup.a))})`)      assertCode(content)    })    // #6022    test('should be able to parse incomplete expressions', () => {      const { cssVars } = parse({        source: `<script setup>let xxx = 1</script>        <style scoped>        label {          font-weight: v-bind("count.toString(");          font-weight: v-bind(xxx);        }        </style>`      })      expect(cssVars).toMatchObject([`count.toString(`, `xxx`])    })  })})
 |