test(compiler-vapor): add props & emits for component

This commit is contained in:
三咲智子 Kevin Deng 2024-04-15 04:09:38 +08:00
parent e95811887a
commit 3787a430f6
No known key found for this signature in database
4 changed files with 267 additions and 90 deletions

View File

@ -1,59 +0,0 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`generate component > generate component with emits 1`] = `
"import { toHandlerKey as _toHandlerKey } from 'vue';
import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Comp"), [{
onClick: () => (fn)
}])
const n1 = _createComponent(_resolveComponent("Comp"), [{
[_toHandlerKey(eventName)]: () => (fn)
}])
return [n0, n1]
}"
`;
exports[`generate component > generate multi root component 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent, template as _template } from 'vue/vapor';
const t0 = _template("123")
export function render(_ctx) {
const n1 = t0()
const n0 = _createComponent(_resolveComponent("Comp"))
return [n0, n1]
}"
`;
exports[`generate component > generate single root component (with props) 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Comp"), [{
foo: () => (foo)
}], true)
return n0
}"
`;
exports[`generate component > generate single root component (without props) 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Comp"), null, true)
return n0
}"
`;
exports[`generate component > should not generate withAttrs if component is not the root of the template 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent, insert as _insert, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n1 = t0()
const n0 = _createComponent(_resolveComponent("Comp"))
_insert(n0, n1)
return n1
}"
`;

View File

@ -1,31 +0,0 @@
import { compile } from '@vue/compiler-vapor'
describe('generate component', () => {
test('generate single root component (without props)', () => {
const { code } = compile(`<Comp/>`)
expect(code).toMatchSnapshot()
})
test('generate single root component (with props)', () => {
const { code } = compile(`<Comp :foo="foo"/>`)
expect(code).toMatchSnapshot()
})
test('generate multi root component', () => {
const { code } = compile(`<Comp/>123`)
expect(code).toMatchSnapshot()
})
test('should not generate withAttrs if component is not the root of the template', () => {
const { code } = compile(`<div><Comp/></div>`)
expect(code).toMatchSnapshot()
})
test('generate component with emits', () => {
const { code } = compile(`
<Comp @click="fn" />
<Comp @[eventName]="fn" />
`)
expect(code).toMatchSnapshot()
})
})

View File

@ -9,6 +9,24 @@ export function render(_ctx) {
}"
`;
exports[`compiler: element transform > component > generate multi root component 1`] = `
"import { createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_ctx.Comp)
return [n0, n1]
}"
`;
exports[`compiler: element transform > component > generate single root component 1`] = `
"import { createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_ctx.Comp, null, true)
return n0
}"
`;
exports[`compiler: element transform > component > import + resolve component 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
@ -18,6 +36,17 @@ export function render(_ctx) {
}"
`;
exports[`compiler: element transform > component > props merging: event handlers 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Foo"), [{
onClick: () => (_ctx.a)
}], true)
return n0
}"
`;
exports[`compiler: element transform > component > resolve component from setup bindings (inline const) 1`] = `
"(() => {
const n0 = _createComponent(Example, null, true)
@ -73,6 +102,62 @@ export function render(_ctx) {
}"
`;
exports[`compiler: element transform > component > static props 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Foo"), [{
id: () => ("foo"),
class: () => ("bar")
}], true)
return n0
}"
`;
exports[`compiler: element transform > component > v-bind="obj" 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Foo"), [() => (_ctx.obj)], true)
return n0
}"
`;
exports[`compiler: element transform > component > v-bind="obj" after static prop 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Foo"), [{
id: () => ("foo")
}, () => (_ctx.obj)], true)
return n0
}"
`;
exports[`compiler: element transform > component > v-bind="obj" before static prop 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Foo"), [() => (_ctx.obj), {
id: () => ("foo")
}], true)
return n0
}"
`;
exports[`compiler: element transform > component > v-bind="obj" between static props 1`] = `
"import { resolveComponent as _resolveComponent, createComponent as _createComponent } from 'vue/vapor';
export function render(_ctx) {
const n0 = _createComponent(_resolveComponent("Foo"), [{
id: () => ("foo")
}, () => (_ctx.obj), {
class: () => ("bar")
}], true)
return n0
}"
`;
exports[`compiler: element transform > props + children 1`] = `
"import { template as _template } from 'vue/vapor';
const t0 = _template("<div id=\\"foo\\"><span></span></div>")

View File

