| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- import Vue from 'vue'
- import { compile } from 'web/compiler'
- import { getAndRemoveAttr } from 'compiler/helpers'
- describe('compile options', () => {
- it('should be compiled', () => {
- const { render, staticRenderFns, errors } = compile(
- `
- <div>
- <input type="text" v-model="msg" required max="8" v-validate:field1.group1.group2>
- </div>
- `,
- {
- directives: {
- validate(el, dir) {
- if (dir.name === 'validate' && dir.arg) {
- el.validate = {
- field: dir.arg,
- groups: dir.modifiers ? Object.keys(dir.modifiers) : []
- }
- }
- }
- },
- modules: [
- {
- transformNode(el) {
- el.validators = el.validators || []
- const validators = [
- 'required',
- 'min',
- 'max',
- 'pattern',
- 'maxlength',
- 'minlength'
- ]
- validators.forEach(name => {
- const rule = getAndRemoveAttr(el, name)
- if (rule !== undefined) {
- el.validators.push({ name, rule })
- }
- })
- },
- genData(el) {
- let data = ''
- if (el.validate) {
- data += `validate:${JSON.stringify(el.validate)},`
- }
- if (el.validators) {
- data += `validators:${JSON.stringify(el.validators)},`
- }
- return data
- },
- transformCode(el, code) {
- // check
- if (!el.validate || !el.validators) {
- return code
- }
- // setup validation result props
- const result = { dirty: false } // define something other prop
- el.validators.forEach(validator => {
- result[validator.name] = null
- })
- // generate code
- return `_c('validate',{props:{
- field:${JSON.stringify(el.validate.field)},
- groups:${JSON.stringify(el.validate.groups)},
- validators:${JSON.stringify(el.validators)},
- result:${JSON.stringify(result)},
- child:${code}}
- })`
- }
- }
- ]
- }
- )
- expect(render).not.toBeUndefined()
- expect(staticRenderFns).toEqual([])
- expect(errors).toEqual([])
- const renderFn = new Function(render)
- const vm = new Vue({
- data: {
- msg: 'hello'
- },
- components: {
- validate: {
- props: ['field', 'groups', 'validators', 'result', 'child'],
- render(h) {
- return this.child
- },
- computed: {
- valid() {
- let ret = true
- for (let i = 0; i < this.validators.length; i++) {
- const { name } = this.validators[i]
- if (!this.result[name]) {
- ret = false
- break
- }
- }
- return ret
- }
- },
- mounted() {
- // initialize validation
- const value = this.$el.value
- this.validators.forEach(validator => {
- const ret = this[validator.name](value, validator.rule)
- this.result[validator.name] = ret
- })
- },
- methods: {
- // something validators logic
- required(val) {
- return val.length > 0
- },
- max(val, rule) {
- return !(parseInt(val, 10) > parseInt(rule, 10))
- }
- }
- }
- },
- render: renderFn,
- staticRenderFns
- }).$mount()
- expect(vm.$el.innerHTML).toBe('<input type="text">')
- expect(vm.$children[0].valid).toBe(true)
- })
- it('should collect errors', () => {
- let compiled = compile('hello')
- expect(compiled.errors.length).toBe(1)
- expect(compiled.errors[0]).toContain('root element')
- compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
- expect(compiled.errors.length).toBe(2)
- expect(compiled.errors[0]).toContain('Raw expression: v-if="a----"')
- expect(compiled.errors[1]).toContain('Raw expression: {{ b++++ }}')
- })
- it('should collect errors with source range', () => {
- let compiled = compile('hello', { outputSourceRange: true })
- expect(compiled.errors.length).toBe(1)
- expect(compiled.errors[0].start).toBe(0)
- expect(compiled.errors[0].end).toBeUndefined()
- compiled = compile('<div v-if="a----">{{ b++++ }}</div>', {
- outputSourceRange: true
- })
- expect(compiled.errors.length).toBe(2)
- expect(compiled.errors[0].start).toBe(5)
- expect(compiled.errors[0].end).toBe(17)
- expect(compiled.errors[1].start).toBe(18)
- expect(compiled.errors[1].end).toBe(29)
- compiled = compile('<div><span></div>', { outputSourceRange: true })
- expect(compiled.errors.length).toBe(1)
- expect(compiled.errors[0].start).toBe(5)
- expect(compiled.errors[0].end).toBe(11)
- })
- it('should collect source range for binding keys', () => {
- const compiled = compile('<div><slot v-bind:key="key" /></div>', {
- outputSourceRange: true
- })
- expect(compiled.errors.length).toBe(1)
- expect(compiled.errors[0].start).toBe(11)
- expect(compiled.errors[0].end).toBe(27)
- })
- })
|