test: add transform tests to `v-html` / `v-text` tests (#49)

Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
This commit is contained in:
Rizumu Ayaka 2023-12-11 03:05:11 +08:00 committed by GitHub
parent 28b11f5cf7
commit c87512f592
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 237 additions and 51 deletions

View File

@ -1,5 +1,19 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`v-html > should convert v-html to innerHTML 1`] = `
"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor';
export function render(_ctx) {
const t0 = _template("<div></div>")
const n0 = t0()
const { 0: [n1],} = _children(n0)
_effect(() => {
_setHtml(n1, undefined, _ctx.code)
})
return n0
}"
`;
exports[`v-html > should raise error and ignore children when v-html is present 1`] = `
"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor';
@ -25,17 +39,3 @@ export function render(_ctx) {
return n0
}"
`;
exports[`v-html > simple expression 1`] = `
"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor';
export function render(_ctx) {
const t0 = _template("<div></div>")
const n0 = t0()
const { 0: [n1],} = _children(n0)
_effect(() => {
_setHtml(n1, undefined, _ctx.code)
})
return n0
}"
`;

View File

@ -1,18 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`v-text > no expression 1`] = `
"import { template as _template, children as _children, setText as _setText } from 'vue/vapor';
export function render(_ctx) {
const t0 = _template("<div></div>")
const n0 = t0()
const { 0: [n1],} = _children(n0)
_setText(n1, undefined, "")
return n0
}"
`;
exports[`v-text > simple expression 1`] = `
exports[`v-text > should convert v-text to textContent 1`] = `
"import { template as _template, children as _children, effect as _effect, setText as _setText } from 'vue/vapor';
export function render(_ctx) {
@ -25,3 +13,29 @@ export function render(_ctx) {
return n0
}"
`;
exports[`v-text > should raise error and ignore children when v-text is present 1`] = `
"import { template as _template, children as _children, effect as _effect, setText as _setText } from 'vue/vapor';
export function render(_ctx) {
const t0 = _template("<div></div>")
const n0 = t0()
const { 0: [n1],} = _children(n0)
_effect(() => {
_setText(n1, undefined, _ctx.test)
})
return n0
}"
`;
exports[`v-text > should raise error if has no expression 1`] = `
"import { template as _template, children as _children, setText as _setText } from 'vue/vapor';
export function render(_ctx) {
const t0 = _template("<div></div>")
const n0 = t0()
const { 0: [n1],} = _children(n0)
_setText(n1, undefined, "")
return n0
}"
`;

View File

@ -1,39 +1,119 @@
import { type RootNode, BindingTypes, DOMErrorCodes } from '@vue/compiler-dom'
import { type CompilerOptions, compile as _compile } from '../../src'
import {
BindingTypes,
DOMErrorCodes,
NodeTypes,
parse,
} from '@vue/compiler-dom'
import {
type CompilerOptions,
compile as _compile,
RootIRNode,
transform,
generate,
IRNodeTypes,
} from '../../src'
import { getBaseTransformPreset } from '../../src/compile'
function compile(template: string | RootNode, options: CompilerOptions = {}) {
let { code } = _compile(template, {
...options,
mode: 'module',
function compileWithVHtml(
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-html', () => {
test('simple expression', () => {
const code = compile(`<div v-html="code"></div>`, {
test('should convert v-html to innerHTML', () => {
const { code, ir } = compileWithVHtml(`<div v-html="code"></div>`, {
bindingMetadata: {
code: BindingTypes.SETUP_REF,
},
})
expect(ir.vaporHelpers).contains('setHtml')
expect(ir.helpers.size).toBe(0)
expect(ir.operation).toEqual([])
expect(ir.effect).toMatchObject([
{
expressions: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'code',
isStatic: false,
},
],
operations: [
{
type: IRNodeTypes.SET_HTML,
element: 1,
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'code',
isStatic: false,
},
},
],
},
])
expect(code).matchSnapshot()
})
test('should raise error and ignore children when v-html is present', () => {
const onError = vi.fn()
const code = compile(`<div v-html="test">hello</div>`, {
const { code, ir } = compileWithVHtml(`<div v-html="test">hello</div>`, {
onError,
})
expect(code).matchSnapshot()
expect(ir.vaporHelpers).contains('setHtml')
expect(ir.helpers.size).toBe(0)
expect(ir.operation).toEqual([])
expect(ir.effect).toMatchObject([
{
expressions: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'test',
isStatic: false,
},
],
operations: [
{
type: IRNodeTypes.SET_HTML,
element: 1,
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'test',
isStatic: false,
},
},
],
},
])
expect(onError.mock.calls).toMatchObject([
[{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }],
])
expect(code).matchSnapshot()
})
test('should raise error if has no expression', () => {
const onError = vi.fn()
const code = compile(`<div v-html></div>`, {
const { code } = compileWithVHtml(`<div v-html></div>`, {
onError,
})
expect(code).matchSnapshot()

View File

@ -1,28 +1,120 @@
import { type RootNode, BindingTypes, DOMErrorCodes } from '@vue/compiler-dom'
import { type CompilerOptions, compile as _compile } from '../../src'
import {
BindingTypes,
DOMErrorCodes,
NodeTypes,
parse,
} from '@vue/compiler-dom'
import {
type CompilerOptions,
compile as _compile,
RootIRNode,
transform,
generate,
IRNodeTypes,
} from '../../src'
import { getBaseTransformPreset } from '../../src/compile'
function compile(template: string | RootNode, options: CompilerOptions = {}) {
let { code } = _compile(template, {
...options,
mode: 'module',
function compileWithVText(
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-text', () => {
test('simple expression', () => {
const code = compile(`<div v-text="str"></div>`, {
test('should convert v-text to textContent', () => {
const { code, ir } = compileWithVText(`<div v-text="str"></div>`, {
bindingMetadata: {
str: BindingTypes.SETUP_REF,
},
})
expect(ir.vaporHelpers).contains('setText')
expect(ir.helpers.size).toBe(0)
expect(ir.operation).toEqual([])
expect(ir.effect).toMatchObject([
{
expressions: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'str',
isStatic: false,
},
],
operations: [
{
type: IRNodeTypes.SET_TEXT,
element: 1,
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'str',
isStatic: false,
},
},
],
},
])
expect(code).matchSnapshot()
})
test('no expression', () => {
test('should raise error and ignore children when v-text is present', () => {
const onError = vi.fn()
const code = compile(`<div v-text></div>`, { onError })
const { code, ir } = compileWithVText(`<div v-text="test">hello</div>`, {
onError,
})
expect(onError.mock.calls).toMatchObject([
[{ code: DOMErrorCodes.X_V_TEXT_WITH_CHILDREN }],
])
// children should have been removed
expect(ir.template).toMatchObject([{ template: '<div></div>' }])
expect(ir.effect).toMatchObject([
{
expressions: [
{
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'test',
isStatic: false,
},
],
operations: [
{
type: IRNodeTypes.SET_TEXT,
element: 1,
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'test',
isStatic: false,
},
},
],
},
])
expect(code).matchSnapshot()
// children should have been removed
expect(code).contains('template("<div></div>")')
})
test('should raise error if has no expression', () => {
const onError = vi.fn()
const { code } = compileWithVText(`<div v-text></div>`, { onError })
expect(code).matchSnapshot()
expect(onError.mock.calls).toMatchObject([
[{ code: DOMErrorCodes.X_V_TEXT_NO_EXPRESSION }],

View File

@ -13,7 +13,7 @@ export const transformVText: DirectiveTransform = (dir, node, context) => {
context.options.onError(
createDOMCompilerError(DOMErrorCodes.X_V_TEXT_WITH_CHILDREN, loc),
)
node.children.length = 0
context.childrenTemplate.length = 0
}
context.registerEffect(