diff --git a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap index efea7f51d..7aa9e632a 100644 --- a/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap +++ b/packages/compiler-vapor/__tests__/transforms/__snapshots__/vOn.spec.ts.snap @@ -12,6 +12,18 @@ export function render(_ctx) { }" `; +exports[`v-on > complex member expression w/ prefixIdentifiers: true 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("
") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", (...args) => (_ctx.a['b' + _ctx.c] && _ctx.a['b' + _ctx.c](...args))) + return n0 +}" +`; + exports[`v-on > dynamic arg 1`] = ` "import { template as _template, children as _children, renderEffect as _renderEffect, on as _on } from 'vue/vapor'; @@ -26,6 +38,34 @@ export function render(_ctx) { }" `; +exports[`v-on > dynamic arg with complex exp prefixing 1`] = ` +"import { template as _template, children as _children, renderEffect as _renderEffect, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _renderEffect(() => { + _on(n1, _ctx.event(_ctx.foo), (...args) => (_ctx.handler && _ctx.handler(...args))) + }) + return n0 +}" +`; + +exports[`v-on > dynamic arg with prefixing 1`] = ` +"import { template as _template, children as _children, renderEffect as _renderEffect, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _renderEffect(() => { + _on(n1, _ctx.event, (...args) => (_ctx.handler && _ctx.handler(...args))) + }) + return n0 +}" +`; + exports[`v-on > event modifier 1`] = ` "import { template as _template, children as _children, on as _on, withModifiers as _withModifiers, withKeys as _withKeys } from 'vue/vapor'; @@ -59,6 +99,133 @@ export function render(_ctx) { }" `; +exports[`v-on > function expression w/ prefixIdentifiers: true 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", e => _ctx.foo(e)) + return n0 +}" +`; + +exports[`v-on > inline statement w/ prefixIdentifiers: true 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => (_ctx.foo($event))) + return n0 +}" +`; + +exports[`v-on > multiple inline statements w/ prefixIdentifiers: true 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => {_ctx.foo($event);_ctx.bar()}) + return n0 +}" +`; + +exports[`v-on > should NOT add a prefix to $event if the expression is a function expression 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => {_ctx.i++;_ctx.foo($event)}) + return n0 +}" +`; + +exports[`v-on > should NOT wrap as function if expression is already function expression (with Typescript) 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", (e: any): any => _ctx.foo(e)) + return n0 +}" +`; + +exports[`v-on > should NOT wrap as function if expression is already function expression (with newlines) 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", + $event => { + _ctx.foo($event) + } + ) + return n0 +}" +`; + +exports[`v-on > should NOT wrap as function if expression is already function expression 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => _ctx.foo($event)) + return n0 +}" +`; + +exports[`v-on > should NOT wrap as function if expression is complex member expression 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", (...args) => (_ctx.a['b' + _ctx.c] && _ctx.a['b' + _ctx.c](...args))) + return n0 +}" +`; + +exports[`v-on > should handle multi-line statement 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => { +_ctx.foo(); +_ctx.bar() +}) + return n0 +}" +`; + +exports[`v-on > should handle multiple inline statement 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => {_ctx.foo();_ctx.bar()}) + return n0 +}" +`; + exports[`v-on > should not wrap keys guard if no key modifier is present 1`] = ` "import { template as _template, children as _children, on as _on, withModifiers as _withModifiers } from 'vue/vapor'; @@ -148,6 +315,32 @@ export function render(_ctx) { }" `; +exports[`v-on > should wrap as function if expression is inline statement 1`] = ` +"import { template as _template, children as _children, on as _on } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _on(n1, "click", $event => (_ctx.i++)) + return n0 +}" +`; + +exports[`v-on > should wrap both for dynamic key event w/ left/right modifiers 1`] = ` +"import { template as _template, children as _children, renderEffect as _renderEffect, on as _on, withKeys as _withKeys, withModifiers as _withModifiers } from 'vue/vapor'; + +export function render(_ctx) { + const t0 = _template("") + const n0 = t0() + const { 0: [n1],} = _children(n0) + _renderEffect(() => { + _on(n1, _ctx.e, _withKeys(_withModifiers((...args) => (_ctx.test && _ctx.test(...args)), ["left"]), ["left"])) + }) + return n0 +}" +`; + exports[`v-on > should wrap keys guard for keyboard events or dynamic events 1`] = ` "import { template as _template, children as _children, on as _on, withKeys as _withKeys, withModifiers as _withModifiers } from 'vue/vapor'; diff --git a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts index 08a73b430..0b6427069 100644 --- a/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-vapor/__tests__/transforms/vOn.spec.ts @@ -124,30 +124,254 @@ describe('v-on', () => { expect(code).matchSnapshot() }) - test.todo('dynamic arg with prefixing') - test.todo('dynamic arg with complex exp prefixing') - test.todo('should wrap as function if expression is inline statement') - test.todo('should handle multiple inline statement') - test.todo('should handle multi-line statement') - test.todo('inline statement w/ prefixIdentifiers: true') - test.todo('multiple inline statements w/ prefixIdentifiers: true') - test.todo( - 'should NOT wrap as function if expression is already function expression', - ) - test.todo( + test('dynamic arg with prefixing', () => { + const { code } = compileWithVOn(``, { + prefixIdentifiers: true, + }) + + expect(code).matchSnapshot() + }) + + test('dynamic arg with complex exp prefixing', () => { + const { ir, code } = compileWithVOn(``, { + prefixIdentifiers: true, + }) + + expect(ir.vaporHelpers).contains('on') + expect(ir.vaporHelpers).contains('renderEffect') + expect(ir.helpers.size).toBe(0) + expect(ir.operation).toEqual([]) + + expect(ir.effect[0].operations[0]).toMatchObject({ + type: IRNodeTypes.SET_EVENT, + element: 1, + key: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'event(foo)', + isStatic: false, + }, + value: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'handler', + isStatic: false, + }, + }) + + expect(code).matchSnapshot() + }) + + test('should wrap as function if expression is inline statement', () => { + const { code, ir } = compileWithVOn(``) + + expect(ir.vaporHelpers).contains('on') + expect(ir.helpers.size).toBe(0) + expect(ir.effect).toEqual([]) + + expect(ir.operation).toMatchObject([ + { + type: IRNodeTypes.SET_EVENT, + element: 1, + value: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: 'i++', + isStatic: false, + }, + }, + ]) + + expect(code).matchSnapshot() + expect(code).contains('_on(n1, "click", $event => (_ctx.i++))') + }) + + test('should handle multiple inline statement', () => { + const { ir, code } = compileWithVOn(``) + + expect(ir.operation).toMatchObject([ + { + type: IRNodeTypes.SET_EVENT, + value: { content: 'foo();bar()' }, + }, + ]) + + expect(code).matchSnapshot() + // should wrap with `{` for multiple statements + // in this case the return value is discarded and the behavior is + // consistent with 2.x + expect(code).contains('_on(n1, "click", $event => {_ctx.foo();_ctx.bar()})') + }) + + test('should handle multi-line statement', () => { + const { code, ir } = compileWithVOn(``) + + expect(ir.operation).toMatchObject([ + { + type: IRNodeTypes.SET_EVENT, + value: { content: '\nfoo();\nbar()\n' }, + }, + ]) + + expect(code).matchSnapshot() + // should wrap with `{` for multiple statements + // in this case the return value is discarded and the behavior is + // consistent with 2.x + expect(code).contains( + '_on(n1, "click", $event => {\n_ctx.foo();\n_ctx.bar()\n})', + ) + }) + + test('inline statement w/ prefixIdentifiers: true', () => { + const { code, ir } = compileWithVOn(``, { + prefixIdentifiers: true, + }) + + expect(ir.operation).toMatchObject([ + { + type: IRNodeTypes.SET_EVENT, + value: { content: 'foo($event)' }, + }, + ]) + + expect(code).matchSnapshot() + // should NOT prefix $event + expect(code).contains('_on(n1, "click", $event => (_ctx.foo($event)))') + }) + + test('multiple inline statements w/ prefixIdentifiers: true', () => { + const { ir, code } = compileWithVOn(``, { + prefixIdentifiers: true, + }) + + expect(ir.operation).toMatchObject([ + { + type: IRNodeTypes.SET_EVENT, + value: { content: 'foo($event);bar()' }, + }, + ]) + + expect(code).matchSnapshot() + // should NOT prefix $event + expect(code).contains( + '_on(n1, "click", $event => {_ctx.foo($event);_ctx.bar()})', + ) + }) + + test('should NOT wrap as function if expression is already function expression', () => { + const { code, ir } = compileWithVOn(`