mirror of https://github.com/vuejs/vue.git
				
				
				
			
		
			
				
	
	
		
			129 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			129 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
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++++ }}')
 | 
						|
  })
 | 
						|
})
 |