From 936c5ec7ac9456333ff9d28d7f4178bffddce879 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 20:43:43 +0800 Subject: [PATCH 1/4] test: combine with transform and codegen tests --- .../__snapshots__/vBind.spec.ts.snap | 50 ++++-- .../__tests__/transforms/vBind.spec.ts | 167 +++++++----------- 2 files changed, 101 insertions(+), 116 deletions(-) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index 0c115735c..2f67d0710 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`compiler: codegen v-bind > .camel modifier 1`] = ` +exports[`compiler: transform 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: transform v-bind > .camel modifier w/ dynamic arg 1`] = ` +"import { camelize as _camelize } from 'vue'; export function render(_ctx) { const t0 = _template("
") 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: transform 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: transform 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: transform 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("
") + const t0 = _template("
") 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: transform 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("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _effect(() => { + _setAttr(n1, "camel-case", undefined, _ctx.camelCase) + }) + return n0 +}" +`; + +exports[`compiler: transform 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: transform v-bind > should error if empty expression 1`] = ` +"import { template as _template } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + return n0 +}" +`; diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 416f65c4e..4b1559779 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -1,9 +1,4 @@ -import { - type RootNode, - ErrorCodes, - NodeTypes, - BindingTypes, -} from '@vue/compiler-dom' +import { ErrorCodes, NodeTypes, BindingTypes } from '@vue/compiler-dom' import { type RootIRNode, type CompilerOptions, @@ -13,35 +8,35 @@ 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, }, + prefixIdentifiers: true, ...options, }) - return ir -} -function compile(template: string | RootNode, options: CompilerOptions = {}) { - let { code } = _compile(template, { - ...options, - mode: 'module', - prefixIdentifiers: true, - }) - return code + const { code } = generate(ir, { prefixIdentifiers: true, ...options }) + + return { ir, code } } describe('compiler: transform v-bind', () => { test('basic', () => { - const node = parseWithVBind(`
`) + const { ir: node, code } = compileWithVBind(`
`) expect(node.dynamic.children[0]).toMatchObject({ id: 1, @@ -89,10 +84,12 @@ describe('compiler: transform v-bind', () => { }, ], }) + + expect(code).matchSnapshot() }) test('no expression', () => { - const node = parseWithVBind(`
`) + const { ir: node, code } = compileWithVBind(`
`) expect(node.effect[0].operations[0]).toMatchObject({ type: IRNodeTypes.SET_PROP, @@ -113,26 +110,34 @@ describe('compiler: transform v-bind', () => { }, }, }) + + expect(code).matchSnapshot() + expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)') }) test('no expression (shorthand)', () => { - const node = parseWithVBind(`
`) + const { ir: node, code } = compileWithVBind(`
`) expect(node.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(`
`) + const { ir: node, code } = compileWithVBind(`
`) expect(node.effect[0].operations[0]).toMatchObject({ type: IRNodeTypes.SET_PROP, element: 1, @@ -147,11 +152,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(`
`, { onError }) + const { ir: node, code } = compileWithVBind(`
`, { + onError, + }) + expect(onError.mock.calls[0][0]).toMatchObject({ code: ErrorCodes.X_V_BIND_NO_EXPRESSION, loc: { @@ -163,10 +174,16 @@ describe('compiler: transform v-bind', () => { type: IRNodeTypes.TEMPLATE_FACTORY, template: '
', }) + + expect(code).matchSnapshot() + expect(code).contains(JSON.stringify('
')) }) test('.camel modifier', () => { - const node = parseWithVBind(`
`) + const { ir: node, code } = compileWithVBind( + `
`, + ) + expect(node.effect[0].operations[0]).toMatchObject({ key: { content: `fooBar`, @@ -177,10 +194,14 @@ 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(`
`) + const { ir: node, code } = compileWithVBind(`
`) + expect(node.effect[0].operations[0]).toMatchObject({ key: { content: `fooBar`, @@ -191,10 +212,17 @@ 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(`
`) + const { ir: node, code } = compileWithVBind( + `
`, + ) + expect(node.effect[0].operations[0]).toMatchObject({ runtimeCamelize: true, key: { @@ -206,6 +234,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 +253,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(`
`, { - bindingMetadata: { - id: BindingTypes.SETUP_REF, - }, - }) - expect(code).matchSnapshot() - }) - - test('should error if no expression', () => { - const onError = vi.fn() - const code = compile(`
`, { 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('
')) - }) - - test('no expression', () => { - const code = compile('
', { - bindingMetadata: { - id: BindingTypes.SETUP_REF, - }, - }) - - expect(code).matchSnapshot() - expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)') - }) - - test('no expression (shorthand)', () => { - const code = compile('
', { - bindingMetadata: { - camelCase: BindingTypes.SETUP_REF, - }, - }) - - expect(code).matchSnapshot() - expect(code).contains( - '_setAttr(n1, "camel-case", undefined, _ctx.camelCase)', - ) - }) - - test('dynamic arg', () => { - const code = compile('
', { - bindingMetadata: { - id: BindingTypes.SETUP_REF, - }, - }) - - expect(code).matchSnapshot() - expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)') - }) - - test('.camel modifier', () => { - const code = compile(`
`) - - expect(code).matchSnapshot() - expect(code).contains('fooBar') - }) -}) From de64d7b3a9c252a0b20e3075992298154368827d Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 20:58:20 +0800 Subject: [PATCH 2/4] chore: clean the import --- packages/compiler-vapor/__tests__/transforms/vBind.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index 4b1559779..b2517ed6b 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -1,4 +1,4 @@ -import { ErrorCodes, NodeTypes, BindingTypes } from '@vue/compiler-dom' +import { ErrorCodes, NodeTypes } from '@vue/compiler-dom' import { type RootIRNode, type CompilerOptions, From 456b30bc648f1ee382fb8d3a58e93a5c75340303 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Sat, 9 Dec 2023 21:40:11 +0800 Subject: [PATCH 3/4] chore: rename test and variable name --- .../__snapshots__/vBind.spec.ts.snap | 16 +++---- .../__tests__/transforms/vBind.spec.ts | 48 +++++++++---------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap index 2f67d0710..910d019cd 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`compiler: transform 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,7 +14,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > .camel modifier w/ dynamic arg 1`] = ` +exports[`compiler v-bind > .camel modifier w/ dynamic arg 1`] = ` "import { camelize as _camelize } from 'vue'; export function render(_ctx) { @@ -28,7 +28,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > .camel modifier w/ no expression 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) { @@ -42,7 +42,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > basic 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,7 +56,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > dynamic arg 1`] = ` +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) { @@ -70,7 +70,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > no expression (shorthand) 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) { @@ -84,7 +84,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > no expression 1`] = ` +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) { @@ -98,7 +98,7 @@ export function render(_ctx) { }" `; -exports[`compiler: transform v-bind > should error if empty expression 1`] = ` +exports[`compiler v-bind > should error if empty expression 1`] = ` "import { template as _template } from 'vue/vapor'; export function render(_ctx) { diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index b2517ed6b..f5486ef49 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -34,22 +34,22 @@ function compileWithVBind( return { ir, code } } -describe('compiler: transform v-bind', () => { +describe('compiler v-bind', () => { test('basic', () => { - const { ir: node, code } = compileWithVBind(`
`) + const { ir, code } = compileWithVBind(`
`) - 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: '
', }) - 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,9 +89,9 @@ describe('compiler: transform v-bind', () => { }) test('no expression', () => { - const { ir: node, code } = compileWithVBind(`
`) + const { ir, code } = compileWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + expect(ir.effect[0].operations[0]).toMatchObject({ type: IRNodeTypes.SET_PROP, key: { content: `id`, @@ -116,9 +116,9 @@ describe('compiler: transform v-bind', () => { }) test('no expression (shorthand)', () => { - const { ir: node, code } = compileWithVBind(`
`) + const { ir, code } = compileWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + expect(ir.effect[0].operations[0]).toMatchObject({ type: IRNodeTypes.SET_PROP, key: { content: `camel-case`, @@ -137,8 +137,8 @@ describe('compiler: transform v-bind', () => { }) test('dynamic arg', () => { - const { ir: node, code } = compileWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + const { ir, code } = compileWithVBind(`
`) + expect(ir.effect[0].operations[0]).toMatchObject({ type: IRNodeTypes.SET_PROP, element: 1, key: { @@ -159,7 +159,7 @@ describe('compiler: transform v-bind', () => { test('should error if empty expression', () => { const onError = vi.fn() - const { ir: node, code } = compileWithVBind(`
`, { + const { ir, code } = compileWithVBind(`
`, { onError, }) @@ -170,7 +170,7 @@ 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: '
', }) @@ -180,11 +180,9 @@ describe('compiler: transform v-bind', () => { }) test('.camel modifier', () => { - const { ir: node, code } = compileWithVBind( - `
`, - ) + const { ir, code } = compileWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + expect(ir.effect[0].operations[0]).toMatchObject({ key: { content: `fooBar`, isStatic: true, @@ -200,9 +198,9 @@ describe('compiler: transform v-bind', () => { }) test('.camel modifier w/ no expression', () => { - const { ir: node, code } = compileWithVBind(`
`) + const { ir, code } = compileWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + expect(ir.effect[0].operations[0]).toMatchObject({ key: { content: `fooBar`, isStatic: true, @@ -219,11 +217,9 @@ describe('compiler: transform v-bind', () => { }) test('.camel modifier w/ dynamic arg', () => { - const { ir: node, code } = compileWithVBind( - `
`, - ) + const { ir, code } = compileWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + expect(ir.effect[0].operations[0]).toMatchObject({ runtimeCamelize: true, key: { content: `foo`, From d6eeeb89130302853c1d17bc5d7a52ff51b3edbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E6=99=BA=E5=AD=90=20Kevin=20Deng?= Date: Sun, 10 Dec 2023 01:30:18 +0800 Subject: [PATCH 4/4] test: update --- packages/compiler-vapor/__tests__/transforms/vBind.spec.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts index f5486ef49..c81f2e51a 100644 --- a/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vBind.spec.ts @@ -19,7 +19,6 @@ function compileWithVBind( code: string } { const ast = parse(template, { prefixIdentifiers: true, ...options }) - const ir = transform(ast, { nodeTransforms: [transformElement], directiveTransforms: { @@ -28,9 +27,7 @@ function compileWithVBind( prefixIdentifiers: true, ...options, }) - const { code } = generate(ir, { prefixIdentifiers: true, ...options }) - return { ir, code } } @@ -86,6 +83,7 @@ describe('compiler v-bind', () => { }) expect(code).matchSnapshot() + expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)') }) test('no expression', () => {