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..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: 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("
") 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("
") + 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 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 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("
") + 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..c81f2e51a 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 } 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(`
`) + 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,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(`
`) + 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`, @@ -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(`
`) + 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`, + 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(`
`) - 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: { @@ -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(`
`, { onError }) + const { ir, code } = compileWithVBind(`
`, { + 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: '
', }) + + expect(code).matchSnapshot() + expect(code).contains(JSON.stringify('
')) }) test('.camel modifier', () => { - const node = parseWithVBind(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + const { ir, code } = compileWithVBind(`
`) + + 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(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + const { ir, code } = compileWithVBind(`
`) + + 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(`
`) - expect(node.effect[0].operations[0]).toMatchObject({ + const { ir, code } = compileWithVBind(`
`) + + 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(`
`, { - 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') - }) -})