test(compiler-dom): add test for vModel transform (#289)

This commit is contained in:
likui 2019-10-16 13:47:58 +08:00 committed by Evan You
parent 260eab85ff
commit 29811d1fe8
2 changed files with 305 additions and 9 deletions

View File

@ -0,0 +1,192 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: transform v-model modifiers .lazy 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[
_vModelText,
model,
void 0,
{ lazy: true }
]
]))
}
}"
`;
exports[`compiler: transform v-model modifiers .number 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[
_vModelText,
model,
void 0,
{ number: true }
]
]))
}
}"
`;
exports[`compiler: transform v-model modifiers .trim 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[
_vModelText,
model,
void 0,
{ trim: true }
]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_vModelText, model]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression for input (checkbox) 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelCheckbox: _vModelCheckbox, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
type: \\"checkbox\\",
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_vModelCheckbox, model]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression for input (dynamic type) 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelDynamic: _vModelDynamic, createVNode: _createVNode, applyDirectives: _applyDirectives, resolveDirective: _resolveDirective, createBlock: _createBlock, openBlock: _openBlock } = _Vue
const _directive_bind = _resolveDirective(\\"bind\\")
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_directive_bind, foo, \\"type\\"],
[_vModelDynamic, model]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression for input (radio) 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelRadio: _vModelRadio, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
type: \\"radio\\",
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_vModelRadio, model]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression for input (text) 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"input\\", {
type: \\"text\\",
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_vModelText, model]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression for select 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelSelect: _vModelSelect, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"select\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_vModelSelect, model]
]))
}
}"
`;
exports[`compiler: transform v-model simple expression for textarea 1`] = `
"const _Vue = Vue
return function render() {
with (this) {
const { vModelText: _vModelText, createVNode: _createVNode, applyDirectives: _applyDirectives, createBlock: _createBlock, openBlock: _openBlock } = _Vue
return (_openBlock(), _applyDirectives(_createBlock(\\"textarea\\", {
modelValue: model,
\\"onUpdate:modelValue\\": $event => (model = $event)
}, null, 8 /* PROPS */, [\\"modelValue\\", \\"onUpdate:modelValue\\"]), [
[_vModelText, model]
]))
}
}"
`;

View File

@ -1,7 +1,14 @@
import { parse, transform, CompilerOptions } from '@vue/compiler-core' import { parse, transform, CompilerOptions, generate } from '@vue/compiler-core'
import { transformModel } from '../../src/transforms/vModel' import { transformModel } from '../../src/transforms/vModel'
import { transformElement } from '../../../compiler-core/src/transforms/transformElement' import { transformElement } from '../../../compiler-core/src/transforms/transformElement'
import { DOMErrorCodes } from '../../src/errors' import { DOMErrorCodes } from '../../src/errors'
import {
V_MODEL_CHECKBOX,
V_MODEL_DYNAMIC,
V_MODEL_RADIO,
V_MODEL_SELECT,
V_MODEL_TEXT
} from '../../src/runtimeHelpers'
function transformWithModel(template: string, options: CompilerOptions = {}) { function transformWithModel(template: string, options: CompilerOptions = {}) {
const ast = parse(template) const ast = parse(template)
@ -15,14 +22,111 @@ function transformWithModel(template: string, options: CompilerOptions = {}) {
return ast return ast
} }
describe('compiler: v-model transform', () => { describe('compiler: transform v-model', () => {
it('should raise error if used file input element', () => { test('simple expression', () => {
const onError = jest.fn() const root = transformWithModel('<input v-model="model" />')
transformWithModel(`<input type="file" v-model="test"></input>`, {
onError expect(root.helpers).toContain(V_MODEL_TEXT)
expect(generate(root).code).toMatchSnapshot()
})
test('simple expression for input (text)', () => {
const root = transformWithModel('<input type="text" v-model="model" />')
expect(root.helpers).toContain(V_MODEL_TEXT)
expect(generate(root).code).toMatchSnapshot()
})
test('simple expression for input (radio)', () => {
const root = transformWithModel('<input type="radio" v-model="model" />')
expect(root.helpers).toContain(V_MODEL_RADIO)
expect(generate(root).code).toMatchSnapshot()
})
test('simple expression for input (checkbox)', () => {
const root = transformWithModel('<input type="checkbox" v-model="model" />')
expect(root.helpers).toContain(V_MODEL_CHECKBOX)
expect(generate(root).code).toMatchSnapshot()
})
test('simple expression for input (dynamic type)', () => {
const root = transformWithModel('<input :type="foo" v-model="model" />')
expect(root.helpers).toContain(V_MODEL_DYNAMIC)
expect(generate(root).code).toMatchSnapshot()
})
test('simple expression for select', () => {
const root = transformWithModel('<select v-model="model" />')
expect(root.helpers).toContain(V_MODEL_SELECT)
expect(generate(root).code).toMatchSnapshot()
})
test('simple expression for textarea', () => {
const root = transformWithModel('<textarea v-model="model" />')
expect(root.helpers).toContain(V_MODEL_TEXT)
expect(generate(root).code).toMatchSnapshot()
})
describe('errors', () => {
test('plain elements with argument', () => {
const onError = jest.fn()
transformWithModel('<input v-model:value="model" />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
code: DOMErrorCodes.X_V_MODEL_ARG_ON_ELEMENT
})
)
})
test('invalid element', () => {
const onError = jest.fn()
transformWithModel('<span v-model="model" />', { onError })
expect(onError).toHaveBeenCalledTimes(1)
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
code: DOMErrorCodes.X_V_MODEL_ON_INVALID_ELEMENT
})
)
})
test('should raise error if used file input element', () => {
const onError = jest.fn()
transformWithModel(`<input type="file" v-model="test"/>`, {
onError
})
expect(onError).toHaveBeenCalledWith(
expect.objectContaining({
code: DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT
})
)
})
})
describe('modifiers', () => {
test('.number', () => {
const root = transformWithModel('<input v-model.number="model" />')
expect(generate(root).code).toMatchSnapshot()
})
test('.trim', () => {
const root = transformWithModel('<input v-model.trim="model" />')
expect(generate(root).code).toMatchSnapshot()
})
test('.lazy', () => {
const root = transformWithModel('<input v-model.lazy="model" />')
expect(generate(root).code).toMatchSnapshot()
}) })
expect(onError.mock.calls).toMatchObject([
[{ code: DOMErrorCodes.X_V_MODEL_ON_FILE_INPUT_ELEMENT }]
])
}) })
}) })