// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`v-once > as root node 1`] = `
+exports[`compiler: v-once > as root node 1`] = `
"import { template as _template, children as _children, setAttr as _setAttr } from 'vue/vapor';
export function render(_ctx) {
}"
`;
-exports[`v-once > basic 1`] = `
+exports[`compiler: v-once > basic 1`] = `
"import { template as _template, children as _children, createTextNode as _createTextNode, setText as _setText, setAttr as _setAttr, prepend as _prepend } from 'vue/vapor';
export function render(_ctx) {
return n0
}"
`;
+
+exports[`compiler: v-once > inside v-once 1`] = `
+"import { template as _template } from 'vue/vapor';
+
+export function render(_ctx) {
+ const t0 = _template("<div><div></div></div>")
+ const n0 = t0()
+ return n0
+}"
+`;
+
+exports[`compiler: v-once > on nested plain element 1`] = `
+"import { template as _template, children as _children, setAttr as _setAttr } from 'vue/vapor';
+
+export function render(_ctx) {
+ const t0 = _template("<div><div></div></div>")
+ const n0 = t0()
+ const { 0: [, { 0: [n1],}],} = _children(n0)
+ _setAttr(n1, "id", undefined, _ctx.foo)
+ return n0
+}"
+`;
-import { type RootNode, BindingTypes } from '@vue/compiler-dom'
-import { type CompilerOptions, compile as _compile } from '../../src'
+import { BindingTypes, NodeTypes, parse } from '@vue/compiler-dom'
+import {
+ type CompilerOptions,
+ compile as _compile,
+ transform,
+ generate as generate,
+ IRNodeTypes,
+ RootIRNode,
+} from '../../src'
+import { getBaseTransformPreset } from '../../src/compile'
-function compile(template: string | RootNode, options: CompilerOptions = {}) {
- let { code } = _compile(template, {
- ...options,
- mode: 'module',
+function compileWithOnce(
+ template: string,
+ options: CompilerOptions = {},
+): {
+ ir: RootIRNode
+ code: string
+} {
+ const ast = parse(template, { prefixIdentifiers: true, ...options })
+ const [nodeTransforms, directiveTransforms] = getBaseTransformPreset(true)
+ const ir = transform(ast, {
+ nodeTransforms,
+ directiveTransforms,
prefixIdentifiers: true,
+ ...options,
})
- return code
+ const { code } = generate(ir, { prefixIdentifiers: true, ...options })
+ return { ir, code }
}
-describe('v-once', () => {
+describe('compiler: v-once', () => {
test('basic', () => {
- const code = compile(
+ const { ir, code } = compileWithOnce(
`<div v-once>
{{ msg }}
<span :class="clz" />
},
},
)
- expect(code).matchSnapshot()
+ expect(ir.helpers.size).toBe(0)
+ expect(ir.effect).toEqual([])
+
+ expect(ir.operation).toMatchObject([
+ {
+ id: 1,
+ type: IRNodeTypes.CREATE_TEXT_NODE,
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'msg',
+ isStatic: false,
+ },
+ },
+ {
+ element: 1,
+ type: IRNodeTypes.SET_TEXT,
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'msg',
+ isStatic: false,
+ },
+ },
+ {
+ element: 2,
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'class',
+ isStatic: true,
+ },
+ type: IRNodeTypes.SET_PROP,
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'clz',
+ isStatic: false,
+ },
+ },
+ {
+ type: IRNodeTypes.PREPEND_NODE,
+ elements: [1],
+ parent: 3,
+ },
+ ])
+
+ expect(code).toMatchSnapshot()
})
test('as root node', () => {
- const code = compile(`<div :id="foo" v-once />`)
+ const { ir, code } = compileWithOnce(`<div :id="foo" v-once />`)
+
+ expect(ir.helpers.size).toBe(0)
+ expect(ir.effect).toEqual([])
+
+ expect(ir.operation).toMatchObject([
+ {
+ type: IRNodeTypes.SET_PROP,
+ element: 1,
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'id',
+ isStatic: true,
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'foo',
+ isStatic: false,
+ },
+ },
+ ])
+
expect(code).toMatchSnapshot()
expect(code).not.contains('effect')
})
+
+ test('on nested plain element', () => {
+ const { ir, code } = compileWithOnce(`<div><div :id="foo" v-once /></div>`)
+ expect(ir.helpers.size).toBe(0)
+ expect(ir.effect).toEqual([])
+
+ expect(ir.operation).toMatchObject([
+ {
+ type: IRNodeTypes.SET_PROP,
+ element: 1,
+ runtimeCamelize: false,
+ key: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'id',
+ isStatic: true,
+ },
+ value: {
+ type: NodeTypes.SIMPLE_EXPRESSION,
+ content: 'foo',
+ isStatic: false,
+ },
+ },
+ ])
+
+ expect(code).toMatchSnapshot()
+ })
+
+ test.todo('on component')
+ test.todo('on slot outlet')
+
+ test('inside v-once', () => {
+ const { ir, code } = compileWithOnce(`<div v-once><div v-once/></div>`)
+ expect(ir.helpers.size).toBe(0)
+ expect(ir.effect).toMatchObject([])
+ expect(ir.operation).toMatchObject([])
+
+ expect(code).toMatchSnapshot()
+ })
+
+ test.todo('with hoistStatic: true')
+ test.todo('with v-if/else')
+ test.todo('with v-for')
})