2016-06-30 23:01:37 +08:00
|
|
|
import Vue from 'vue'
|
2017-04-18 12:37:36 +08:00
|
|
|
import { compile } from 'web/compiler'
|
2016-06-30 23:01:37 +08:00
|
|
|
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>
|
|
|
|
`,
|
|
|
|
{
|
2018-03-08 22:52:27 +08:00
|
|
|
directives: {
|
|
|
|
validate(el, dir) {
|
|
|
|
if (dir.name === 'validate' && dir.arg) {
|
|
|
|
el.validate = {
|
|
|
|
field: dir.arg,
|
|
|
|
groups: dir.modifiers ? Object.keys(dir.modifiers) : []
|
2022-05-23 17:21:17 +08:00
|
|
|
}
|
2016-06-30 23:01:37 +08:00
|
|
|
}
|
|
|
|
}
|
2018-03-08 22:52:27 +08:00
|
|
|
},
|
|
|
|
modules: [
|
|
|
|
{
|
2017-12-26 00:05:54 +08:00
|
|
|
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 })
|
2022-05-23 17:21:17 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
},
|
2017-12-26 00:05:54 +08:00
|
|
|
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:{
|
2018-03-08 22:52:27 +08:00
|
|
|
field:${JSON.stringify(el.validate.field)},
|
|
|
|
groups:${JSON.stringify(el.validate.groups)},
|
|
|
|
validators:${JSON.stringify(el.validators)},
|
|
|
|
result:${JSON.stringify(result)},
|
|
|
|
child:${code}}
|
|
|
|
})`
|
2022-05-23 17:21:17 +08:00
|
|
|
}
|
2017-12-26 00:05:54 +08:00
|
|
|
}
|
2018-03-08 22:52:27 +08:00
|
|
|
]
|
|
|
|
}
|
|
|
|
)
|
2016-06-30 23:01:37 +08:00
|
|
|
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
|
2018-10-25 00:08:32 +08:00
|
|
|
for (let i = 0; i < this.validators.length; i++) {
|
2016-06-30 23:01:37 +08:00
|
|
|
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)
|
|
|
|
})
|
2016-07-04 03:03:48 +08:00
|
|
|
|
|
|
|
it('should collect errors', () => {
|
|
|
|
let compiled = compile('hello')
|
|
|
|
expect(compiled.errors.length).toBe(1)
|
2016-10-10 04:33:23 +08:00
|
|
|
expect(compiled.errors[0]).toContain('root element')
|
2016-07-04 03:03:48 +08:00
|
|
|
|
|
|
|
compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
|
|
|
|
expect(compiled.errors.length).toBe(2)
|
2017-10-12 23:15:23 +08:00
|
|
|
expect(compiled.errors[0]).toContain('Raw expression: v-if="a----"')
|
|
|
|
expect(compiled.errors[1]).toContain('Raw expression: {{ b++++ }}')
|
2016-07-04 03:03:48 +08:00
|
|
|
})
|
2018-12-22 10:58:32 +08:00
|
|
|
|
|
|
|
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)
|
2019-03-01 22:56:13 +08:00
|
|
|
|
|
|
|
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)
|
2018-12-22 10:58:32 +08:00
|
|
|
})
|
|
|
|
|
|
|
|
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)
|
|
|
|
})
|
2016-06-30 23:01:37 +08:00
|
|
|
})
|