|
|
@@ -0,0 +1,117 @@
|
|
|
+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)
|
|
|
+ })
|
|
|
+})
|