@ -174,6 +174,188 @@ describe('compiler: element transform', () => {
},
])
})
test('generate single root component', () => {
const { code } = compileWithElementTransform(`<Comp/>`, {
bindingMetadata: { Comp: BindingTypes.SETUP_CONST },
})
expect(code).toMatchSnapshot()
expect(code).contains('_createComponent(_ctx.Comp, null, true)')
})
test('generate multi root component', () => {
const { code } = compileWithElementTransform(`<Comp/>123`, {
bindingMetadata: { Comp: BindingTypes.SETUP_CONST },
})
expect(code).toMatchSnapshot()
expect(code).contains('_createComponent(_ctx.Comp)')
})
test('static props', () => {
const { code, ir } = compileWithElementTransform(
`<Foo id="foo" class="bar" />`,
)
expect(code).toMatchSnapshot()
expect(code).contains('_createComponent(_resolveComponent("Foo"), [{')
expect(code).contains(' id: () => ("foo")')
expect(code).contains(' class: () => ("bar")')
expect(code).contains('}], true)')
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.CREATE_COMPONENT_NODE,
tag: 'Foo',
resolve: true,
root: true,
props: [
[
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'id',
isStatic: true,
},
values: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'foo',
isStatic: true,
},
],
},
{
key: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'class',
isStatic: true,
},
values: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'bar',
isStatic: true,
},
],
},
],
],
},
])
})
test('v-bind="obj"', () => {
const { code, ir } = compileWithElementTransform(`<Foo v-bind="obj" />`)
expect(code).toMatchSnapshot()
expect(code).contains('[() => (_ctx.obj)]')
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.CREATE_COMPONENT_NODE,
tag: 'Foo',
props: [{ content: 'obj', isStatic: false }],
},
])
})
test('v-bind="obj" after static prop', () => {
const { code, ir } = compileWithElementTransform(
`<Foo id="foo" v-bind="obj" />`,
)
expect(code).toMatchSnapshot()
expect(code).contains('id: () => ("foo")')
expect(code).contains('}, () => (_ctx.obj)]')
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.CREATE_COMPONENT_NODE,
tag: 'Foo',
props: [
[{ key: { content: 'id' }, values: [{ content: 'foo' }] }],
{ content: 'obj' },
],
},
])
})
test('v-bind="obj" before static prop', () => {
const { code, ir } = compileWithElementTransform(
`<Foo v-bind="obj" id="foo" />`,
)
expect(code).toMatchSnapshot()
expect(code).contains('[() => (_ctx.obj), {')
expect(code).contains('id: () => ("foo")')
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.CREATE_COMPONENT_NODE,
tag: 'Foo',
props: [
{ content: 'obj' },
[{ key: { content: 'id' }, values: [{ content: 'foo' }] }],
],
},
])
})
test('v-bind="obj" between static props', () => {
const { code, ir } = compileWithElementTransform(
`<Foo id="foo" v-bind="obj" class="bar" />`,
)
expect(code).toMatchSnapshot()
expect(code).contains('id: () => ("foo")')
expect(code).contains('}, () => (_ctx.obj), {')
expect(code).contains('class: () => ("bar")')
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.CREATE_COMPONENT_NODE,
tag: 'Foo',
props: [
[{ key: { content: 'id' }, values: [{ content: 'foo' }] }],
{ content: 'obj' },
[{ key: { content: 'class' }, values: [{ content: 'bar' }] }],
],
},
])
})
test('props merging: event handlers', () => {
const { code, ir } = compileWithElementTransform(
`<Foo @click.foo="a" @click.bar="b" />`,
)
expect(code).toMatchSnapshot()
expect(code).contains('onClick: () => (_ctx.a)')
expect(ir.block.operation).toMatchObject([
{
type: IRNodeTypes.CREATE_COMPONENT_NODE,
tag: 'Foo',
props: [
[
{
key: { content: 'onClick', isStatic: true },
values: [{ content: 'a' }],
},
],
],
},
])
})
test.todo('props merging: style', () => {
const { code } = compileWithElementTransform(
`<Foo style="color: green" :style="{ color: 'red' }" />`,
)
expect(code).toMatchSnapshot()
})
test.todo('props merging: class', () => {
const { code } = compileWithElementTransform(
`<Foo class="foo" :class="{ bar: isBar }" />`,
)
expect(code).toMatchSnapshot()
})
test.todo('v-on="obj"', () => {
const { code } = compileWithElementTransform(`<Foo v-on="obj" />`)
expect(code).toMatchSnapshot()
})
})
test('static props', () => {