]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
test: combine with transform and codegen tests for `v-bind` (#45)
authorRizumu Ayaka <rizumu@ayaka.moe>
Sat, 9 Dec 2023 17:33:29 +0000 (01:33 +0800)
committerGitHub <noreply@github.com>
Sat, 9 Dec 2023 17:33:29 +0000 (01:33 +0800)
Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/vBind.spec.ts

index 0c115735cf5d6875d5a3f4c029c2ec4b6006ac84..910d019cd663414ed8aa7b8038434bd4768bbfd0 100644 (file)
@@ -1,6 +1,6 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
-exports[`compiler: codegen v-bind > .camel modifier 1`] = `
+exports[`compiler v-bind > .camel modifier 1`] = `
 "import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
 
 export function render(_ctx) {
@@ -14,21 +14,21 @@ export function render(_ctx) {
 }"
 `;
 
-exports[`compiler: codegen v-bind > dynamic arg 1`] = `
-"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
+exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = `
+"import { camelize as _camelize } from 'vue';
 
 export function render(_ctx) {
   const t0 = _template("<div></div>")
   const n0 = t0()
   const { 0: [n1],} = _children(n0)
   _effect(() => {
-    _setAttr(n1, _ctx.id, undefined, _ctx.id)
+    _setAttr(n1, _camelize(_ctx.foo), undefined, _ctx.id)
   })
   return n0
 }"
 `;
 
-exports[`compiler: codegen v-bind > no expression (shorthand) 1`] = `
+exports[`compiler v-bind > .camel modifier w/ no expression 1`] = `
 "import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
 
 export function render(_ctx) {
@@ -36,13 +36,13 @@ export function render(_ctx) {
   const n0 = t0()
   const { 0: [n1],} = _children(n0)
   _effect(() => {
-    _setAttr(n1, "camel-case", undefined, _ctx.camelCase)
+    _setAttr(n1, "fooBar", undefined, _ctx.fooBar)
   })
   return n0
 }"
 `;
 
-exports[`compiler: codegen v-bind > no expression 1`] = `
+exports[`compiler v-bind > basic 1`] = `
 "import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
 
 export function render(_ctx) {
@@ -56,17 +56,35 @@ export function render(_ctx) {
 }"
 `;
 
-exports[`compiler: codegen v-bind > should error if no expression 1`] = `
-"import { template as _template } from 'vue/vapor';
+exports[`compiler v-bind > dynamic arg 1`] = `
+"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
 
 export function render(_ctx) {
-  const t0 = _template("<div arg=\\"\\"></div>")
+  const t0 = _template("<div></div>")
   const n0 = t0()
+  const { 0: [n1],} = _children(n0)
+  _effect(() => {
+    _setAttr(n1, _ctx.id, undefined, _ctx.id)
+  })
   return n0
 }"
 `;
 
-exports[`compiler: codegen v-bind > simple expression 1`] = `
+exports[`compiler v-bind > no expression (shorthand) 1`] = `
+"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
+
+export function render(_ctx) {
+  const t0 = _template("<div></div>")
+  const n0 = t0()
+  const { 0: [n1],} = _children(n0)
+  _effect(() => {
+    _setAttr(n1, "camel-case", undefined, _ctx.camelCase)
+  })
+  return n0
+}"
+`;
+
+exports[`compiler v-bind > no expression 1`] = `
 "import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
 
 export function render(_ctx) {
@@ -79,3 +97,13 @@ export function render(_ctx) {
   return n0
 }"
 `;
+
+exports[`compiler v-bind > should error if empty expression 1`] = `
+"import { template as _template } from 'vue/vapor';
+
+export function render(_ctx) {
+  const t0 = _template("<div arg=\\"\\"></div>")
+  const n0 = t0()
+  return n0
+}"
+`;
index 416f65c4eba27fcdb93aec1c751b8a7a9cb34c84..c81f2e51a48336e1c57ea03efea8a29edb22337a 100644 (file)
@@ -1,9 +1,4 @@
-import {
-  type RootNode,
-  ErrorCodes,
-  NodeTypes,
-  BindingTypes,
-} from '@vue/compiler-dom'
+import { ErrorCodes, NodeTypes } from '@vue/compiler-dom'
 import {
   type RootIRNode,
   type CompilerOptions,
@@ -13,48 +8,45 @@ import {
   transformElement,
   IRNodeTypes,
   compile as _compile,
+  generate,
 } from '../../src'
 
-function parseWithVBind(
+function compileWithVBind(
   template: string,
   options: CompilerOptions = {},
-): RootIRNode {
-  const ast = parse(template)
+): {
+  ir: RootIRNode
+  code: string
+} {
+  const ast = parse(template, { prefixIdentifiers: true, ...options })
   const ir = transform(ast, {
     nodeTransforms: [transformElement],
     directiveTransforms: {
       bind: transformVBind,
     },
-    ...options,
-  })
-  return ir
-}
-
-function compile(template: string | RootNode, options: CompilerOptions = {}) {
-  let { code } = _compile(template, {
-    ...options,
-    mode: 'module',
     prefixIdentifiers: true,
+    ...options,
   })
-  return code
+  const { code } = generate(ir, { prefixIdentifiers: true, ...options })
+  return { ir, code }
 }
 
-describe('compiler: transform v-bind', () => {
+describe('compiler v-bind', () => {
   test('basic', () => {
-    const node = parseWithVBind(`<div v-bind:id="id"/>`)
+    const { ir, code } = compileWithVBind(`<div v-bind:id="id"/>`)
 
-    expect(node.dynamic.children[0]).toMatchObject({
+    expect(ir.dynamic.children[0]).toMatchObject({
       id: 1,
       referenced: true,
     })
-    expect(node.template[0]).toMatchObject({
+    expect(ir.template[0]).toMatchObject({
       type: IRNodeTypes.TEMPLATE_FACTORY,
       template: '<div></div>',
     })
-    expect(node.effect).lengthOf(1)
-    expect(node.effect[0].expressions).lengthOf(1)
-    expect(node.effect[0].operations).lengthOf(1)
-    expect(node.effect[0]).toMatchObject({
+    expect(ir.effect).lengthOf(1)
+    expect(ir.effect[0].expressions).lengthOf(1)
+    expect(ir.effect[0].operations).lengthOf(1)
+    expect(ir.effect[0]).toMatchObject({
       expressions: [
         {
           type: NodeTypes.SIMPLE_EXPRESSION,
@@ -89,12 +81,15 @@ describe('compiler: transform v-bind', () => {
         },
       ],
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
   })
 
   test('no expression', () => {
-    const node = parseWithVBind(`<div v-bind:id />`)
+    const { ir, code } = compileWithVBind(`<div v-bind:id />`)
 
-    expect(node.effect[0].operations[0]).toMatchObject({
+    expect(ir.effect[0].operations[0]).toMatchObject({
       type: IRNodeTypes.SET_PROP,
       key: {
         content: `id`,
@@ -113,27 +108,35 @@ describe('compiler: transform v-bind', () => {
         },
       },
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
   })
 
   test('no expression (shorthand)', () => {
-    const node = parseWithVBind(`<div :id />`)
+    const { ir, code } = compileWithVBind(`<div :camel-case />`)
 
-    expect(node.effect[0].operations[0]).toMatchObject({
+    expect(ir.effect[0].operations[0]).toMatchObject({
       type: IRNodeTypes.SET_PROP,
       key: {
-        content: `id`,
+        content: `camel-case`,
         isStatic: true,
       },
       value: {
-        content: `id`,
+        content: `camelCase`,
         isStatic: false,
       },
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains(
+      '_setAttr(n1, "camel-case", undefined, _ctx.camelCase)',
+    )
   })
 
   test('dynamic arg', () => {
-    const node = parseWithVBind(`<div v-bind:[id]="id"/>`)
-    expect(node.effect[0].operations[0]).toMatchObject({
+    const { ir, code } = compileWithVBind(`<div v-bind:[id]="id"/>`)
+    expect(ir.effect[0].operations[0]).toMatchObject({
       type: IRNodeTypes.SET_PROP,
       element: 1,
       key: {
@@ -147,11 +150,17 @@ describe('compiler: transform v-bind', () => {
         isStatic: false,
       },
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)')
   })
 
   test('should error if empty expression', () => {
     const onError = vi.fn()
-    const node = parseWithVBind(`<div v-bind:arg="" />`, { onError })
+    const { ir, code } = compileWithVBind(`<div v-bind:arg="" />`, {
+      onError,
+    })
+
     expect(onError.mock.calls[0][0]).toMatchObject({
       code: ErrorCodes.X_V_BIND_NO_EXPRESSION,
       loc: {
@@ -159,15 +168,19 @@ describe('compiler: transform v-bind', () => {
         end: { line: 1, column: 19 },
       },
     })
-    expect(node.template[0]).toMatchObject({
+    expect(ir.template[0]).toMatchObject({
       type: IRNodeTypes.TEMPLATE_FACTORY,
       template: '<div arg=""></div>',
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains(JSON.stringify('<div arg=""></div>'))
   })
 
   test('.camel modifier', () => {
-    const node = parseWithVBind(`<div v-bind:foo-bar.camel="id"/>`)
-    expect(node.effect[0].operations[0]).toMatchObject({
+    const { ir, code } = compileWithVBind(`<div v-bind:foo-bar.camel="id"/>`)
+
+    expect(ir.effect[0].operations[0]).toMatchObject({
       key: {
         content: `fooBar`,
         isStatic: true,
@@ -177,11 +190,15 @@ describe('compiler: transform v-bind', () => {
         isStatic: false,
       },
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains('_setAttr(n1, "fooBar", undefined, _ctx.id)')
   })
 
   test('.camel modifier w/ no expression', () => {
-    const node = parseWithVBind(`<div v-bind:foo-bar.camel />`)
-    expect(node.effect[0].operations[0]).toMatchObject({
+    const { ir, code } = compileWithVBind(`<div v-bind:foo-bar.camel />`)
+
+    expect(ir.effect[0].operations[0]).toMatchObject({
       key: {
         content: `fooBar`,
         isStatic: true,
@@ -191,11 +208,16 @@ describe('compiler: transform v-bind', () => {
         isStatic: false,
       },
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains('effect')
+    expect(code).contains('_setAttr(n1, "fooBar", undefined, _ctx.fooBar)')
   })
 
   test('.camel modifier w/ dynamic arg', () => {
-    const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`)
-    expect(node.effect[0].operations[0]).toMatchObject({
+    const { ir, code } = compileWithVBind(`<div v-bind:[foo].camel="id"/>`)
+
+    expect(ir.effect[0].operations[0]).toMatchObject({
       runtimeCamelize: true,
       key: {
         content: `foo`,
@@ -206,6 +228,12 @@ describe('compiler: transform v-bind', () => {
         isStatic: false,
       },
     })
+
+    expect(code).matchSnapshot()
+    expect(code).contains('effect')
+    expect(code).contains(
+      `_setAttr(n1, _camelize(_ctx.foo), undefined, _ctx.id)`,
+    )
   })
 
   test.todo('.camel modifier w/ dynamic arg + prefixIdentifiers')
@@ -219,80 +247,3 @@ describe('compiler: transform v-bind', () => {
   test.todo('.attr modifier')
   test.todo('.attr modifier w/ no expression')
 })
-
-// TODO: combine with above
-describe('compiler: codegen v-bind', () => {
-  test('simple expression', () => {
-    const code = compile(`<div :id="id"></div>`, {
-      bindingMetadata: {
-        id: BindingTypes.SETUP_REF,
-      },
-    })
-    expect(code).matchSnapshot()
-  })
-
-  test('should error if no expression', () => {
-    const onError = vi.fn()
-    const code = compile(`<div v-bind:arg="" />`, { onError })
-
-    expect(onError.mock.calls[0][0]).toMatchObject({
-      code: ErrorCodes.X_V_BIND_NO_EXPRESSION,
-      loc: {
-        start: {
-          line: 1,
-          column: 6,
-        },
-        end: {
-          line: 1,
-          column: 19,
-        },
-      },
-    })
-
-    expect(code).matchSnapshot()
-    // the arg is static
-    expect(code).contains(JSON.stringify('<div arg=""></div>'))
-  })
-
-  test('no expression', () => {
-    const code = compile('<div v-bind:id />', {
-      bindingMetadata: {
-        id: BindingTypes.SETUP_REF,
-      },
-    })
-
-    expect(code).matchSnapshot()
-    expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
-  })
-
-  test('no expression (shorthand)', () => {
-    const code = compile('<div :camel-case />', {
-      bindingMetadata: {
-        camelCase: BindingTypes.SETUP_REF,
-      },
-    })
-
-    expect(code).matchSnapshot()
-    expect(code).contains(
-      '_setAttr(n1, "camel-case", undefined, _ctx.camelCase)',
-    )
-  })
-
-  test('dynamic arg', () => {
-    const code = compile('<div v-bind:[id]="id"/>', {
-      bindingMetadata: {
-        id: BindingTypes.SETUP_REF,
-      },
-    })
-
-    expect(code).matchSnapshot()
-    expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)')
-  })
-
-  test('.camel modifier', () => {
-    const code = compile(`<div v-bind:foo-bar.camel="id"/>`)
-
-    expect(code).matchSnapshot()
-    expect(code).contains('fooBar')
-  })
-})