You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

128 lines
3.9 KiB

import Vue from 'vue'
import { compile } from 'entries/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 `_h('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('should contain exactly one root element')
compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
expect(compiled.errors.length).toBe(2)
expect(compiled.errors[0]).toContain('invalid expression: v-if="a----"')
expect(compiled.errors[1]).toContain('invalid expression: {{ b++++ }}')
})
})