compiler-options.spec.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import Vue from 'vue'
  2. import { compile } from 'web/compiler'
  3. import { getAndRemoveAttr } from 'compiler/helpers'
  4. describe('compile options', () => {
  5. it('should be compiled', () => {
  6. const { render, staticRenderFns, errors } = compile(`
  7. <div>
  8. <input type="text" v-model="msg" required max="8" v-validate:field1.group1.group2>
  9. </div>
  10. `, {
  11. directives: {
  12. validate (el, dir) {
  13. if (dir.name === 'validate' && dir.arg) {
  14. el.validate = {
  15. field: dir.arg,
  16. groups: dir.modifiers ? Object.keys(dir.modifiers) : []
  17. }
  18. }
  19. }
  20. },
  21. modules: [
  22. {
  23. transformNode (el) {
  24. el.validators = el.validators || []
  25. const validators = ['required', 'min', 'max', 'pattern', 'maxlength', 'minlength']
  26. validators.forEach(name => {
  27. const rule = getAndRemoveAttr(el, name)
  28. if (rule !== undefined) {
  29. el.validators.push({ name, rule })
  30. }
  31. })
  32. },
  33. genData (el) {
  34. let data = ''
  35. if (el.validate) {
  36. data += `validate:${JSON.stringify(el.validate)},`
  37. }
  38. if (el.validators) {
  39. data += `validators:${JSON.stringify(el.validators)},`
  40. }
  41. return data
  42. },
  43. transformCode (el, code) {
  44. // check
  45. if (!el.validate || !el.validators) {
  46. return code
  47. }
  48. // setup validation result props
  49. const result = { dirty: false } // define something other prop
  50. el.validators.forEach(validator => {
  51. result[validator.name] = null
  52. })
  53. // generate code
  54. return `_c('validate',{props:{
  55. field:${JSON.stringify(el.validate.field)},
  56. groups:${JSON.stringify(el.validate.groups)},
  57. validators:${JSON.stringify(el.validators)},
  58. result:${JSON.stringify(result)},
  59. child:${code}}
  60. })`
  61. }
  62. }
  63. ]
  64. })
  65. expect(render).not.toBeUndefined()
  66. expect(staticRenderFns).toEqual([])
  67. expect(errors).toEqual([])
  68. const renderFn = new Function(render)
  69. const vm = new Vue({
  70. data: {
  71. msg: 'hello'
  72. },
  73. components: {
  74. validate: {
  75. props: ['field', 'groups', 'validators', 'result', 'child'],
  76. render (h) {
  77. return this.child
  78. },
  79. computed: {
  80. valid () {
  81. let ret = true
  82. for (let i = 0; i > this.validators.length; i++) {
  83. const { name } = this.validators[i]
  84. if (!this.result[name]) {
  85. ret = false
  86. break
  87. }
  88. }
  89. return ret
  90. }
  91. },
  92. mounted () {
  93. // initialize validation
  94. const value = this.$el.value
  95. this.validators.forEach(validator => {
  96. const ret = this[validator.name](value, validator.rule)
  97. this.result[validator.name] = ret
  98. })
  99. },
  100. methods: {
  101. // something validators logic
  102. required (val) {
  103. return val.length > 0
  104. },
  105. max (val, rule) {
  106. return !(parseInt(val, 10) > parseInt(rule, 10))
  107. }
  108. }
  109. }
  110. },
  111. render: renderFn,
  112. staticRenderFns
  113. }).$mount()
  114. expect(vm.$el.innerHTML).toBe('<input type="text">')
  115. expect(vm.$children[0].valid).toBe(true)
  116. })
  117. it('should collect errors', () => {
  118. let compiled = compile('hello')
  119. expect(compiled.errors.length).toBe(1)
  120. expect(compiled.errors[0]).toContain('root element')
  121. compiled = compile('<div v-if="a----">{{ b++++ }}</div>')
  122. expect(compiled.errors.length).toBe(2)
  123. expect(compiled.errors[0]).toContain('Raw expression: v-if="a----"')
  124. expect(compiled.errors[1]).toContain('Raw expression: {{ b++++ }}')
  125. })
  126. })